From 9eec9a6037c96d74cb27a2f8c9bc1cc95017472f Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Fri, 30 Oct 2020 16:12:22 +0100 Subject: [PATCH 01/99] [bugfix][monotonecubicspline] Enable increasing and decreasing values for both function and argument --- dumux/common/monotonecubicspline.hh | 115 ++++++------ .../common/spline/test_monotonecubicspline.cc | 167 ++++++++++-------- 2 files changed, 155 insertions(+), 127 deletions(-) diff --git a/dumux/common/monotonecubicspline.hh b/dumux/common/monotonecubicspline.hh index 9fa462e634..75abcfd61f 100644 --- a/dumux/common/monotonecubicspline.hh +++ b/dumux/common/monotonecubicspline.hh @@ -77,7 +77,7 @@ public: // check some requirements assert (x.size() == y.size()); assert (x.size() >=2); - assert (std::is_sorted(x.begin(), x.end())); + assert (std::is_sorted(x.begin(), x.end()) || std::is_sorted(x.rbegin(), x.rend())); // save a copy of the control points x_ = x; @@ -87,7 +87,8 @@ public: numPoints_ = x.size(); // whether we are increasing - increasing_ = y_.back() > y_.front(); + increasingX_ = x_.back() > x_.front(); + increasingY_ = y_.back() > y_.front(); // the slope at every control point m_.resize(numPoints_); @@ -114,21 +115,12 @@ public: */ Scalar eval(const Scalar x) const { - if (x <= x_.front()) + if ((x <= x_.front() && increasingX_) || (x >= x_.front() && !increasingX_)) return y_.front() + m_.front()*(x - x_.front()); - else if (x > x_.back()) + else if ((x > x_.back() && increasingX_) || (x < x_.back() && !increasingX_)) return y_.back() + m_.back()*(x - x_.back()); - else - { - const auto lookUpIndex = std::distance(x_.begin(), std::lower_bound(x_.begin(), x_.end(), x)); - assert(lookUpIndex != 0); - // interpolate parametrization parameter t in [0,1] - const auto h = (x_[lookUpIndex] - x_[lookUpIndex-1]); - const auto t = (x - x_[lookUpIndex-1])/h; - return y_[lookUpIndex-1]*Basis::h00(t) + h*m_[lookUpIndex-1]*Basis::h10(t) - + y_[lookUpIndex]*Basis::h01(t) + h*m_[lookUpIndex]*Basis::h11(t); - } + return eval_(x); } /*! @@ -138,22 +130,12 @@ public: */ Scalar evalDerivative(const Scalar x) const { - if (x <= x_.front()) + if ((x <= x_.front() && increasingX_) || (x >= x_.front() && !increasingX_)) return m_.front(); - else if (x > x_.back()) + else if ((x > x_.back() && increasingX_) || (x < x_.back() && !increasingX_)) return m_.back(); - else - { - const auto lookUpIndex = std::distance(x_.begin(), std::lower_bound(x_.begin(), x_.end(), x)); - assert(lookUpIndex != 0); - // interpolate parametrization parameter t in [0,1] - const auto h = (x_[lookUpIndex] - x_[lookUpIndex-1]); - const auto t = (x - x_[lookUpIndex-1])/h; - const auto dtdx = 1.0/h; - return y_[lookUpIndex-1]*Basis::dh00(t)*dtdx + m_[lookUpIndex-1]*Basis::dh10(t) - + y_[lookUpIndex]*Basis::dh01(t)*dtdx + m_[lookUpIndex]*Basis::dh11(t); - } + return evalDerivative_(x); } /*! @@ -164,40 +146,39 @@ public: */ Scalar evalInverse(const Scalar y) const { - if (increasing_) - { - if (y <= y_.front()) - return x_.front() + (y - y_.front())/m_.front(); - else if (y > y_.back()) - return x_.back() + (y - y_.back())/m_.back(); - else - { - const auto lookUpIndex = std::distance(y_.begin(), std::lower_bound(y_.begin(), y_.end(), y)); - assert(lookUpIndex != 0); - - return evalInverse_(y, lookUpIndex); - } - } + if ((y <= y_.front() && increasingY_) || (y >= y_.front() && !increasingY_)) + return x_.front() + (y - y_.front())/m_.front(); + else if ((y > y_.back() && increasingY_) || (y < y_.back() && !increasingY_)) + return x_.back() + (y - y_.back())/m_.back(); - else - { - if (y >= y_.front()) - return x_.front() + (y - y_.front())/m_.front(); - else if (y < y_.back()) - return x_.back() + (y - y_.back())/m_.back(); - else - { - const auto lookUpIndex = y_.size() - std::distance(y_.rbegin(), std::lower_bound(y_.rbegin(), y_.rend(), y)); - assert(lookUpIndex != 0); - - return evalInverse_(y, lookUpIndex); - } - } + return evalInverse_(y); } private: - Scalar evalInverse_(const Scalar y, const std::size_t lookUpIndex) const + Scalar eval_(const Scalar x) const { + // interpolate parametrization parameter t in [0,1] + const auto lookUpIndex = lookUpIndex_(x_, x, increasingX_); + const auto h = (x_[lookUpIndex] - x_[lookUpIndex-1]); + const auto t = (x - x_[lookUpIndex-1])/h; + return y_[lookUpIndex-1]*Basis::h00(t) + h*m_[lookUpIndex-1]*Basis::h10(t) + + y_[lookUpIndex]*Basis::h01(t) + h*m_[lookUpIndex]*Basis::h11(t); + } + + Scalar evalDerivative_(const Scalar x) const + { + // interpolate parametrization parameter t in [0,1] + const auto lookUpIndex = lookUpIndex_(x_, x, increasingX_); + const auto h = (x_[lookUpIndex] - x_[lookUpIndex-1]); + const auto t = (x - x_[lookUpIndex-1])/h; + const auto dtdx = 1.0/h; + return y_[lookUpIndex-1]*Basis::dh00(t)*dtdx + m_[lookUpIndex-1]*Basis::dh10(t) + + y_[lookUpIndex]*Basis::dh01(t)*dtdx + m_[lookUpIndex]*Basis::dh11(t); + } + + Scalar evalInverse_(const Scalar y) const + { + const auto lookUpIndex = lookUpIndex_(y_, y, increasingY_); auto localPolynomial = [&](const auto x) { // interpolate parametrization parameter t in [0,1] const auto h = (x_[lookUpIndex] - x_[lookUpIndex-1]); @@ -211,11 +192,31 @@ private: return findScalarRootBrent(x_[lookUpIndex-1]-eps, x_[lookUpIndex]+eps, localPolynomial); } + auto lookUpIndex_(const std::vector& vec, const Scalar v, bool increasing) const + { + return increasing ? lookUpIndexIncreasing_(vec, v) : lookUpIndexDecreasing_(vec, v); + } + + auto lookUpIndexIncreasing_(const std::vector& vec, const Scalar v) const + { + const auto lookUpIndex = std::distance(vec.begin(), std::lower_bound(vec.begin(), vec.end(), v)); + assert(lookUpIndex != 0); + return lookUpIndex; + } + + auto lookUpIndexDecreasing_(const std::vector& vec, const Scalar v) const + { + const auto lookUpIndex = vec.size() - std::distance(vec.rbegin(), std::lower_bound(vec.rbegin(), vec.rend(), v)); + assert(lookUpIndex != 0); + return lookUpIndex; + } + std::vector x_; //!< the x-coordinates std::vector y_; //!< the y-coordinates std::vector m_; //!< the slope for each control point std::size_t numPoints_; //!< the number of control points - bool increasing_; //!< if we are increasing monotone or not + bool increasingX_; //!< if we are increasing monotone or not + bool increasingY_; //!< if we are increasing monotone or not }; } // end namespace Dumux diff --git a/test/common/spline/test_monotonecubicspline.cc b/test/common/spline/test_monotonecubicspline.cc index dc59b47701..04596dcb17 100644 --- a/test/common/spline/test_monotonecubicspline.cc +++ b/test/common/spline/test_monotonecubicspline.cc @@ -45,82 +45,109 @@ int main(int argc, char** argv) { Dune::MPIHelper::instance(argc, argv); - // we test the spline interpolation against a sample function - const auto f = [](double x){ return x*x*x; }; - const auto df = [](double x){ return 3*x*x; }; - - // create some test samples - const auto testPoints = Dumux::linspace(0.0, 4.0, 1000); - const auto ref = eval(f, testPoints); - const auto refDeriv = eval(df, testPoints); - - // create the spline sample points - const auto samplePoints = Dumux::linspace(0.0, 5.0, 10); - const auto y = eval(f, samplePoints); - - // create the spline - Dumux::MonotoneCubicSpline spline(samplePoints, y); - - // evaluate spline and derivative - const auto result = eval([&](const double x) { return spline.eval(x); }, testPoints); - const auto resultDeriv = eval([&](const double x) { return spline.evalDerivative(x); }, testPoints); - - // compute largest difference - auto diff = result; auto diffDeriv = result; - std::transform(result.begin(), result.end(), ref.begin(), diff.begin(), [](auto a, auto b){ return std::abs(a-b); }); - std::transform(resultDeriv.begin(), resultDeriv.end(), refDeriv.begin(), diffDeriv.begin(), [](auto a, auto b){ return std::abs(a-b); }); - const auto maxNorm = std::accumulate(diff.begin(), diff.end(), diff[0], [](auto a, auto b){ return std::max(a, b); }) - /(*std::max_element(ref.begin(), ref.end())); - const auto maxNormDeriv = std::accumulate(diffDeriv.begin(), diffDeriv.end(), diffDeriv[0], [](auto a, auto b){ return std::max(a, b); }) - /(*std::max_element(refDeriv.begin(), refDeriv.end())); - std::cout << "Maximum error: " << maxNorm << "\n"; - std::cout << "Maximum error in derivative: " << maxNormDeriv << "\n"; - - if (maxNorm > 0.0008 || maxNormDeriv > 0.013) - DUNE_THROW(Dune::Exception, "Maximum error in spline interpolation too large!"); - - // test inverse by evaluating (x = f^-1(f(x))) for monotonically increasing function + const auto test = [](auto f, auto df, const auto& testPoints, const auto& samplePoints, const std::string& prefix) { - const auto resultX = eval([&](double x){ return spline.evalInverse(spline.eval(x)); }, testPoints); - auto diffInverse = resultX; - std::transform(resultX.begin(), resultX.end(), testPoints.begin(), diffInverse.begin(), [](auto a, auto b){ return std::abs(a-b); }); - const auto maxNormInverse = std::accumulate(diffInverse.begin(), diffInverse.end(), diffInverse[0], [](auto a, auto b){ return std::max(a, b); }) - /(*std::max_element(testPoints.begin(), testPoints.end())); + // create some test samples + const auto ref = eval(f, testPoints); + const auto refDeriv = eval(df, testPoints); + + // create the spline sample points + const auto y = eval(f, samplePoints); + + // create the spline + Dumux::MonotoneCubicSpline spline(samplePoints, y); + + // evaluate spline and derivative + const auto result = eval([&](const double x) { return spline.eval(x); }, testPoints); + const auto resultDeriv = eval([&](const double x) { return spline.evalDerivative(x); }, testPoints); + + // compute largest difference + auto diff = result; auto diffDeriv = result; + std::transform(result.begin(), result.end(), ref.begin(), diff.begin(), [](auto a, auto b){ return std::abs(a-b); }); + std::transform(resultDeriv.begin(), resultDeriv.end(), refDeriv.begin(), diffDeriv.begin(), [](auto a, auto b){ return std::abs(a-b); }); + const auto maxNorm = std::accumulate(diff.begin(), diff.end(), diff[0], [](auto a, auto b){ return std::max(a, b); }) + /std::abs(*std::max_element(ref.begin(), ref.end(), [](auto a, auto b){ return abs(a) < abs(b); })); + const auto maxNormDeriv = std::accumulate(diffDeriv.begin(), diffDeriv.end(), diffDeriv[0], [](auto a, auto b){ return std::max(a, b); }) + /std::abs(*std::max_element(refDeriv.begin(), refDeriv.end(), [](auto a, auto b){ return abs(a) < abs(b); })); + std::cout << "Maximum error: " << std::scientific << maxNorm << "\n"; + std::cout << "Maximum error in derivative: " << std::scientific << maxNormDeriv << "\n"; + + if (maxNorm > 0.0008 || maxNormDeriv > 0.013) + DUNE_THROW(Dune::Exception, "Maximum error in spline interpolation too large!"); + // test inverse by evaluating (x = f^-1(f(x))) for monotonically increasing function + { + const auto resultX = eval([&](double x){ return spline.evalInverse(spline.eval(x)); }, testPoints); + auto diffInverse = resultX; + std::transform(resultX.begin(), resultX.end(), testPoints.begin(), diffInverse.begin(), [](auto a, auto b){ return std::abs(a-b); }); + const auto maxNormInverse = std::accumulate(diffInverse.begin(), diffInverse.end(), diffInverse[0], [](auto a, auto b){ return std::max(a, b); }) + /std::abs(*std::max_element(testPoints.begin(), testPoints.end(), [](auto a, auto b){ return abs(a) < abs(b); })); + + + std::cout << "Maximum error in identity using the inverse (mon. incr.): " << std::scientific << maxNormInverse << "\n"; + if (maxNormInverse > 1e-13) + DUNE_THROW(Dune::Exception, "Maximum error in spline interpolation too large!"); + } + // test inverse by evaluating (x = f^-1(f(x))) for monotonically decreasing function + { + auto reverseTest = testPoints; + std::reverse(reverseTest.begin(), reverseTest.end()); + const auto resultX = eval([&](double x){ return spline.evalInverse(spline.eval(x)); }, reverseTest); + auto diffInverse = resultX; + std::transform(resultX.begin(), resultX.end(), reverseTest.begin(), diffInverse.begin(), [](auto a, auto b){ return std::abs(a-b); }); + const auto maxNormInverse = std::accumulate(diffInverse.begin(), diffInverse.end(), diffInverse[0], [](auto a, auto b){ return std::max(a, b); }) + /std::abs(*std::max_element(reverseTest.begin(), reverseTest.end(), [](auto a, auto b){ return abs(a) < abs(b); })); + + std::cout << "Maximum error in identity using the inverse (mon. decr.): " << std::scientific << maxNormInverse << "\n"; + if (maxNormInverse > 1e-13) + DUNE_THROW(Dune::Exception, "Maximum error in spline interpolation too large!"); + } + + // plot with Gnuplot (plot a bit more so we can see the linear extension) + const auto plotPoints = Dumux::linspace(-1.0, 5.0, 1000); + const auto refPlot = eval(f, plotPoints); + const auto refDerivPlot = eval(df, plotPoints); + const auto resultPlot = eval([&](const double x) { return spline.eval(x); }, plotPoints); + const auto resultDerivPlot = eval([&](const double x) { return spline.evalDerivative(x); }, plotPoints); + + Dumux::GnuplotInterface gnuplot(/*persist=*/false); + gnuplot.setOpenPlotWindow(false); + gnuplot.addDataSetToPlot(plotPoints, refPlot, prefix + "exp_reference"); + gnuplot.addDataSetToPlot(plotPoints, refDerivPlot, prefix + "exp_reference_derivative"); + gnuplot.addDataSetToPlot(plotPoints, resultPlot, prefix + "monotspline"); + gnuplot.addDataSetToPlot(plotPoints, resultDerivPlot, prefix + "monotspline_derivative"); + gnuplot.plot(prefix + "monotspline"); + }; - std::cout << "Maximum error in identity using the inverse (mon. incr.): " << std::scientific << maxNormInverse << "\n"; - if (maxNormInverse > 1e-13) - DUNE_THROW(Dune::Exception, "Maximum error in spline interpolation too large!"); - } - // test inverse by evaluating (x = f^-1(f(x))) for monotonically decreasing function { - auto reverseTest = testPoints; - std::reverse(reverseTest.begin(), reverseTest.end()); - const auto resultX = eval([&](double x){ return spline.evalInverse(spline.eval(x)); }, reverseTest); - auto diffInverse = resultX; - std::transform(resultX.begin(), resultX.end(), reverseTest.begin(), diffInverse.begin(), [](auto a, auto b){ return std::abs(a-b); }); - const auto maxNormInverse = std::accumulate(diffInverse.begin(), diffInverse.end(), diffInverse[0], [](auto a, auto b){ return std::max(a, b); }) - /(*std::max_element(reverseTest.begin(), reverseTest.end())); - - std::cout << "Maximum error in identity using the inverse (mon. decr.): " << std::scientific << maxNormInverse << "\n"; - if (maxNormInverse > 1e-13) - DUNE_THROW(Dune::Exception, "Maximum error in spline interpolation too large!"); + // we test the spline interpolation against a sample function + // monotonically increasing function + const auto f = [](double x){ return x*x*x; }; + const auto df = [](double x){ return 3*x*x; }; + + const auto testPoints = Dumux::linspace(0.0, 4.0, 1000); + const auto samplePoints = Dumux::linspace(0.0, 5.0, 10); + test(f, df, testPoints, samplePoints, "x3in"); + + const auto testPoints2 = Dumux::linspace(4.0, 0.0, 1000); + const auto samplePoints2 = Dumux::linspace(5.0, 0.0, 10); + test(f, df, testPoints2, samplePoints2, "x3de"); } - // plot with Gnuplot (plot a bit more so we can see the linear extension) - const auto plotPoints = Dumux::linspace(-1.0, 5.0, 1000); - const auto refPlot = eval(f, plotPoints); - const auto refDerivPlot = eval(df, plotPoints); - const auto resultPlot = eval([&](const double x) { return spline.eval(x); }, plotPoints); - const auto resultDerivPlot = eval([&](const double x) { return spline.evalDerivative(x); }, plotPoints); - - Dumux::GnuplotInterface gnuplot(/*persist=*/false); - gnuplot.setOpenPlotWindow(false); - gnuplot.addDataSetToPlot(plotPoints, refPlot, "exp_reference"); - gnuplot.addDataSetToPlot(plotPoints, refDerivPlot, "exp_reference_derivative"); - gnuplot.addDataSetToPlot(plotPoints, resultPlot, "monotspline"); - gnuplot.addDataSetToPlot(plotPoints, resultDerivPlot, "monotspline_derivative"); - gnuplot.plot("monotspline"); + { + // we test the spline interpolation against a sample function + // monotonically decreasing function + const auto f = [](double x){ return -x*x*x; }; + const auto df = [](double x){ return -3*x*x; }; + + const auto testPoints = Dumux::linspace(0.0, 4.0, 1000); + const auto samplePoints = Dumux::linspace(0.0, 5.0, 10); + test(f, df, testPoints, samplePoints, "mx3in"); + + const auto testPoints2 = Dumux::linspace(4.0, 0.0, 1000); + const auto samplePoints2 = Dumux::linspace(5.0, 0.0, 10); + test(f, df, testPoints2, samplePoints2, "mx3de"); + } return 0; } -- GitLab From 16c922b5bb84d83b3f2cd4908cc3b8c55a9004b4 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 7 Oct 2020 16:53:18 +0200 Subject: [PATCH 02/99] [fluidmatrixinteraction] Add common class --- .../fluidmatrixinteraction.hh | 254 ++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh diff --git a/dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh b/dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh new file mode 100644 index 0000000000..c5291d14f7 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh @@ -0,0 +1,254 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Wrapper type to combine an arbitrary number of different laws + * for fluid-matrix interaction (e.g., pc-Sw-curves). + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_INTERACTIONS_FLUIDMATRIX_INTERACTION_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_INTERACTIONS_FLUIDMATRIX_INTERACTION_HH + +#include +#include + +namespace Dumux { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper type to combine an arbitrary number of different laws + * for fluid-matrix interaction (e.g., pc-Sw-curves). + */ +template +struct FluidMatrixInteraction : public Laws... +{ + FluidMatrixInteraction(Laws&&... laws) : Laws(std::forward(laws))... {} +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Helper function to create an FluidMatrixInteraction object containing an arbitrary number + * of fluid matrix interaction laws (e.g., pc-Sw curves and interfacial area laws). + * To be used in the spatial parameters. + */ +template +auto makeFluidMatrixInteraction(Laws&&... laws) +{ + return FluidMatrixInteraction(wrap(std::forward(laws))...); +} + +} // end namespace Dumux + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Adapter to inherit from, allowing the inheriting class to be wrapped + * by the @ref makeFluidMatrixInteraction function. + */ +template class Wrapper> +struct Adapter +{ + template>, int> = 0> + friend auto wrap(T&& t) { return Wrapper(std::forward(t)); } +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper type for laws providing pc-Sw and kr-Sw rules. + */ +template +class PcKrSw +{ +public: + using Scalar = typename std::decay_t::Scalar; + + using PcKrSwType = const T; + + PcKrSw(T&& impl) : impl_(std::forward(impl)) {} + + Scalar pc(const Scalar sw) const { return impl_.pc(sw); } + Scalar dpc_dsw(const Scalar sw) const { return impl_.dpc_dsw(sw); } + Scalar endPointPc() const { return impl_.endPointPc(); } + Scalar sw(const Scalar pc) const { return impl_.sw(pc); } + Scalar dsw_dpc(const Scalar pc) const { return impl_.dsw_dpc(pc); } + Scalar krw(const Scalar sw) const { return impl_.krw(sw); } + Scalar dkrw_dsw(const Scalar sw) const { return impl_.dkrw_dsw(sw); } + Scalar krn(const Scalar sw) const { return impl_.krn(sw); } + Scalar dkrn_dsw(const Scalar sw) const { return impl_.dkrn_dsw(sw); } + + const T& pcSwCurve() const { return impl_; } + const T& krSwCurve() const { return impl_; } + +private: + const T impl_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Deduction guide for the PcKrSw class. + * Makes sure that PcKrSw stores a copy of T if + * the constructor is called with a temporary object. + */ +template +PcKrSw(T&&) -> PcKrSw; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper type for multiphase interface laws providing pc-S and kr-S rules. + */ +template +class MultiPhasePcKrSw +{ +public: + using Scalar = typename std::decay_t::Scalar; + + MultiPhasePcKrSw(T&& impl) : impl_(std::forward(impl)) {} + + template + auto capillaryPressures(const FS& fs, int wp) const { return impl_.capillaryPressures(fs, wp); } + template + auto relativePermeabilities(const FS& fs, int wp) const { return impl_.relativePermeabilities(fs, wp); } + + const T& multiPhasePcKrS() const { return impl_; } + +private: + const T impl_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Deduction guide for the MultiPhasePcKrSw class. + * Makes sure that MultiPhasePcKrSw stores a copy of T if + * the constructor is called with a temporary object. + */ +template +MultiPhasePcKrSw(T&&) -> MultiPhasePcKrSw; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper type for 3p interface laws providing pc-S and kr-S rules. + */ +template +struct ThreePhasePcKrSw +{ + using Scalar = typename std::decay_t::Scalar; + using value_type = const T; + + using PcKrSwType = const T; + + ThreePhasePcKrSw(T&& impl) : impl_(std::forward(impl)) {} + + Scalar pcgw(const Scalar sw, const Scalar sn) const { return impl_.pcgw(sw, sn); } + Scalar pcnw(const Scalar sw, const Scalar sn) const { return impl_.pcnw(sw, sn); } + Scalar pcgn(const Scalar sw, const Scalar sn) const { return impl_.pcgn(sw, sn); } + Scalar pcAlpha(const Scalar sw, const Scalar sn) const { return impl_.pcAlpha(sw, sn); } + + Scalar krw(const Scalar sw, const Scalar sn) const { return impl_.krw(sw, sn); } + Scalar krn(const Scalar sw, const Scalar sn) const { return impl_.krn(sw, sn); } + Scalar krg(const Scalar sw, const Scalar sn) const { return impl_.krn(sw, sn); } + Scalar kr(const int phaseIdx, const Scalar sw, const Scalar sn) const { return impl_.kr(phaseIdx, sw, sn); } + + const T& pcSwCurve() const { return impl_; } + const T& krSwCurve() const { return impl_; } +private: + const T impl_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Deduction guide for the ThreePhasePcKrSw class. + * Makes sure that ThreePhasePcKrSw stores a copy of T if + * the constructor is called with a temporary object. + */ +template +ThreePhasePcKrSw(T&&) -> ThreePhasePcKrSw; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper type for laws providing rules for the wetting-nonwetting interfacial area. + */ +template +class WettingNonwettingInterfacialAreaPcSw +{ +public: + WettingNonwettingInterfacialAreaPcSw(T&& impl) : impl_(std::forward(impl)) {} + const T& wettingNonwettingInterface() const { return impl_; } +private: + const T impl_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Deduction guide for the WettingNonwettingInterfacialAreaPcSw class. + * Makes sure that WettingNonwettingInterfacialAreaPcSw stores a copy of T if + * the constructor is called with a temporary object. + */ +template +WettingNonwettingInterfacialAreaPcSw(T&&) -> WettingNonwettingInterfacialAreaPcSw; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper type for laws providing rules for the wetting-solid interfacial area. + */ +template +class WettingSolidInterfacialAreaPcSw +{ +public: + WettingSolidInterfacialAreaPcSw(T&& impl) : impl_(std::forward(impl)) {} + const T& wettingSolidInterface() const { return impl_; } +private: + const T impl_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Deduction guide for the WettingSolidInterfacialAreaPcSw class. + * Makes sure that WettingSolidInterfacialAreaPcSw stores a copy of T if + * the constructor is called with a temporary object. + */ +template +WettingSolidInterfacialAreaPcSw(T&&) -> WettingSolidInterfacialAreaPcSw; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper type for laws providing rules for the nonwetting-solid interfacial area. + */ +template +class NonwettingSolidInterfacialAreaPcSw +{ +public: + NonwettingSolidInterfacialAreaPcSw(T&& impl) : impl_(std::forward(impl)) {} + const T& nonwettingSolidInterface() const { return impl_; } +private: + const T impl_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Deduction guide for the NonwettingSolidInterfacialAreaPcSw class. + * Makes sure that NonwettingSolidInterfacialAreaPcSw stores a copy of T if + * the constructor is called with a temporary object. + */ +template +NonwettingSolidInterfacialAreaPcSw(T&&) -> NonwettingSolidInterfacialAreaPcSw; + +} // end namespace Dumux::FluidMatrix + +#endif -- GitLab From b0084e7edf3320ca6cee3ae38a5421b4aa75ea91 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 14 Oct 2020 10:40:24 +0200 Subject: [PATCH 03/99] [fluidmatrixinteraction] Add NoRegularization header --- .../2p/noregularization.hh | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/2p/noregularization.hh diff --git a/dumux/material/fluidmatrixinteractions/2p/noregularization.hh b/dumux/material/fluidmatrixinteractions/2p/noregularization.hh new file mode 100644 index 0000000000..24036477d1 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/noregularization.hh @@ -0,0 +1,45 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief A tag to turn off regularization and it's overhead + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWOP_NO_REGULARIZATION_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_TWOP_NO_REGULARIZATION_HH + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A tag to turn off regularization and it's overhead + */ +struct NoRegularization +{ + //! Empty parameter structure + template struct Params {}; + + //! We are always equal to other instances of our kind + bool operator== (const NoRegularization& o) const + { return true; } +}; + +} // end namespace Dumux::FluidMatrix + +#endif -- GitLab From 20c52fb258edf430cfe2c0f1ceb9d5fb4ccd428d Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Tue, 13 Oct 2020 11:50:16 +0200 Subject: [PATCH 04/99] [fluidmatrixinteractions][2p] Add MaterialLaw class to wrap base laws --- .../fluidmatrixinteractions/2p/materiallaw.hh | 278 ++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/2p/materiallaw.hh diff --git a/dumux/material/fluidmatrixinteractions/2p/materiallaw.hh b/dumux/material/fluidmatrixinteractions/2p/materiallaw.hh new file mode 100644 index 0000000000..6a9b098725 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/materiallaw.hh @@ -0,0 +1,278 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Implementation helper for capillary pressure and + * relative permeability <-> saturation relations for two-phase models + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWOP_MATERIAL_LAW_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_TWOP_MATERIAL_LAW_HH + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper class to implement regularized material laws (pc-sw, kr-sw) + * with a conversion policy between absolution and effective saturations + * \note See vangenuchten.hh / brookscorey.hh for default configurations using this class + * \tparam ScalarType the scalar type + * \tparam BaseLaw the base law (e.g. VanGenuchten, BrooksCorey, Linear, ...) + * \tparam Regularization the regularization type (set to NoRegularization to turn it off) + * \tparam EffToAbsPolicy the policy how to convert effective <-> absolute saturations + * + * \note The regularization interface is expected to return Dumux::OptionalScalars which + * are wrappers around a Scalar type that provide a boolean operator to + * check whether the result is valid. If the regularization returns + * a non-valid value, it means that the given parameter + * range is outside the regularized region. + * For that case we forward to the call to the standard law. + */ +template +class TwoPMaterialLaw : public Adapter, PcKrSw> +{ +public: + + using Scalar = ScalarType; + + using BasicParams = typename BaseLaw::template Params; + using EffToAbsParams = typename EffToAbsPolicy::template Params; + using RegularizationParams = typename Regularization::template Params; + + using EffToAbs = EffToAbsPolicy; + + /*! + * \brief Return the number of fluid phases + */ + static constexpr int numFluidPhases() + { return 2; } + + /*! + * \brief Return whether this law is regularized + */ + static constexpr bool isRegularized() + { return !std::is_same::value; } + + /*! + * \brief Deleted default constructor (so we are never in an undefined state) + * \note store owning pointers to laws instead if you need default-constructible objects + */ + TwoPMaterialLaw() = delete; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + explicit TwoPMaterialLaw(const std::string& paramGroup) + : basicParams_(BaseLaw::template makeParams(paramGroup)) + , effToAbsParams_(EffToAbs::template makeParams(paramGroup)) + { + if constexpr (isRegularized()) + regularization_.init(this, paramGroup); + } + + /*! + * \brief Construct from parameter structs + * \note More efficient constructor but you need to ensure all parameters are initialized + */ + TwoPMaterialLaw(const BasicParams& baseParams, + const EffToAbsParams& effToAbsParams = {}, + const RegularizationParams& regParams = {}) + : basicParams_(baseParams) + , effToAbsParams_(effToAbsParams) + { + if constexpr (isRegularized()) + regularization_.init(this, baseParams, effToAbsParams, regParams); + } + + /*! + * \brief The capillary pressure-saturation curve + */ + template + Scalar pc(const Scalar sw) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.pc(swe); + if (regularized) + return regularized.value(); + } + + return BaseLaw::pc(swe, basicParams_); + } + + /*! + * \brief The partial derivative of the capillary pressure w.r.t. the saturation + */ + template + Scalar dpc_dsw(const Scalar sw) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.dpc_dswe(swe); + if (regularized) + return regularized.value()*EffToAbs::dswe_dsw(effToAbsParams_); + } + + return BaseLaw::dpc_dswe(swe, basicParams_)*EffToAbs::dswe_dsw(effToAbsParams_); + } + + /*! + * \brief The capillary pressure at Swe = 1.0 also called end point capillary pressure + */ + Scalar endPointPc() const + { + return BaseLaw::endPointPc(basicParams_); + } + + /*! + * \brief The saturation-capillary pressure curve + */ + template + Scalar sw(const Scalar pc) const + { + if constexpr (enableRegularization) + { + const auto regularized = regularization_.swe(pc); + if (regularized) + return EffToAbs::sweToSw(regularized.value(), effToAbsParams_); + } + + return EffToAbs::sweToSw(BaseLaw::swe(pc, basicParams_), effToAbsParams_); + } + + /*! + * \brief The partial derivative of the saturation to the capillary pressure + */ + template + Scalar dsw_dpc(const Scalar pc) const + { + if constexpr (enableRegularization) + { + const auto regularized = regularization_.dswe_dpc(pc); + if (regularized) + return regularized.value()*EffToAbs::dsw_dswe(effToAbsParams_); + } + + return BaseLaw::dswe_dpc(pc, basicParams_)*EffToAbs::dsw_dswe(effToAbsParams_); + } + + /*! + * \brief The relative permeability for the wetting phase + */ + template + Scalar krw(const Scalar sw) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.krw(swe); + if (regularized) + return regularized.value(); + } + + return BaseLaw::krw(swe, basicParams_); + } + + /*! + * \brief The derivative of the relative permeability for the wetting phase w.r.t. saturation + */ + template + Scalar dkrw_dsw(const Scalar sw) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.dkrw_dswe(swe); + if (regularized) + return regularized.value()*EffToAbs::dswe_dsw(effToAbsParams_); + } + + return BaseLaw::dkrw_dswe(swe, basicParams_)*EffToAbs::dswe_dsw(effToAbsParams_); + } + + /*! + * \brief The relative permeability for the non-wetting phase + */ + template + Scalar krn(const Scalar sw) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.krn(swe); + if (regularized) + return regularized.value(); + } + + return BaseLaw::krn(swe, basicParams_); + } + + /*! + * \brief The derivative of the relative permeability for the non-wetting phase w.r.t. saturation + */ + template + Scalar dkrn_dsw(const Scalar sw) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.dkrn_dswe(swe); + if (regularized) + return regularized.value()*EffToAbs::dswe_dsw(effToAbsParams_); + } + + return BaseLaw::dkrn_dswe(swe, basicParams_)*EffToAbs::dswe_dsw(effToAbsParams_); + } + + /*! + * \brief Equality comparison with another instance + */ + bool operator== (const TwoPMaterialLaw& o) const + { + return basicParams_ == o.basicParams_ + && effToAbsParams_ == o.effToAbsParams_ + && regularization_ == o.regularization_; + } + + const BasicParams& basicParams() const + { return basicParams_; } + + const EffToAbsParams& effToAbsParams() const + { return effToAbsParams_; } + +private: + BasicParams basicParams_; + EffToAbsParams effToAbsParams_; + Regularization regularization_; +}; + +} // end namespace Dumux::FluidMatrix + +#endif -- GitLab From 52f03465bd87a9bb7353d327d16731b1d561a758 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Sun, 19 May 2019 16:04:24 +0200 Subject: [PATCH 05/99] [fluidmatrixinteractions][2p] Add efftoAbsDefaultPolicy --- .../2p/efftoabsdefaultpolicy.hh | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/2p/efftoabsdefaultpolicy.hh diff --git a/dumux/material/fluidmatrixinteractions/2p/efftoabsdefaultpolicy.hh b/dumux/material/fluidmatrixinteractions/2p/efftoabsdefaultpolicy.hh new file mode 100644 index 0000000000..c0af48e267 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/efftoabsdefaultpolicy.hh @@ -0,0 +1,166 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief This is a policy for 2p material laws how to convert absolute to relative + * saturations and vice versa. + * + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWOP_EFF_TO_ABS_DEFAULT_POLICY_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_TWOP_EFF_TO_ABS_DEFAULT_POLICY_HH + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * + * \brief This is a policy for 2p material laws how to convert absolute to relative + * saturations and vice versa. + * + * Material laws (like VanGenuchten or BrooksCorey) are defined for effective saturations. + * The numeric calculations however are performed with absolute saturations. The policy class converts + * the saturations. This allows for changing the calculation of the effective + * saturations easily, as this is subject of discussion / may be problem specific. + */ +class TwoPEffToAbsDefaultPolicy +{ +public: + /*! + * \brief The parameter type + * \tparam Scalar The scalar type + * \note The efftoabs policy need two parameters: \f$\mathrm{S_{w,r}}, \mathrm{S_{n,r}}\f$. + * For the respective formulas check out the description of the free function. + */ + template + struct Params + { + Params(const Scalar swr = 0.0, const Scalar snr = 0.0) + : swr_(swr), snr_(snr) + {} + + /*! + * \brief Return the residual wetting saturation. + */ + Scalar swr() const + { return swr_; } + + /*! + * \brief Set the residual wetting saturation. + */ + void setSwr(Scalar v) + { swr_ = v; } + + /*! + * \brief Return the residual non-wetting saturation. + */ + Scalar snr() const + { return snr_; } + + /*! + * \brief Set the residual non-wetting saturation. + */ + void setSnr(Scalar v) + { snr_ = v; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(swr(), p.swr(), 1e-6) + && Dune::FloatCmp::eq(snr(), p.snr(), 1e-6); + } + private: + Scalar swr_; + Scalar snr_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + Params params; + params.setSwr(getParamFromGroup(paramGroup, "Swr", 0.0)); + params.setSnr(getParamFromGroup(paramGroup, "Snr", 0.0)); + return params; + } + + /*! + * \brief Convert an absolute wetting saturation to an effective one. + * + * \param sw Absolute saturation of the wetting phase \f$\mathrm{[{S}_w]}\f$. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Effective saturation of the wetting phase. + */ + template + static Scalar swToSwe(const Scalar sw, const Params& params) + { + return (sw - params.swr())/(1.0 - params.swr() - params.snr()); + } + + /*! + * \brief Convert an effective wetting saturation to an absolute one. + * + * \param swe Effective saturation of the non-wetting phase \f$\mathrm{[\overline{S}_n]}\f$. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Absolute saturation of the non-wetting phase. + */ + template + static Scalar sweToSw(const Scalar swe, const Params& params) + { + return swe*(1.0 - params.swr() - params.snr()) + params.swr(); + } + + /*! + * \brief Derivative of the effective saturation w.r.t. the absolute saturation. + * + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Derivative of the effective saturation w.r.t. the absolute saturation. + */ + template + static Scalar dswe_dsw(const Params& params) + { + return 1.0/(1.0 - params.swr() - params.snr()); + } + + /*! + * \brief Derivative of the absolute saturation w.r.t. the effective saturation. + * + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Derivative of the absolute saturation w.r.t. the effective saturation. + */ + template + static Scalar dsw_dswe(const Params& params) + { + return 1.0 - params.swr() - params.snr(); + } +}; + +} // end namespace Dumux::FluidMatrix + +#endif -- GitLab From 976f3b62a1988fdfb133de4c8bae8f66588ee5f6 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 24 Sep 2020 00:39:47 +0200 Subject: [PATCH 06/99] [fluidmatrixinteractions][2p] Add new implementation of BrooksCorey --- .../fluidmatrixinteractions/2p/brookscorey.hh | 509 +++++++++++++++++- 1 file changed, 506 insertions(+), 3 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2p/brookscorey.hh b/dumux/material/fluidmatrixinteractions/2p/brookscorey.hh index 19cfc930bc..a69963c302 100644 --- a/dumux/material/fluidmatrixinteractions/2p/brookscorey.hh +++ b/dumux/material/fluidmatrixinteractions/2p/brookscorey.hh @@ -22,9 +22,10 @@ * \brief Implementation of the capillary pressure and * relative permeability <-> saturation relations according to Brooks and Corey. */ -#ifndef DUMUX_BROOKS_COREY_HH -#define DUMUX_BROOKS_COREY_HH +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_BROOKS_COREY_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_BROOKS_COREY_HH +// remove from here after release 3.3 ///////////// #include "brookscoreyparams.hh" #include @@ -45,7 +46,7 @@ namespace Dumux { *\see BrooksCoreyParams */ template > -class BrooksCorey +class [[deprecated("Use new material laws and FluidMatrix::BrooksCorey instead!")]] BrooksCorey { public: using Params = ParamsT; @@ -272,5 +273,507 @@ public: }; } // end namespace Dumux +// remove until here after release 3.3 ///////////// + +#include +#include + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * + * \brief Implementation of the Brooks-Corey capillary pressure <-> + * saturation relation. This class bundles the "raw" curves + * as static members and doesn't concern itself converting + * absolute to effective saturations and vice versa. + * + * For general info: EffToAbsLaw + * + *\see BrooksCoreyParams + */ +class BrooksCorey +{ +public: + /*! + * \brief The parameter type + * \tparam Scalar The scalar type + * \note The Brooks Corey laws are parameterized with two parameters: \f$\mathrm{p_{ce}, \lambda}\f$, + * the capillary entry pressure in \f$\mathrm{[Pa]}\f$] and a dimensionless shape parameter, respectively. + */ + template + struct Params + { + Params(Scalar pcEntry, Scalar lambda) + : pcEntry_(pcEntry), lambda_(lambda) + {} + + Scalar pcEntry() const{ return pcEntry_; } + void setPcEntry(Scalar pcEntry){ pcEntry_ = pcEntry; } + + Scalar lambda() const { return lambda_; } + void setLambda(Scalar lambda) { lambda_ = lambda; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(pcEntry(), p.pcEntry(), 1e-6) + && Dune::FloatCmp::eq(lambda(), p.lambda(), 1e-6); + } + + private: + Scalar pcEntry_, lambda_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + const auto pcEntry = getParamFromGroup(paramGroup, "BrooksCoreyPcEntry"); + const auto lambda = getParamFromGroup(paramGroup, "BrooksCoreyLambda"); + return {pcEntry, lambda}; + } + + /*! + * \brief The capillary pressure-saturation curve according to Brooks & Corey. + * + * The Brooks-Corey empirical capillary pressure <-> saturation + * function is given by + * + * \f$\mathrm{ p_c = p_{ce}\overline{S}_w^{-1/\lambda} + * }\f$ + * + * \param swe Effective saturation of the wetting phase \f$\mathrm{[\overline{S}_w]}\f$ + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Capillary pressure calculated by Brooks & Corey constitutive relation. + * + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar pc(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + return params.pcEntry()*pow(swe, -1.0/params.lambda()); + } + + /*! + * \brief The saturation-capillary pressure curve according to Brooks & Corey. + * + * This is the inverse of the capillary pressure-saturation curve: + * \f$\mathrm{ \overline{S}_w = (\frac{p_c}{p_{ce}})^{-\lambda}}\f$ + * + * \param pc Capillary pressure \f$\mathrm{[p_c]}\f$ in \f$\mathrm{[Pa]}\f$. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, and then the params container + * is constructed accordingly. Afterwards the values are set there, too. + * \return Effective wetting phase saturation calculated as inverse of BrooksCorey constitutive relation. + * + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar swe(Scalar pc, const Params& params) + { + using std::pow; + using std::max; + + pc = max(pc, 0.0); // the equation below is undefined for negative pcs + + return pow(pc/params.pcEntry(), -params.lambda()); + } + + /*! + * \brief The capillary pressure at Swe = 1.0 also called end point capillary pressure + * + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, and then the params container + * is constructed accordingly. Afterwards the values are set there, too. + */ + template + static Scalar endPointPc(const Params& params) + { return params.pcEntry(); } + + /*! + * \brief The partial derivative of the capillary + * pressure w.r.t. the effective saturation according to Brooks & Corey. + * + * This is equivalent to + * \f$\mathrm{\frac{\partial p_c}{\partial \overline{S}_w} = + * -\frac{p_{ce}}{\lambda} \overline{S}_w^{-1/\lambda - 1} + * }\f$ + * + * \param swe Effective saturation of the wetting phase \f$\mathrm{[\overline{S}_w]}\f$ + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, and then the params container + * is constructed accordingly. Afterwards the values are set there, too. + * \return Partial derivative of \f$\mathrm{[p_c]}\f$ w.r.t. effective saturation according to Brooks & Corey. + * + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar dpc_dswe(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + return -params.pcEntry()/params.lambda() * pow(swe, -1.0/params.lambda() - 1.0); + } + + /*! + * \brief The partial derivative of the effective + * saturation w.r.t. the capillary pressure according to Brooks & Corey. + * + * \param pc Capillary pressure \f$\mathrm{[p_c]}\f$ in \f$\mathrm{[Pa]}\f$. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, and then the params container + * is constructed accordingly. Afterwards the values are set there, too. + * \return Partial derivative of effective saturation w.r.t. \f$\mathrm{[p_c]}\f$ according to Brooks & Corey. + * + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar dswe_dpc(Scalar pc, const Params& params) + { + using std::pow; + using std::max; + + pc = max(pc, 0.0); // the equation below is undefined for negative pcs + + return -params.lambda()/params.pcEntry() * pow(pc/params.pcEntry(), - params.lambda() - 1.0); + } + + /*! + * \brief The relative permeability for the wetting phase of + * the medium implied by the Brooks-Corey + * parameterization. + * + * \param swe The mobile saturation of the wetting phase. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Relative permeability of the wetting phase calculated as implied by Brooks & Corey. + * + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar krw(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + return pow(swe, 2.0/params.lambda() + 3.0); + } + + /*! + * \brief The derivative of the relative permeability for the + * wetting phase with regard to the wetting saturation of the + * medium implied by the Brooks-Corey parameterization. + * + * \param swe The mobile saturation of the wetting phase. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Derivative of the relative permeability of the wetting phase w.r.t. effective wetting phase + * saturation calculated as implied by Brooks & Corey. + * + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar dkrw_dswe(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + return (2.0/params.lambda() + 3.0)*pow(swe, 2.0/params.lambda() + 2.0); + } + + /*! + * \brief The relative permeability for the non-wetting phase of + * the medium as implied by the Brooks-Corey + * parameterization. + * + * \param swe The mobile saturation of the wetting phase. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, and then the params container + * is constructed accordingly. Afterwards the values are set there, too. + * \return Relative permeability of the non-wetting phase calculated as implied by Brooks & Corey. + * + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar krn(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + const Scalar exponent = 2.0/params.lambda() + 1.0; + const Scalar sne = 1.0 - swe; + return sne*sne*(1.0 - pow(swe, exponent)); + } + + /*! + * \brief The derivative of the relative permeability for the + * non-wetting phase in regard to the wetting saturation of + * the medium as implied by the Brooks-Corey + * parameterization. + * + * \param swe The mobile saturation of the wetting phase. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Derivative of the relative permeability of the non-wetting phase w.r.t. effective wetting phase + * saturation calculated as implied by Brooks & Corey. + * + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar dkrn_dswe(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + const auto lambdaInv = 1.0/params.lambda(); + const auto swePow = pow(swe, 2*lambdaInv); + return 2.0*(swe - 1.0)*(1.0 + (0.5 + lambdaInv)*swePow - (1.5 + lambdaInv)*swePow*swe); + } +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A regularization for the BrooksCorey material law + * \note Regularization can be turned of by setting the threshold parameters + * out of range (runtime) or by replacing + * this class by NoRegularization (compile time). + */ +template +class BrooksCoreyRegularization +{ +public: + //! Regularization parameters + template + struct Params + { + Params(S pcLowSwe = 0.01) : pcLowSwe_(pcLowSwe) {} + + S pcLowSwe() const { return pcLowSwe_; } + void setPcLowSwe(S pcLowSwe) { pcLowSwe_ = pcLowSwe; } + + private: + S pcLowSwe_ = 0.01; + }; + + //! Initialize the spline + template + void init(const MaterialLaw* m, const std::string& paramGroup) + { + pcLowSwe_ = getParamFromGroup(paramGroup, "BrooksCoreyPcLowSweThreshold", 0.01); + entryPressure_ = getParamFromGroup(paramGroup, "BrooksCoreyPcEntry"); + + initPcParameters_(m, pcLowSwe_); + } + + template + void init(const MaterialLaw* m, const BaseParams& bp, const EffToAbsParams& etap, const Params& p) + { + pcLowSwe_ = p.pcLowSwe(); + entryPressure_ = bp.pcEntry(); + + initPcParameters_(m, pcLowSwe_); + } + + /*! + * \brief Equality comparison with another instance + */ + bool operator== (const BrooksCoreyRegularization& o) const + { + return Dune::FloatCmp::eq(pcLowSwe_, o.pcLowSwe_, 1e-6) + && Dune::FloatCmp::eq(entryPressure_, o.entryPressure_, 1e-6); + } + + /*! + * \brief The regularized capillary pressure-saturation curve + * regularized part: + * - low saturation: extend the \f$\mathrm{p_c(S_w)}\f$ curve with the slope at the regularization point (i.e. no kink). + * - high saturation: connect the high regularization point with \f$\mathrm{\overline{S}_w =1}\f$ + * with a spline and continue linearly for \f$\mathrm{\overline{S}_w > 1}\f$ + */ + OptionalScalar pc(const Scalar swe) const + { + // make sure that the capillary pressure observes a derivative + // != 0 for 'illegal' saturations. This is favourable for the + // newton solver (if the derivative is calculated numerically) + // in order to get the saturation moving to the right + // direction if it temporarily is in an 'illegal' range. + if (swe <= pcLowSwe_) + return pcLowSwePcValue_ + pcDerivativeLowSw_*(swe - pcLowSwe_); + + else if (swe > 1.0) + return pcDerivativeHighSwEnd_*(swe - 1.0) + entryPressure_; + + else + return {}; // no regularization + } + + /*! + * \brief The regularized partial derivative of the capillary pressure w.r.t. the saturation + */ + OptionalScalar dpc_dswe(const Scalar swe) const + { + if (swe < pcLowSwe_) + return pcDerivativeLowSw_; + + else if (swe > 1.0) + return pcDerivativeHighSwEnd_; + + else + return {}; // no regularization + } + + /*! + * \brief The regularized saturation-capillary pressure curve + */ + OptionalScalar swe(const Scalar pc) const + { + if (pc <= entryPressure_) + return 1.0 + (pc - entryPressure_)/pcDerivativeHighSwEnd_; + + else if (pc >= pcLowSwePcValue_) + return (pc - pcLowSwePcValue_)/pcDerivativeLowSw_ + pcLowSwe_; + + else + return {}; // no regularization + } + + /*! + * \brief The regularized partial derivative of the saturation to the capillary pressure + */ + OptionalScalar dswe_dpc(const Scalar pc) const + { + if (pc <= entryPressure_) + return 1.0/pcDerivativeHighSwEnd_; + + else if (pc >= pcLowSwePcValue_) + return 1.0/pcDerivativeLowSw_; + + else + return {}; // no regularization + } + + /*! + * \brief The regularized relative permeability for the wetting phase + */ + OptionalScalar krw(const Scalar swe) const + { + if (swe <= 0.0) + return 0.0; + else if (swe >= 1.0) + return 1.0; + else + return {}; // no regularization + } + + /*! + * \brief The regularized derivative of the relative permeability for the wetting phase w.r.t. saturation + */ + OptionalScalar dkrw_dswe(const Scalar swe) const + { + if (swe < 0.0) + return 0.0; + else if (swe >= 1.0) + return 0.0; + else + return {}; // no regularization + } + + /*! + * \brief The regularized relative permeability for the non-wetting phase + */ + OptionalScalar krn(const Scalar swe) const + { + if (swe <= 0.0) + return 1.0; + else if (swe >= 1.0) + return 0.0; + else + return {}; // no regularization + } + + /*! + * \brief The regularized derivative of the relative permeability for the non-wetting phase w.r.t. saturation + */ + OptionalScalar dkrn_dswe(const Scalar swe) const + { + if (swe <= 0.0) + return 0.0; + else if (swe >= 1.0) + return 0.0; + else + return {}; // no regularization + } + +private: + template + void initPcParameters_(const MaterialLaw* m, const Scalar lowSwe) + { + const auto lowSw = MaterialLaw::EffToAbs::sweToSw(lowSwe, m->effToAbsParams()); + const auto highSw = MaterialLaw::EffToAbs::sweToSw(1.0, m->effToAbsParams()); + const auto dsw_dswe = MaterialLaw::EffToAbs::dsw_dswe(m->effToAbsParams()); + pcDerivativeLowSw_ = m->template dpc_dsw(lowSw)*dsw_dswe; + pcDerivativeHighSwEnd_ = m->template dpc_dsw(highSw)*dsw_dswe; + pcLowSwePcValue_ = m->template pc(lowSw); + } + + Scalar pcLowSwe_; + Scalar pcLowSwePcValue_; + Scalar entryPressure_; + Scalar pcDerivativeLowSw_; + Scalar pcDerivativeHighSwEnd_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A default configuration for using the VanGenuchten material law + */ +template +using BrooksCoreyDefault = TwoPMaterialLaw, TwoPEffToAbsDefaultPolicy>; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A default configuration without regularization for using the VanGenuchten material law + */ +template +using BrooksCoreyNoReg = TwoPMaterialLaw; + +} // end namespace Dumux::FluidMatrix #endif -- GitLab From 46bc6ad81410fdea33aa92cc3dd77173604d0828 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 13 Oct 2020 11:48:53 +0200 Subject: [PATCH 07/99] [fluidmatrixinteractions][2p] Add new implementation of VanGenuchten --- .../2p/vangenuchten.hh | 629 +++++++++++++++++- 1 file changed, 626 insertions(+), 3 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2p/vangenuchten.hh b/dumux/material/fluidmatrixinteractions/2p/vangenuchten.hh index 0f124f0699..323aac975d 100644 --- a/dumux/material/fluidmatrixinteractions/2p/vangenuchten.hh +++ b/dumux/material/fluidmatrixinteractions/2p/vangenuchten.hh @@ -22,9 +22,10 @@ * \brief Implementation of the capillary pressure and * relative permeability <-> saturation relations according to van Genuchten. */ -#ifndef DUMUX_VAN_GENUCHTEN_HH -#define DUMUX_VAN_GENUCHTEN_HH +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_VAN_GENUCHTEN_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_VAN_GENUCHTEN_HH +// remove from here after release 3.3 ///////////// #include "vangenuchtenparams.hh" #include @@ -48,7 +49,7 @@ namespace Dumux { * \see VanGenuchtenParams */ template > -class VanGenuchten +class [[deprecated("Use new material laws and FluidMatrix::VanGenuchten instead!")]] VanGenuchten { public: using Params = ParamsT; @@ -280,5 +281,627 @@ public: }; } // end namespace Dumux +// remove until here after release 3.3 ///////////// + +#include +#include + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implementation of the van Genuchten capillary pressure <-> + * saturation relation, and relative permeability. + * + * \note Capillary pressure model from van Genuchten (1980), + * relative permeability model from Mualem (1976) + */ +class VanGenuchten +{ + +public: + /*! + * \brief The parameter type + * \tparam Scalar The scalar type + * \note The van Genuchten laws are parameterized with four parameters: \f$\mathrm{n, m, \alpha, l}\f$. + * + * - \f$\mathrm{\alpha}\f$ shape parameter \f$\mathrm{[1/Pa]}\f$ + * - \f$\mathrm{m}\f$ shape parameter \f$\mathrm{[-]}\f$ + * - \f$\mathrm{n}\f$ shape parameter \f$\mathrm{[-]}\f$ + * - \f$\mathrm{l}\f$ pore-connectivity parameter \f$\mathrm{[-]}\f$ of Mualem's relative permeability curve + * + * \note In the original Mualem (1976) paper the pore-connectivity parameter is called "n". It's referred to as "l" in + * several later publication of van Genuchten, e.g. van Genuchten (1991), Shaap & van Genuchten (2006). + */ + template + struct Params + { + Params(Scalar alpha, Scalar n, Scalar l = 0.5) + : alpha_(alpha), n_(n), m_(1.0 - 1.0/n), l_(l) + {} + + Scalar alpha() const { return alpha_; } + void setAlpha(Scalar alpha) { alpha_ = alpha; } + + Scalar m() const { return m_; } + void setM(Scalar m) { m_ = m; n_ = 1.0/(1.0 - m); } + + Scalar n() const{ return n_; } + void setN(Scalar n){ n_ = n; m_ = 1.0 - 1.0/n; } + + Scalar l() const { return l_; } + void setL(Scalar l) { l_ = l; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(alpha_, p.alpha_, 1e-6) + && Dune::FloatCmp::eq(n_, p.n_, 1e-6) + && Dune::FloatCmp::eq(m_, p.m_, 1e-6) + && Dune::FloatCmp::eq(l_, p.l_, 1e-6); + } + + private: + Scalar alpha_, n_, m_, l_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + const auto n = getParamFromGroup(paramGroup, "VanGenuchtenN"); + const auto alpha = getParamFromGroup(paramGroup, "VanGenuchtenAlpha"); + // l is usually chosen to be 0.5 (according to Mualem (1976), WRR) + const auto l = getParamFromGroup(paramGroup, "VanGenuchtenL", 0.5); + return Params(alpha, n, l); + } + + /*! + * \brief The capillary pressure-saturation curve according to van Genuchten. + * + * Van Genuchten's empirical capillary pressure <-> saturation + * function is given by + * \f$\mathrm{ + p_c = (\overline{S}_w^{-1/m} - 1)^{1/n}/\alpha + }\f$ + * \param swe Effective saturation of the wetting phase \f$\mathrm{\overline{S}_w}\f$ + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * \note Instead of undefined behaviour if swe is not in the valid range, we return a valid number, + * by clamping the input. Note that pc(swe = 0.0) = inf, have a look at RegularizedVanGenuchten if this is a problem. + */ + template + static Scalar pc(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + const Scalar pc = pow(pow(swe, -1.0/params.m()) - 1, 1.0/params.n())/params.alpha(); + return pc; + } + + /*! + * \brief The saturation-capillary pressure curve according to van Genuchten. + * + * This is the inverse of the capillary pressure-saturation curve: + * \f$\mathrm{ + \overline{S}_w = {p_c}^{-1} = ((\alpha p_c)^n + 1)^{-m} + }\f$ + * + * \param pc Capillary pressure \f$\mathrm{p_c}\f$ in \f$\mathrm{[Pa]}\f$ + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * \return The effective saturation of the wetting phase \f$\mathrm{\overline{S}_w}\f$ + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * i.e. sw(pc < 0.0) = 0.0, by clamping the input to the physical bounds. + */ + template + static Scalar swe(Scalar pc, const Params& params) + { + using std::pow; + using std::max; + + pc = max(pc, 0.0); // the equation below is undefined for negative pcs + + const Scalar sw = pow(pow(params.alpha()*pc, params.n()) + 1, -params.m()); + return sw; + } + + /*! + * \brief The capillary pressure at Swe = 1.0 also called end point capillary pressure + * \param params A container object that is populated with the appropriate coefficients for the respective law. + */ + template + static Scalar endPointPc(const Params& params) + { return 0.0; } + + /*! + * \brief The partial derivative of the capillary + * pressure w.r.t. the effective saturation according to van Genuchten. + * + * This is equivalent to + * \f$\mathrm{ + \frac{\partial p_c}{\partial \overline{S}_w} = + -\frac{1}{\alpha} (\overline{S}_w^{-1/m} - 1)^{1/n - } + \overline{S}_w^{-1/m} / \overline{S}_w / m + }\f$ + * + * \param swe Effective saturation of the wetting phase \f$\mathrm{\overline{S}_w}\f$ + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * \note Instead of undefined behaviour if swe is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar dpc_dswe(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + const Scalar powSwe = pow(swe, -1/params.m()); + return - 1.0/params.alpha() * pow(powSwe - 1, 1.0/params.n() - 1)/params.n() + * powSwe/swe/params.m(); + } + + /*! + * \brief The partial derivative of the effective + * saturation to the capillary pressure according to van Genuchten. + * + * \param pc Capillary pressure \f$\mathrm{p_C}\f$ in \f$\mathrm{[Pa]}\f$ + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar dswe_dpc(Scalar pc, const Params& params) + { + using std::pow; + using std::max; + + pc = max(pc, 0.0); // the equation below is undefined for negative pcs + + const Scalar powAlphaPc = pow(params.alpha()*pc, params.n()); + return -pow(powAlphaPc + 1, -params.m()-1)*params.m()*powAlphaPc/pc*params.n(); + } + + /*! + * \brief The relative permeability for the wetting phase of + * the medium implied by van Genuchten / Mualem + * parameterization. + * + * \param swe The mobile saturation of the wetting phase. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar krw(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + const Scalar r = 1.0 - pow(1.0 - pow(swe, 1.0/params.m()), params.m()); + return pow(swe, params.l())*r*r; + } + + /*! + * \brief The derivative of the relative permeability for the + * wetting phase in regard to the wetting saturation of the + * medium implied by the van Genuchten parameterization. + * + * \param swe The mobile saturation of the wetting phase. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar dkrw_dswe(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + const Scalar x = 1.0 - pow(swe, 1.0/params.m()); + const Scalar xToM = pow(x, params.m()); + return (1.0 - xToM)*pow(swe, params.l()-1) * ( (1.0 - xToM)*params.l() + 2*xToM*(1.0-x)/x ); + } + + /*! + * \brief The relative permeability for the non-wetting phase + * of the medium implied by van Genuchten's + * parameterization. + * + * \param swe The mobile saturation of the wetting phase. + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar krn(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + return pow(1 - swe, params.l()) * pow(1 - pow(swe, 1.0/params.m()), 2*params.m()); + } + + /*! + * \brief The derivative of the relative permeability for the + * non-wetting phase in regard to the wetting saturation of + * the medium as implied by the van Genuchten + * parameterization. + * + * \param swe The mobile saturation of the wetting phase. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, + * by clamping the input. + */ + template + static Scalar dkrn_dswe(Scalar swe, const Params& params) + { + using std::pow; + using std::clamp; + + swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0 + + const auto sne = 1.0 - swe; + const auto x = 1.0 - pow(swe, 1.0/params.m()); + return -pow(sne, params.l()-1.0) * pow(x, 2*params.m() - 1.0) * ( params.l()*x + 2.0*sne/swe*(1.0 - x) ); + } +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A regularization for the VanGenuchten material law + * \note Regularization can be turned of by setting the threshold parameters + * out of range (runtime) or by replacing + * this class by NoRegularization (compile time). + */ +template +class VanGenuchtenRegularization +{ +public: + //! Regularization parameters + template + struct Params + { + /*! + * \brief Set the threshold saturation below which the capillary pressure is regularized. + * + * Most problems are very sensitive to this value (e.g. making it smaller might + * result in very high capillary pressures) + */ + void setPcLowSwe(Scalar pcLowSwe) + { pcLowSwe_ = pcLowSwe; } + + /*! + * \brief Threshold saturation below which the capillary pressure is regularized. + */ + Scalar pcLowSwe() const + { return pcLowSwe_; } + + /*! + * \brief Set the threshold saturation above which the capillary pressure is regularized. + */ + void setPcHighSwe(Scalar pcHighSwe) + { pcHighSwe_ = pcHighSwe; } + + /*! + * \brief Threshold saturation above which the capillary pressure is regularized. + * + * Most problems are very sensitive to this value (e.g. making it smaller might + * result in negative capillary pressures). + */ + Scalar pcHighSwe() const + { return pcHighSwe_; } + + /*! + * \brief Set the threshold saturation below which the relative + * permeability of the non-wetting phase gets regularized. + */ + void setKrnLowSwe(Scalar krnLowSwe) + { krnLowSwe_ = krnLowSwe; } + + /*! + * \brief Threshold saturation below which the relative + * permeability of the non-wetting phase gets regularized. + */ + Scalar krnLowSwe() const + { return krnLowSwe_; } + + /*! + * \brief Set the threshold saturation above which the relative + * permeability of the wetting phase gets regularized. + */ + void setKrwHighSwe(Scalar krwHighSwe) + { krwHighSwe_ = krwHighSwe; } + + /*! + * \brief Threshold saturation above which the relative + * permeability of the wetting phase gets regularized. + */ + Scalar krwHighSwe() const + { return krwHighSwe_; } + +private: + S pcLowSwe_ = 0.01; + S pcHighSwe_ = 0.99; + S krnLowSwe_ = 0.1; + S krwHighSwe_ = 0.9; + }; + + //! Initialize the spline + template + void init(const MaterialLaw* m, const std::string& paramGroup) + { + pcLowSwe_ = getParamFromGroup(paramGroup, "VanGenuchtenPcLowSweThreshold", 0.01); + pcHighSwe_ = getParamFromGroup(paramGroup, "VanGenuchtenPcHighSweThreshold", 0.99); + krwHighSwe_ = getParamFromGroup(paramGroup, "VanGenuchtenKrwHighSweThreshold", 0.9); + krnLowSwe_ = getParamFromGroup(paramGroup, "VanGenuchtenKrnLowSweThreshold", 0.1); + + initPcParameters_(m, pcLowSwe_, pcHighSwe_); + initKrParameters_(m, krnLowSwe_, krwHighSwe_); + } + + template + void init(const MaterialLaw* m, const BaseParams& bp, const EffToAbsParams& etap, const Params& p) + { + pcLowSwe_ = p.pcLowSwe(); + pcHighSwe_ = p.pcHighSwe(); + krwHighSwe_ = p.krwHighSwe(); + krnLowSwe_ = p.krnLowSwe(); + + initPcParameters_(m, pcLowSwe_, pcHighSwe_); + initKrParameters_(m, krnLowSwe_, krwHighSwe_); + } + + /*! + * \brief Equality comparison with another instance + */ + bool operator== (const VanGenuchtenRegularization& o) const + { + return Dune::FloatCmp::eq(pcLowSwe_, o.pcLowSwe_, 1e-6) + && Dune::FloatCmp::eq(pcHighSwe_, o.pcHighSwe_, 1e-6) + && Dune::FloatCmp::eq(krwHighSwe_, o.krwHighSwe_, 1e-6) + && Dune::FloatCmp::eq(krnLowSwe_, o.krnLowSwe_, 1e-6); + } + + /*! + * \brief The regularized capillary pressure-saturation curve + * regularized part: + * - low saturation: extend the \f$\mathrm{p_c(S_w)}\f$ curve with the slope at the regularization point (i.e. no kink). + * - high saturation: connect the high regularization point with \f$\mathrm{\overline{S}_w =1}\f$ + * with a spline and continue linearly for \f$\mathrm{\overline{S}_w > 1}\f$ + */ + OptionalScalar pc(const Scalar swe) const + { + // make sure that the capillary pressure observes a derivative + // != 0 for 'illegal' saturations. This is favourable for the + // newton solver (if the derivative is calculated numerically) + // in order to get the saturation moving to the right + // direction if it temporarily is in an 'illegal' range. + if (swe < pcLowSwe_) + return pcLowSwePcValue_ + pcDerivativeLowSw_*(swe - pcLowSwe_); + + else if (swe > 1.0) + return pcDerivativeHighSweEnd_*(swe - 1.0); + + else if (swe > pcHighSwe_) + return pcSpline_.eval(swe); + + else + return {}; // no regularization + } + + /*! + * \brief The regularized partial derivative of the capillary pressure w.r.t. the saturation + */ + OptionalScalar dpc_dswe(const Scalar swe) const + { + if (swe < pcLowSwe_) + return pcDerivativeLowSw_; + + else if (swe > 1.0) + return pcDerivativeHighSweEnd_; + + else if (swe > pcHighSwe_) + return pcSpline_.evalDerivative(swe); + + else + return {}; // no regularization + } + + /*! + * \brief The regularized saturation-capillary pressure curve + */ + OptionalScalar swe(const Scalar pc) const + { + if (pc <= 0.0) + { + if (pcHighSwe_ > 1.0 - std::numeric_limits::epsilon()) + return 1.0; + else + return pc/pcDerivativeHighSweEnd_ + 1.0; + } + + // invert spline + else if (pc < pcHighSwePcValue_) + return pcSpline_.intersectInterval(pcHighSwe_, 1.0, 0.0, 0.0, 0.0, pc); + + else if (pc >= pcLowSwePcValue_) + return (pc - pcLowSwePcValue_)/pcDerivativeLowSw_ + pcLowSwe_; + + else + return {}; // no regularization + } + + /*! + * \brief The regularized partial derivative of the saturation to the capillary pressure + */ + OptionalScalar dswe_dpc(const Scalar pc) const + { + if (pc <= 0.0) + { + if (pcHighSwe_ > 1.0 - std::numeric_limits::epsilon()) + return 0.0; + else + return 1.0/pcDerivativeHighSweEnd_; + } + + // derivative of the inverse of the function is one over derivative of the function + else if (pc < pcHighSwePcValue_) + return 1.0/pcSpline_.evalDerivative(pcSpline_.intersectInterval(pcHighSwe_, 1.0, 0.0, 0.0, 0.0, pc)); + + else if (pc >= pcLowSwePcValue_) + return 1.0/pcDerivativeLowSw_; + + else + return {}; // no regularization + } + + /*! + * \brief The regularized relative permeability for the wetting phase + */ + OptionalScalar krw(const Scalar swe) const + { + if (swe < 0.0) + return 0.0; + else if (swe > 1.0 - std::numeric_limits::epsilon()) + return 1.0; + else if (swe > krwHighSwe_) + return krwSpline_.eval(swe); + else + return {}; // no regularization + } + + /*! + * \brief The regularized derivative of the relative permeability for the wetting phase w.r.t. saturation + */ + OptionalScalar dkrw_dswe(const Scalar swe) const + { + if (swe < 0.0) + return 0.0; + else if (swe > 1.0 - std::numeric_limits::epsilon()) + return 0.0; + else if (swe > krwHighSwe_) + return krwSpline_.evalDerivative(swe); + else + return {}; // no regularization + } + + /*! + * \brief The regularized relative permeability for the non-wetting phase + */ + OptionalScalar krn(const Scalar swe) const + { + if (swe < 0.0) + return 1.0; + else if (swe > 1.0 - std::numeric_limits::epsilon()) + return 0.0; + else if (swe < krnLowSwe_) + return krnSpline_.eval(swe); + else + return {}; // no regularization + } + + /*! + * \brief The regularized derivative of the relative permeability for the non-wetting phase w.r.t. saturation + */ + OptionalScalar dkrn_dswe(const Scalar swe) const + { + if (swe < 0.0) + return 0.0; + else if (swe > 1.0 - std::numeric_limits::epsilon()) + return 0.0; + else if (swe < krnLowSwe_) + return krnSpline_.evalDerivative(swe); + else + return {}; // no regularization + } + +private: + template + void initPcParameters_(const MaterialLaw* m, const Scalar lowSwe, const Scalar highSwe) + { + const auto lowSw = MaterialLaw::EffToAbs::sweToSw(lowSwe, m->effToAbsParams()); + const auto highSw = MaterialLaw::EffToAbs::sweToSw(highSwe, m->effToAbsParams()); + const auto dsw_dswe = MaterialLaw::EffToAbs::dsw_dswe(m->effToAbsParams()); + + pcDerivativeLowSw_ = m->template dpc_dsw(lowSw)*dsw_dswe; + + pcDerivativeHighSweThreshold_ = m->template dpc_dsw(highSw)*dsw_dswe; + pcDerivativeHighSweEnd_ = 2.0*(0.0 - m->template pc(highSw))/(1.0 - highSwe); + + pcLowSwePcValue_ = m->template pc(lowSw); + pcHighSwePcValue_ = m->template pc(highSw); + + pcSpline_ = Spline(highSwe, 1.0, // x0, x1 + pcHighSwePcValue_, 0, // y0, y1 + pcDerivativeHighSweThreshold_, pcDerivativeHighSweEnd_); // m0, m1 + + + } + + template + void initKrParameters_(const MaterialLaw* m, const Scalar lowSwe, const Scalar highSwe) + { + const auto lowSw = MaterialLaw::EffToAbs::sweToSw(lowSwe, m->effToAbsParams()); + const auto highSw = MaterialLaw::EffToAbs::sweToSw(highSwe, m->effToAbsParams()); + const auto dsw_dswe = MaterialLaw::EffToAbs::dsw_dswe(m->effToAbsParams()); + + const auto krwHighSw = m->template krw(highSw); + const auto dkrwHighSw = m->template dkrw_dsw(highSw)*dsw_dswe; + + const auto krnLowSw = m->template krn(lowSw); + const auto dkrnLowSw = m->template dkrn_dsw(lowSw)*dsw_dswe; + + krwSpline_ = Spline(highSwe, 1.0, // x0, x1 + krwHighSw, 1.0, // y0, y1 + dkrwHighSw, 0.0); // m0, m1 + + krnSpline_ = Spline(0.0, lowSwe, // x0, x1 + 1.0, krnLowSw, // y0, y1 + 0.0, dkrnLowSw); // m0, m1 + + } + + Scalar pcLowSwe_, pcHighSwe_; + Scalar pcLowSwePcValue_, pcHighSwePcValue_; + Scalar krwHighSwe_, krnLowSwe_; + Scalar pcDerivativeLowSw_; + Scalar pcDerivativeHighSweThreshold_, pcDerivativeHighSweEnd_; + + Spline pcSpline_; + Spline krwSpline_; + Spline krnSpline_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A default configuration for using the VanGenuchten material law + */ +template +using VanGenuchtenDefault = TwoPMaterialLaw, TwoPEffToAbsDefaultPolicy>; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A default configuration without regularization for using the VanGenuchten material law + */ +template +using VanGenuchtenNoReg = TwoPMaterialLaw; + +} // end namespace Dumux::FluidMatrix #endif -- GitLab From 2f65ce118eaf8b729a6e714e27573ab96598aa6b Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 13 Oct 2020 11:49:03 +0200 Subject: [PATCH 08/99] [fluidmatrixinteractions][2p] Add new implementation of LinearLaw --- .../2p/linearmaterial.hh | 154 +++++++++++++++++- 1 file changed, 151 insertions(+), 3 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2p/linearmaterial.hh b/dumux/material/fluidmatrixinteractions/2p/linearmaterial.hh index b35f3dac9b..09ce3ac3fc 100644 --- a/dumux/material/fluidmatrixinteractions/2p/linearmaterial.hh +++ b/dumux/material/fluidmatrixinteractions/2p/linearmaterial.hh @@ -22,9 +22,10 @@ * \brief Linear capillary pressure and * relative permeability <-> saturation relations */ -#ifndef LINEAR_MATERIAL_HH -#define LINEAR_MATERIAL_HH +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_LINEAR_MATERIAL_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_LINEAR_MATERIAL_HH +// remove from here after release 3.3 ///////////// #include "linearmaterialparams.hh" #include @@ -44,7 +45,7 @@ namespace Dumux { * \see LinearMaterialParams */ template > -class LinearMaterial +class [[deprecated("Use new material laws and FluidMatrix::LinearMaterial instead!")]] LinearMaterial { public: using Params = ParamsT; @@ -164,5 +165,152 @@ public: } }; } // end namespace Dumux +// remove until here after release 3.3 ///////////// + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * + * \brief Linear capillary pressure and + * relative permeability <-> saturation relations + * + * The entry pressure is reached at \f$\mathrm{ \overline{S}_w = 1}\f$, the maximum + * capillary pressure is observed at \f$\mathrm{ \overline{S}_w = 0}\f$. + * + */ +class LinearMaterial +{ +public: + /*! + * \brief The parameter type + * \tparam Scalar The scalar type + */ + template + struct Params + { + Params(Scalar pcEntry, Scalar pcMax) + : pcEntry_(pcEntry), pcMax_(pcMax) + {} + + Scalar pcEntry() const { return pcEntry_; } + void setPcEntry(Scalar pcEntry) { pcEntry_ = pcEntry; } + + Scalar pcMax() const { return pcMax_; } + void setPcMax(Scalar pcMax) { pcMax_ = pcMax; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(pcEntry(), p.pcEntry(), 1e-6) + && Dune::FloatCmp::eq(pcMax(), p.pcMax(), 1e-6); + } + + private: + Scalar pcEntry_, pcMax_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + const auto pcEntry = getParamFromGroup(paramGroup, "LinearPcEntry"); + const auto pcMax = getParamFromGroup(paramGroup, "LinearPcMax"); + return {pcEntry, pcMax}; + } + + /*! + * \brief The capillary pressure-saturation curve + */ + template + static Scalar pc(Scalar swe, const Params& params) + { + return (1.0 - swe)*(params.pcMax() - params.pcEntry()) + params.pcEntry(); + } + + /*! + * \brief The inverse saturation-capillary pressure curve + */ + template + static Scalar swe(Scalar pc, const Params& params) + { + return 1.0 - (pc - params.pcEntry())/(params.pcMax() - params.pcEntry()); + } + + /*! + * \brief The capillary pressure at Swe = 1.0 also called end point capillary pressure + */ + template + static Scalar endPointPc(const Params& params) + { return params.pcEntry(); } + + /*! + * \brief The partial derivative of the capillary pressure w.r.t. the effective saturation + */ + template + static Scalar dpc_dswe(Scalar swe, const Params& params) + { + return params.pcEntry() - params.pcMax(); + } + + /*! + * \brief The partial derivative of the effective saturation w.r.t. the capillary pressure + */ + template + static Scalar dswe_dpc(Scalar pc, const Params& params) + { + return 1.0/(params.pcEntry() - params.pcMax()); + } + + /*! + * \brief The relative permeability for the wetting phase + */ + template + static Scalar krw(Scalar swe, const Params& params) + { + using std::clamp; + return clamp(swe, 0.0, 1.0); + } + + /*! + * \brief The derivative of the relative permeability + */ + template + static Scalar dkrw_dswe(Scalar swe, const Params& params) + { + return 1.0; + } + + /*! + * \brief The relative permeability for the non-wetting phase + */ + template + static Scalar krn(Scalar swe, const Params& params) + { + using std::clamp; + return clamp(1.0-swe, 0.0, 1.0); + } + + /*! + * \brief The derivative of the relative permeability + */ + template + static Scalar dkrn_dswe(Scalar swe, const Params& params) + { + return -1.0; + } +}; + +template +using LinearMaterialDefault = TwoPMaterialLaw; + +} // end namespace Dumux::FluidMatrix #endif -- GitLab From 5c5061a367afe2b346c7ed3a61e80d09554b5eca Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 13 Oct 2020 10:21:28 +0200 Subject: [PATCH 09/99] [fluidmatrixinteraction][2p] Add SmoothedLinearLaw to replace RegularizedLinearLaw *RegularizedLinearLaw is not just a regularized version of LinearLaw, it is an entirely different curve. --- .../2p/smoothedlinearlaw.hh | 245 ++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/2p/smoothedlinearlaw.hh diff --git a/dumux/material/fluidmatrixinteractions/2p/smoothedlinearlaw.hh b/dumux/material/fluidmatrixinteractions/2p/smoothedlinearlaw.hh new file mode 100644 index 0000000000..7cf2badd39 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/smoothedlinearlaw.hh @@ -0,0 +1,245 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Implementation of the capillary pressure / relPerm <-> saturation relation + * using a linear relation smoothed at the upper and lower bounds for kr. + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWOP_SMOOTHED_LINEAR_LAW_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_TWOP_SMOOTHED_LINEAR_LAW_HH + + +#include +#include + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implements a linear saturation-capillary pressure relation + * + * The entry pressure is reached at \f$\mathrm{\overline{S}_w = 1}\f$, the maximum + * capillary pressure is observed at \f$\mathrm{\overline{S}_w = 0}\f$. + * + * The relative permeabilities are 0 or 1 outside of the range of effective saturation. + * However, the transition between the linearly changing and the constant part is not smooth but with a kink. + * The Newton scheme does not like that. Therefore a smooth transition is accomplished by interpolating these + * regions with a spline. + * + * An example of the regularization of the relative permeability is shown below: + * \image html regularizedLinearKr.png + */ +template +class SmoothedLinearLaw : public Adapter, PcKrSw> +{ + +public: + using Scalar = ScalarType; + using EffToAbsParams = typename EffToAbsPolicy::template Params; + using EffToAbs = EffToAbsPolicy; + + /*! + * \brief Return whether this law is regularized + */ + static constexpr bool isRegularized() + { return false; } + + /*! + * \brief The parameter type + * \tparam Scalar The scalar type + */ + struct Params + { + Params(Scalar pe, Scalar pcMax, Scalar krLowS, Scalar krHighS) + : pe_(pe), pcMax_(pcMax), krLowS_(krLowS), krHighS_(krHighS) + {} + + Scalar pe() const { return pe_; } + void setPe(Scalar pe) { pe_ = pe; } + + Scalar pcMax() const { return pcMax_; } + void setPcMax(Scalar pcMax) { pcMax_ = pcMax; } + + Scalar krLowS() const { return krLowS_; } + void setKrLowS(Scalar krLowS) { krLowS_ = krLowS; } + + Scalar krHighS() const { return krHighS_; } + void setKrHighS(Scalar krHighS) { krHighS_ = krHighS; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(pe(), p.pe(), 1e-6) + && Dune::FloatCmp::eq(pcMax(), p.pcMax(), 1e-6) + && Dune::FloatCmp::eq(krLowS(), p.krLowS(), 1e-6) + && Dune::FloatCmp::eq(krHighS(), p.krHighS(), 1e-6); + } + + private: + Scalar pe_, pcMax_, krLowS_, krHighS_; + }; + + /*! + * \brief Deleted default constructor (so we are never in an undefined state) + * \note store owning pointers to laws instead if you need default-constructible objects + */ + SmoothedLinearLaw() = delete; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + explicit SmoothedLinearLaw(const std::string& paramGroup) + : SmoothedLinearLaw(makeParams(paramGroup), EffToAbs::template makeParams(paramGroup)) + {} + + /*! + * \brief Construct from parameter structs + * \note More efficient constructor but you need to ensure all parameters are initialized + */ + SmoothedLinearLaw(const Params& params, + const EffToAbsParams& effToAbsParams = {}) + : params_(params) + , effToAbsParams_(effToAbsParams) + , splineM_((1.0 - ((1.0 - params_.krHighS()) + params_.krLowS())/2.0 ) + / (1.0 - (1.0 - params_.krHighS()) - params_.krLowS())) + , splineLowS_(0.0, params_.krLowS(), // x1, x2 + 0.0, params_.krLowS()/2.0, // y1, y2 + 0.0, splineM_) // m1, m2 + , splineHighS_(params_.krHighS(), 1.0, // x1, x2 + 1.0 - (1.0 - params_.krHighS())/2.0, 1.0, // y1, y2 + splineM_, 0.0) // m1, m2 + {} + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + static Params makeParams(const std::string& paramGroup) + { + const auto pe = getParamFromGroup(paramGroup, "SmoothedLinearLawPe"); + const auto pcMax = getParamFromGroup(paramGroup, "SmoothedLinearLawPcMax"); + const auto krLowS = getParamFromGroup(paramGroup, "SmoothedLinearLawKrLowS"); + const auto krHighS = getParamFromGroup(paramGroup, "SmoothedLinearLawKrHighS"); + return {pe, pcMax, krLowS, krHighS}; + } + + /*! + * \brief The capillary pressure-saturation curve + */ + Scalar pc(Scalar swe) const + { + return (1.0 - swe)*(params_.pcMax() - params_.pe()) + params_.pe(); + } + + /*! + * \brief The inverse saturation-capillary pressure curve + */ + Scalar swe(Scalar pc) const + { + return 1.0 - (pc - params_.pe())/(params_.pcMax() - params_.pe()); + } + + /*! + * \brief The capillary pressure at Swe = 1.0 also called end point capillary pressure + */ + Scalar endPointPc() const + { return params_.pe(); } + + /*! + * \brief The partial derivative of the capillary pressure w.r.t. the effective saturation + */ + Scalar dpc_dswe(Scalar swe) const + { + return params_.pe() - params_.pcMax(); + } + + /*! + * \brief The partial derivative of the effective saturation w.r.t. the capillary pressure + */ + Scalar dswe_dpc(Scalar pc) const + { + return 1.0/(params_.pe() - params_.pcMax()); + } + + /*! + * \brief The relative permeability for the wetting phase. + */ + Scalar krw(Scalar swe) const + { + return relperm_(swe); + } + + /*! + * \brief The relative permeability for the non-wetting phase. + */ + Scalar krn(Scalar swe) const + { + Scalar sne = 1.0 - swe; + return relperm_(sne); + } + + /*! + * \brief Equality comparison with another instance + */ + bool operator== (const SmoothedLinearLaw& o) const + { + return params_ == o.params_ + && effToAbsParams_ == o.effToAbsParams_; + } + + const EffToAbsParams& effToAbsParams() const + { return effToAbsParams_; } + +private: + + Scalar relperm_(Scalar S) const + { + const Scalar lowS = params_.krLowS(); + const Scalar highS = params_.krHighS(); + + // check whether the saturation is unpyhsical + if (S >= 1.0) + return 1.0; + else if (S <= 0.0) + return 0; + // check wether the permeability needs to be regularized + else if (S < lowS) + return splineLowS_.eval(S); + else if (S > highS) + return splineHighS_.eval(S); + + // straight line for S \in [lowS, highS] + return lowS/2.0 + splineM_*(S - lowS); + } + + Params params_; + EffToAbsParams effToAbsParams_; + Scalar splineM_; + Dumux::Spline splineLowS_; + Dumux::Spline splineHighS_; +}; +} // end namespace Dumux::FluidMatrix + +#endif -- GitLab From cdc1bacd77911d1c5574af3f38afc4b66678825a Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 29 Sep 2020 13:09:51 +0200 Subject: [PATCH 10/99] [2p] Add new-style heatpipe law --- .../fluidmatrixinteractions/2p/heatpipelaw.hh | 219 +++++++++++++++++- 1 file changed, 216 insertions(+), 3 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2p/heatpipelaw.hh b/dumux/material/fluidmatrixinteractions/2p/heatpipelaw.hh index b21b2ebe5f..3a5437d690 100644 --- a/dumux/material/fluidmatrixinteractions/2p/heatpipelaw.hh +++ b/dumux/material/fluidmatrixinteractions/2p/heatpipelaw.hh @@ -22,9 +22,10 @@ * \brief Implementation of the capillary pressure <-> saturation relation * for the heatpipe problem. */ -#ifndef HEATPIPELAW_HH -#define HEATPIPELAW_HH +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWOP_HEATPIPELAW_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_TWOP_HEATPIPELAW_HH +// remove from here after release 3.3 ///////////// #include "heatpipelawparams.hh" #include @@ -45,7 +46,7 @@ namespace Dumux { * converting absolute to effective saturations and vince versa. */ template > -class HeatPipeLaw +class [[deprecated("Use new material laws and FluidMatrix::HeatPipeLaw instead!")]] HeatPipeLaw { public: using Params = ParamsT; @@ -166,5 +167,217 @@ private: }; } // end namespace Dumux +// remove until here after release 3.3 ///////////// + +#include +#include + +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implementation of the capillary pressure <-> saturation + * relation for the heatpipe problem. + */ +template +class HeatPipeLaw : Adapter, PcKrSw> +{ + +public: + using Scalar = ScalarType; + using EffToAbsParams = typename EffToAbsPolicy::template Params; + using EffToAbs = EffToAbsPolicy; + + /*! + * \brief Return the number of fluid phases + */ + static constexpr int numFluidPhases() + { return 2; } + + /*! + * \brief Return whether this law is regularized + */ + static constexpr bool isRegularized() + { return false; } + + /*! + * \brief The parameter type + * \tparam Scalar The scalar type + */ + struct Params + { + Params(Scalar gamma, Scalar p0) + : gamma_(gamma), p0_(p0) + {} + + Scalar gamma() const { return gamma_; } + void setGamma(Scalar gamma) { gamma_ = gamma; } + + Scalar p0() const { return p0_; } + void setP0(Scalar p0) { p0_ = p0; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(gamma(), p.gamma(), 1e-6) + && Dune::FloatCmp::eq(p0(), p.p0(), 1e-6); + } + + private: + Scalar gamma_, p0_; + }; + + /*! + * \brief Deleted default constructor (so we are never in an undefined state) + * \note store owning pointers to laws instead if you need default-constructible objects + */ + HeatPipeLaw() = delete; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + explicit HeatPipeLaw(const std::string& paramGroup) + { + params_ = makeParams(paramGroup); + effToAbsParams_ = EffToAbs::template makeParams(paramGroup); + } + + /*! + * \brief Construct from parameter structs + * \note More efficient constructor but you need to ensure all parameters are initialized + */ + HeatPipeLaw(const Params& params, + const EffToAbsParams& effToAbsParams = {}) + : params_(params) + , effToAbsParams_(effToAbsParams) + , spline_(eps_, 1.0, // x1, x2 + eps_*eps_*eps_, 1.0, // y1, y2 + 3.0*eps_*eps_, 0.0) // m1, m2 + {} + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + static Params makeParams(const std::string& paramGroup) + { + const auto gamma = getParamFromGroup(paramGroup, "HeatpipeLawGamma"); + const auto p0 = getParamFromGroup(paramGroup, "HeatpipeLawP0"); + return {gamma, p0}; + } + + /*! + * \brief The capillary pressure-saturation curve. + * + }\f$ + * \param swe Effective saturation of the wetting phase \f$\mathrm{\overline{S}_w}\f$ + */ + template + Scalar pc(Scalar swe) const + { + const Scalar sne = 1 - swe; + const Scalar p0Gamma = params_.p0()*params_.gamma(); + + // regularization + if (sne >= 1.0) + { + const Scalar y = p0Gamma*( (1.263*1.0 - 2.120)*1.0 + 1.417)*1.0; + const Scalar m = p0Gamma*((3*1.263*1.0 - 2*2.120)*1.0 + 1.417); + return (sne - 1)*m + y; + } + else if (sne <= 0.0) + return sne * p0Gamma*1.417; + else + return p0Gamma*((1.263*sne - 2.120)*sne + 1.417) * sne; + } + + /*! + * \brief The capillary pressure at Swe = 1.0 also called end point capillary pressure + */ + template + Scalar endPointPc() const + { return 0.0; } + + /*! + * \brief The partial derivative of the capillary + * pressure w.r.t. the effective saturation. + + * + * \param swe Effective saturation of the wetting phase \f$\mathrm{\overline{S}_w}\f$ + */ + template + Scalar dpc_dswe(Scalar swe) const + { + const Scalar sne = 1 - swe; + const Scalar p0Gamma = params_.p0()*params_.gamma(); + if (sne > 1.0) + sne = 1.0; + else if (sne <= 0.0) + return -p0Gamma*1.417; + else + return - p0Gamma*((3*1.263*sne - 2*2.120)*sne + 1.417); + } + + /*! + * \brief The relative permeability for the wetting phase of + * the medium. + * + * \param swe The mobile saturation of the wetting phase. + */ + template + Scalar krw(Scalar swe) const + { + return kr_(swe); + } + + /*! + * \brief The relative permeability for the non-wetting phase + * of the medium. + * + * \param swe The mobile saturation of the wetting phase. + */ + template + Scalar krn(Scalar swe) const + { + const Scalar sne = 1 - swe; // TODO does this make sense? + return kr_(sne); + } + + /*! + * \brief Equality comparison with another instance + */ + bool operator== (const HeatPipeLaw& o) const + { + return params_ == o.params_ + && effToAbsParams_ == o.effToAbsParams_; + } + + const EffToAbsParams& effToAbsParams() const + { return effToAbsParams_; } + +private: + + Scalar kr_(Scalar s) const + { + if (s >= 1.0) + return 1; + else if (s <= 0.0) + return 0; + else if (s > eps_) + return spline_.eval(s); // regularize + else + return s*s*s; + } + + Params params_; + EffToAbsParams effToAbsParams_; + static constexpr Scalar eps_ = 0.95; + Dumux::Spline spline_; +}; +} // end namespace Dumux::FluidMatrix #endif -- GitLab From 4d7d64c4e2cba0a2c985454a3d284e6cc310c63a Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Fri, 25 Sep 2020 13:14:08 +0200 Subject: [PATCH 11/99] [2p][material] Add spline twop material law --- .../2p/splinemateriallaw.hh | 258 ++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/2p/splinemateriallaw.hh diff --git a/dumux/material/fluidmatrixinteractions/2p/splinemateriallaw.hh b/dumux/material/fluidmatrixinteractions/2p/splinemateriallaw.hh new file mode 100644 index 0000000000..59e54d6f51 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/splinemateriallaw.hh @@ -0,0 +1,258 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief A spline approximation wrapper for 2p material laws + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWOP_SPLINE_MATERIAL_LAW_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_TWOP_SPLINE_MATERIAL_LAW_HH + +#include // unique_ptr + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A spline approximation wrapper for 2p material laws + * \tparam TwoPMaterialLaw the type of material law to be wrapped + * \tpraram approximatePcSwInverse if this is set true, the + * spline approximates sw(pc) and evaluating pc(sw) needs spline inversion. + * if this is false, the spline approximates pc(sw) and evaluating + * sw(pc) needs spline inversion. Spline inversion is rather expensive + * since it has to be done numerically. + */ +template +class SplineTwoPMaterialLaw +: public TwoPMaterialLaw +, public Adapter, PcKrSw> +{ +public: + using Scalar = typename TwoPMaterialLaw::Scalar; + + using BasicParams = typename TwoPMaterialLaw::BasicParams; + using EffToAbsParams = typename TwoPMaterialLaw::BasicParams; + using RegularizationParams = typename TwoPMaterialLaw::RegularizationParams; + + /*! + * \brief Return the number of fluid phases + */ + static constexpr int numFluidPhases() + { return 2; } + + /*! + * \brief We are always regularized in the sense that we replace + * the orginal curve by a cubic spline + */ + static constexpr bool isRegularized() + { return true; } + + /*! + * \brief Deleted default constructor (so we are never in an undefined state) + * \note store owning pointers to laws instead if you need default-constructible objects + */ + SplineTwoPMaterialLaw() = delete; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + explicit SplineTwoPMaterialLaw(const std::string& paramGroup) + : TwoPMaterialLaw(paramGroup) + { + const std::array defaultInterval{{ 0.01, 1.0 }}; + const auto sweInterval = getParamFromGroup>(paramGroup, "SplineSweInterval", defaultInterval); + swInterval_ = {{ TwoPMaterialLaw::EffToAbs::sweToSw(sweInterval[0], this->effToAbsParams()), + TwoPMaterialLaw::EffToAbs::sweToSw(sweInterval[1], this->effToAbsParams()) }}; + swIntervalPc_ = {{ TwoPMaterialLaw::pc(swInterval_[1]), + TwoPMaterialLaw::pc(swInterval_[0]) }}; + numSwSamples_ = getParamFromGroup(paramGroup, "SplineNumSwSamples", 30); + + pcSpline_ = makeSweSpline_( + [this](const auto s){ return TwoPMaterialLaw::pc(s); }, + approximatePcSwInverse + ); + + krwSpline_ = makeSweSpline_( + [this](const auto s){ return TwoPMaterialLaw::krw(s); } + ); + + krnSpline_ = makeSweSpline_( + [this](const auto s){ return TwoPMaterialLaw::krn(s); } + ); + } + + /*! + * \brief Construct from parameter structs + * \note More efficient constructor but you need to ensure all parameters are initialized + */ + SplineTwoPMaterialLaw(const std::array& sweInterval, + std::size_t numSwSamples, + TwoPMaterialLaw&& twoP) + : TwoPMaterialLaw(std::move(twoP)) + , numSwSamples_(numSwSamples) + { + swInterval_ = {{ TwoPMaterialLaw::EffToAbs::sweToSw(sweInterval[0], this->effToAbsParams()), + TwoPMaterialLaw::EffToAbs::sweToSw(sweInterval[1], this->effToAbsParams()) }}; + swIntervalPc_ = {{ TwoPMaterialLaw::pc(swInterval_[1]), + TwoPMaterialLaw::pc(swInterval_[0]) }}; + } + + /*! + * \brief The capillary pressure-saturation curve + */ + Scalar pc(const Scalar sw) const + { + if (sw > swInterval_[0] && sw < swInterval_[1]) + { + if constexpr (approximatePcSwInverse) + return pcSpline_->evalInverse(sw); + else + return pcSpline_->eval(sw); + } + + return TwoPMaterialLaw::pc(sw); + } + + /*! + * \brief The partial derivative of the capillary pressure w.r.t. the saturation + */ + Scalar dpc_dsw(const Scalar sw) const + { + if (sw > swInterval_[0] && sw < swInterval_[1]) + { + if constexpr (approximatePcSwInverse) + return 1.0/pcSpline_->evalDerivative(pcSpline_->evalInverse(sw)); + else + return pcSpline_->evalDerivative(sw); + } + + return TwoPMaterialLaw::dpc_dsw(sw); + } + + /*! + * \brief The saturation-capillary pressure curve + */ + Scalar sw(const Scalar pc) const + { + if (pc > swIntervalPc_[0] && pc < swIntervalPc_[1]) + { + if constexpr (approximatePcSwInverse) + return pcSpline_->eval(pc); + else + return pcSpline_->evalInverse(pc); + } + + return TwoPMaterialLaw::sw(pc); + } + + /*! + * \brief The partial derivative of the saturation to the capillary pressure + */ + Scalar dsw_dpc(const Scalar pc) const + { + if (pc > swIntervalPc_[0] && pc < swIntervalPc_[1]) + { + if constexpr (approximatePcSwInverse) + return pcSpline_->evalDerivative(pc); + else + return 1.0/pcSpline_->evalDerivative(pcSpline_->evalInverse(pc)); + } + + return TwoPMaterialLaw::dsw_dpc(pc); + } + + /*! + * \brief The relative permeability for the wetting phase + */ + Scalar krw(const Scalar sw) const + { + if (sw > swInterval_[0] && sw < swInterval_[1]) + return krwSpline_->eval(sw); + + return TwoPMaterialLaw::krw(sw); + } + + /*! + * \brief The derivative of the relative permeability for the wetting phase w.r.t. saturation + */ + Scalar dkrw_dsw(const Scalar sw) const + { + if (sw > swInterval_[0] && sw < swInterval_[1]) + return krwSpline_->evalDerivative(sw); + + return TwoPMaterialLaw::dkrw_dsw(sw); + } + + /*! + * \brief The relative permeability for the non-wetting phase + */ + Scalar krn(const Scalar sw) const + { + if (sw > swInterval_[0] && sw < swInterval_[1]) + return krnSpline_->eval(sw); + + return TwoPMaterialLaw::krn(sw); + } + + /*! + * \brief The derivative of the relative permeability for the non-wetting phase w.r.t. saturation + */ + Scalar dkrn_dsw(const Scalar sw) const + { + if (sw > swInterval_[0] && sw < swInterval_[1]) + return krnSpline_->evalDerivative(sw); + + return TwoPMaterialLaw::dkrn_dsw(sw); + } + +private: + template + auto makeSweSpline_(const Function& f, bool invert = false) const + { + const auto sw = linspace(swInterval_[0], swInterval_[1], numSwSamples_); + + auto values = sw; + std::transform(sw.begin(), sw.end(), values.begin(), + [&](auto s){ return f(s); } + ); + + if (invert) + return std::make_unique>(values, sw); + else + return std::make_unique>(sw, values); + } + + std::unique_ptr> pcSpline_; + std::unique_ptr> krwSpline_; + std::unique_ptr> krnSpline_; + + std::array swInterval_; + std::array swIntervalPc_; + std::size_t numSwSamples_; +}; + +} // end namespace Dumux::FluidMatrix + +#endif -- GitLab From 2286e39b9105710dc125968c3077ef23f70484b2 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Fri, 25 Sep 2020 14:12:51 +0200 Subject: [PATCH 12/99] [material][2p] Add user data spline material law --- .../2p/datasplinemateriallaw.hh | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/2p/datasplinemateriallaw.hh diff --git a/dumux/material/fluidmatrixinteractions/2p/datasplinemateriallaw.hh b/dumux/material/fluidmatrixinteractions/2p/datasplinemateriallaw.hh new file mode 100644 index 0000000000..794fe36049 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/datasplinemateriallaw.hh @@ -0,0 +1,201 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Pc- and Kr-sw curves based on monotone splines through given data points + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_DATA_SPLINE_MATERIAL_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_DATA_SPLINE_MATERIAL_HH + +#include +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Pc- and Kr-sw curves based on monotone splines through given data points + * \tparam S the type for scalar numbers + * \tpraram approximatePcSwInverse if this is set true, the + * spline approximates sw(pc) and evaluating pc(sw) needs spline inversion. + * if this is false, the spline approximates pc(sw) and evaluating + * sw(pc) needs spline inversion. Spline inversion is rather expensive + * since it has to be done numerically. + */ +template +class DataSplineTwoPMaterialLaw +: public Adapter, PcKrSw> +{ +public: + + using Scalar = S; + + /*! + * \brief Return the number of fluid phases + */ + static constexpr int numFluidPhases() + { return 2; } + + static constexpr bool isRegularized() + { return false; } + + /*! + * \brief Deleted default constructor (so we are never in an undefined state) + * \note store owning pointers to laws instead if you need default-constructible objects + */ + DataSplineTwoPMaterialLaw() = delete; + + /*! + * \brief Construct from a subgroup from the global parameter tree + */ + explicit DataSplineTwoPMaterialLaw(const std::string& paramGroup) + { + using V = std::vector; + const std::string swPcGroup = paramGroup.empty() ? "Pc" : paramGroup + ".Pc"; + const auto swPc = getParamFromGroup(swPcGroup, "SwData"); + const std::string krwPcGroup = paramGroup.empty() ? "Krw" : paramGroup + ".Krw"; + const auto swKrw = getParamFromGroup(krwPcGroup, "SwData"); + const std::string krnPcGroup = paramGroup.empty() ? "Krn" : paramGroup + ".Krn"; + const auto swKrn = getParamFromGroup(krnPcGroup, "SwData"); + + const auto pc = getParamFromGroup(paramGroup, "PcData"); + const auto krw = getParamFromGroup(paramGroup, "KrwData"); + const auto krn = getParamFromGroup(paramGroup, "KrnData"); + + updateData_(swPc, pc, swKrw, krw, swKrn, krn); + } + + /*! + * \brief Construct from user data + */ + DataSplineTwoPMaterialLaw(const std::vector& swPc, + const std::vector& pc, + const std::vector& swKrw, + const std::vector& krw, + const std::vector& swKrn, + const std::vector& krn) + { + updateData_(swPc, pc, swKrw, krw, swKrn, krn); + } + + /*! + * \brief The capillary pressure-saturation curve + */ + Scalar pc(const Scalar sw) const + { + if constexpr (approximatePcSwInverse) + return pcSpline_.evalInverse(sw); + else + return pcSpline_.eval(sw); + } + + /*! + * \brief The partial derivative of the capillary pressure w.r.t. the saturation + */ + Scalar dpc_dsw(const Scalar sw) const + { + if constexpr (approximatePcSwInverse) + return 1.0/pcSpline_.evalDerivative(pcSpline_.evalInverse(sw)); + else + return pcSpline_.evalDerivative(sw); + } + + /*! + * \brief The saturation-capillary pressure curve + */ + Scalar sw(const Scalar pc) const + { + if constexpr (approximatePcSwInverse) + return pcSpline_.eval(pc); + else + return pcSpline_.evalInverse(pc); + } + + /*! + * \brief The partial derivative of the saturation to the capillary pressure + */ + Scalar dsw_dpc(const Scalar pc) const + { + if constexpr (approximatePcSwInverse) + return pcSpline_.evalDerivative(pc); + else + return 1.0/pcSpline_.evalDerivative(pcSpline_.evalInverse(pc)); + } + + /*! + * \brief The relative permeability for the wetting phase + */ + Scalar krw(const Scalar sw) const + { + return krwSpline_.eval(sw); + } + + /*! + * \brief The derivative of the relative permeability for the wetting phase w.r.t. saturation + */ + Scalar dkrw_dsw(const Scalar sw) const + { + return krwSpline_.evalDerivative(sw); + } + + /*! + * \brief The relative permeability for the non-wetting phase + */ + Scalar krn(const Scalar sw) const + { + return krnSpline_.eval(sw); + } + + /*! + * \brief The derivative of the relative permeability for the non-wetting phase w.r.t. saturation + */ + Scalar dkrn_dsw(const Scalar sw) const + { + return krnSpline_.evalDerivative(sw); + } + +private: + void updateData_(const std::vector& swPc, + const std::vector& pc, + const std::vector& swKrw, + const std::vector& krw, + const std::vector& swKrn, + const std::vector& krn) + { + if constexpr (approximatePcSwInverse) + pcSpline_.updatePoints(pc, swPc); + else + pcSpline_.updatePoints(swPc, pc); + + krwSpline_.updatePoints(swKrw, krw); + krnSpline_.updatePoints(swKrn, krn); + } + + MonotoneCubicSpline pcSpline_; + MonotoneCubicSpline krwSpline_; + MonotoneCubicSpline krnSpline_; +}; + +} // end namespace Dumux::FluidMatrix + +#endif -- GitLab From ea0b18769004c21c95d54c58ef4e78079df4e76d Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Sun, 19 May 2019 17:17:36 +0200 Subject: [PATCH 13/99] [test] Implement test for new 2p material laws --- .../fluidmatrixinteractions/2p/CMakeLists.txt | 6 + .../2p/test_2p_materiallaw.cc | 107 ++++++++++++++++++ .../2p/test_2p_materiallaw.input | 6 + 3 files changed, 119 insertions(+) create mode 100644 test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.cc create mode 100644 test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.input diff --git a/test/material/fluidmatrixinteractions/2p/CMakeLists.txt b/test/material/fluidmatrixinteractions/2p/CMakeLists.txt index ce1b775409..cd6a5708a7 100644 --- a/test/material/fluidmatrixinteractions/2p/CMakeLists.txt +++ b/test/material/fluidmatrixinteractions/2p/CMakeLists.txt @@ -23,3 +23,9 @@ dumux_add_test(SOURCES test_material_2p_brookscorey.cc --files ${CMAKE_SOURCE_DIR}/test/references/test_pcsw_brookscorey.dat ${CMAKE_CURRENT_BINARY_DIR}/test_pcsw_brookscorey.dat --command "${CMAKE_CURRENT_BINARY_DIR}/test_material_2p_brookscorey") + + +dune_add_test(SOURCES test_2p_materiallaw.cc + LABELS unit material) + +dune_symlink_to_source_files(FILES test_2p_materiallaw.input) diff --git a/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.cc b/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.cc new file mode 100644 index 0000000000..997af42093 --- /dev/null +++ b/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.cc @@ -0,0 +1,107 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup MaterialTests + * \brief Test for two-phase material laws + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +template +std::vector eval(const Function& f, const std::vector& x) +{ + auto y = x; + std::transform(x.begin(), x.end(), y.begin(), [&](const double x) { return f(x); }); + return y; +} + +int main(int argc, char** argv) try +{ + using namespace Dumux; + + Parameters::init(argc, argv); + + using MaterialLaw = FluidMatrix::TwoPMaterialLaw>; + auto vg = std::make_shared("MaterialLaw"); // read parameters from input file (group MaterialLaw) + + using MaterialLawSpline = FluidMatrix::TwoPMaterialLaw>; + auto vgSpline = std::make_shared("MaterialLaw"); // read parameters from input file (group MaterialLaw) + + const auto swMinPlot = getParam("Plot.SwMin", 0.1); + const auto swMaxPlot = getParam("Plot.SwMax", 1.0); + const auto sw = linspace(swMinPlot, swMaxPlot, 1000); + const auto pc = eval([&](auto sw){ return vg->pc(sw); }, sw); + const auto pcSpline = eval([&](auto sw){ return vgSpline->pc(sw); }, sw); + + GnuplotInterface gnuplot(false); + gnuplot.addDataSetToPlot(sw, pc, "pcsw.dat", "title 'van Genuchten pc-sw curve'"); + gnuplot.addDataSetToPlot(sw, pcSpline, "pcswspline.dat", "title 'van Genuchten pc-sw curve (spline interpolation)'"); + gnuplot.setOption("set xrange [0.0 : 1.0]"); + gnuplot.plot("vangenuchten"); + + // speed test + { + const auto swMinSpline = getParam("MaterialLaw.Spline.MinSw", 0.1); + const auto swMaxSpline = getParam("MaterialLaw.Spline.MaxSw", 1.0); + constexpr std::size_t testSamples = 1000000; + const auto swTest = linspace(swMinSpline, swMaxSpline, testSamples); + auto pcTest = swTest; + + Dune::Timer timer; + double res = 0.0; + for (int i = 0; i < testSamples; ++i) + res += vg->pc(swTest[i]); + timer.stop(); + const auto vgTime = timer.elapsed(); + std::cout << "Unregularized law computed " << testSamples << " samples in " << vgTime << " seconds." << std::endl; + timer.reset(); + timer.start(); + res = 0.0; + for (int i = 0; i < testSamples; ++i) + res += vgSpline->pc(swTest[i]); + timer.stop(); + const auto vgSplineTime = timer.elapsed(); + std::cout << "Spline law computed " << testSamples << " samples in " << vgSplineTime << " seconds." << std::endl; + std::cout << "Speed-up factor ca. " << std::ceil(vgTime/vgSplineTime) << "x (only in spline region)" << std::endl; + } + + return 0; +} +// ////////////////////////////////// +// Error handler +// ///////////////////////////////// +catch (const Dune::Exception& e) { + + std::cout << e << std::endl; + return 1; +} diff --git a/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.input b/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.input new file mode 100644 index 0000000000..ed12b1ae4d --- /dev/null +++ b/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.input @@ -0,0 +1,6 @@ +[MaterialLaw] +VgAlpha = 2.956e-4 +Vgn = 1.5 +Spline.NumPoints = 40 +Spline.MinSw = 0.1 +Spline.MaxSw = 0.9 -- GitLab From c43e8e28e58c9cfdba2b140e402fb600718b3934 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Fri, 25 Sep 2020 13:17:26 +0200 Subject: [PATCH 14/99] [2p][material][test] Add test for spline material law --- .../fluidmatrixinteractions/2p/CMakeLists.txt | 4 +- .../2p/test_2p_materiallaw.input | 6 -- ...eriallaw.cc => test_material_2p_spline.cc} | 88 +++++++++++++------ .../2p/test_material_2p_spline.input | 9 ++ 4 files changed, 73 insertions(+), 34 deletions(-) delete mode 100644 test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.input rename test/material/fluidmatrixinteractions/2p/{test_2p_materiallaw.cc => test_material_2p_spline.cc} (52%) create mode 100644 test/material/fluidmatrixinteractions/2p/test_material_2p_spline.input diff --git a/test/material/fluidmatrixinteractions/2p/CMakeLists.txt b/test/material/fluidmatrixinteractions/2p/CMakeLists.txt index cd6a5708a7..e7db7f7a02 100644 --- a/test/material/fluidmatrixinteractions/2p/CMakeLists.txt +++ b/test/material/fluidmatrixinteractions/2p/CMakeLists.txt @@ -25,7 +25,7 @@ dumux_add_test(SOURCES test_material_2p_brookscorey.cc --command "${CMAKE_CURRENT_BINARY_DIR}/test_material_2p_brookscorey") -dune_add_test(SOURCES test_2p_materiallaw.cc +dune_add_test(SOURCES test_material_2p_spline.cc LABELS unit material) -dune_symlink_to_source_files(FILES test_2p_materiallaw.input) +dune_symlink_to_source_files(FILES test_material_2p_spline.input) diff --git a/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.input b/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.input deleted file mode 100644 index ed12b1ae4d..0000000000 --- a/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.input +++ /dev/null @@ -1,6 +0,0 @@ -[MaterialLaw] -VgAlpha = 2.956e-4 -Vgn = 1.5 -Spline.NumPoints = 40 -Spline.MinSw = 0.1 -Spline.MaxSw = 0.9 diff --git a/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.cc b/test/material/fluidmatrixinteractions/2p/test_material_2p_spline.cc similarity index 52% rename from test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.cc rename to test/material/fluidmatrixinteractions/2p/test_material_2p_spline.cc index 997af42093..28f4fd6824 100644 --- a/test/material/fluidmatrixinteractions/2p/test_2p_materiallaw.cc +++ b/test/material/fluidmatrixinteractions/2p/test_material_2p_spline.cc @@ -33,9 +33,10 @@ #include #include -#include -#include -#include +#include +#include + +namespace Dumux { template std::vector eval(const Function& f, const std::vector& x) @@ -45,34 +46,37 @@ std::vector eval(const Function& f, const std::vector& x) return y; } -int main(int argc, char** argv) try +template +void runTest(const std::string& name, const Function& f, + const Orig& orig, const Spline& spline, + bool plot = true) { - using namespace Dumux; + std::cout << "-----------------------\n" + << name << "\n" + << "-----------------------\n"; - Parameters::init(argc, argv); - using MaterialLaw = FluidMatrix::TwoPMaterialLaw>; - auto vg = std::make_shared("MaterialLaw"); // read parameters from input file (group MaterialLaw) - - using MaterialLawSpline = FluidMatrix::TwoPMaterialLaw>; - auto vgSpline = std::make_shared("MaterialLaw"); // read parameters from input file (group MaterialLaw) + if (plot) + { + const auto [swMinPlot, swMaxPlot] + = getParam>("Plot.Range", std::array{{0.1, 1.0}}); - const auto swMinPlot = getParam("Plot.SwMin", 0.1); - const auto swMaxPlot = getParam("Plot.SwMax", 1.0); - const auto sw = linspace(swMinPlot, swMaxPlot, 1000); - const auto pc = eval([&](auto sw){ return vg->pc(sw); }, sw); - const auto pcSpline = eval([&](auto sw){ return vgSpline->pc(sw); }, sw); + const auto sw = linspace(swMinPlot, swMaxPlot, 1000); + const auto value = eval([&](auto sw){ return f(sw, orig); }, sw); + const auto valueSpline = eval([&](auto sw){ return f(sw, spline); }, sw); - GnuplotInterface gnuplot(false); - gnuplot.addDataSetToPlot(sw, pc, "pcsw.dat", "title 'van Genuchten pc-sw curve'"); - gnuplot.addDataSetToPlot(sw, pcSpline, "pcswspline.dat", "title 'van Genuchten pc-sw curve (spline interpolation)'"); - gnuplot.setOption("set xrange [0.0 : 1.0]"); - gnuplot.plot("vangenuchten"); + GnuplotInterface gnuplot(false); + gnuplot.addDataSetToPlot(sw, value, name + "-orig.dat", "title 'orig. curve'"); + gnuplot.addDataSetToPlot(sw, valueSpline, name + "-spline.dat", "title 'spline'"); + gnuplot.setOption("set xrange [0.0 : 1.0]"); + gnuplot.plot(name); + } // speed test { - const auto swMinSpline = getParam("MaterialLaw.Spline.MinSw", 0.1); - const auto swMaxSpline = getParam("MaterialLaw.Spline.MaxSw", 1.0); + const auto [swMinSpline, swMaxSpline] + = getParam>("MaterialLaw.SplineSweInterval", std::array{{0.1, 1.0}}); + constexpr std::size_t testSamples = 1000000; const auto swTest = linspace(swMinSpline, swMaxSpline, testSamples); auto pcTest = swTest; @@ -80,20 +84,52 @@ int main(int argc, char** argv) try Dune::Timer timer; double res = 0.0; for (int i = 0; i < testSamples; ++i) - res += vg->pc(swTest[i]); + res += f(swTest[i], orig); timer.stop(); + const auto vgTime = timer.elapsed(); std::cout << "Unregularized law computed " << testSamples << " samples in " << vgTime << " seconds." << std::endl; + timer.reset(); timer.start(); res = 0.0; for (int i = 0; i < testSamples; ++i) - res += vgSpline->pc(swTest[i]); + res += f(swTest[i], spline); timer.stop(); + const auto vgSplineTime = timer.elapsed(); std::cout << "Spline law computed " << testSamples << " samples in " << vgSplineTime << " seconds." << std::endl; - std::cout << "Speed-up factor ca. " << std::ceil(vgTime/vgSplineTime) << "x (only in spline region)" << std::endl; + + std::cout << "Speed-up factor ca. " << (vgTime/vgSplineTime) << "x (only in spline region)" << std::endl; } +} + +} // end namespace Dumux + +int main(int argc, char** argv) try +{ + using namespace Dumux; + + Parameters::init(argc, argv); + + using MaterialLaw = FluidMatrix::VanGenuchtenNoReg; + MaterialLaw vg("MaterialLaw"); // read parameters from input file (group MaterialLaw) + + using MaterialLawSpline = FluidMatrix::SplineTwoPMaterialLaw; + MaterialLawSpline vgSpline("MaterialLaw"); // read parameters from input file (group MaterialLaw) + + const bool plot = getParam("Plot.EnablePlot"); + + runTest("vg-pc", [](auto sw, const auto& law){ return law.pc(sw); }, vg, vgSpline, plot); + runTest("vg-dpc", [](auto sw, const auto& law){ return law.dpc_dsw(sw); }, vg, vgSpline, plot); + runTest("vg-krw", [](auto sw, const auto& law){ return law.krw(sw); }, vg, vgSpline, plot); + runTest("vg-dkrw", [](auto sw, const auto& law){ return law.dkrw_dsw(sw); }, vg, vgSpline, plot); + runTest("vg-krn", [](auto sw, const auto& law){ return law.krn(sw); }, vg, vgSpline, plot); + runTest("vg-dkrn", [](auto sw, const auto& law){ return law.dkrn_dsw(sw); }, vg, vgSpline, plot); + + // inversions + runTest("vg-sw-i", [](auto sw, const auto& law){ return law.sw(law.pc(sw)); }, vg, vgSpline, plot); + runTest("vg-dsw-i", [](auto sw, const auto& law){ return law.dsw_dpc(law.pc(sw)); }, vg, vgSpline, plot); return 0; } diff --git a/test/material/fluidmatrixinteractions/2p/test_material_2p_spline.input b/test/material/fluidmatrixinteractions/2p/test_material_2p_spline.input new file mode 100644 index 0000000000..6a8c5c01a1 --- /dev/null +++ b/test/material/fluidmatrixinteractions/2p/test_material_2p_spline.input @@ -0,0 +1,9 @@ +[MaterialLaw] +VanGenuchtenAlpha = 2.956e-4 +VanGenuchtenN = 1.5 +SplineSweInterval = 0.1 0.9 +SplineNumSwSamples = 100 + +[Plot] +EnablePlot = false +Range = 0.05 1.0 -- GitLab From 8f2f7379a0663d022ff5547950388a5b85d6f4b7 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Fri, 25 Sep 2020 14:13:22 +0200 Subject: [PATCH 15/99] [2p][material][test] Add test for user data spline material law --- .../fluidmatrixinteractions/2p/CMakeLists.txt | 5 +- .../2p/test_material_2p_dataspline.cc | 112 ++++++++++++++++++ .../2p/test_material_2p_dataspline.input | 12 ++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 test/material/fluidmatrixinteractions/2p/test_material_2p_dataspline.cc create mode 100644 test/material/fluidmatrixinteractions/2p/test_material_2p_dataspline.input diff --git a/test/material/fluidmatrixinteractions/2p/CMakeLists.txt b/test/material/fluidmatrixinteractions/2p/CMakeLists.txt index e7db7f7a02..4b9a096a99 100644 --- a/test/material/fluidmatrixinteractions/2p/CMakeLists.txt +++ b/test/material/fluidmatrixinteractions/2p/CMakeLists.txt @@ -28,4 +28,7 @@ dumux_add_test(SOURCES test_material_2p_brookscorey.cc dune_add_test(SOURCES test_material_2p_spline.cc LABELS unit material) -dune_symlink_to_source_files(FILES test_material_2p_spline.input) +dune_add_test(SOURCES test_material_2p_dataspline.cc + LABELS unit material) + +dune_symlink_to_source_files(FILES test_material_2p_spline.input test_material_2p_dataspline.input) diff --git a/test/material/fluidmatrixinteractions/2p/test_material_2p_dataspline.cc b/test/material/fluidmatrixinteractions/2p/test_material_2p_dataspline.cc new file mode 100644 index 0000000000..82e66f2482 --- /dev/null +++ b/test/material/fluidmatrixinteractions/2p/test_material_2p_dataspline.cc @@ -0,0 +1,112 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup MaterialTests + * \brief Test for two-phase material laws + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +namespace Dumux { + +template +std::vector eval(const Function& f, const std::vector& x) +{ + auto y = x; + std::transform(x.begin(), x.end(), y.begin(), [&](const double x) { return f(x); }); + return y; +} + +template +void runTest(const std::string& name, const Function& f, + const Orig& orig, const Spline& spline, + bool plot = true) +{ + std::cout << "-----------------------\n" + << name << "\n" + << "-----------------------\n"; + + + if (plot) + { + const auto [swMinPlot, swMaxPlot] + = getParam>("Plot.Range", std::array{{0.1, 1.0}}); + + const auto sw = linspace(swMinPlot, swMaxPlot, 1000); + const auto value = eval([&](auto sw){ return f(sw, orig); }, sw); + const auto valueSpline = eval([&](auto sw){ return f(sw, spline); }, sw); + + GnuplotInterface gnuplot(false); + gnuplot.addDataSetToPlot(sw, value, name + "-orig.dat", "title 'orig. curve'"); + gnuplot.addDataSetToPlot(sw, valueSpline, name + "-spline.dat", "title 'spline'"); + gnuplot.setOption("set xrange [0.0 : 1.0]"); + gnuplot.plot(name); + } +} + +} // end namespace Dumux + +int main(int argc, char** argv) try +{ + using namespace Dumux; + + Parameters::init(argc, argv); + + using MaterialLaw = FluidMatrix::LinearMaterialDefault; + MaterialLaw lin("MaterialLaw"); // read parameters from input file (group MaterialLaw) + + using MaterialLawSpline = FluidMatrix::DataSplineTwoPMaterialLaw; + MaterialLawSpline linSpline("MaterialLaw"); // read parameters from input file (group MaterialLaw) + + const bool plot = getParam("Plot.EnablePlot"); + + runTest("lin-pc", [](auto sw, const auto& law){ return law.pc(sw); }, lin, linSpline, plot); + runTest("lin-dpc", [](auto sw, const auto& law){ return law.dpc_dsw(sw); }, lin, linSpline, plot); + runTest("lin-krw", [](auto sw, const auto& law){ return law.krw(sw); }, lin, linSpline, plot); + runTest("lin-dkrw", [](auto sw, const auto& law){ return law.dkrw_dsw(sw); }, lin, linSpline, plot); + runTest("lin-krn", [](auto sw, const auto& law){ return law.krn(sw); }, lin, linSpline, plot); + runTest("lin-dkrn", [](auto sw, const auto& law){ return law.dkrn_dsw(sw); }, lin, linSpline, plot); + + // inversions + runTest("lin-sw-i", [](auto sw, const auto& law){ return law.sw(law.pc(sw)); }, lin, linSpline, plot); + runTest("lin-dsw-i", [](auto sw, const auto& law){ return law.dsw_dpc(law.pc(sw)); }, lin, linSpline, plot); + + return 0; +} +// ////////////////////////////////// +// Error handler +// ///////////////////////////////// +catch (const Dune::Exception& e) { + + std::cout << e << std::endl; + return 1; +} diff --git a/test/material/fluidmatrixinteractions/2p/test_material_2p_dataspline.input b/test/material/fluidmatrixinteractions/2p/test_material_2p_dataspline.input new file mode 100644 index 0000000000..9e1ee32f54 --- /dev/null +++ b/test/material/fluidmatrixinteractions/2p/test_material_2p_dataspline.input @@ -0,0 +1,12 @@ +[MaterialLaw] +LinearPcEntry = 0.0 +LinearPcMax = 1.0 +SwData = 0.0 0.2 0.5 0.7 1.0 +PcData = 1.0 0.8 0.5 0.3 0.0 +KrwData= 0.0 0.2 0.5 0.7 1.0 +KrnData = 1.0 0.8 0.6 0.5 0.3 0.0 +Krn.SwData = 0.0 0.2 0.4 0.5 0.7 1.0 + +[Plot] +EnablePlot = false +Range = 0.0 1.0 -- GitLab From 883477d8190f7e629d8bbac5f03703a94d7af9a5 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 30 Sep 2020 17:46:26 +0200 Subject: [PATCH 16/99] [2p][interfacialarea] Add new classes --- doc/handbook/dumux-handbook.bib | 11 ++ .../2p/interfacialarea/exponential.hh | 147 +++++++++++++++ .../2p/interfacialarea/exponentialcubic.hh | 110 +++++++++++ .../2p/interfacialarea/interfacialarea.hh | 178 ++++++++++++++++++ .../2p/interfacialarea/pcmax.hh | 113 +++++++++++ .../2p/interfacialarea/polynomial2ndorder.hh | 149 +++++++++++++++ .../polynomialedgezero2ndorder.hh | 145 ++++++++++++++ 7 files changed, 853 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponential.hh create mode 100644 dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponentialcubic.hh create mode 100644 dumux/material/fluidmatrixinteractions/2p/interfacialarea/interfacialarea.hh create mode 100644 dumux/material/fluidmatrixinteractions/2p/interfacialarea/pcmax.hh create mode 100644 dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomial2ndorder.hh create mode 100644 dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomialedgezero2ndorder.hh diff --git a/doc/handbook/dumux-handbook.bib b/doc/handbook/dumux-handbook.bib index 9b5588c9ac..a3b6a3ecb4 100644 --- a/doc/handbook/dumux-handbook.bib +++ b/doc/handbook/dumux-handbook.bib @@ -426,6 +426,17 @@ url = {http://elib.uni-stuttgart.de/opus/volltexte/2013/8141} } +@PhdThesis{nuske2014, + author = {Philipp Nuske}, + title = {{Beyond local equilibrium : relaxing local equilibrium assumptions in multiphase flow in porous media}}, + school = {Universit\"at Stuttgart}, + year = {2014}, + address = {Holzgartenstr. 16, 70174 Stuttgart}, + isbn = {978-3-942036-41-2}, + language = {eng}, + url = {https://elib.uni-stuttgart.de/handle/11682/614} +} + @ARTICLE{A3:Braun:2002, author = {Braun, C. and Helmig, R. and Manthey, S.}, title = {{Determination of constitutive relationships for two-phase flow processes diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponential.hh b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponential.hh new file mode 100644 index 0000000000..552922aaf5 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponential.hh @@ -0,0 +1,147 @@ +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Specification of a function relating volume specific interfacial area to capillary pressure and saturation. + * This function is exponential. + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_EXPONENTIAL +#define DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_EXPONENTIAL + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implementation of the exponential function relating + * specific interfacial area to wetting phase saturation and + * capillary pressure as suggested by Nuske(2009) (Diploma thesis) \cite nuske2009 . + */ +class InterfacialAreaExponential +{ +public: + + template + struct Params + { + Params(Scalar swr = 0, Scalar a1 = 0, Scalar a2 = 0, Scalar a3 = 0) + : swr_(swr), a1_(a1), a2_(a2), a3_(a3) {} + + Scalar swr() const { return swr_; } + void setSwr(Scalar swr) { swr_ = swr; } + + Scalar a1() const { return a1_; } + void setA1(Scalar a1) { a1_ = a1; } + + Scalar a2() const { return a2_; } + void setA2(Scalar a2) { a2_ = a2; } + + Scalar a3() const { return a3_; } + void setA3(Scalar a3) { a3_ = a3; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(swr(), p.swr(), 1e-6) + && Dune::FloatCmp::eq(a1(), p.a1(), 1e-6) + && Dune::FloatCmp::eq(a2(), p.a2(), 1e-6) + && Dune::FloatCmp::eq(a3(), p.a3(), 1e-6); + } + + private: + Scalar swr_, a1_, a2_, a3_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + const auto swr = getParamFromGroup(paramGroup, "Swr", 0.0); + const auto a1 = getParamFromGroup(paramGroup, "A1"); + const auto a2 = getParamFromGroup(paramGroup, "A2"); + const auto a3 = getParamFromGroup(paramGroup, "A3"); + return {swr, a1, a2, a3}; + } + + + /*! + * \brief The interfacial area + * + * the suggested (as estimated from pore network models) awn surface: + * \f$\mathrm{ + a_{wn} = a_1 * (S_{wr}-S_w) .* (1-S_w) + a_2 * (S_{wr}-S_w) * (1-S_w) * \exp( a_3 * p_c) ; + }\f$ + * \param sw Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + * \param params parameter container for the coefficients of the surface + */ + template + static Scalar area(const Scalar swe, const Scalar pc, const Params& params) + { + const Scalar a1 = params.a1(); + const Scalar a2 = params.a2(); + const Scalar a3 = params.a3(); + const Scalar swr = params.swr(); + using std::exp; + return a1 * (swr-swe) * (1-swe) + a2 * (swr-swe) * (1-swe) * exp( a3 * pc) ; + } + + /*! \brief the derivative of specific interfacial area function w.r.t. capillary pressure + * + * \param params parameter container for the coefficients of the surface + * \param Sw Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + */ + template + static Scalar darea_dpc(const Scalar swe, const Scalar pc, const Params& params) + { + const Scalar a2 = params.a2(); + const Scalar a3 = params.a3(); + const Scalar swr = params.swr(); + using std::exp; + return a2 * a3 * (swr-swe) * (1-swe) * exp(a3*pc); + } + + /*! \brief the derivative of specific interfacial area function w.r.t. saturation + * + * \param params parameter container for the coefficients of the surface + * \param Sw Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + */ + template + static Scalar darea_dsw(const Scalar swe, const Scalar pc, const Params& params) + { + Scalar a1 = params.a1(); + Scalar a2 = params.a2(); + Scalar a3 = params.a3(); + Scalar swr = params.swr(); + using std::exp; + return - a1 *(1+swr-2*swe) - a2 * exp(a3*pc) * (1+swr-2*swe); + } + +}; + +} // namespace Dumux::FluidMatrix + +#endif diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponentialcubic.hh b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponentialcubic.hh new file mode 100644 index 0000000000..131912dcfb --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponentialcubic.hh @@ -0,0 +1,110 @@ +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Specification of a function relating volume specific interfacial area to capillary pressure and saturation. + * This function is of third order in pc. + * \note It is used for calculating the interfacial area between the nonwetting and solid phase + * by Nuske 2014 (https://elib.uni-stuttgart.de/handle/11682/614, page 62) \cite nuske2014. + * + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_EXPONENTIAL_CUBIC +#define DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_EXPONENTIAL_CUBIC + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implementation of a exponential function relating + * specific interfacial area to wetting phase saturation and capillary pressure. + */ +class InterfacialAreaExponentialCubic +{ +public: + + template + struct Params + { + Params(Scalar a1 = 0, Scalar a2 = 0, Scalar a3 = 0) + : a1_(a1), a2_(a2), a3_(a3) {} + + Scalar a1() const { return a1_; } + void setA1(Scalar a1) { a1_ = a1; } + + Scalar a2() const { return a2_; } + void setA2(Scalar a2) { a2_ = a2; } + + Scalar a3() const { return a3_; } + void setA3(Scalar a3) { a3_ = a3; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(a1(), p.a1(), 1e-6) + && Dune::FloatCmp::eq(a2(), p.a2(), 1e-6) + && Dune::FloatCmp::eq(a3(), p.a3(), 1e-6); + } + + private: + Scalar a1_, a2_, a3_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + const auto a1 = getParamFromGroup(paramGroup, "A1"); + const auto a2 = getParamFromGroup(paramGroup, "A2"); + const auto a3 = getParamFromGroup(paramGroup, "A3"); + return {a1, a2, a3}; + } + + /*! + * \brief The interfacial area + * + * the suggested (as estimated from pore network models) interfacial area between the nonwetting and solid phase: + * \f$\mathrm{ + a_{ns} = a_1 e^{a_2 * S_w } + a_3 * p_c^3 ; + }\f$ + * \param swe Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + * \param params parameter container for the coefficients of the surface + */ + template + static Scalar area(const Scalar swe, const Scalar pc, const Params& params) + { + // TODO think about awn surface for relative saturation + const Scalar a1 = params.a1(); + const Scalar a2 = params.a2(); + const Scalar a3 = params.a3(); + + using std::exp; + return a1 * exp( a2 * swe) + a3 * pc * pc * pc ; + } +}; + +} // namespace Dumux::FluidMatrix + +#endif diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/interfacialarea.hh b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/interfacialarea.hh new file mode 100644 index 0000000000..722c8caaec --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/interfacialarea.hh @@ -0,0 +1,178 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Implementation helper for capillary-pressure-saturation-interfacial-area relations + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_HH + +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper class to implement regularized laws (pc-sw-a) + * with a conversion policy between absolution and effective saturations + * \tparam ScalarType the scalar type + * \tparam BaseLaw the base law (e.g. VanGenuchten, BrooksCorey, Linear, ...) + * \tparam Regularization the regularization type (set to NoAwnRegularization to turn it off) + * \tparam EffToAbsPolicy the policy how to convert effective <-> absolute saturations + * + * \note The regularization interface is expected to return Dumux::OptionalScalars which + * are wrappers around a Scalar type that provide a boolean operator to + * check whether the result is valid. If the regularization returns + * a non-valid value, it means that the given parameter + * range is outside the regularized region. + * For that case we forward to the call to the standard law. + */ +template class InterfaceType, + class Regularization = NoRegularization, + class EffToAbsPolicy = TwoPEffToAbsDefaultPolicy> +class InterfacialArea : public Adapter, InterfaceType> +{ +public: + + using Scalar = ScalarType; + + using BasicParams = typename BaseLaw::template Params; + using EffToAbsParams = typename EffToAbsPolicy::template Params; + using RegularizationParams = typename Regularization::template Params; + + using EffToAbs = EffToAbsPolicy; + + /*! + * \brief Return whether this law is regularized + */ + static constexpr bool isRegularized() + { return !std::is_same::value; } + + /*! + * \brief Deleted default constructor (so we are never in an undefined state) + * \note store owning pointers to laws instead if you need default-constructible objects + */ + InterfacialArea() = delete; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + explicit InterfacialArea(const std::string& paramGroup) + { + basicParams_ = BaseLaw::template makeParams(paramGroup); + effToAbsParams_ = EffToAbs::template makeParams(paramGroup); + + if constexpr (isRegularized()) + regularization_.init(this, paramGroup); + } + + /*! + * \brief Construct from parameter structs + * \note More efficient constructor but you need to ensure all parameters are initialized + */ + InterfacialArea(const BasicParams& baseParams, + const EffToAbsParams& effToAbsParams = {}, + const RegularizationParams& regParams = {}) + : basicParams_(baseParams) + , effToAbsParams_(effToAbsParams) + { + if constexpr (isRegularized()) + regularization_.init(this, baseParams, effToAbsParams, regParams); + } + + /*! + * \brief The capillary pressure-saturation curve + */ + template + Scalar area(const Scalar sw, const Scalar pc) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.area(swe, pc); + if (regularized) + return regularized.value(); + } + + return BaseLaw::area(swe, pc, basicParams_); + } + + /*! + * \brief The partial derivative of the capillary pressure w.r.t. the saturation + */ + template + Scalar darea_dpc(const Scalar sw, const Scalar pc) const + { + if constexpr (enableRegularization) + { + const auto regularized = regularization_.darea_dpc(sw, pc); + if (regularized) + return regularized.value(); + } + + return BaseLaw::darea_dpc(sw, pc, basicParams_); + } + + /*! + * \brief The partial derivative of the saturation to the capillary pressure + */ + template + Scalar darea_dsw(const Scalar sw, const Scalar pc) const + { + if constexpr (enableRegularization) + { + const auto regularized = regularization_.darea_dsw(sw, pc); + if (regularized) + return regularized.value(); + } + + return BaseLaw::darea_dsw(sw, pc, basicParams_); + } + + /*! + * \brief Equality comparison with another instance + */ + bool operator== (const InterfacialArea& o) const + { + return basicParams_ == o.basicParams_ + && effToAbsParams_ == o.effToAbsParams_ + && regularization_ == o.regularization_; + } + + const BasicParams& basicParams() const + { return basicParams_; } + + const EffToAbsParams& effToAbsParams() const + { return effToAbsParams_; } + +private: + BasicParams basicParams_; + EffToAbsParams effToAbsParams_; + Regularization regularization_; +}; + +} // end namespace Dumux::FluidMatrix + +#endif diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/pcmax.hh b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/pcmax.hh new file mode 100644 index 0000000000..e77234ecc6 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/pcmax.hh @@ -0,0 +1,113 @@ +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Specification of a function relating volume specific interfacial area to capillary pressure and saturation. + * This parametrization uses a maximum value of capillary pressure. + * + * \note It is used for calculating the interfacial area between the nonwetting and wetting phase + * by Nuske 2014 (https://elib.uni-stuttgart.de/handle/11682/614, page 60) \cite nuske2014. + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_PC_MAX +#define DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_PC_MAX + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implementation of the polynomial of second order relating + * specific interfacial area to wetting phase saturation and capillary pressure. + */ +class InterfacialAreaPcMax +{ +public: + + template + struct Params + { + Params(Scalar pcMax = 0, Scalar a1 = 0, Scalar a2 = 0, Scalar a3 = 0) + : pcMax_(pcMax), a1_(a1), a2_(a2), a3_(a3) {} + + Scalar pcMax() const { return pcMax_; } + void setPcMax(Scalar pcMax) { pcMax_ = pcMax; } + + Scalar a1() const { return a1_; } + void setA1(Scalar a1) { a1_ = a1; } + + Scalar a2() const { return a2_; } + void setA2(Scalar a2) { a2_ = a2; } + + Scalar a3() const { return a3_; } + void setA3(Scalar a3) { a3_ = a3; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(pcMax(), p.pcMax(), 1e-6) + && Dune::FloatCmp::eq(a1(), p.a1(), 1e-6) + && Dune::FloatCmp::eq(a2(), p.a2(), 1e-6) + && Dune::FloatCmp::eq(a3(), p.a3(), 1e-6); + } + + private: + Scalar pcMax_, a1_, a2_, a3_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + const auto pcMax = getParamFromGroup(paramGroup, "PcMax"); + const auto a1 = getParamFromGroup(paramGroup, "A1"); + const auto a2 = getParamFromGroup(paramGroup, "A2"); + const auto a3 = getParamFromGroup(paramGroup, "A3"); + return {pcMax, a1, a2, a3}; + } + + /*! + * \brief The interfacial area + * + * the suggested (as estimated from pore network models) interfacial area between the nonwetting and wetting phase: + * \f$\mathrm{ + a_{wn} = a_{1} (p_{c { \sf max} } - p_{c}) (1-S_{w}) + a_{2} (p_{c {\sf max} } -p_{c})^2 (1-S_{w}) + a_{3} (p_{c {\sf max} }- p_{c}) (1-S_{w})^2 + }\f$ + * \param swe Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + * \param params parameter container for the coefficients of the surface + */ + template + static Scalar area(const Scalar swe, const Scalar pc, const Params& params) + { + const Scalar a1 = params.a1(); + const Scalar a2 = params.a2(); + const Scalar a3 = params.a3(); + const Scalar pcMax = params.pcMax(); + return a1 * (pcMax-pc) * (1.0-swe) + a2*(pcMax-pc)*(pcMax-pc) * (1.-swe) + a3 * (pcMax-pc)*(1-swe)*(1-swe); + } +}; + +} // namespace Dumux::FluidMatrix + +#endif diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomial2ndorder.hh b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomial2ndorder.hh new file mode 100644 index 0000000000..1b0f44599c --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomial2ndorder.hh @@ -0,0 +1,149 @@ +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Specification of a function relating volume specific interfacial area to capillary pressure and saturation. + * This parametrization is a second order polynomial. + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_POLYNOMIAL_SECOND_ORDER_HH +#define DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_POLYNOMIAL_SECOND_ORDER_HH + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implementation of the polynomial of second order relating + * specific interfacial area to wetting phase saturation and capillary pressure as suggested by Joekar-Niasar(2008) \cite joekar2008 . + */ +class InterfacialAreaPolynomialSecondOrder +{ +public: + + template + struct Params + { + Params(Scalar a00 = 0, Scalar a01 = 0, Scalar a02 = 0, Scalar a10 = 0, Scalar a11 = 0, Scalar a20 = 0) + : a00_(a00), a01_(a01), a02_(a02), a10_(a10), a11_(a11), a20_(a20) {} + + Scalar a00() const { return a00_; } + void setA00(Scalar a00) { a00_ = a00; } + + Scalar a01() const { return a01_; } + void setA01(Scalar a01) { a01_ = a01; } + + Scalar a02() const { return a02_; } + void setA02(Scalar a02) { a02_ = a02; } + + Scalar a10() const { return a10_; } + void setA10(Scalar a10) { a10_ = a10; } + + Scalar a11() const { return a11_; } + void setA11(Scalar a11) { a11_ = a11; } + + Scalar a20() const { return a20_; } + void setA20(Scalar a20) { a20_ = a20; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(a00(), p.a00(), 1e-6) + && Dune::FloatCmp::eq(a01(), p.a01(), 1e-6) + && Dune::FloatCmp::eq(a02(), p.a02(), 1e-6) + && Dune::FloatCmp::eq(a10(), p.a10(), 1e-6) + && Dune::FloatCmp::eq(a11(), p.a11(), 1e-6) + && Dune::FloatCmp::eq(a20(), p.a20(), 1e-6); + } + + private: + Scalar a00_, a01_, a02_, a10_, a11_, a20_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + const auto a00 = getParamFromGroup(paramGroup, "A00", 0.0); + const auto a01 = getParamFromGroup(paramGroup, "A01"); + const auto a02 = getParamFromGroup(paramGroup, "A02"); + const auto a10 = getParamFromGroup(paramGroup, "A10"); + const auto a11 = getParamFromGroup(paramGroup, "A11"); + const auto a20 = getParamFromGroup(paramGroup, "A20"); + return {a00, a01, a02, a10, a11, a20}; + } + + /*! + * \brief The interfacial area + * + * the suggested (as estimated from pore network models) awn surface: + * \f$[ + a_{wn} = a_{00} + a_{10}S_{w} + a_{20}S_{w}^2 + a_{11} S_{w} p_{c} + a_{01} p_{c} + a_{02}p_{c}^2 + \f$] + * \param params parameter container for the coefficients of the surface + * \param Sw Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + */ + template + static Scalar area(const Scalar swe, const Scalar pc, const Params& params) + { + const Scalar a00 = params.a00(); + const Scalar a10 = params.a10(); + const Scalar a20 = params.a20(); + const Scalar a11 = params.a11(); + const Scalar a01 = params.a01(); + const Scalar a02 = params.a02(); + + return a00 + a10 * swe + a20 * swe*swe + a11*swe*pc + a01*pc + a02*pc*pc; + } + + /*! + * \brief the derivative of specific interfacial area function w.r.t. capillary pressure + * + * \param params parameter container for the coefficients of the surface + * \param Sw Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + */ + template + static Scalar darea_dpc(const Scalar swe, const Scalar pc, const Params& params) + { + return params.a11()*swe + params.a01() + 2.0*params.a02() * pc; + } + + /*! + * \brief the derivative of specific interfacial area function w.r.t. saturation + * + * \param params parameter container for the coefficients of the surface + * \param Sw Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + */ + template + static Scalar darea_dsw(const Scalar swe, const Scalar pc, const Params& params) + { + return params.a11()*pc + params.a10() + 2.0*params.a20()*swe; + } +}; + +} // end namespace Dumux::FluidMatrix + +#endif diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomialedgezero2ndorder.hh b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomialedgezero2ndorder.hh new file mode 100644 index 0000000000..4c07969b90 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomialedgezero2ndorder.hh @@ -0,0 +1,145 @@ +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Specification of a function relating volume specific interfacial area to capillary pressure and saturation. + * This parametrization is a second order polynomial which is zero for saturations of zero and one. + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_EXPONENTIAL_CUBIC +#define DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_EXPONENTIAL_CUBIC + +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implementation of the polynomial of second order relating + * specific interfacial area to wetting phase saturation and capillary pressure. + */ +class InterfacialAreaolynomialEdgeZero2ndOrder +{ +public: + + template + struct Params + { + Params(Scalar swr = 0, Scalar a1 = 0, Scalar a2 = 0, Scalar a3 = 0) + : swr_(swr), a1_(a1), a2_(a2), a3_(a3) {} + + Scalar swr() const { return swr_; } + void setSwr(Scalar swr) { swr_ = swr; } + + Scalar a1() const { return a1_; } + void setA1(Scalar a1) { a1_ = a1; } + + Scalar a2() const { return a2_; } + void setA2(Scalar a2) { a2_ = a2; } + + Scalar a3() const { return a3_; } + void setA3(Scalar a3) { a3_ = a3; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(swr(), p.swr(), 1e-6) + && Dune::FloatCmp::eq(a1(), p.a1(), 1e-6) + && Dune::FloatCmp::eq(a2(), p.a2(), 1e-6) + && Dune::FloatCmp::eq(a3(), p.a3(), 1e-6); + } + + private: + Scalar swr_, a1_, a2_, a3_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + const auto swr = getParamFromGroup(paramGroup, "Swr", 0.0); + const auto a1 = getParamFromGroup(paramGroup, "A1"); + const auto a2 = getParamFromGroup(paramGroup, "A2"); + const auto a3 = getParamFromGroup(paramGroup, "A3"); + return {swr, a1, a2, a3}; + } + + /*! + * \brief The interfacial area + * the suggested (as estimated from pore network models) awn surface: + * \f$[ + a_{wn} = a_{1} (S_{wr}-S_{w})(1.-S_{w}) + a_2 (S_{wr}-S_{w})(1.-S_{w}) p_{c} + a_{3} (S_{wr}-S_{w})(1.-S_{w}) p_{c}^2 + \f$] + * \param sw Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + * \param params parameter container for the coefficients of the surface + */ + template + static Scalar area(const Scalar sw, const Scalar pc, const Params& params) + { + const Scalar a1 = params.a1(); + const Scalar a2 = params.a2(); + const Scalar a3 = params.a3(); + const Scalar swr = params.swr(); + const Scalar factor = (swr-sw)*(1.0-sw) ; + return a1*factor + a2*factor*pc + a3*factor*pc*pc; + } + + /*! + * \brief the derivative of specific interfacial area function w.r.t. capillary pressure + * + * \param sw Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + * \param params parameter container for the coefficients of the surface + */ + template + static Scalar darea_dpc(const Scalar sw, const Scalar pc, const Params& params) + { + const Scalar swr = params.swr(); + const Scalar a1 = params.a1(); + const Scalar a2 = params.a2(); + const Scalar a3 = params.a3(); + return a2*(swr-sw)*(1-sw) + a3*(swr-sw)*(1-sw)*pc; + } + + /*! + * \brief the derivative of specific interfacial area function w.r.t. saturation + * + * \param sw Effective saturation of the wetting phase + * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ + * \param params parameter container for the coefficients of the surface + */ + template + static Scalar darea_dsw(const Scalar sw, const Scalar pc, const Params& params) + { + const Scalar swr = params.swr(); + const Scalar a1 = params.a1(); + const Scalar a2 = params.a2(); + const Scalar a3 = params.a3(); + const Scalar derivativeFactor = (sw-1.0)+(sw-swr); + return a1 * derivativeFactor + a2 * derivativeFactor * pc + a3 * derivativeFactor * pc*pc ; + } +}; + +} // namespace Dumux::FluidMatrix + +#endif -- GitLab From 12e258c216638173a70b8406cb51db86b8c176f6 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 1 Oct 2020 18:51:43 +0200 Subject: [PATCH 17/99] [fluidmatrixinteractions] Update CMakeLists.txt --- dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt | 5 +++++ dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt | 6 ++++++ dumux/material/fluidmatrixinteractions/CMakeLists.txt | 1 + 3 files changed, 12 insertions(+) diff --git a/dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt b/dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt index d2a4aacc96..84bbb5107a 100644 --- a/dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt +++ b/dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt @@ -3,18 +3,23 @@ add_subdirectory(thermalconductivity) install(FILES brookscorey.hh brookscoreyparams.hh +datasplinemateriallaw.hh +efftoabsdefaultpolicy.hh efftoabslaw.hh efftoabslawparams.hh heatpipelaw.hh heatpipelawparams.hh linearmaterial.hh linearmaterialparams.hh +materiallaw.hh regularizedbrookscorey.hh regularizedbrookscoreyparams.hh regularizedlinearmaterial.hh regularizedlinearmaterialparams.hh regularizedvangenuchten.hh regularizedvangenuchtenparams.hh +smoothedlinearlaw.hh +splinemateriallaw.hh thermalconductivityjohansen.hh thermalconductivitysimplefluidlumping.hh thermalconductivitysomerton.hh diff --git a/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt b/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt index 4040d3bc88..4e84fedb46 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt +++ b/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt @@ -11,4 +11,10 @@ awnsurfacepolynomialedgezero2ndorder.hh awnsurfacepolynomialedgezero2ndorderparams.hh efftoabslawia.hh efftoabslawiaparams.hh +interfacialarea.hh +interfacialareaexponential.hh +interfacialareaexponentialcubic.hh +interfacialareapcmax.hh +interfacialareapolynomial2ndorder.hh +interfacialareapolynomialedgezero2ndorder.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/material/fluidmatrixinteractions/2pia) diff --git a/dumux/material/fluidmatrixinteractions/CMakeLists.txt b/dumux/material/fluidmatrixinteractions/CMakeLists.txt index 1d9150947d..a91d616193 100644 --- a/dumux/material/fluidmatrixinteractions/CMakeLists.txt +++ b/dumux/material/fluidmatrixinteractions/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(mp) install(FILES diffusivityconstanttortuosity.hh diffusivitymillingtonquirk.hh +fluidmatrixinteraction.hh permeabilitykozenycarman.hh porositydeformation.hh porosityprecipitation.hh -- GitLab From 40244ba1974db74c31af69110533978a2527c187 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 27 Jun 2019 15:51:09 +0200 Subject: [PATCH 18/99] [spatialparams] Deprecate old materialLawParams interface --- dumux/material/spatialparams/fv.hh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dumux/material/spatialparams/fv.hh b/dumux/material/spatialparams/fv.hh index 4fb8c097b5..655061380f 100644 --- a/dumux/material/spatialparams/fv.hh +++ b/dumux/material/spatialparams/fv.hh @@ -68,6 +68,16 @@ public: : ParentType(gridGeometry) {} + // make sure we get a deprecation warning (remove this after release 3.3) + template + [[deprecated("Use the new style material laws. Old material laws and this interface will no longer be supported after release 3.3")]] + decltype(auto) materialLawParamsDeprecated(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { + return this->asImp_().materialLawParams(element, scv, elemSol); + } + /*! * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). * @@ -77,6 +87,7 @@ public: * \return the material parameters object */ template + [[deprecated("Use the new style material laws. Old material laws and this interface will no longer be supported after release 3.3")]] decltype(auto) materialLawParams(const Element& element, const SubControlVolume& scv, const ElementSolution& elemSol) const -- GitLab From bbcd3c6567f9937a1376e79ecbbf59b05ad25cb0 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 27 Jun 2019 15:51:55 +0200 Subject: [PATCH 19/99] [deprecated] Implement a wrapper that support old and new material law interfaces --- dumux/common/deprecated.hh | 345 ++++++++++++++++++++++++++++++++++++- 1 file changed, 344 insertions(+), 1 deletion(-) diff --git a/dumux/common/deprecated.hh b/dumux/common/deprecated.hh index 3e191a6891..ab57ac33c5 100644 --- a/dumux/common/deprecated.hh +++ b/dumux/common/deprecated.hh @@ -26,6 +26,8 @@ #define DUMUX_COMMON_DEPRECATED_HH #include +#include +#include namespace Dumux { @@ -43,9 +45,350 @@ namespace Deprecated { //////////////////////////////////////////// /////////////////////////////////////////////////////////////// -// Deprecation warnings for effective diffusion coefficients // +// Deprecation warnings for the new material law // /////////////////////////////////////////////////////////////// +// support old interface of the effective thermal conductivity laws +template +struct HasNewFIAIF +{ + template + auto operator()(S&& sp) + -> decltype(sp.fluidMatrixInteraction(std::declval(), + std::declval(), + std::declval())) {} +}; + +template +struct HasNewFIAIFAtPos +{ + template + auto operator()(S&& sp) + -> decltype(sp.fluidMatrixInteractionAtPos(std::declval())) {} +}; + + +template +class PcKrSwHelper : public FluidMatrix::Adapter, FluidMatrix::PcKrSw> +{ +public: + using Scalar = ScalarT; + + // pass scalar so template arguments can all be deduced + PcKrSwHelper(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol) + : spatialParams_(sp), element_(element), scv_(scv), elemSol_(elemSol) + {} + + Scalar krw(const Scalar sw) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::krw(params, sw); + } + + Scalar krn(const Scalar sw) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::krn(params, sw); + } + + Scalar pc(const Scalar sw) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::pc(params, sw); + } + + Scalar dpc_dsw(const Scalar sw) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::dpc_dsw(params, sw); + } + + Scalar endPointPc() const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::endPointPc(params); + } + + Scalar sw(const Scalar pc) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::sw(params, pc); + } + + Scalar dsw_dpc(const Scalar pc) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::dsw_dpc(params, pc); + } + + Scalar dkrw_dsw(const Scalar sw) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::dkrw_dsw(params, sw); + } + + Scalar dkrn_dsw(const Scalar sw) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::dkrn_dsw(params, sw); + } + +private: + const SpatialParams& spatialParams_; + const Element& element_; + const Scv& scv_; + const ElemSol& elemSol_; +}; + +template +auto makeDeprecationPcKrSwHelper(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol) +{ + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + constexpr bool hasNew = decltype(isValid(HasNewFIAIF()).template check())::value; + constexpr bool hasNewAtPos = decltype(isValid(HasNewFIAIFAtPos()).template check())::value; + if constexpr (hasNew) + return sp.fluidMatrixInteraction(element, scv, elemSol); + else if constexpr (hasNewAtPos) + return sp.fluidMatrixInteractionAtPos(scv.center()); + else + return makeFluidMatrixInteraction(PcKrSwHelper(scalar, sp, element, scv, elemSol)); +} + + + +/////////////////////////////////////////////////////////////// +// Deprecation warnings for the kinetic surface areas // +/////////////////////////////////////////////////////////////// + +// support old interface of surface area +template +struct HasNewAns +{ + template + auto operator()(S&& sp) + -> decltype(sp.nonwettingSolidInterfacialArea(std::declval(), + std::declval(), + std::declval())) {} +}; + +template +struct HasNewAnsAtPos +{ + template + auto operator()(S&& sp) + -> decltype(sp.nonwettingSolidInterfacialAreaAtPos(std::declval())) {} +}; + +// support old interface of surface area +template +struct HasNewAnw +{ + template + auto operator()(S&& sp) + -> decltype(sp.wettingNonwettingInterfacialArea(std::declval(), + std::declval(), + std::declval())) {} +}; + +template +struct HasNewAnwAtPos +{ + template + auto operator()(S&& sp) + -> decltype(sp.wettingNonwettingInterfacialAreaAtPos(std::declval())) {} +}; + +// support old interface of surface area +template +struct HasNewAws +{ + template + auto operator()(S&& sp) + -> decltype(sp.wettingSolidInterfacialArea(std::declval(), + std::declval(), + std::declval())) {} +}; + +template +struct HasNewAwsAtPos +{ + template + auto operator()(S&& sp) + -> decltype(sp.wettingSolidInterfacialAreaAtPos(std::declval())) {} +}; + +template +class WettingNonwettingInterfacialArea : public FluidMatrix::Adapter, FluidMatrix::WettingNonwettingInterfacialAreaPcSw> +{ +public: + using Scalar = ScalarT; + + WettingNonwettingInterfacialArea(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol) + : spatialParams_(sp), element_(element), scv_(scv), elemSol_(elemSol) + {} + + const auto& basicParams() const + { + return spatialParams_.aWettingNonWettingSurfaceParams(element_, scv_, elemSol_); + } + + Scalar area(const Scalar sw, const Scalar pc) const + { + const auto& surfaceParams = spatialParams_.aWettingNonWettingSurfaceParams(element_, scv_, elemSol_); + const auto& materialParams = spatialParams_.materialLawParams(element_, scv_, elemSol_); + using AwnSurface = typename SpatialParams::AwnSurface; + return AwnSurface::interfacialArea(surfaceParams, materialParams, sw, pc); + } + + Scalar darea_dpc(const Scalar sw, const Scalar pc) + { + const auto& surfaceParams = spatialParams_.aWettingNonWettingSurfaceParams(element_, scv_, elemSol_); + using AwnSurface = typename SpatialParams::AwnSurface; + return AwnSurface::dawn_dpc(surfaceParams, sw, pc); + } + + Scalar darea_dsw(const Scalar sw, const Scalar pc) + { + const auto& surfaceParams = spatialParams_.aWettingNonWettingSurfaceParams(element_, scv_, elemSol_); + using AwnSurface = typename SpatialParams::AwnSurface; + return AwnSurface::dawn_dsw(surfaceParams, sw, pc); + } + +private: + const SpatialParams& spatialParams_; + const Element& element_; + const Scv& scv_; + const ElemSol& elemSol_; +}; + +template +class NonwettingSolidInterfacialArea : public FluidMatrix::Adapter, FluidMatrix::NonwettingSolidInterfacialAreaPcSw> +{ +public: + using Scalar = ScalarT; + + NonwettingSolidInterfacialArea(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol) + : spatialParams_(sp), element_(element), scv_(scv), elemSol_(elemSol) + {} + + const auto& basicParams() const + { + return spatialParams_.aNonWettingSolidSurfaceParams(element_, scv_, elemSol_); + } + + Scalar area(const Scalar sw, const Scalar pc) const + { + const auto& surfaceParams = spatialParams_.aNonWettingSolidSurfaceParams(element_, scv_, elemSol_); + const auto& materialParams = spatialParams_.materialLawParams(element_, scv_, elemSol_); + using AnsSurface = typename SpatialParams::AnsSurface; + return AnsSurface::interfacialArea(surfaceParams, materialParams, sw, pc); + } + + Scalar darea_dpc(const Scalar sw, const Scalar pc) + { + const auto& surfaceParams = spatialParams_.aNonWettingSolidSurfaceParams(element_, scv_, elemSol_); + using AnsSurface = typename SpatialParams::AnsSurface; + return AnsSurface::dawn_dpc(surfaceParams, sw, pc); + } + + Scalar darea_dsw(const Scalar sw, const Scalar pc) + { + const auto& surfaceParams = spatialParams_.aNonWettingSolidSurfaceParams(element_, scv_, elemSol_); + using AnsSurface = typename SpatialParams::AnsSurface; + return AnsSurface::dawn_dsw(surfaceParams, sw, pc); + } + +private: + const SpatialParams& spatialParams_; + const Element& element_; + const Scv& scv_; + const ElemSol& elemSol_; +}; + +template +class WettingSolidInterfacialArea : public FluidMatrix::Adapter, FluidMatrix::WettingSolidInterfacialAreaPcSw> +{ +public: + using Scalar = ScalarT; + + WettingSolidInterfacialArea(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol) + : spatialParams_(sp), element_(element), scv_(scv), elemSol_(elemSol) + {} + + const auto& basicParams() const + { + return spatialParams_.aWettingSolidSurfaceParams(element_, scv_, elemSol_); + } + + Scalar area(const Scalar sw, const Scalar pc) const + { + const auto& surfaceParams = spatialParams_.aWettingSolidSurfaceParams(element_, scv_, elemSol_); + const auto& materialParams = spatialParams_.materialLawParams(element_, scv_, elemSol_); + using AwsSurface = typename SpatialParams::AwsSurface; + return AwsSurface::interfacialArea(surfaceParams, materialParams, sw, pc); + } + + Scalar darea_dpc(const Scalar sw, const Scalar pc) + { + const auto& surfaceParams = spatialParams_.aWettingSolidSurfaceParams(element_, scv_, elemSol_); + using AwsSurface = typename SpatialParams::AwsSurface; + return AwsSurface::dawn_dpc(surfaceParams, sw, pc); + } + + Scalar darea_dsw(const Scalar sw, const Scalar pc) + { + const auto& surfaceParams = spatialParams_.aWettingSolidSurfaceParams(element_, scv_, elemSol_); + using AwsSurface = typename SpatialParams::AwsSurface; + return AwsSurface::dawn_dsw(surfaceParams, sw, pc); + } + +private: + const SpatialParams& spatialParams_; + const Element& element_; + const Scv& scv_; + const ElemSol& elemSol_; +}; + +template +auto makeInterfacialAreaHelper(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol) +{ + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + constexpr bool hasNew = decltype(isValid(HasNewFIAIF()).template check())::value; + constexpr bool hasNewAtPos = decltype(isValid(HasNewFIAIFAtPos()).template check())::value; + if constexpr (hasNew) + return sp.fluidMatrixInteraction(element, scv, elemSol); + else if constexpr (hasNewAtPos) + return sp.fluidMatrixInteractionAtPos(scv.center()); + else + return makeFluidMatrixInteraction(WettingNonwettingInterfacialArea(scalar, sp, element, scv, elemSol), + NonwettingSolidInterfacialArea(scalar, sp, element, scv, elemSol), + WettingSolidInterfacialArea(scalar, sp, element, scv, elemSol)); +} + } // end namespace Deprecated #endif -- GitLab From 792b99773b3e95d20f68466e4aac77940bf8ad3c Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 24 Sep 2020 15:05:16 +0200 Subject: [PATCH 20/99] [material] Deprecate classes and headers for 2p materials --- .../material/fluidmatrixinteractions/2p/brookscoreyparams.hh | 1 + dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh | 2 ++ .../material/fluidmatrixinteractions/2p/efftoabslawparams.hh | 4 +++- .../material/fluidmatrixinteractions/2p/heatpipelawparams.hh | 1 + .../fluidmatrixinteractions/2p/linearmaterialparams.hh | 2 ++ .../fluidmatrixinteractions/2p/regularizedbrookscorey.hh | 2 ++ .../2p/regularizedbrookscoreyparams.hh | 4 +++- .../fluidmatrixinteractions/2p/regularizedlinearmaterial.hh | 2 ++ .../2p/regularizedlinearmaterialparams.hh | 4 +++- .../fluidmatrixinteractions/2p/regularizedvangenuchten.hh | 2 ++ .../2p/regularizedvangenuchtenparams.hh | 4 +++- .../fluidmatrixinteractions/2p/vangenuchtenoftemperature.hh | 4 +++- .../material/fluidmatrixinteractions/2p/vangenuchtenparams.hh | 4 +++- 13 files changed, 30 insertions(+), 6 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2p/brookscoreyparams.hh b/dumux/material/fluidmatrixinteractions/2p/brookscoreyparams.hh index ad0f28a6e7..a8100a1458 100644 --- a/dumux/material/fluidmatrixinteractions/2p/brookscoreyparams.hh +++ b/dumux/material/fluidmatrixinteractions/2p/brookscoreyparams.hh @@ -36,6 +36,7 @@ namespace Dumux { * for the Brooks Corey constitutive relations. * \see BrooksCorey */ +// "Use new material laws! Removal after 3.3") template class BrooksCoreyParams { diff --git a/dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh b/dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh index 6afd11a0fa..41a49ea7a1 100644 --- a/dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh +++ b/dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh @@ -26,6 +26,8 @@ #ifndef DUMUX_EFF_TO_ABS_LAW_HH #define DUMUX_EFF_TO_ABS_LAW_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include "efftoabslawparams.hh" namespace Dumux { diff --git a/dumux/material/fluidmatrixinteractions/2p/efftoabslawparams.hh b/dumux/material/fluidmatrixinteractions/2p/efftoabslawparams.hh index bd83efb546..a9f03997e2 100644 --- a/dumux/material/fluidmatrixinteractions/2p/efftoabslawparams.hh +++ b/dumux/material/fluidmatrixinteractions/2p/efftoabslawparams.hh @@ -26,6 +26,8 @@ #ifndef DUMUX_EFF_TO_ABS_LAW_PARAMS_HH #define DUMUX_EFF_TO_ABS_LAW_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include namespace Dumux { @@ -37,7 +39,7 @@ namespace Dumux { * saturations. */ template -class EffToAbsLawParams : public EffLawParamsT +class [[deprecated("Use new material laws! Removal after 3.3")]] EffToAbsLawParams : public EffLawParamsT { using EffLawParams = EffLawParamsT; public: diff --git a/dumux/material/fluidmatrixinteractions/2p/heatpipelawparams.hh b/dumux/material/fluidmatrixinteractions/2p/heatpipelawparams.hh index 4f127d89c4..b51e786235 100644 --- a/dumux/material/fluidmatrixinteractions/2p/heatpipelawparams.hh +++ b/dumux/material/fluidmatrixinteractions/2p/heatpipelawparams.hh @@ -32,6 +32,7 @@ namespace Dumux { * \brief Reference implementation of a params for the heat pipe's * material law */ +// "Use new material laws! Removal after 3.3") template class HeatPipeLawParams { diff --git a/dumux/material/fluidmatrixinteractions/2p/linearmaterialparams.hh b/dumux/material/fluidmatrixinteractions/2p/linearmaterialparams.hh index aa6df583d8..6e8609abbd 100644 --- a/dumux/material/fluidmatrixinteractions/2p/linearmaterialparams.hh +++ b/dumux/material/fluidmatrixinteractions/2p/linearmaterialparams.hh @@ -25,6 +25,8 @@ #ifndef LINEAR_MATERIAL_PARAMS_HH #define LINEAR_MATERIAL_PARAMS_HH +// TODO Deprecated. Remove after 3.3 + namespace Dumux { /*! diff --git a/dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh b/dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh index 4857f91b05..e891f04c0a 100644 --- a/dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh +++ b/dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh @@ -25,6 +25,8 @@ #ifndef REGULARIZED_BROOKS_COREY_HH #define REGULARIZED_BROOKS_COREY_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include "brookscorey.hh" #include "regularizedbrookscoreyparams.hh" diff --git a/dumux/material/fluidmatrixinteractions/2p/regularizedbrookscoreyparams.hh b/dumux/material/fluidmatrixinteractions/2p/regularizedbrookscoreyparams.hh index 3ea49468a0..7e769ae215 100644 --- a/dumux/material/fluidmatrixinteractions/2p/regularizedbrookscoreyparams.hh +++ b/dumux/material/fluidmatrixinteractions/2p/regularizedbrookscoreyparams.hh @@ -25,6 +25,8 @@ #ifndef DUMUX_REGULARIZED_BROOKS_COREY_PARAMS_HH #define DUMUX_REGULARIZED_BROOKS_COREY_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include #include "brookscoreyparams.hh" @@ -37,7 +39,7 @@ namespace Dumux { * the Brooks-Corey capillary pressure model. */ template -class RegularizedBrooksCoreyParams : public BrooksCoreyParams +class [[deprecated("Use new material laws! Removal after 3.3")]] RegularizedBrooksCoreyParams : public BrooksCoreyParams { using BrooksCoreyParams = Dumux::BrooksCoreyParams; diff --git a/dumux/material/fluidmatrixinteractions/2p/regularizedlinearmaterial.hh b/dumux/material/fluidmatrixinteractions/2p/regularizedlinearmaterial.hh index 02f81c4a07..1a96667ca5 100644 --- a/dumux/material/fluidmatrixinteractions/2p/regularizedlinearmaterial.hh +++ b/dumux/material/fluidmatrixinteractions/2p/regularizedlinearmaterial.hh @@ -25,6 +25,8 @@ #ifndef DUMUX_REGULARIZED_LINEAR_MATERIAL_HH #define DUMUX_REGULARIZED_LINEAR_MATERIAL_HH +#warning "This header is deprecated. Removal after 3.3" + #include "linearmaterial.hh" #include "regularizedlinearmaterialparams.hh" diff --git a/dumux/material/fluidmatrixinteractions/2p/regularizedlinearmaterialparams.hh b/dumux/material/fluidmatrixinteractions/2p/regularizedlinearmaterialparams.hh index 71970148c9..cc1885fc94 100644 --- a/dumux/material/fluidmatrixinteractions/2p/regularizedlinearmaterialparams.hh +++ b/dumux/material/fluidmatrixinteractions/2p/regularizedlinearmaterialparams.hh @@ -25,6 +25,8 @@ #ifndef REGULARIZED_LINEAR_PARAMS_HH #define REGULARIZED_LINEAR_PARAMS_HH +#warning "This header is deprecated. Use SmoothedLinearLaw instead. Removal after 3.3" + #include "linearmaterialparams.hh" namespace Dumux { @@ -35,7 +37,7 @@ namespace Dumux { * the linear constitutive relations. */ template -class RegularizedLinearMaterialParams : public LinearMaterialParams +class [[deprecated("Use new material laws! Removal after 3.3")]] RegularizedLinearMaterialParams : public LinearMaterialParams { public: using Scalar = ScalarT; diff --git a/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh b/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh index 1973cf212c..897a40b573 100644 --- a/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh +++ b/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh @@ -25,6 +25,8 @@ #ifndef REGULARIZED_VAN_GENUCHTEN_HH #define REGULARIZED_VAN_GENUCHTEN_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include "vangenuchten.hh" #include "regularizedvangenuchtenparams.hh" diff --git a/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchtenparams.hh b/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchtenparams.hh index 452d158257..03e7657d32 100644 --- a/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchtenparams.hh +++ b/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchtenparams.hh @@ -25,6 +25,8 @@ #ifndef REGULARIZED_VAN_GENUCHTEN_PARAMS_HH #define REGULARIZED_VAN_GENUCHTEN_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include #include "vangenuchtenparams.hh" @@ -37,7 +39,7 @@ namespace Dumux { * VanGenuchten "material law". */ template -class RegularizedVanGenuchtenParams : public VanGenuchtenParams +class [[deprecated("Use new material laws! Removal after 3.3")]] RegularizedVanGenuchtenParams : public VanGenuchtenParams { public: using Scalar = ScalarT; diff --git a/dumux/material/fluidmatrixinteractions/2p/vangenuchtenoftemperature.hh b/dumux/material/fluidmatrixinteractions/2p/vangenuchtenoftemperature.hh index 87c8afeed4..92a0e00511 100644 --- a/dumux/material/fluidmatrixinteractions/2p/vangenuchtenoftemperature.hh +++ b/dumux/material/fluidmatrixinteractions/2p/vangenuchtenoftemperature.hh @@ -26,6 +26,8 @@ #ifndef REGULARIZED_VAN_GENUCHTEN_OF_TEMPERATURE_HH #define REGULARIZED_VAN_GENUCHTEN_OF_TEMPERATURE_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include #include @@ -40,7 +42,7 @@ namespace Dumux { * Everything except the capillary pressure is taken from the parent, i.e. Regularized VanGenuchten. */ template > -class RegularizedVanGenuchtenOfTemperature : public RegularizedVanGenuchten +class [[deprecated("Use new material laws! Removal after 3.3")]] RegularizedVanGenuchtenOfTemperature : public RegularizedVanGenuchten { using RegularizedVanGenuchten = Dumux::RegularizedVanGenuchten; // Data is in /home/pnuske/paper/pcOfT/ diff --git a/dumux/material/fluidmatrixinteractions/2p/vangenuchtenparams.hh b/dumux/material/fluidmatrixinteractions/2p/vangenuchtenparams.hh index 1f35d26e25..f5c3ab1756 100644 --- a/dumux/material/fluidmatrixinteractions/2p/vangenuchtenparams.hh +++ b/dumux/material/fluidmatrixinteractions/2p/vangenuchtenparams.hh @@ -25,6 +25,8 @@ #ifndef DUMUX_VAN_GENUCHTEN_PARAMS_HH #define DUMUX_VAN_GENUCHTEN_PARAMS_HH +// TODO Deprecated. Remove after 3.3 + #include namespace Dumux { @@ -109,7 +111,7 @@ public: */ void setVgn(Scalar n) { vgn_ = n; vgm_ = 1 - 1/vgn_; } - + /*! * \brief Return the \f$\mathrm{n}\f$ shape parameter \f$\mathrm{[-]}\f$ of van Genuchten's * curve. -- GitLab From c78b7c310084d46046d0272cab83ec848f2b5c69 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 1 Oct 2020 18:42:14 +0200 Subject: [PATCH 21/99] [material][2pia] Deprecate old awn classes --- .../material/fluidmatrixinteractions/2pia/awnsurfaceexpfct.hh | 4 +++- .../fluidmatrixinteractions/2pia/awnsurfaceexpfctparams.hh | 2 ++ .../fluidmatrixinteractions/2pia/awnsurfaceexpswpcto3.hh | 4 +++- .../2pia/awnsurfaceexpswpcto3params.hh | 2 ++ .../fluidmatrixinteractions/2pia/awnsurfacepcmaxfct.hh | 4 +++- .../fluidmatrixinteractions/2pia/awnsurfacepcmaxfctparams.hh | 2 ++ .../2pia/awnsurfacepolynomial2ndorder.hh | 4 +++- .../2pia/awnsurfacepolynomial2ndorderparams.hh | 2 ++ .../2pia/awnsurfacepolynomialedgezero2ndorder.hh | 4 +++- .../2pia/awnsurfacepolynomialedgezero2ndorderparams.hh | 2 ++ dumux/material/fluidmatrixinteractions/2pia/efftoabslawia.hh | 2 ++ .../fluidmatrixinteractions/2pia/efftoabslawiaparams.hh | 4 +++- 12 files changed, 30 insertions(+), 6 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpfct.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpfct.hh index 556e25dd2e..2faca94bcc 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpfct.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpfct.hh @@ -31,6 +31,8 @@ #include #include +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! @@ -40,7 +42,7 @@ namespace Dumux { * apillary pressure as suggested by Nuske(2009) (Diploma thesis) \cite nuske2009 . */ template -class AwnSurfaceExpFct +class [[deprecated("Use new material laws and FluidMatrix::InterfacialAreaExponential instead!")]] AwnSurfaceExpFct { public: using Params = ParamsT; diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpfctparams.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpfctparams.hh index f954343a6d..c8d8ab9636 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpfctparams.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpfctparams.hh @@ -23,6 +23,8 @@ #ifndef AWN_SURFACE_EXP_FCT_PARAMS_HH #define AWN_SURFACE_EXP_FCT_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpswpcto3.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpswpcto3.hh index 7551db9a6d..6a49616d85 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpswpcto3.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpswpcto3.hh @@ -31,6 +31,8 @@ #include #include +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! @@ -39,7 +41,7 @@ namespace Dumux { * specific interfacial area to wetting phase saturation and capillary pressure. */ template > -class AwnSurfaceExpSwPcTo3 +class [[deprecated("Use new material laws and FluidMatrix::InterfacialAreaExponentialCubic instead!")]] AwnSurfaceExpSwPcTo3 { public: using Params = ParamsT; diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpswpcto3params.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpswpcto3params.hh index 7b3b390b46..884d72556f 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpswpcto3params.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfaceexpswpcto3params.hh @@ -23,6 +23,8 @@ #ifndef AWN_SURFACE_EXP_SW_PC_TO_3_PARAMS #define AWN_SURFACE_EXP_SW_PC_TO_3_PARAMS +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepcmaxfct.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepcmaxfct.hh index 35baae348e..e09298706d 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepcmaxfct.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepcmaxfct.hh @@ -26,6 +26,8 @@ #include "awnsurfacepcmaxfctparams.hh" #include +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! @@ -40,7 +42,7 @@ namespace Dumux { */ template > -class AwnSurfacePcMaxFct +class [[deprecated("Use new material laws and FluidMatrix::InterfacialAreaPcMax instead!")]] AwnSurfacePcMaxFct { public: using Params = ParamsT; diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepcmaxfctparams.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepcmaxfctparams.hh index 99801bad24..a7c18332ba 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepcmaxfctparams.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepcmaxfctparams.hh @@ -23,6 +23,8 @@ #ifndef AWN_SURFACE_PCMAX_FCT_PARAMS_HH #define AWN_SURFACE_PCMAX_FCT_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomial2ndorder.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomial2ndorder.hh index b9d27b88ce..d4a60bb2ba 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomial2ndorder.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomial2ndorder.hh @@ -31,6 +31,8 @@ #include #include +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! @@ -39,7 +41,7 @@ namespace Dumux { * specific interfacial area to wetting phase saturation and capillary pressure as suggested by Joekar-Niasar(2008) \cite joekar2008 . */ template > -class AwnSurfacePolynomial2ndOrder +class [[deprecated("Use new material laws and FluidMatrix::InterfacialAreaPolynomialSecondOrder instead!")]] AwnSurfacePolynomial2ndOrder { public: using Params = ParamsT; diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomial2ndorderparams.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomial2ndorderparams.hh index 8a4227a807..24fbc5924a 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomial2ndorderparams.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomial2ndorderparams.hh @@ -23,6 +23,8 @@ #ifndef AWN_SURFACE_POLYNOMIAL_2ND_ORDER_PARAMS_HH #define AWN_SURFACE_POLYNOMIAL_2ND_ORDER_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomialedgezero2ndorder.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomialedgezero2ndorder.hh index 14380960bb..e8698ffeae 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomialedgezero2ndorder.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomialedgezero2ndorder.hh @@ -31,6 +31,8 @@ #include #include +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! @@ -39,7 +41,7 @@ namespace Dumux { * specific interfacial area to wetting phase saturation and capillary pressure. */ template -class AwnSurfacePolynomialEdgeZero2ndOrder +class [[deprecated("Use new material laws and FluidMatrix::InterfacialAreaolynomialEdgeZero2ndOrder instead!")]] AwnSurfacePolynomialEdgeZero2ndOrder { public: using Params = ParamsT; diff --git a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomialedgezero2ndorderparams.hh b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomialedgezero2ndorderparams.hh index 109f695301..37a6ed9b03 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomialedgezero2ndorderparams.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/awnsurfacepolynomialedgezero2ndorderparams.hh @@ -23,6 +23,8 @@ #ifndef AWN_SURFACE_POLYNOMIAL_EDGE_ZERO_2ND_ORDER_PARAMS_HH #define AWN_SURFACE_POLYNOMIAL_EDGE_ZERO_2ND_ORDER_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! diff --git a/dumux/material/fluidmatrixinteractions/2pia/efftoabslawia.hh b/dumux/material/fluidmatrixinteractions/2pia/efftoabslawia.hh index 6d8fc4ffc5..c959fa69c9 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/efftoabslawia.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/efftoabslawia.hh @@ -26,6 +26,8 @@ #ifndef DUMUX_EFF_TO_ABS_LAW_IA_HH #define DUMUX_EFF_TO_ABS_LAW_IA_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include #include "efftoabslawiaparams.hh" diff --git a/dumux/material/fluidmatrixinteractions/2pia/efftoabslawiaparams.hh b/dumux/material/fluidmatrixinteractions/2pia/efftoabslawiaparams.hh index f1d0881e41..72dd0d763e 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/efftoabslawiaparams.hh +++ b/dumux/material/fluidmatrixinteractions/2pia/efftoabslawiaparams.hh @@ -26,6 +26,8 @@ #ifndef DUMUX_EFF_TO_ABS_LAW_IA_PARAMS_HH #define DUMUX_EFF_TO_ABS_LAW_IA_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! @@ -35,7 +37,7 @@ namespace Dumux { * from effective to absolute saturations. */ template -class EffToAbsLawIAParams : public EffIALawParamsT +class [[deprecated("Use new material laws! Removal after 3.3")]] EffToAbsLawIAParams : public EffIALawParamsT { using EffIALawParams = EffIALawParamsT; public: -- GitLab From 428c11badd66569586e46d8734b8ea18ca931f42 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Tue, 29 Sep 2020 13:10:23 +0200 Subject: [PATCH 22/99] [mp][adapter] Add new mpadapter and mplinearmaterial --- .../fluidmatrixinteractions/mp/mpadapter.hh | 81 ++++++++++++++++- .../mp/mplinearmaterial.hh | 87 ++++++++++++++++++- .../mp/mplinearmaterialparams.hh | 1 + 3 files changed, 166 insertions(+), 3 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/mp/mpadapter.hh b/dumux/material/fluidmatrixinteractions/mp/mpadapter.hh index 7176f552b3..bb3b4a2c9a 100644 --- a/dumux/material/fluidmatrixinteractions/mp/mpadapter.hh +++ b/dumux/material/fluidmatrixinteractions/mp/mpadapter.hh @@ -27,24 +27,27 @@ #ifndef DUMUX_MP_ADAPTER_HH #define DUMUX_MP_ADAPTER_HH +// remove from here after release 3.3 ///////////// + #include #include #include namespace Dumux { + /*! * \ingroup Fluidmatrixinteractions * \brief An adapter for mpnc to use the capillary pressure-saturation relationships */ -template +template class MPAdapter { static_assert(AlwaysFalse::value, "Adapter not implemented for the specified number of phases"); }; template -class MPAdapter +class [[deprecated("Use new material laws and FluidMatrix::MPAdapter instead!")]] MPAdapter { public: using Params = typename MaterialLaw::Params; @@ -88,6 +91,80 @@ public: values[nPhaseIdx] = MaterialLaw::krn(params, state.saturation(wPhaseIdx)); } }; + + } // end namespace Dumux +// remove until here after release 3.3 ///////////// + +#include +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief An adapter for mpnc to use the capillary pressure-saturation relationships + */ +template +class MPAdapter +{ + static_assert(AlwaysFalse::value, "Adapter not implemented for the specified number of phases"); +}; + + +template +class MPAdapter +: public Adapter, MultiPhasePcKrSw> +{ +public: + using Scalar = typename MaterialLaw::Scalar; + + MPAdapter(const MaterialLaw& pcKrS) + : pcKrS_(pcKrS) + {} + + /*! + * \brief The capillary pressure-saturation curve. + * \param state Fluidstate + * \param wPhaseIdx the phase index of the wetting phase + */ + template + auto capillaryPressures(const FluidState& state, int wPhaseIdx) const + { + Dune::FieldVector values; + + const int nPhaseIdx = 1 - wPhaseIdx; + // non-wetting phase gets the capillary pressure added + values[nPhaseIdx] = 0; + // wetting phase does not get anything added + values[wPhaseIdx] = - pcKrS_.pc(state.saturation(wPhaseIdx)); + + return values; + } + + /*! + * \brief The relative permeability of all phases. + * \param state Fluidstate + * \param wPhaseIdx The phase index of the wetting phase + */ + template + auto relativePermeabilities(const FluidState& state, int wPhaseIdx) const + { + Dune::FieldVector values; + + const int nPhaseIdx = 1 - wPhaseIdx; + values[wPhaseIdx] = pcKrS_.krw(state.saturation(wPhaseIdx)); + values[nPhaseIdx] = pcKrS_.krn(state.saturation(wPhaseIdx)); + + return values; + } +private: + const MaterialLaw& pcKrS_; +}; + +} // end namespace Dumux::FluidMatrix + + #endif diff --git a/dumux/material/fluidmatrixinteractions/mp/mplinearmaterial.hh b/dumux/material/fluidmatrixinteractions/mp/mplinearmaterial.hh index e5bb06f603..09f59be976 100644 --- a/dumux/material/fluidmatrixinteractions/mp/mplinearmaterial.hh +++ b/dumux/material/fluidmatrixinteractions/mp/mplinearmaterial.hh @@ -43,7 +43,7 @@ namespace Dumux { * \sa MpLinearMaterialParams */ template > -class MpLinearMaterial +class [[deprecated("Use FluidMatrix::MPLinearMaterial. Will be removed after 3.3")]] MpLinearMaterial { public: using Params = ParamsT; @@ -97,4 +97,89 @@ public: }; } // end namespace Dumux +#include +#include + +namespace Dumux::FluidMatrix { + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implements a linear saturation-capillary pressure relation + * + * Implements a linear saturation-capillary pressure relation for + * M-phase fluid systems. + * + */ +template +class MPLinearMaterial +: public Adapter, MultiPhasePcKrSw> +{ + struct Params + { + Params(const std::array& pcMaxSat, + const std::array& pcMinSat) + : pcMaxSat_(pcMaxSat), pcMinSat_(pcMinSat) {} + + S pcMaxSat(int phaseIdx) const { return pcMaxSat_[phaseIdx]; } + S pcMinSat(int phaseIdx) const { return pcMinSat_[phaseIdx]; } + private: + std::array pcMaxSat_; + std::array pcMinSat_; + }; + +public: + using BasicParams = Params; + using Scalar = S; + + MPLinearMaterial(const BasicParams& basicParams) + : basicParams_(basicParams) + {} + + /*! + * \brief The linear capillary pressure-saturation curve. + * + * This material law is linear: + * \f[ + p_C = (1 - \overline{S}_w) (p_{C,max} - p_{C,entry}) + p_{C,entry} + \f] + * + * \param state The fluid state + * \param wPhaseIdx The phase index of the wetting phase + */ + template + auto capillaryPressures(const FluidState& state, int wPhaseIdx = 0) const + { + static_assert(FluidState::numPhases == numFluidPhases, "FluidState doesn't match the number of fluid phases!"); + Dune::FieldVector values; + for (int phaseIdx = 0; phaseIdx < numFluidPhases; ++phaseIdx) + { + const Scalar saturation = state.saturation(phaseIdx); + values[phaseIdx] = + saturation*basicParams_.pcMaxSat(phaseIdx) + + (1 - saturation)*basicParams_.pcMinSat(phaseIdx); + } + return values; + } + + /*! + * \brief The relative permeability of all phases. + * \param state The fluid state + * \param wPhaseIdx The phase index of the wetting phase + */ + template + auto relativePermeabilities(const FluidState& state, int wPhaseIdx = 0) const + { + static_assert(FluidState::numPhases == numFluidPhases, "FluidState doesn't match the number of fluid phases!"); + using std::clamp; + Dune::FieldVector values; + for (int phaseIdx = 0; phaseIdx < FluidState::numPhases; ++phaseIdx) + values[phaseIdx] = clamp(state.saturation(phaseIdx), 0.0, 1.0); + return values; + } +private: + BasicParams basicParams_; +}; + +} // end namespace Dumux::FluidMatrix + #endif diff --git a/dumux/material/fluidmatrixinteractions/mp/mplinearmaterialparams.hh b/dumux/material/fluidmatrixinteractions/mp/mplinearmaterialparams.hh index 6a4477f651..2d12172450 100644 --- a/dumux/material/fluidmatrixinteractions/mp/mplinearmaterialparams.hh +++ b/dumux/material/fluidmatrixinteractions/mp/mplinearmaterialparams.hh @@ -39,6 +39,7 @@ public: using Scalar = ScalarT; enum { numPhases = numPhasesV }; + [[deprecated("Use FluidMatrix::MPLinearMaterial. Class will be removed after 3.3.")]] MpLinearMaterialParams() { for (int i = 0; i < numPhases; ++i) { -- GitLab From 3ffb463d0ac1e62215d8054db6b98748928b8e86 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 29 Sep 2020 13:11:05 +0200 Subject: [PATCH 23/99] [mpnc][volVars] Use deprecation helper --- .../porousmediumflow/mpnc/volumevariables.hh | 61 +++++++++++++------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/dumux/porousmediumflow/mpnc/volumevariables.hh b/dumux/porousmediumflow/mpnc/volumevariables.hh index 1ab4d5ec0f..621738b3f9 100644 --- a/dumux/porousmediumflow/mpnc/volumevariables.hh +++ b/dumux/porousmediumflow/mpnc/volumevariables.hh @@ -26,6 +26,8 @@ #ifndef DUMUX_MPNC_VOLUME_VARIABLES_HH #define DUMUX_MPNC_VOLUME_VARIABLES_HH +#include + #include #include @@ -108,13 +110,18 @@ public: completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); + // Old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported. + // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports + // two phases anyway... + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + //calculate the remaining quantities - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); const int wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); // relative permeabilities - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - using MPAdapter = MPAdapter; - MPAdapter::relativePermeabilities(relativePermeability_, materialParams, fluidState_, wPhaseIdx); + using MPAdapter = FluidMatrix::MPAdapter; + MPAdapter::relativePermeabilities(relativePermeability_, fluidMatrixInteraction, fluidState_, wPhaseIdx); typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState_); @@ -178,13 +185,18 @@ public: // capillary pressure parameters const int wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); fluidState.setWettingPhase(wPhaseIdx); - const auto& materialParams = - problem.spatialParams().materialLawParams(element, scv, elemSol); // capillary pressures - std::vector capPress(numFluidPhases()); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - using MPAdapter = MPAdapter; - MPAdapter::capillaryPressures(capPress, materialParams, fluidState, wPhaseIdx); + + // Old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported. + // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports + // two phases anyway... + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + std::array capPress; + using MPAdapter = FluidMatrix::MPAdapter; + MPAdapter::capillaryPressures(capPress, fluidMatrixInteraction, fluidState, wPhaseIdx); // add to the pressure of the first fluid phase // depending on which pressure is stored in the primary variables @@ -549,13 +561,19 @@ public: completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); // calculate the remaining quantities - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); const int wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); // relative permeabilities - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - using MPAdapter = MPAdapter; - MPAdapter::relativePermeabilities(relativePermeability_, materialParams, fluidState_, wPhaseIdx); + using MPAdapter = FluidMatrix::MPAdapter; + + // Old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported. + // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports + // two phases anyway... + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + MPAdapter::relativePermeabilities(relativePermeability_, fluidMatrixInteraction, fluidState_, wPhaseIdx); typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState_); @@ -612,15 +630,20 @@ public: // set the phase pressures ///////////// // capillary pressure parameters - const auto& materialParams = - problem.spatialParams().materialLawParams(element, scv, elemSol); const int wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); fluidState.setWettingPhase(wPhaseIdx); // capillary pressures + + // Old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported. + // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports + // two phases anyway... + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + std::vector capPress(numFluidPhases()); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - using MPAdapter = MPAdapter; - MPAdapter::capillaryPressures(capPress, materialParams, fluidState, wPhaseIdx); + using MPAdapter = FluidMatrix::MPAdapter; + MPAdapter::capillaryPressures(capPress, fluidMatrixInteraction, fluidState, wPhaseIdx); // add to the pressure of the first fluid phase // depending on which pressure is stored in the primary variables -- GitLab From 6c31e8f6da547eae43112b991da181f7298cac19 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 27 Jun 2019 15:53:51 +0200 Subject: [PATCH 24/99] [richards] Use material law deprecation wrapper --- .../richards/localresidual.hh | 56 +++++++++++-------- .../porousmediumflow/richards/newtonsolver.hh | 19 ++++--- .../richards/volumevariables.hh | 31 ++++++---- 3 files changed, 66 insertions(+), 40 deletions(-) diff --git a/dumux/porousmediumflow/richards/localresidual.hh b/dumux/porousmediumflow/richards/localresidual.hh index dbf42d9544..9a7cd7bbc3 100644 --- a/dumux/porousmediumflow/richards/localresidual.hh +++ b/dumux/porousmediumflow/richards/localresidual.hh @@ -33,6 +33,8 @@ #include #include +#include + namespace Dumux { /*! @@ -198,13 +200,14 @@ public: const auto poreVolume = Extrusion::volume(scv)*curVolVars.porosity(); static const auto rho = curVolVars.density(0); - // material law for pc-sw - const auto& matParams = problem.spatialParams().materialLawParams(element, scv, InvalidElemSol{}); + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, InvalidElemSol{}); // partial derivative of storage term w.r.t. p_w // d(Sw*rho*phi*V/dt)/dpw = rho*phi*V/dt*dsw/dpw = rho*phi*V/dt*dsw/dpc*dpc/dpw = -rho*phi*V/dt*dsw/dpc - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - partialDerivatives[conti0EqIdx][0] += -rho*poreVolume/this->timeLoop().timeStepSize()*MaterialLaw::dsw_dpc(matParams, curVolVars.capillaryPressure()); + partialDerivatives[conti0EqIdx][0] += -rho*poreVolume/this->timeLoop().timeStepSize()*fluidMatrixInteraction.dsw_dpc(curVolVars.capillaryPressure()); } /*! @@ -267,8 +270,6 @@ public: const auto& outsideScv = fvGeometry.scv(outsideScvIdx); const auto& insideVolVars = curElemVolVars[insideScvIdx]; const auto& outsideVolVars = curElemVolVars[outsideScvIdx]; - const auto& insideMaterialParams = problem.spatialParams().materialLawParams(element, insideScv, InvalidElemSol{}); - const auto& outsideMaterialParams = problem.spatialParams().materialLawParams(outsideElement, outsideScv, InvalidElemSol{}); // some quantities to be reused (rho & mu are constant and thus equal for all cells) static const auto rho = insideVolVars.density(0); @@ -284,16 +285,21 @@ public: const auto outsideWeight = 1.0 - insideWeight; const auto upwindTerm = rho*insideVolVars.mobility(0)*insideWeight + rho*outsideVolVars.mobility(0)*outsideWeight; + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto insideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, insideScv, InvalidElemSol{}); + const auto outsideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), outsideElement, outsideScv, InvalidElemSol{}); + // material law derivatives const auto insideSw = insideVolVars.saturation(0); const auto outsideSw = outsideVolVars.saturation(0); const auto insidePc = insideVolVars.capillaryPressure(); const auto outsidePc = outsideVolVars.capillaryPressure(); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto dkrw_dsw_inside = MaterialLaw::dkrw_dsw(insideMaterialParams, insideSw); - const auto dkrw_dsw_outside = MaterialLaw::dkrw_dsw(outsideMaterialParams, outsideSw); - const auto dsw_dpw_inside = -MaterialLaw::dsw_dpc(insideMaterialParams, insidePc); - const auto dsw_dpw_outside = -MaterialLaw::dsw_dpc(outsideMaterialParams, outsidePc); + const auto dkrw_dsw_inside = insideFluidMatrixInteraction.dkrw_dsw(insideSw); + const auto dkrw_dsw_outside = outsideFluidMatrixInteraction.dkrw_dsw(outsideSw); + const auto dsw_dpw_inside = -insideFluidMatrixInteraction.dsw_dpc(insidePc); + const auto dsw_dpw_outside = -outsideFluidMatrixInteraction.dsw_dpc(outsidePc); // the transmissibility const auto tij = elemFluxVarsCache[scvf].advectionTij(); @@ -342,8 +348,6 @@ public: const auto& outsideScv = fvGeometry.scv(outsideScvIdx); const auto& insideVolVars = curElemVolVars[insideScvIdx]; const auto& outsideVolVars = curElemVolVars[outsideScvIdx]; - const auto& insideMaterialParams = problem.spatialParams().materialLawParams(element, insideScv, InvalidElemSol{}); - const auto& outsideMaterialParams = problem.spatialParams().materialLawParams(element, outsideScv, InvalidElemSol{}); // some quantities to be reused (rho & mu are constant and thus equal for all cells) static const auto rho = insideVolVars.density(0); @@ -359,16 +363,21 @@ public: const auto outsideWeight = 1.0 - insideWeight; const auto upwindTerm = rho*insideVolVars.mobility(0)*insideWeight + rho*outsideVolVars.mobility(0)*outsideWeight; + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto insideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, insideScv, InvalidElemSol{}); + const auto outsideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, outsideScv, InvalidElemSol{}); + // material law derivatives const auto insideSw = insideVolVars.saturation(0); const auto outsideSw = outsideVolVars.saturation(0); const auto insidePc = insideVolVars.capillaryPressure(); const auto outsidePc = outsideVolVars.capillaryPressure(); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto dkrw_dsw_inside = MaterialLaw::dkrw_dsw(insideMaterialParams, insideSw); - const auto dkrw_dsw_outside = MaterialLaw::dkrw_dsw(outsideMaterialParams, outsideSw); - const auto dsw_dpw_inside = -MaterialLaw::dsw_dpc(insideMaterialParams, insidePc); - const auto dsw_dpw_outside = -MaterialLaw::dsw_dpc(outsideMaterialParams, outsidePc); + const auto dkrw_dsw_inside = insideFluidMatrixInteraction.dkrw_dsw(insideSw); + const auto dkrw_dsw_outside = outsideFluidMatrixInteraction.dkrw_dsw(outsideSw); + const auto dsw_dpw_inside = -insideFluidMatrixInteraction.dsw_dpc(insidePc); + const auto dsw_dpw_outside = -outsideFluidMatrixInteraction.dsw_dpc(outsidePc); // so far it was the same as for tpfa // the transmissibilities (flux derivatives with respect to all pw-dofs on the element) @@ -439,7 +448,11 @@ public: const auto& insideScv = fvGeometry.scv(insideScvIdx); const auto& insideVolVars = curElemVolVars[insideScvIdx]; const auto& outsideVolVars = curElemVolVars[scvf.outsideScvIdx()]; - const auto& insideMaterialParams = problem.spatialParams().materialLawParams(element, insideScv, InvalidElemSol{}); + + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto insideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, insideScv, InvalidElemSol{}); // some quantities to be reused (rho & mu are constant and thus equal for all cells) static const auto rho = insideVolVars.density(0); @@ -458,9 +471,8 @@ public: // material law derivatives const auto insideSw = insideVolVars.saturation(0); const auto insidePc = insideVolVars.capillaryPressure(); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto dkrw_dsw_inside = MaterialLaw::dkrw_dsw(insideMaterialParams, insideSw); - const auto dsw_dpw_inside = -MaterialLaw::dsw_dpc(insideMaterialParams, insidePc); + const auto dkrw_dsw_inside = insideFluidMatrixInteraction.dkrw_dsw(insideSw); + const auto dsw_dpw_inside = -insideFluidMatrixInteraction.dsw_dpc(insidePc); // the transmissibility const auto tij = elemFluxVarsCache[scvf].advectionTij(); diff --git a/dumux/porousmediumflow/richards/newtonsolver.hh b/dumux/porousmediumflow/richards/newtonsolver.hh index fd3e9dbbd5..002ccc62e6 100644 --- a/dumux/porousmediumflow/richards/newtonsolver.hh +++ b/dumux/porousmediumflow/richards/newtonsolver.hh @@ -26,6 +26,8 @@ #define DUMUX_RICHARDS_NEWTON_SOLVER_HH #include +#include +#include #include #include @@ -44,8 +46,6 @@ class RichardsNewtonSolver : public NewtonSolver using Scalar = typename Assembler::Scalar; using ParentType = NewtonSolver; using SolutionVector = typename Assembler::ResidualType; - - using MaterialLaw = typename Assembler::Problem::SpatialParams::MaterialLaw; using Indices = typename Assembler::GridVariables::VolumeVariables::Indices; enum { pressureIdx = Indices::pressureIdx }; @@ -86,17 +86,22 @@ private: // calculate the old wetting phase saturation const auto& spatialParams = this->assembler().problem().spatialParams(); const auto elemSol = elementSolution(element, uCurrentIter, gridGeometry); - const auto& materialLawParams = spatialParams.materialLawParams(element, scv, elemSol); - const Scalar pcMin = MaterialLaw::pc(materialLawParams, 1.0); + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.1, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, spatialParams, element, scv, elemSol); + + const Scalar pcMin = fluidMatrixInteraction.pc(1.0); const Scalar pw = uLastIter[dofIdxGlobal][pressureIdx]; using std::max; const Scalar pn = max(this->assembler().problem().nonwettingReferencePressure(), pw + pcMin); const Scalar pcOld = pn - pw; - const Scalar SwOld = max(0.0, MaterialLaw::sw(materialLawParams, pcOld)); + const Scalar SwOld = max(0.0, fluidMatrixInteraction.sw(pcOld)); // convert into minimum and maximum wetting phase pressures - const Scalar pwMin = pn - MaterialLaw::pc(materialLawParams, SwOld - 0.2); - const Scalar pwMax = pn - MaterialLaw::pc(materialLawParams, SwOld + 0.2); + const Scalar pwMin = pn - fluidMatrixInteraction.pc(SwOld - 0.2); + const Scalar pwMax = pn - fluidMatrixInteraction.pc(SwOld + 0.2); // clamp the result using std::clamp; diff --git a/dumux/porousmediumflow/richards/volumevariables.hh b/dumux/porousmediumflow/richards/volumevariables.hh index 218e88abfc..d98769bc84 100644 --- a/dumux/porousmediumflow/richards/volumevariables.hh +++ b/dumux/porousmediumflow/richards/volumevariables.hh @@ -29,6 +29,8 @@ #include +#include + #include #include #include @@ -48,7 +50,7 @@ struct VolVarsWithPVSwitch struct VolVarsWithOutPVSwitch {}; -} +} // end namespace Detail /*! * \ingroup RichardsModel @@ -105,14 +107,18 @@ public: const Scv& scv) { ParentType::update(elemSol, problem, element, scv); - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto& priVars = elemSol[scv.localDofIndex()]; const auto phasePresence = priVars.state(); // precompute the minimum capillary pressure (entry pressure) // needed to make sure we don't compute unphysical capillary pressures and thus saturations - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - minPc_ = MaterialLaw::endPointPc(materialParams); + minPc_ = fluidMatrixInteraction.endPointPc(); typename FluidSystem::ParameterCache paramCache; auto getEffectiveDiffusionCoefficient = [&](int phaseIdx, int compIIdx, int compJIdx) @@ -138,7 +144,7 @@ public: EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState_, solidState_); // get pc for sw = 0.0 - const Scalar pc = MaterialLaw::pc(materialParams, 0.0); + const Scalar pc = fluidMatrixInteraction.pc(0.0); // set the wetting pressure fluidState_.setPressure(FluidSystem::liquidPhaseIdx, problem.nonwettingReferencePressure() - pc); @@ -215,7 +221,7 @@ public: ////////// // specify the other parameters ////////// - relativePermeabilityWetting_ = MaterialLaw::krw(materialParams, fluidState_.saturation(FluidSystem::liquidPhaseIdx)); + relativePermeabilityWetting_ = fluidMatrixInteraction.krw(fluidState_.saturation(FluidSystem::liquidPhaseIdx)); updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps); EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); @@ -246,13 +252,16 @@ public: { EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto& priVars = elemSol[scv.localDofIndex()]; // set the wetting pressure using std::max; - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - Scalar minPc = MaterialLaw::pc(materialParams, 1.0); + Scalar minPc = fluidMatrixInteraction.pc(1.0); fluidState.setPressure(FluidSystem::liquidPhaseIdx, priVars[Indices::pressureIdx]); fluidState.setPressure(FluidSystem::gasPhaseIdx, max(problem.nonwettingReferencePressure(), fluidState.pressure(FluidSystem::liquidPhaseIdx) + minPc)); @@ -260,9 +269,9 @@ public: // make sure that we the capillary pressure is not smaller than the minimum pc // this would possibly return unphysical values from regularized material laws using std::max; - const Scalar pc = max(MaterialLaw::endPointPc(materialParams), + const Scalar pc = max(fluidMatrixInteraction.endPointPc(), problem.nonwettingReferencePressure() - fluidState.pressure(FluidSystem::liquidPhaseIdx)); - const Scalar sw = MaterialLaw::sw(materialParams, pc); + const Scalar sw = fluidMatrixInteraction.sw(pc); fluidState.setSaturation(FluidSystem::liquidPhaseIdx, sw); fluidState.setSaturation(FluidSystem::gasPhaseIdx, 1.0-sw); -- GitLab From 1a2b196828dfb8398169d49e098f0155da1e73ef Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 30 Sep 2020 15:19:11 +0200 Subject: [PATCH 25/99] [richardsnc][volVars] Use TwoPMaterialLawWrapper --- .../richardsnc/volumevariables.hh | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/dumux/porousmediumflow/richardsnc/volumevariables.hh b/dumux/porousmediumflow/richardsnc/volumevariables.hh index 6e2194f452..63de8e17d1 100644 --- a/dumux/porousmediumflow/richardsnc/volumevariables.hh +++ b/dumux/porousmediumflow/richardsnc/volumevariables.hh @@ -33,6 +33,8 @@ #include #include +#include + namespace Dumux { /*! @@ -93,13 +95,17 @@ public: ////////// // specify the other parameters ////////// - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - relativePermeabilityWetting_ = MaterialLaw::krw(materialParams, fluidState_.saturation(0)); + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + relativePermeabilityWetting_ = fluidMatrixInteraction.krw(fluidState_.saturation(0)); // precompute the minimum capillary pressure (entry pressure) // needed to make sure we don't compute unphysical capillary pressures and thus saturations - minPc_ = MaterialLaw::endPointPc(materialParams); + minPc_ = fluidMatrixInteraction.endPointPc(); pn_ = problem.nonwettingReferencePressure(); //porosity updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, ParentType::numFluidComponents()); @@ -150,7 +156,11 @@ public: { EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto& priVars = elemSol[scv.localDofIndex()]; // set the wetting pressure @@ -160,10 +170,9 @@ public: // make sure that we the capillary pressure is not smaller than the minimum pc // this would possibly return unphysical values from regularized material laws using std::max; - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const Scalar pc = max(MaterialLaw::endPointPc(materialParams), + const Scalar pc = max(fluidMatrixInteraction.endPointPc(), problem.nonwettingReferencePressure() - fluidState.pressure(0)); - const Scalar sw = MaterialLaw::sw(materialParams, pc); + const Scalar sw = fluidMatrixInteraction.sw(pc); fluidState.setSaturation(0, sw); // set the mole/mass fractions -- GitLab From 455701bca4f4ddf3dc8ffae34f65d0b0794a7abb Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 30 Sep 2020 15:18:12 +0200 Subject: [PATCH 26/99] [2p][volVars] Use TwoPMaterialLawWrapper --- dumux/porousmediumflow/2p/volumevariables.hh | 27 ++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/dumux/porousmediumflow/2p/volumevariables.hh b/dumux/porousmediumflow/2p/volumevariables.hh index e65fdfc30b..d353f1a6a6 100644 --- a/dumux/porousmediumflow/2p/volumevariables.hh +++ b/dumux/porousmediumflow/2p/volumevariables.hh @@ -31,6 +31,8 @@ #include #include +#include + namespace Dumux { /*! @@ -93,18 +95,20 @@ public: completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); const int wPhaseIdx = fluidState_.wettingPhase(); const int nPhaseIdx = 1 - wPhaseIdx; mobility_[wPhaseIdx] = - MaterialLaw::krw(materialParams, fluidState_.saturation(wPhaseIdx)) + fluidMatrixInteraction.krw(fluidState_.saturation(wPhaseIdx)) / fluidState_.viscosity(wPhaseIdx); mobility_[nPhaseIdx] = - MaterialLaw::krn(materialParams, fluidState_.saturation(wPhaseIdx)) + fluidMatrixInteraction.krn(fluidState_.saturation(wPhaseIdx)) / fluidState_.viscosity(nPhaseIdx); // porosity calculation over inert volumefraction @@ -136,8 +140,11 @@ public: { EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto& priVars = elemSol[scv.localDofIndex()]; const auto wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); @@ -149,7 +156,7 @@ public: { fluidState.setSaturation(phase1Idx, priVars[saturationIdx]); fluidState.setSaturation(phase0Idx, 1 - priVars[saturationIdx]); - pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); fluidState.setPressure(phase1Idx, priVars[pressureIdx] - pc_); } else @@ -158,7 +165,7 @@ public: scv, elemSol, priVars[saturationIdx]); fluidState.setSaturation(phase1Idx, Sn); fluidState.setSaturation(phase0Idx, 1 - Sn); - pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); fluidState.setPressure(phase1Idx, priVars[pressureIdx] + pc_); } } @@ -171,14 +178,14 @@ public: scv, elemSol, priVars[saturationIdx]); fluidState.setSaturation(phase0Idx, Sn); fluidState.setSaturation(phase1Idx, 1 - Sn); - pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); fluidState.setPressure(phase0Idx, priVars[pressureIdx] + pc_); } else { fluidState.setSaturation(phase0Idx, priVars[saturationIdx]); fluidState.setSaturation(phase1Idx, 1 - priVars[saturationIdx]); - pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); fluidState.setPressure(phase0Idx, priVars[pressureIdx] - pc_); } } -- GitLab From 0978bfb451ec14eb2e4a0cd3da055483a1ba7013 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 30 Sep 2020 15:18:29 +0200 Subject: [PATCH 27/99] [2p1c][volVars] Use TwoPMaterialLawWrapper --- .../porousmediumflow/2p1c/volumevariables.hh | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/dumux/porousmediumflow/2p1c/volumevariables.hh b/dumux/porousmediumflow/2p1c/volumevariables.hh index 2359d89fc4..a5ed6e5432 100644 --- a/dumux/porousmediumflow/2p1c/volumevariables.hh +++ b/dumux/porousmediumflow/2p1c/volumevariables.hh @@ -36,6 +36,8 @@ #include "primaryvariableswitch.hh" +#include + namespace Dumux { /*! @@ -126,8 +128,11 @@ public: ///////////// // calculate the remaining quantities ///////////// - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); // Second instance of a parameter cache. // Could be avoided if diffusion coefficients also @@ -140,10 +145,10 @@ public: // relative permeabilities Scalar kr; if (phaseIdx == wPhaseIdx) - kr = MaterialLaw::krw(materialParams, saturation(wPhaseIdx)); + kr = fluidMatrixInteraction.krw(saturation(wPhaseIdx)); else // ATTENTION: krn requires the wetting phase saturation // as parameter! - kr = MaterialLaw::krn(materialParams, saturation(wPhaseIdx)); + kr = fluidMatrixInteraction.krn(saturation(wPhaseIdx)); relativePermeability_[phaseIdx] = kr; } @@ -176,7 +181,6 @@ public: { // capillary pressure parameters - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); const auto wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); fluidState.setWettingPhase(wPhaseIdx); @@ -211,8 +215,12 @@ public: DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); // set pressures of the fluid phases - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); if (formulation == TwoPFormulation::p0s1) { fluidState.setPressure(liquidPhaseIdx, priVars[pressureIdx]); -- GitLab From ef22548e81b0e6452f77f0c3c5a5c0592a1bf2c4 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 30 Sep 2020 15:18:42 +0200 Subject: [PATCH 28/99] [2pnc][volVars] Use TwoPMaterialLawWrapper --- .../porousmediumflow/2pnc/volumevariables.hh | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/dumux/porousmediumflow/2pnc/volumevariables.hh b/dumux/porousmediumflow/2pnc/volumevariables.hh index 7886ee8391..babd8c2c13 100644 --- a/dumux/porousmediumflow/2pnc/volumevariables.hh +++ b/dumux/porousmediumflow/2pnc/volumevariables.hh @@ -44,6 +44,8 @@ #include "primaryvariableswitch.hh" +#include + namespace Dumux { /*! @@ -140,14 +142,18 @@ public: // calculate the remaining quantities ///////////// - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& matParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const int wPhaseIdx = fluidState_.wettingPhase(); const int nPhaseIdx = 1 - wPhaseIdx; // mobilities -> require wetting phase saturation as parameter! - mobility_[wPhaseIdx] = MaterialLaw::krw(matParams, saturation(wPhaseIdx))/fluidState_.viscosity(wPhaseIdx); - mobility_[nPhaseIdx] = MaterialLaw::krn(matParams, saturation(wPhaseIdx))/fluidState_.viscosity(nPhaseIdx); + mobility_[wPhaseIdx] = fluidMatrixInteraction.krw(saturation(wPhaseIdx))/fluidState_.viscosity(wPhaseIdx); + mobility_[nPhaseIdx] = fluidMatrixInteraction.krn(saturation(wPhaseIdx))/fluidState_.viscosity(nPhaseIdx); //update porosity before calculating the effective properties depending on it updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps); @@ -190,8 +196,11 @@ public: const auto& priVars = elemSol[scv.localDofIndex()]; const auto phasePresence = priVars.state(); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); fluidState.setWettingPhase(wPhaseIdx); @@ -223,7 +232,7 @@ public: DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); // set pressures of the fluid phases - pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); if (formulation == TwoPFormulation::p0s1) { fluidState.setPressure(phase0Idx, priVars[pressureIdx]); @@ -260,13 +269,12 @@ public: } else if (phasePresence == secondPhaseOnly) { - - Dune::FieldVector moleFrac; + Dune::FieldVector moleFrac; moleFrac[comp0Idx] = priVars[switchIdx]; Scalar sumMoleFracOtherComponents = moleFrac[comp0Idx]; - for (int compIdx = numMajorComponents; compIdx < ModelTraits::numFluidComponents(); ++compIdx) + for (int compIdx = numMajorComponents; compIdx < ModelTraits::numFluidComponents(); ++compIdx) { moleFrac[compIdx] = priVars[compIdx]; sumMoleFracOtherComponents += moleFrac[compIdx]; -- GitLab From 37a8fa0c8014cd1bfda12378eab52472ccca0461 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 30 Sep 2020 15:19:02 +0200 Subject: [PATCH 29/99] [co2][volVars] Use TwoPMaterialLawWrapper --- dumux/porousmediumflow/co2/volumevariables.hh | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/dumux/porousmediumflow/co2/volumevariables.hh b/dumux/porousmediumflow/co2/volumevariables.hh index 17cfd5725e..09097d3839 100644 --- a/dumux/porousmediumflow/co2/volumevariables.hh +++ b/dumux/porousmediumflow/co2/volumevariables.hh @@ -37,6 +37,8 @@ #include "primaryvariableswitch.hh" +#include + namespace Dumux { /*! @@ -135,15 +137,17 @@ public: typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState_); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& matParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); const int wPhaseIdx = fluidState_.wettingPhase(); const int nPhaseIdx = 1 - wPhaseIdx; // relative permeabilities -> require wetting phase saturation as parameter! - relativePermeability_[wPhaseIdx] = MaterialLaw::krw(matParams, saturation(wPhaseIdx)); - relativePermeability_[nPhaseIdx] = MaterialLaw::krn(matParams, saturation(wPhaseIdx)); + relativePermeability_[wPhaseIdx] = fluidMatrixInteraction.krw(saturation(wPhaseIdx)); + relativePermeability_[nPhaseIdx] = fluidMatrixInteraction.krn(saturation(wPhaseIdx)); // porosity & permeabilty updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps); @@ -187,11 +191,14 @@ public: const auto& priVars = elemSol[scv.localDofIndex()]; const auto phasePresence = priVars.state(); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); const auto wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); fluidState.setWettingPhase(wPhaseIdx); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + // set the saturations if (phasePresence == secondPhaseOnly) { @@ -220,7 +227,7 @@ public: DUNE_THROW(Dune::InvalidStateException, "Invalid phase presence."); // set pressures of the fluid phases - pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); if (formulation == TwoPFormulation::p0s1) { fluidState.setPressure(phase0Idx, priVars[pressureIdx]); -- GitLab From 0b9d2fe912dab0dd363c2a506e06b0bcb45ce9e5 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 13 Oct 2020 09:04:30 +0200 Subject: [PATCH 30/99] [2p2c][volVars] Use TwoPMaterialLawWrapper --- .../porousmediumflow/2p2c/volumevariables.hh | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/dumux/porousmediumflow/2p2c/volumevariables.hh b/dumux/porousmediumflow/2p2c/volumevariables.hh index a4c440e698..38cab433fa 100644 --- a/dumux/porousmediumflow/2p2c/volumevariables.hh +++ b/dumux/porousmediumflow/2p2c/volumevariables.hh @@ -37,6 +37,8 @@ #include #include +#include + namespace Dumux { // forward declaration @@ -141,15 +143,17 @@ public: ParentType::update(elemSol, problem, element, scv); asImp_().completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& matParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); const int wPhaseIdx = fluidState_.wettingPhase(); const int nPhaseIdx = 1 - wPhaseIdx; // relative permeabilities -> require wetting phase saturation as parameter! - relativePermeability_[wPhaseIdx] = MaterialLaw::krw(matParams, saturation(wPhaseIdx)); - relativePermeability_[nPhaseIdx] = MaterialLaw::krn(matParams, saturation(wPhaseIdx)); + relativePermeability_[wPhaseIdx] = fluidMatrixInteraction.krw(saturation(wPhaseIdx)); + relativePermeability_[nPhaseIdx] = fluidMatrixInteraction.krn(saturation(wPhaseIdx)); // porosity & permeabilty updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps); @@ -192,8 +196,11 @@ public: const auto& priVars = elemSol[scv.localDofIndex()]; const auto phasePresence = priVars.state(); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); fluidState.setWettingPhase(wPhaseIdx); @@ -225,7 +232,7 @@ public: DUNE_THROW(Dune::InvalidStateException, "Invalid phase presence."); // set pressures of the fluid phases - pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); if (formulation == TwoPFormulation::p0s1) { fluidState.setPressure(phase0Idx, priVars[pressureIdx]); -- GitLab From c679ed4a4e7c9f6626f08fbc28c11fea70ad24cd Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 30 Sep 2020 17:48:31 +0200 Subject: [PATCH 31/99] [noneq][volVars] Use deprecation wrapper --- .../nonequilibrium/volumevariables.hh | 74 +++++++++---------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/dumux/porousmediumflow/nonequilibrium/volumevariables.hh b/dumux/porousmediumflow/nonequilibrium/volumevariables.hh index 54ec786a08..edc8789add 100644 --- a/dumux/porousmediumflow/nonequilibrium/volumevariables.hh +++ b/dumux/porousmediumflow/nonequilibrium/volumevariables.hh @@ -36,6 +36,8 @@ #include #include +#include + namespace Dumux { /*! @@ -176,24 +178,23 @@ public: const Element& element, const Scv& scv) { - // obtain (standard) material parameters (needed for the residual saturations) - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - - //obtain parameters for interfacial area constitutive relations - const auto& aWettingNonwettingSurfaceParams = problem.spatialParams().aWettingNonwettingSurfaceParams(element, scv, elemSol); - const Scalar pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx); const Scalar Sw = fluidState.saturation(phase0Idx); - using AwnSurface = typename Problem::SpatialParams::AwnSurface; - const auto awn = AwnSurface::interfacialArea(aWettingNonwettingSurfaceParams, materialParams, Sw, pc); + // old material law interface is deprecated: Replace this by + // const auto& wettingNonwettingInterfacialArea = spatialParams.wettingNonwettingInterfacialArea(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeInterfacialAreaHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + const auto awn = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc); interfacialArea_[phase0Idx][phase1Idx] = awn; interfacialArea_[phase1Idx][phase0Idx] = interfacialArea_[phase0Idx][phase1Idx]; interfacialArea_[phase0Idx][phase0Idx] = 0.; - using AnsSurface = typename Problem::SpatialParams::AnsSurface; - const auto& aNonwettingSolidSurfaceParams = problem.spatialParams().aNonwettingSolidSurfaceParams(element, scv, elemSol); - const auto ans = AnsSurface::interfacialArea(aNonwettingSolidSurfaceParams, materialParams, Sw, pc); + // old material law interface is deprecated: Replace this by + // const auto& nonwettingSolidInterfacialArea = spatialParams.nonwettingSolidInterfacialArea(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto ans = fluidMatrixInteraction.nonwettingSolidInterface().area(Sw, pc); // Switch for using a a_{wn} relations that has some "maximum capillary pressure" as parameter // That value is obtained by regularization of the pc(Sw) function. @@ -201,15 +202,17 @@ public: if (computeAwsFromAnsAndPcMax) { // I know the solid surface from the pore network. But it is more consistent to use the fit value. - const Scalar pcMax = aWettingNonwettingSurfaceParams.pcMax(); - const auto solidSurface = AnsSurface::interfacialArea(aNonwettingSolidSurfaceParams, materialParams, /*Sw=*/0., pcMax); + const Scalar pcMax = fluidMatrixInteraction.wettingNonwettingInterface().basicParams().pcMax(); + const auto solidSurface = fluidMatrixInteraction.nonwettingSolidInterface().area(/*Sw=*/0., pcMax); interfacialArea_[phase0Idx][sPhaseIdx] = solidSurface - ans; } else { - using AwsSurface = typename Problem::SpatialParams::AwsSurface; - const auto& aWettingSolidSurfaceParams = problem.spatialParams().aWettingSolidSurfaceParams(element, scv, elemSol); - interfacialArea_[phase0Idx][sPhaseIdx] = AwsSurface::interfacialArea(aWettingSolidSurfaceParams, materialParams, Sw, pc); + // old material law interface is deprecated: Replace this by + // const auto& wettingSolidInterfacialArea = spatialParams.wettingSolidInterfacialArea(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeInterfacialAreaHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + interfacialArea_[phase0Idx][sPhaseIdx] = fluidMatrixInteraction.wettingSolidInterface().area(Sw, pc); } interfacialArea_[sPhaseIdx][phase0Idx] = interfacialArea_[phase0Idx][sPhaseIdx]; @@ -536,16 +539,17 @@ public: const Scv& scv) { // obtain parameters for awnsurface and material law - const auto& awnSurfaceParams = problem.spatialParams().aWettingNonwettingSurfaceParams(element, scv, elemSol) ; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol) ; + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeInterfacialAreaHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto Sw = fluidState.saturation(phase0Idx) ; const auto pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx); // when we only consider chemical non-equilibrium there is only mass transfer between - // the fluid phases, so in 2p only interfacial area between wetting and nonwetting - using AwnSurface = typename Problem::SpatialParams::AwnSurface; - interfacialArea_ = AwnSurface::interfacialArea(awnSurfaceParams, materialParams, Sw, pc); + // the fluid phases, so in 2p only interfacial area between wetting and non-wetting + interfacialArea_ = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc); } /*! @@ -720,24 +724,20 @@ public: const Element& element, const Scv& scv) { - // obtain (standard) material parameters (needed for the residual saturations) - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - - //obtain parameters for interfacial area constitutive relations - const auto& aWettingNonwettingSurfaceParams = problem.spatialParams().aWettingNonwettingSurfaceParams(element, scv, elemSol); - const Scalar pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx); const Scalar Sw = fluidState.saturation(phase0Idx); - using AwnSurface = typename Problem::SpatialParams::AwnSurface; - const auto awn = AwnSurface::interfacialArea(aWettingNonwettingSurfaceParams, materialParams, Sw, pc); + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makeInterfacialAreaHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + const auto awn = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc); interfacialArea_[phase0Idx][phase1Idx] = awn; interfacialArea_[phase1Idx][phase0Idx] = interfacialArea_[phase0Idx][phase1Idx]; interfacialArea_[phase0Idx][phase0Idx] = 0.; - using AnsSurface = typename Problem::SpatialParams::AnsSurface; - const auto& aNonwettingSolidSurfaceParams = problem.spatialParams().aNonwettingSolidSurfaceParams(element, scv, elemSol); - const auto ans = AnsSurface::interfacialArea(aNonwettingSolidSurfaceParams, materialParams, Sw, pc); + const auto ans = fluidMatrixInteraction.nonwettingSolidInterface().area(Sw, pc); // Switch for using a a_{wn} relations that has some "maximum capillary pressure" as parameter. // That value is obtained by regularization of the pc(Sw) function. @@ -745,16 +745,12 @@ public: if (computeAwsFromAnsAndPcMax) { // I know the solid surface from the pore network. But it is more consistent to use the fit value. - const Scalar pcMax = aWettingNonwettingSurfaceParams.pcMax(); - const auto solidSurface = AnsSurface::interfacialArea(aNonwettingSolidSurfaceParams, materialParams, /*Sw=*/0., pcMax); + const Scalar pcMax = fluidMatrixInteraction.wettingNonwettingInterface().basicParams().pcMax(); + const auto solidSurface = fluidMatrixInteraction.nonwettingSolidInterface().area(/*Sw=*/0., pcMax); interfacialArea_[phase0Idx][sPhaseIdx] = solidSurface - ans; } else - { - using AwsSurface = typename Problem::SpatialParams::AwsSurface; - const auto& aWettingSolidSurfaceParams = problem.spatialParams().aWettingSolidSurfaceParams(element, scv, elemSol); - interfacialArea_[phase0Idx][sPhaseIdx] = AwsSurface::interfacialArea(aWettingSolidSurfaceParams, materialParams, Sw, pc); - } + interfacialArea_[phase0Idx][sPhaseIdx] = fluidMatrixInteraction.wettingSolidInterface().area(Sw, pc); interfacialArea_[sPhaseIdx][phase0Idx] = interfacialArea_[phase0Idx][sPhaseIdx]; interfacialArea_[sPhaseIdx][sPhaseIdx] = 0.; -- GitLab From 3a7b068fd902ded27bcb698f7b0944f9dc661c76 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 27 Jun 2019 20:45:04 +0200 Subject: [PATCH 32/99] [test] Use new law in a Richards tests --- .../implicit/analytical/spatialparams.hh | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/test/porousmediumflow/richards/implicit/analytical/spatialparams.hh b/test/porousmediumflow/richards/implicit/analytical/spatialparams.hh index 19ef43964d..6a450aa0e8 100644 --- a/test/porousmediumflow/richards/implicit/analytical/spatialparams.hh +++ b/test/porousmediumflow/richards/implicit/analytical/spatialparams.hh @@ -27,7 +27,6 @@ #include #include -#include #include @@ -50,22 +49,20 @@ class RichardsAnalyticalSpatialParams using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; -public: + using PcKrSwCurve = FluidMatrix::LinearMaterialDefault; - using MaterialLaw = EffToAbsLaw>; - using MaterialLawParams = typename MaterialLaw::Params; +public: // export permeability type using PermeabilityType = Scalar; RichardsAnalyticalSpatialParams(std::shared_ptr gridGeometry) - : ParentType(gridGeometry) + : ParentType(gridGeometry) { permeability_ = 5e-12; - materialParams_.setSwr(0.0); - materialParams_.setSnr(0.0); - materialParams_.setEntryPc(0); - materialParams_.setMaxPc(1e10); + + typename PcKrSwCurve::BasicParams params(0/*pcEntry*/, 1e10/*pcMax*/); + pcKrSwCurve_ = std::make_unique(params); } /*! @@ -88,14 +85,14 @@ public: * \brief Returns the parameters for the material law at a given location * \param globalPos A global coordinate vector */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition &globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const { - return materialParams_; + return makeFluidMatrixInteraction(*pcKrSwCurve_); } private: Scalar permeability_; - MaterialLawParams materialParams_; + std::unique_ptr pcKrSwCurve_; }; } // end namespace Dumux -- GitLab From abc16bd4ae8e1317d9344a9ecf4fd3c97b50ab3e Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Wed, 30 Sep 2020 18:30:39 +0200 Subject: [PATCH 33/99] [test] Use new 2p material laws in the unit tests --- .../2p/test_material_2p_brookscorey.cc | 50 +++++++------- .../2p/test_material_2p_vangenuchten.cc | 66 ++++++++++--------- .../2p/testmateriallawfunctions.hh | 40 ++++++----- 3 files changed, 79 insertions(+), 77 deletions(-) diff --git a/test/material/fluidmatrixinteractions/2p/test_material_2p_brookscorey.cc b/test/material/fluidmatrixinteractions/2p/test_material_2p_brookscorey.cc index c9e487ba50..81f5d15930 100644 --- a/test/material/fluidmatrixinteractions/2p/test_material_2p_brookscorey.cc +++ b/test/material/fluidmatrixinteractions/2p/test_material_2p_brookscorey.cc @@ -2,11 +2,7 @@ #include -#include #include -#include -#include -#include #include #include "testmateriallawfunctions.hh" @@ -15,11 +11,10 @@ namespace Dumux::Test { // test if endPointPc() is the same as evaluation at sw=1 template -void checkEndPointPc(const typename Law::Params& params) +void checkEndPointPc(const Law& law, const double entryPressure) { - const auto pcSat = Law::pc(params, Law::sweToSw(params, 1.0)); - const auto endPointPc = Law::endPointPc(params); - const auto entryPressure = params.pe(); + const auto pcSat = law.pc(Law::EffToAbs::sweToSw(1.0, law.effToAbsParams())); + const auto endPointPc = law.endPointPc(); static constexpr double eps = 1e-10; if (Dune::FloatCmp::ne(pcSat, endPointPc, eps)) @@ -34,27 +29,34 @@ int main(int argc, char** argv) { using namespace Dumux; - using BCRegEff = RegularizedBrooksCorey; - using BCEff = BrooksCorey; - using BCReg = EffToAbsLaw; - using BC = EffToAbsLaw; + using BCReg = FluidMatrix::BrooksCoreyDefault; + using BC = FluidMatrix::BrooksCoreyNoReg; // set some parameters - BCReg::Params params; - params.setPe(1e4); - params.setLambda(2.0); - params.setSwr(0.1); - params.setSnr(0.1); - params.setThresholdSw(0.01); + const double pcEntry = 1e4; + const double lambda = 2.0; + BCReg::BasicParams params(pcEntry, lambda); - Test::checkEndPointPc(params); - Test::checkEndPointPc(params); + BCReg::EffToAbsParams eaParams; + eaParams.setSwr(0.1); + eaParams.setSnr(0.1); - const auto sw = Dumux::linspace(0.0, 1.0, 100); - const auto swNonReg = Dumux::linspace(BCReg::sweToSw(params, params.thresholdSw()), BCReg::sweToSw(params, 1.0), 100); + BCReg::RegularizationParams regParams; + const double thresholdSw = 0.01; + regParams.setPcLowSwe(thresholdSw); - Test::runMaterialLawTest("brookscorey", params, sw, swNonReg); - Test::runEffToAbsTest("brookscorey-efftoabs", params, sw); + BCReg bcRegLaw(params, eaParams, regParams); + BC bcLaw(params, eaParams); + + Test::checkEndPointPc(bcRegLaw, pcEntry); + Test::checkEndPointPc(bcLaw, pcEntry); + + const auto sw = linspace(0.0, 1.0, 100); + const auto swNonReg = linspace(BCReg::EffToAbs::sweToSw(thresholdSw, eaParams), BCReg::EffToAbs::sweToSw(1.0, eaParams), 100); + + Test::runMaterialLawTest("brookscorey", bcLaw, bcRegLaw, sw, swNonReg); + Test::runEffToAbsTest("brookscorey-efftoabs", bcLaw, sw); + Test::runEffToAbsTest("brookscorey-reg-efftoabs", bcRegLaw, sw); return 0; } diff --git a/test/material/fluidmatrixinteractions/2p/test_material_2p_vangenuchten.cc b/test/material/fluidmatrixinteractions/2p/test_material_2p_vangenuchten.cc index fa2830c8c0..f092cbe9d3 100644 --- a/test/material/fluidmatrixinteractions/2p/test_material_2p_vangenuchten.cc +++ b/test/material/fluidmatrixinteractions/2p/test_material_2p_vangenuchten.cc @@ -2,11 +2,7 @@ #include -#include #include -#include -#include -#include #include #include "testmateriallawfunctions.hh" @@ -15,13 +11,13 @@ namespace Dumux::Test { // test if endPointPc() is the same as evaluation at sw=1 template -void checkEndPointPc(const typename Law::Params& params) +void checkEndPointPc(const Law& law) { - const auto pcSat = Law::pc(params, Law::sweToSw(params, 1.0)); - const auto endPointPc = Law::endPointPc(params); - static constexpr double eps = 1e-10; + const auto pcSat = law.pc(Law::EffToAbs::sweToSw(1.0, law.effToAbsParams())); + const auto endPointPc = law.endPointPc(); + static constexpr double eps = 1e-7; - if (Dune::FloatCmp::ne(pcSat, endPointPc, eps)) + if (Dune::FloatCmp::lt(eps, std::abs(pcSat-endPointPc))) DUNE_THROW(Dune::Exception, "pc(sw=1) != endPointPc(): " << pcSat << " != " << endPointPc); } @@ -31,31 +27,37 @@ int main(int argc, char** argv) { using namespace Dumux; - using VGRegEff = RegularizedVanGenuchten; - using VGEff = VanGenuchten; - using VGReg = EffToAbsLaw; - using VG = EffToAbsLaw; + using VGReg = FluidMatrix::VanGenuchtenDefault; + using VG = FluidMatrix::VanGenuchtenNoReg; // set some parameters - VGReg::Params params; - params.setVgAlpha(6.66e-5); - params.setVgn(3.652); - params.setVgl(0.5); - params.setSwr(0.1); - params.setSnr(0.1); - params.setPcLowSw(0.01); - params.setPcHighSw(0.99); - params.setKrnLowSw(0.1); - params.setKrwHighSw(0.9); - - Test::checkEndPointPc(params); - Test::checkEndPointPc(params); - - const auto sw = Dumux::linspace(0.0, 1.0, 100); - const auto swNonReg = Dumux::linspace(VGReg::sweToSw(params, params.pcLowSw()), VGReg::sweToSw(params, params.pcHighSw()), 100); - - Test::runMaterialLawTest("vangenuchten", params, sw, swNonReg); - Test::runEffToAbsTest("vangenuchten-efftoabs", params, sw); + const double alpha = 6.66e-5; + const double n = 3.652; + const double l = 0.5; + VGReg::BasicParams params(alpha, n, l); + + VGReg::EffToAbsParams eaParams; + eaParams.setSwr(0.1); + eaParams.setSnr(0.1); + + VGReg::RegularizationParams regParams; + regParams.setPcLowSwe(0.01); + regParams.setPcHighSwe(0.99); + regParams.setKrnLowSwe(0.1); + regParams.setKrwHighSwe(0.9); + + VGReg vgRegLaw(params, eaParams, regParams); + VG vgLaw(params, eaParams); + + Test::checkEndPointPc(vgRegLaw); + Test::checkEndPointPc(vgLaw); + + const auto sw = linspace(0.0, 1.0, 100); + const auto swNonReg = linspace(VGReg::EffToAbs::sweToSw(regParams.pcLowSwe(), eaParams), VGReg::EffToAbs::sweToSw(regParams.pcHighSwe(), eaParams), 100); + + Test::runMaterialLawTest("vangenuchten", vgLaw, vgRegLaw, sw, swNonReg); + Test::runEffToAbsTest("vangenuchten-efftoabs", vgLaw, sw); + Test::runEffToAbsTest("vangenuchten-reg-efftoabs", vgRegLaw, sw); return 0; } diff --git a/test/material/fluidmatrixinteractions/2p/testmateriallawfunctions.hh b/test/material/fluidmatrixinteractions/2p/testmateriallawfunctions.hh index f6e893348d..2ceed1fd75 100644 --- a/test/material/fluidmatrixinteractions/2p/testmateriallawfunctions.hh +++ b/test/material/fluidmatrixinteractions/2p/testmateriallawfunctions.hh @@ -76,46 +76,44 @@ void testValueEqualRange(std::string_view testName, template -void runMaterialLawTest(const std::string& name, const typename RegLaw::Params& params, +void runMaterialLawTest(const std::string& name, + const Law& law, + const RegLaw& regLaw, const std::vector& sw, const std::vector& swNonReg) { const auto pc = [&](){ auto pc = sw; for (int i = 0; i < sw.size(); ++i) - pc[i] = RegLaw::pc(params, sw[i]); + pc[i] = regLaw.pc(sw[i]); return pc; }(); - testDerivatives("dpc_dsw", sw, [&](auto sw){ return RegLaw::pc(params, sw); }, [&](auto sw){ return RegLaw::dpc_dsw(params, sw); }); - testDerivatives("dkrw_dsw", sw, [&](auto sw){ return RegLaw::krw(params, sw); }, [&](auto sw){ return RegLaw::dkrw_dsw(params, sw); }); - testDerivatives("dkrn_dsw", sw, [&](auto sw){ return RegLaw::krn(params, sw); }, [&](auto sw){ return RegLaw::dkrn_dsw(params, sw); }); - testDerivatives("dsw_dpc", pc, [&](auto pc){ return RegLaw::sw(params, pc); }, [&](auto pc){ return RegLaw::dsw_dpc(params, pc); }); - testValueEqualRange("Checking sw == sw(pc(sw))", sw, [](auto sw){ return sw; }, [&](auto sw) { return RegLaw::sw(params, RegLaw::pc(params, sw)); }); - testValueEqualRange("Checking 1.0 == dsw_dpc*dpc_dsw^-1", sw, [](auto sw){ return 1.0; }, [&](auto sw) { return RegLaw::dpc_dsw(params, sw)*RegLaw::dsw_dpc(params, RegLaw::pc(params, sw)); }); + testDerivatives("dpc_dsw", sw, [&](auto sw){ return regLaw.pc(sw); }, [&](auto sw){ return regLaw.dpc_dsw(sw); }); + testDerivatives("dkrw_dsw", sw, [&](auto sw){ return regLaw.krw(sw); }, [&](auto sw){ return regLaw.dkrw_dsw(sw); }); + testDerivatives("dkrn_dsw", sw, [&](auto sw){ return regLaw.krn(sw); }, [&](auto sw){ return regLaw.dkrn_dsw(sw); }); + testDerivatives("dsw_dpc", pc, [&](auto pc){ return regLaw.sw(pc); }, [&](auto pc){ return regLaw.dsw_dpc(pc); }); + testValueEqualRange("Checking sw == sw(pc(sw))", sw, [](auto sw){ return sw; }, [&](auto sw) { return regLaw.sw(regLaw.pc(sw)); }); + testValueEqualRange("Checking 1.0 == dsw_dpc*dpc_dsw^-1", sw, [](auto sw){ return 1.0; }, [&](auto sw) { return regLaw.dpc_dsw(sw)*regLaw.dsw_dpc(regLaw.pc(sw)); }); // check that regularized and unregularized are the same in the region without regularization - testValueEqualRange("Checking NoReg::pc == Reg::pc", swNonReg, [&](auto sw){ return RegLaw::pc(params, sw); }, [&](auto sw) { return Law::pc(params, sw); }); + testValueEqualRange("Checking NoReg::pc == Reg::pc", swNonReg, [&](auto sw){ return law.pc(sw); }, [&](auto sw) { return regLaw.pc(sw); }); // test pc-sw curve against some precomputed values writeContainerToFile(pc, "test_pcsw_" + name + ".dat", 100); } -template -void runEffToAbsTest(const std::string& name, const typename AbsLaw::Params& params, - const std::vector& sw) +template +void runEffToAbsTest(const std::string& name, const FluidMatrix& fmLaw, + const std::vector& sw) { - testValueEqualRange("Checking 1.0 == Abs::swToSwe(1-snr)", sw, [](auto sw){ return 1.0; }, [&](auto sw) { return AbsLaw::swToSwe(params, 1-params.snr()); }); - testValueEqualRange("Checking 0.0 == Abs::swToSwe(snr)", sw, [](auto sw){ return 0.0; }, [&](auto sw) { return AbsLaw::swToSwe(params, params.snr()); }); - testValueEqualRange("Checking 1.0 == Abs::snToSne(1-swr)", sw, [](auto sw){ return 1.0; }, [&](auto sw) { return AbsLaw::snToSne(params, 1-params.swr()); }); - testValueEqualRange("Checking 0.0 == Abs::snToSne(swr)", sw, [](auto sw){ return 0.0; }, [&](auto sw) { return AbsLaw::snToSne(params, params.swr()); }); + using EffToAbs = typename FluidMatrix::EffToAbs; + const auto params = fmLaw.effToAbsParams(); - testValueEqualRange("Checking sn == sneToSn(snToSne(sn))", sw, [](auto sn){ return sn; }, [&](auto sn) { return AbsLaw::sneToSn(params, AbsLaw::snToSne(params, sn)); }); - testValueEqualRange("Checking sw == sweToSw(swToSwe(sw))", sw, [](auto sw){ return sw; }, [&](auto sw) { return AbsLaw::sweToSw(params, AbsLaw::swToSwe(params, sw)); }); - - testValueEqualRange("Checking Abs::pc(1-snr) == Eff::pc(1.0)", sw, [&](auto pc){ return AbsLaw::pc(params, 1-params.snr()); }, [&](auto pc) { return EffLaw::pc(params, 1.0); }); - testValueEqualRange("Checking Abs::endPointPc == Eff::pc(1.0)", sw, [&](auto pc){ return AbsLaw::endPointPc(params); }, [&](auto pc) { return EffLaw::pc(params, 1.0); }); + testValueEqualRange("Checking 1.0 == Abs::swToSwe(1-snr)", sw, [](auto sw){ return 1.0; }, [&](auto sw) { return EffToAbs::swToSwe(1-params.snr(), params); }); + testValueEqualRange("Checking 0.0 == Abs::swToSwe(snr)", sw, [](auto sw){ return 0.0; }, [&](auto sw) { return EffToAbs::swToSwe(params.snr(), params); }); + testValueEqualRange("Checking sw == sweToSw(swToSwe(sw))", sw, [](auto sw){ return sw; }, [&](auto sw) { return EffToAbs::sweToSw(EffToAbs::swToSwe(sw, params), params); }); } } // end namespace Dumux -- GitLab From fc4846b8cb91805a6db7cc7f590cded4f9301192 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 29 Sep 2020 13:11:38 +0200 Subject: [PATCH 34/99] [test][mpnc] Adapt thermalnonequil test --- .../implicit/thermalnonequilibrium/problem.hh | 13 ++--- .../thermalnonequilibrium/spatialparams.hh | 50 ++++++++----------- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/problem.hh b/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/problem.hh index de62ede286..8b68189255 100644 --- a/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/problem.hh +++ b/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/problem.hh @@ -197,7 +197,6 @@ class CombustionProblemOneComponent: public PorousMediumFlowProblem using Indices = typename ModelTraits::Indices; enum {dimWorld = GridView::dimensionworld}; - enum {numPhases = ModelTraits::numFluidPhases()}; enum {numComponents = ModelTraits::numFluidComponents()}; enum {s0Idx = Indices::s0Idx}; enum {p0Idx = Indices::p0Idx}; @@ -211,6 +210,8 @@ class CombustionProblemOneComponent: public PorousMediumFlowProblem enum {wCompIdx = FluidSystem::H2OIdx}; enum {nCompIdx = FluidSystem::N2Idx}; + static constexpr auto numPhases = ModelTraits::numFluidPhases(); + // formulations static constexpr auto pressureFormulation = ModelTraits::pressureFormulation(); static constexpr auto mostWettingFirst = MpNcPressureFormulation::mostWettingFirst; @@ -448,16 +449,12 @@ private: ////////////////////////////////////// priVars[energyEq0Idx] = thisTemperature; priVars[energyEqSolidIdx] = thisTemperature; - std::vector capPress(numPhases); + std::array capPress; //obtain pc according to saturation - const auto &materialParams = - this->spatialParams().materialLawParamsAtPos(globalPos); - using MaterialLaw = typename ParentType::SpatialParams::MaterialLaw; - using MPAdapter = MPAdapter; - const int wettingPhaseIdx = this->spatialParams().template wettingPhaseAtPos(globalPos); - MPAdapter::capillaryPressures(capPress, materialParams, fluidState, wettingPhaseIdx); + using MPAdapter = FluidMatrix::MPAdapter; + MPAdapter::capillaryPressures(capPress, this->spatialParams().fluidMatrixInteractionAtPos(globalPos), fluidState, wettingPhaseIdx); Scalar p[numPhases]; diff --git a/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/spatialparams.hh b/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/spatialparams.hh index 32ef6c727d..fbfd4fca83 100644 --- a/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/spatialparams.hh @@ -30,9 +30,7 @@ #include #include -#include #include -#include #include #include #include @@ -57,16 +55,14 @@ class CombustionSpatialParams enum {dimWorld = GridView::dimensionworld}; using GlobalPosition = typename SubControlVolume::GlobalPosition; - using EffectiveLaw = HeatPipeLaw; + using PcKrSwCurve = FluidMatrix::HeatPipeLaw; public: //! Export the type used for the permeability using PermeabilityType = Scalar; - //! Export the material law type used - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using FluidSolidInterfacialAreaFormulation = FluidSolidInterfacialAreaShiWang; + CombustionSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) { // this is the parameter value from file part @@ -75,9 +71,6 @@ public: porosityOutFlow_ = getParam("SpatialParams.Outflow.porosityOutFlow"); interfacialTension_ = getParam("Constants.interfacialTension"); - Swr_ = getParam("SpatialParams.soil.Swr"); - Snr_ = getParam("SpatialParams.soil.Snr"); - characteristicLength_ =getParam("SpatialParams.PorousMedium.meanPoreSize"); using std::pow; @@ -86,13 +79,16 @@ public: factorEnergyTransfer_ = getParam("SpatialParams.PorousMedium.factorEnergyTransfer"); lengthPM_ = getParam("Grid.lengthPM"); - // residual saturations - materialParams_.setSwr(Swr_) ; - materialParams_.setSnr(Snr_) ; - using std::sqrt; - materialParams_.setP0(sqrt(porosity_/intrinsicPermeability_)); - materialParams_.setGamma(interfacialTension_); // interfacial tension of water-air at 100°C + const Scalar p0 = sqrt(porosity_/intrinsicPermeability_); + const Scalar gamma = interfacialTension_; // interfacial tension of water-air at 100°C + typename PcKrSwCurve::Params params(p0, gamma); + + typename PcKrSwCurve::EffToAbsParams effToAbsParams; + effToAbsParams.setSwr(getParam("SpatialParams.soil.Swr")); + effToAbsParams.setSnr(getParam("SpatialParams.soil.Snr")); + + pcKrSwCurve_ = std::make_unique(params, effToAbsParams); } template @@ -169,13 +165,6 @@ public: return FluidSystem::phase0Idx; } - /*! - * \brief Returns a reference to the material parameters of the material law. - * \param globalPos The position in global coordinates. - */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition & globalPos) const - { return materialParams_ ; } - /*! * \brief Returns the characteristic length for the mass transfer. * \param globalPos The position in global coordinates. @@ -197,6 +186,15 @@ public: //! Returns the interfacial tension Scalar interfacialTension() const { return interfacialTension_ ; } + /*! + * \brief Returns the parameters for the material law at a given location + * \param globalPos A global coordinate vector + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const + { + return makeFluidMatrixInteraction(*pcKrSwCurve_); + } + private: static constexpr Scalar eps_ = 1e-6; @@ -205,7 +203,6 @@ private: Scalar porosity_ ; Scalar factorEnergyTransfer_ ; Scalar characteristicLength_ ; - MaterialLawParams materialParams_ ; // Outflow Domain Scalar intrinsicPermeabilityOutFlow_ ; @@ -214,13 +211,10 @@ private: // solid parameters Scalar interfacialTension_ ; - - // capillary pressures parameters - Scalar Swr_ ; - Scalar Snr_ ; - // grid Scalar lengthPM_ ; + + std::unique_ptr pcKrSwCurve_; }; } -- GitLab From 82b83f75dceb82891be1b779cc3b5b7c806120dd Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Wed, 30 Sep 2020 17:49:11 +0200 Subject: [PATCH 35/99] [test][mpnckinetic] Adapt spatialparams --- .../mpnc/implicit/kinetic/problem.hh | 15 +- .../mpnc/implicit/kinetic/spatialparams.hh | 249 ++++++++---------- 2 files changed, 116 insertions(+), 148 deletions(-) diff --git a/test/porousmediumflow/mpnc/implicit/kinetic/problem.hh b/test/porousmediumflow/mpnc/implicit/kinetic/problem.hh index 92a34e8a35..8423989dd1 100644 --- a/test/porousmediumflow/mpnc/implicit/kinetic/problem.hh +++ b/test/porousmediumflow/mpnc/implicit/kinetic/problem.hh @@ -51,14 +51,6 @@ #include "spatialparams.hh" -// material laws for interfacial area -#include -#include -#include -#include -#include -#include - namespace Dumux { /*! * \ingroup MPNCTests @@ -389,15 +381,12 @@ private: equilibriumFluidState.setTemperature(phaseIdx, TInitial_ ); } - const auto &materialParams = - this->spatialParams().materialLawParamsAtPos(globalPos); std::vector capPress(numPhases); // obtain pc according to saturation - using MaterialLaw = typename ParentType::SpatialParams::MaterialLaw; - using MPAdapter = MPAdapter; + using MPAdapter = FluidMatrix::MPAdapter; const int wPhaseIdx = this->spatialParams().template wettingPhaseAtPos(globalPos); - MPAdapter::capillaryPressures(capPress, materialParams, equilibriumFluidState, wPhaseIdx); + MPAdapter::capillaryPressures(capPress, this->spatialParams().fluidMatrixInteractionAtPos(globalPos), equilibriumFluidState, wPhaseIdx); Scalar p[numPhases]; if (this->spatialParams().inPM_(globalPos)){ diff --git a/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh b/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh index 644fb6d817..15c3c3863c 100644 --- a/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh @@ -28,18 +28,17 @@ #include #include -#include -#include -#include -#include -#include + +#include +#include + #include // material laws for interfacial area -#include -#include -#include -#include +#include +#include +#include +#include namespace Dumux { @@ -61,37 +60,33 @@ class EvaporationAtmosphereSpatialParams using GlobalPosition = typename Element::Geometry::GlobalCoordinate; static constexpr auto dimWorld = GridView::dimensionworld; + + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; + + using NonwettingSolidInterfacialArea = FluidMatrix::InterfacialArea; + using WettingSolidInterfacialArea = FluidMatrix::InterfacialArea; + using WettingNonwettingInterfacialArea = FluidMatrix::InterfacialArea; public: //! Export the type used for the permeability using PermeabilityType = Scalar; - //! Export the material law type used - using MaterialLaw = EffToAbsLaw>; - //! Convenience aliases of the law parameters - using MaterialLawParams = typename MaterialLaw::Params; - - //! Export the types used for interfacial area calculations - using EffectiveIALawAws = AwnSurfacePolynomial2ndOrder; - using EffectiveIALawAwn = AwnSurfacePcMaxFct; - using EffectiveIALawAns = AwnSurfaceExpSwPcTo3; - using AwnSurface = EffToAbsLawIA; - using AwsSurface = EffToAbsLawIA; - using AnsSurface = EffToAbsLawIA; - - using AwnSurfaceParams = typename AwnSurface::Params; - using AwsSurfaceParams = typename AwsSurface::Params; - using AnsSurfaceParams = typename AnsSurface::Params; EvaporationAtmosphereSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) { - heightPM_ = getParam>("Grid.Positions1")[1]; - heightDomain_ = getParam>("Grid.Positions1")[2]; + heightPM_ = getParam>("Grid.Positions1")[1]; + heightDomain_ = getParam>("Grid.Positions1")[2]; - porosityPM_ = getParam("SpatialParams.PorousMedium.porosity"); - intrinsicPermeabilityPM_ = getParam("SpatialParams.PorousMedium.permeability"); + porosityPM_ = getParam("SpatialParams.PorousMedium.porosity"); + intrinsicPermeabilityPM_ = getParam("SpatialParams.PorousMedium.permeability"); - porosityFF_ = getParam("SpatialParams.FreeFlow.porosity"); - intrinsicPermeabilityFF_ = getParam("SpatialParams.FreeFlow.permeability"); + porosityFF_ = getParam("SpatialParams.FreeFlow.porosity"); + intrinsicPermeabilityFF_ = getParam("SpatialParams.FreeFlow.permeability"); aWettingNonwettingA1_ = getParam("SpatialParams.soil.aWettingNonwettingA1"); aWettingNonwettingA2_ = getParam("SpatialParams.soil.aWettingNonwettingA2"); @@ -101,31 +96,26 @@ public: aNonwettingSolidA2_ = getParam("SpatialParams.soil.aNonwettingSolidA2"); aNonwettingSolidA3_ = getParam("SpatialParams.soil.aNonwettingSolidA3"); - BCPd_ = getParam("SpatialParams.soil.BCPd"); - BClambda_ = getParam("SpatialParams.soil.BClambda"); - Swr_ = getParam("SpatialParams.soil.Swr"); - Snr_ = getParam("SpatialParams.soil.Snr"); + BCPd_ = getParam("SpatialParams.soil.BCPd"); + BClambda_ = getParam("SpatialParams.soil.BClambda"); + Swr_ = getParam("SpatialParams.soil.Swr"); + Snr_ = getParam("SpatialParams.soil.Snr"); - characteristicLengthFF_ = getParam("SpatialParams.FreeFlow.meanPoreSize"); - characteristicLengthPM_ = getParam("SpatialParams.PorousMedium.meanPoreSize"); + characteristicLengthFF_ = getParam("SpatialParams.FreeFlow.meanPoreSize"); + characteristicLengthPM_ = getParam("SpatialParams.PorousMedium.meanPoreSize"); factorEnergyTransfer_ = getParam("SpatialParams.PorousMedium.factorEnergyTransfer"); factorMassTransfer_ = getParam("SpatialParams.PorousMedium.factorMassTransfer"); - // residual saturations - materialParamsFF_.setSwr(0.0); - materialParamsFF_.setSnr(0.00); - - materialParamsPM_.setSwr(Swr_); - materialParamsPM_.setSnr(Snr_); - - // pc / kr parameters - materialParamsPM_.setLambda(BClambda_); - materialParamsPM_.setPe(BCPd_); + // PM parameters for Brooks-Corey + typename PcKrSwCurve::BasicParams paramsPM(BCPd_, BClambda_); + typename PcKrSwCurve::EffToAbsParams effToAbsParamsPM(Swr_, Snr_); + pcKrSwCurvePM_ = std::make_unique(paramsPM, effToAbsParamsPM); - // for making pc == 0 in the FF - materialParamsFF_.setLambda(42.); - materialParamsFF_.setPe(0.); + // FF parameters for Brooks-Corey + typename PcKrSwCurve::BasicParams paramsFF(0/*dummy pe*/, 42/*dummy lambda*/); + typename PcKrSwCurve::EffToAbsParams effToAbsParamsFF(0.0/*swr*/, 0.0/*snr*/); + pcKrSwCurveFF_ = std::make_unique(paramsFF, effToAbsParamsFF); // determine maximum capillary pressure for wetting-nonwetting surface /* Of course physically there is no such thing as a maximum capillary pressure. @@ -136,30 +126,33 @@ public: * Technically this value is obtained as the capillary pressure of saturation zero. * This value of course only exists for the case of a regularized pc-Sw relation. */ - using TwoPLaw = EffToAbsLaw>; - const auto pcMax = TwoPLaw::pc(materialParamsPM_, /*sw = */0.0); - aWettingNonwettingSurfaceParams_.setPcMax(pcMax); + const auto pcMax = pcKrSwCurvePM_->pc(/*sw = */0.0); + + // non-wetting-solid + using NonwettingSolidInterfacialAreaParams = typename NonwettingSolidInterfacialArea::BasicParams; + NonwettingSolidInterfacialAreaParams ansParams; + ansParams.setA1(aNonwettingSolidA1_); + ansParams.setA2(aNonwettingSolidA2_); + ansParams.setA3(aNonwettingSolidA3_); + aNs_ = std::make_unique(ansParams, effToAbsParamsPM); // wetting-non wetting: surface which goes to zero on the edges, but is a polynomial - aWettingNonwettingSurfaceParams_.setA1(aWettingNonwettingA1_); - aWettingNonwettingSurfaceParams_.setA2(aWettingNonwettingA2_); - aWettingNonwettingSurfaceParams_.setA3(aWettingNonwettingA3_); - - // nonwetting-solid - aNonwettingSolidSurfaceParams_.setA1(aNonwettingSolidA1_); - aNonwettingSolidSurfaceParams_.setA2(aNonwettingSolidA2_); - aNonwettingSolidSurfaceParams_.setA3(aNonwettingSolidA3_); - - // dummys for free flow: no interface where there is only one phase - aWettingNonwettingSurfaceParamsFreeFlow_.setA1(0.); - aWettingNonwettingSurfaceParamsFreeFlow_.setA2(0.); - aWettingNonwettingSurfaceParamsFreeFlow_.setA3(0.); - aWettingNonwettingSurfaceParamsFreeFlow_.setPcMax(42.); // not needed because it is anyways zero; - - // dummys for free flow: no interface where there is only one phase - aNonwettingSolidSurfaceParamsFreeFlow_.setA1(0.); - aNonwettingSolidSurfaceParamsFreeFlow_.setA2(0.); - aNonwettingSolidSurfaceParamsFreeFlow_.setA3(0.); + using WettingNonwettingInterfacialAreaParams = typename WettingNonwettingInterfacialArea::BasicParams; + WettingNonwettingInterfacialAreaParams anwParams; + anwParams.setPcMax(pcMax); + anwParams.setA1(aWettingNonwettingA1_); + anwParams.setA2(aWettingNonwettingA2_); + anwParams.setA3(aWettingNonwettingA3_); + aNw_ = std::make_unique(anwParams, effToAbsParamsPM); + + // zero-initialized dummys for free flow: no interface where there is only one phase + aNwFreeFlow_ = std::make_unique(WettingNonwettingInterfacialAreaParams(), effToAbsParamsFF); + aNsFreeFlow_ = std::make_unique(NonwettingSolidInterfacialAreaParams(), effToAbsParamsFF); + + // dummy + using WettingSolidInterfacialAreaParams = typename WettingSolidInterfacialArea::BasicParams; + WettingSolidInterfacialAreaParams awsParams; + aWs_ = std::make_unique(awsParams, effToAbsParamsPM); // use ctor without effToAbs } template @@ -200,81 +193,63 @@ public: DUNE_THROW(Dune::InvalidStateException, "You should not be here: x=" << globalPos[0] << " y= "<< globalPos[dimWorld-1]); } - template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { return materialLawParamsAtPos(scv.dofPosition()); } - - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + /*! + * \brief Returns the parameters for the material law at a given location + * \param globalPos A global coordinate vector + */ + const NonwettingSolidInterfacialArea& nonwettingSolidInterfacialAreaAtPos(const GlobalPosition &globalPos) const { - if (inFF_(globalPos)) - return materialParamsFF_; + if (inFF_(globalPos) ) + return *aNsFreeFlow_ ; else if (inPM_(globalPos)) - return materialParamsPM_; + return *aNs_ ; else DUNE_THROW(Dune::InvalidStateException, "You should not be here: x=" << globalPos[0] << " y= "<< globalPos[dimWorld-1]); } - /*!\brief Returns a reference to the container object for the - * parametrization of the surface between wetting and nonwetting phase. - * - * The position is determined based on the coordinate of - * the vertex belonging to the considered sub-control volume. - * - * \param element The finite element - * \param scv The sub-control volume - * \param elemSol The element solution + /*! + * \brief Returns the parameters for the material law at a given location + * \param globalPos A global coordinate vector */ - template - const AwnSurfaceParams& aWettingNonwettingSurfaceParams(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + const WettingSolidInterfacialArea& wettingSolidInterfacialAreaAtPos(const GlobalPosition &globalPos) const { - const auto& globalPos = scv.dofPosition(); - if (inFF_(globalPos) ) - return aWettingNonwettingSurfaceParamsFreeFlow_ ; - else if (inPM_(globalPos)) - return aWettingNonwettingSurfaceParams_ ; - else DUNE_THROW(Dune::InvalidStateException, "You should not be here: x=" << globalPos[0] << " y= "<< globalPos[dimWorld-1]); + DUNE_THROW(Dune::InvalidStateException, "Should not be called in this test."); } - /*!\brief Returns a reference to the container object for the - * parametrization of the surface between nonwetting and solid phase. - * - * The position is determined based on the coordinate of - * the vertex belonging to the considered sub-control volume. - * \param element The finite element - * \param scv The sub-control volume - * \param elemSol The element solution + /*! + * \brief Returns the parameters for the material law at a given location + * \param globalPos A global coordinate vector */ - template - const AnsSurfaceParams& aNonwettingSolidSurfaceParams(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + const WettingNonwettingInterfacialArea& wettingNonwettingInterfacialAreaAtPos(const GlobalPosition &globalPos) const { - const auto& globalPos = scv.dofPosition(); if (inFF_(globalPos) ) - return aNonwettingSolidSurfaceParamsFreeFlow_ ; + return *aNwFreeFlow_ ; else if (inPM_(globalPos)) - return aNonwettingSolidSurfaceParams_ ; + return *aNw_ ; else DUNE_THROW(Dune::InvalidStateException, "You should not be here: x=" << globalPos[0] << " y= "<< globalPos[dimWorld-1]); + } - /*!\brief Returns a reference to the container object for the - * parametrization of the surface between wetting and solid phase. - * - * The position is determined based on the coordinate of - * the vertex belonging to the considered sub-control volume. - * \param element The finite element - * \param scv The sub-control volume - * \param elemSol The element solution + /*! + * \brief Returns the parameters for the material law at a given location */ template - const AwsSurfaceParams& aWettingSolidSurfaceParams(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + auto fluidMatrixInteraction(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { + return fluidMatrixInteractionAtPos(scv.dofPosition()); + } + + /*! + * \brief Returns the parameters for the material law at a given location + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const { - DUNE_THROW(Dune::NotImplemented, "wetting-solid-interface surface params"); + if (inFF_(globalPos)) + return makeFluidMatrixInteraction(*pcKrSwCurveFF_, *aNsFreeFlow_, *aNwFreeFlow_, *aWs_); + else if (inPM_(globalPos)) + return makeFluidMatrixInteraction(*pcKrSwCurvePM_, *aNs_, *aNw_, *aWs_); + else DUNE_THROW(Dune::InvalidStateException, "You should not be here: x=" << globalPos[0] << " y= "<< globalPos[dimWorld-1]); } /*! @@ -368,11 +343,6 @@ private: static constexpr Scalar eps_ = 1e-6; Scalar heightDomain_ ; - AwnSurfaceParams aWettingNonwettingSurfaceParams_; - AnsSurfaceParams aNonwettingSolidSurfaceParams_ ; - AwnSurfaceParams aWettingNonwettingSurfaceParamsFreeFlow_; - AnsSurfaceParams aNonwettingSolidSurfaceParamsFreeFlow_ ; - // Porous Medium Domain Scalar intrinsicPermeabilityPM_ ; Scalar porosityPM_ ; @@ -380,13 +350,13 @@ private: Scalar factorEnergyTransfer_ ; Scalar factorMassTransfer_ ; Scalar characteristicLengthPM_ ; - MaterialLawParams materialParamsPM_ ; + std::unique_ptr pcKrSwCurvePM_; // Free Flow Domain Scalar porosityFF_ ; Scalar intrinsicPermeabilityFF_ ; Scalar characteristicLengthFF_ ; - MaterialLawParams materialParamsFF_ ; + std::unique_ptr pcKrSwCurveFF_; // interfacial area parameters Scalar aWettingNonwettingA1_ ; @@ -403,6 +373,15 @@ private: Scalar Swr_ ; Scalar Snr_ ; std::vector gridVector_; + + std::unique_ptr aNs_; + std::unique_ptr aNw_; + + std::unique_ptr aNwFreeFlow_; + std::unique_ptr aNsFreeFlow_; + + std::unique_ptr aWs_; // dummy, never used + }; } // end namespace Dumux -- GitLab From de973e64acfe2e3698e9083ce55760a1f103db3c Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 13 Oct 2020 10:30:23 +0200 Subject: [PATCH 36/99] [test][mpnc] Use new fluidmatrix interaction in obstacle problem --- .../mpnc/implicit/obstacle/params.input | 6 ++ .../mpnc/implicit/obstacle/problem.hh | 9 ++- .../mpnc/implicit/obstacle/spatialparams.hh | 61 ++++++------------- 3 files changed, 29 insertions(+), 47 deletions(-) diff --git a/test/porousmediumflow/mpnc/implicit/obstacle/params.input b/test/porousmediumflow/mpnc/implicit/obstacle/params.input index 49708ce61f..d3db3d37d4 100644 --- a/test/porousmediumflow/mpnc/implicit/obstacle/params.input +++ b/test/porousmediumflow/mpnc/implicit/obstacle/params.input @@ -11,3 +11,9 @@ ResidualReduction = 1e-12 [Problem] Name = obstacle + +[SpatialParams] +SmoothedLinearLawPe = 0.0 +SmoothedLinearLawPcMax = 0.0 +SmoothedLinearLawKrLowS = 0.05 +SmoothedLinearLawKrHighS = 0.95 diff --git a/test/porousmediumflow/mpnc/implicit/obstacle/problem.hh b/test/porousmediumflow/mpnc/implicit/obstacle/problem.hh index 35b9d03dab..71ded1bbe2 100644 --- a/test/porousmediumflow/mpnc/implicit/obstacle/problem.hh +++ b/test/porousmediumflow/mpnc/implicit/obstacle/problem.hh @@ -329,14 +329,13 @@ private: // set the other saturation fs.setSaturation(otherPhaseIdx, 1.0 - fs.saturation(refPhaseIdx)); - // calulate the capillary pressure - const auto& matParams = this->spatialParams().materialLawParamsAtPos(globalPos); + // calculate the capillary pressure + const auto fluidMatrixInteraction = this->spatialParams().fluidMatrixInteractionAtPos(globalPos); PhaseVector pc; - using MaterialLaw = typename ParentType::SpatialParams::MaterialLaw; - using MPAdapter = MPAdapter; + using MPAdapter = FluidMatrix::MPAdapter; const int wPhaseIdx = this->spatialParams().template wettingPhaseAtPos(globalPos); - MPAdapter::capillaryPressures(pc, matParams, fs, wPhaseIdx); + MPAdapter::capillaryPressures(pc, fluidMatrixInteraction, fs, wPhaseIdx); fs.setPressure(otherPhaseIdx, fs.pressure(refPhaseIdx) + (pc[otherPhaseIdx] - pc[refPhaseIdx])); diff --git a/test/porousmediumflow/mpnc/implicit/obstacle/spatialparams.hh b/test/porousmediumflow/mpnc/implicit/obstacle/spatialparams.hh index 1272af0a7e..16b9f81b30 100644 --- a/test/porousmediumflow/mpnc/implicit/obstacle/spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/obstacle/spatialparams.hh @@ -27,8 +27,8 @@ #include #include -#include -#include +#include +#include namespace Dumux { @@ -51,37 +51,21 @@ class ObstacleSpatialParams enum {dimWorld=GridView::dimensionworld}; using GlobalPosition = typename SubControlVolume::GlobalPosition; - using EffectiveLaw = RegularizedLinearMaterial; + + using PcKrSwCurve = FluidMatrix::SmoothedLinearLaw; public: //! Export the type used for the permeability using PermeabilityType = Scalar; - //! Export the material law type used - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; - ObstacleSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) - { - // intrinsic permeabilities - coarseK_ = 1e-12; - fineK_ = 1e-15; - - // the porosity - porosity_ = 0.3; - - // residual saturations - fineMaterialParams_.setSwr(0.0); - fineMaterialParams_.setSnr(0.0); - coarseMaterialParams_.setSwr(0.0); - coarseMaterialParams_.setSnr(0.0); - - // parameters for the linear law, i.e. minimum and maximum - // pressures - fineMaterialParams_.setEntryPc(0.0); - coarseMaterialParams_.setEntryPc(0.0); - fineMaterialParams_.setMaxPc(0.0); - coarseMaterialParams_.setMaxPc(0.0); - } + + ObstacleSpatialParams(std::shared_ptr gridGeometry) + : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") // initialize the material law + , coarseK_(1e-12) // intrinsic permeability + , fineK_(1e-15) // intrinsic permeability + , porosity_(0.3) + {} template PermeabilityType permeability(const Element& element, @@ -103,17 +87,11 @@ public: { return porosity_; } /*! - * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). - * - * \param globalPos The global position of the sub-control volume. - * \return The material parameters object + * \brief Returns the parameters for the material law at a given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const { - if (isFineMaterial_(globalPos)) - return fineMaterialParams_; - else - return coarseMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } /*! @@ -140,11 +118,10 @@ private: 0 - eps_ <= pos[1] && pos[1] <= 35 + eps_; } - Scalar coarseK_; - Scalar fineK_; - Scalar porosity_; - MaterialLawParams fineMaterialParams_; - MaterialLawParams coarseMaterialParams_; + const PcKrSwCurve pcKrSwCurve_; + const Scalar coarseK_; + const Scalar fineK_; + const Scalar porosity_; static constexpr Scalar eps_ = 1e-6; }; -- GitLab From 6398ef3bc527bf064500acff87cbff7bf202236c Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Wed, 14 Oct 2020 18:57:54 +0200 Subject: [PATCH 37/99] [cleanup][deprecated] Simplify deprecation helper function names --- dumux/common/deprecated.hh | 37 ++++++++++++++++--- dumux/porousmediumflow/2p/volumevariables.hh | 4 +- .../porousmediumflow/2p1c/volumevariables.hh | 4 +- .../porousmediumflow/2p2c/volumevariables.hh | 4 +- .../porousmediumflow/2pnc/volumevariables.hh | 4 +- dumux/porousmediumflow/co2/volumevariables.hh | 4 +- .../porousmediumflow/mpnc/volumevariables.hh | 8 ++-- .../nonequilibrium/volumevariables.hh | 8 ++-- .../richards/localresidual.hh | 12 +++--- .../porousmediumflow/richards/newtonsolver.hh | 2 +- .../richards/volumevariables.hh | 4 +- .../richardsnc/volumevariables.hh | 4 +- 12 files changed, 60 insertions(+), 35 deletions(-) diff --git a/dumux/common/deprecated.hh b/dumux/common/deprecated.hh index ab57ac33c5..15d3b9d2d1 100644 --- a/dumux/common/deprecated.hh +++ b/dumux/common/deprecated.hh @@ -137,6 +137,12 @@ public: return SpatialParams::MaterialLaw::dkrn_dsw(params, sw); } + const auto& basicParams() const + { return spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); } + + const auto& effToAbsParams() const + { return spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); } + private: const SpatialParams& spatialParams_; const Element& element_; @@ -144,12 +150,13 @@ private: const ElemSol& elemSol_; }; +// for implicit models template -auto makeDeprecationPcKrSwHelper(const Scalar& scalar, - const SpatialParams& sp, - const Element& element, - const Scv& scv, - const ElemSol& elemSol) +auto makePcKrSw(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol) { using GlobalPosition = typename Element::Geometry::GlobalCoordinate; constexpr bool hasNew = decltype(isValid(HasNewFIAIF()).template check())::value; @@ -162,6 +169,24 @@ auto makeDeprecationPcKrSwHelper(const Scalar& scalar, return makeFluidMatrixInteraction(PcKrSwHelper(scalar, sp, element, scv, elemSol)); } +// for sequential models +template +auto makePcKrSw(const Scalar& scalar, + const SpatialParams& sp, + const Element& element) +{ + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + constexpr bool hasNewAtPos = decltype(isValid(HasNewFIAIFAtPos()).template check())::value; + if constexpr (hasNewAtPos) + return sp.fluidMatrixInteractionAtPos(element.geometry().center()); + else + { + using DummyScv = int; + using DummyElemSol = int; + return makeFluidMatrixInteraction(PcKrSwHelper(scalar, sp, element, DummyScv(), DummyElemSol())); + } +} + /////////////////////////////////////////////////////////////// @@ -370,7 +395,7 @@ private: }; template -auto makeInterfacialAreaHelper(const Scalar& scalar, +auto makeInterfacialArea(const Scalar& scalar, const SpatialParams& sp, const Element& element, const Scv& scv, diff --git a/dumux/porousmediumflow/2p/volumevariables.hh b/dumux/porousmediumflow/2p/volumevariables.hh index d353f1a6a6..e1f1ee6d96 100644 --- a/dumux/porousmediumflow/2p/volumevariables.hh +++ b/dumux/porousmediumflow/2p/volumevariables.hh @@ -98,7 +98,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const int wPhaseIdx = fluidState_.wettingPhase(); const int nPhaseIdx = 1 - wPhaseIdx; @@ -143,7 +143,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto& priVars = elemSol[scv.localDofIndex()]; diff --git a/dumux/porousmediumflow/2p1c/volumevariables.hh b/dumux/porousmediumflow/2p1c/volumevariables.hh index a5ed6e5432..4908100d5e 100644 --- a/dumux/porousmediumflow/2p1c/volumevariables.hh +++ b/dumux/porousmediumflow/2p1c/volumevariables.hh @@ -132,7 +132,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); // Second instance of a parameter cache. // Could be avoided if diffusion coefficients also @@ -218,7 +218,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); if (formulation == TwoPFormulation::p0s1) diff --git a/dumux/porousmediumflow/2p2c/volumevariables.hh b/dumux/porousmediumflow/2p2c/volumevariables.hh index 38cab433fa..44667dc375 100644 --- a/dumux/porousmediumflow/2p2c/volumevariables.hh +++ b/dumux/porousmediumflow/2p2c/volumevariables.hh @@ -146,7 +146,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const int wPhaseIdx = fluidState_.wettingPhase(); const int nPhaseIdx = 1 - wPhaseIdx; @@ -199,7 +199,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); fluidState.setWettingPhase(wPhaseIdx); diff --git a/dumux/porousmediumflow/2pnc/volumevariables.hh b/dumux/porousmediumflow/2pnc/volumevariables.hh index babd8c2c13..f50e8cab62 100644 --- a/dumux/porousmediumflow/2pnc/volumevariables.hh +++ b/dumux/porousmediumflow/2pnc/volumevariables.hh @@ -146,7 +146,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const int wPhaseIdx = fluidState_.wettingPhase(); const int nPhaseIdx = 1 - wPhaseIdx; @@ -199,7 +199,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); fluidState.setWettingPhase(wPhaseIdx); diff --git a/dumux/porousmediumflow/co2/volumevariables.hh b/dumux/porousmediumflow/co2/volumevariables.hh index 09097d3839..14821bd693 100644 --- a/dumux/porousmediumflow/co2/volumevariables.hh +++ b/dumux/porousmediumflow/co2/volumevariables.hh @@ -140,7 +140,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const int wPhaseIdx = fluidState_.wettingPhase(); const int nPhaseIdx = 1 - wPhaseIdx; @@ -197,7 +197,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); // set the saturations if (phasePresence == secondPhaseOnly) diff --git a/dumux/porousmediumflow/mpnc/volumevariables.hh b/dumux/porousmediumflow/mpnc/volumevariables.hh index 621738b3f9..af207b8022 100644 --- a/dumux/porousmediumflow/mpnc/volumevariables.hh +++ b/dumux/porousmediumflow/mpnc/volumevariables.hh @@ -115,7 +115,7 @@ public: // after the release of 3.3, when the deprecated interface is no longer supported. // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports // two phases anyway... - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); //calculate the remaining quantities const int wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); @@ -192,7 +192,7 @@ public: // after the release of 3.3, when the deprecated interface is no longer supported. // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports // two phases anyway... - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); std::array capPress; using MPAdapter = FluidMatrix::MPAdapter; @@ -571,7 +571,7 @@ public: // after the release of 3.3, when the deprecated interface is no longer supported. // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports // two phases anyway... - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); MPAdapter::relativePermeabilities(relativePermeability_, fluidMatrixInteraction, fluidState_, wPhaseIdx); typename FluidSystem::ParameterCache paramCache; @@ -639,7 +639,7 @@ public: // after the release of 3.3, when the deprecated interface is no longer supported. // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports // two phases anyway... - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); std::vector capPress(numFluidPhases()); using MPAdapter = FluidMatrix::MPAdapter; diff --git a/dumux/porousmediumflow/nonequilibrium/volumevariables.hh b/dumux/porousmediumflow/nonequilibrium/volumevariables.hh index edc8789add..d5081ccd67 100644 --- a/dumux/porousmediumflow/nonequilibrium/volumevariables.hh +++ b/dumux/porousmediumflow/nonequilibrium/volumevariables.hh @@ -184,7 +184,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& wettingNonwettingInterfacialArea = spatialParams.wettingNonwettingInterfacialArea(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeInterfacialAreaHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makeInterfacialArea(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto awn = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc); interfacialArea_[phase0Idx][phase1Idx] = awn; @@ -211,7 +211,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& wettingSolidInterfacialArea = spatialParams.wettingSolidInterfacialArea(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeInterfacialAreaHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makeInterfacialArea(Scalar{}, problem.spatialParams(), element, scv, elemSol); interfacialArea_[phase0Idx][sPhaseIdx] = fluidMatrixInteraction.wettingSolidInterface().area(Sw, pc); } @@ -542,7 +542,7 @@ public: // old material law interface is deprecated: Replace this by // const auto fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeInterfacialAreaHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makeInterfacialArea(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto Sw = fluidState.saturation(phase0Idx) ; const auto pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx); @@ -730,7 +730,7 @@ public: // old material law interface is deprecated: Replace this by // const auto fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeInterfacialAreaHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makeInterfacialArea(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto awn = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc); interfacialArea_[phase0Idx][phase1Idx] = awn; diff --git a/dumux/porousmediumflow/richards/localresidual.hh b/dumux/porousmediumflow/richards/localresidual.hh index 9a7cd7bbc3..748e978a43 100644 --- a/dumux/porousmediumflow/richards/localresidual.hh +++ b/dumux/porousmediumflow/richards/localresidual.hh @@ -203,7 +203,7 @@ public: // old material law interface is deprecated: Replace this by // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, InvalidElemSol{}); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, InvalidElemSol{}); // partial derivative of storage term w.r.t. p_w // d(Sw*rho*phi*V/dt)/dpw = rho*phi*V/dt*dsw/dpw = rho*phi*V/dt*dsw/dpc*dpc/dpw = -rho*phi*V/dt*dsw/dpc @@ -288,8 +288,8 @@ public: // old material law interface is deprecated: Replace this by // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto insideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, insideScv, InvalidElemSol{}); - const auto outsideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), outsideElement, outsideScv, InvalidElemSol{}); + const auto insideFluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, insideScv, InvalidElemSol{}); + const auto outsideFluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), outsideElement, outsideScv, InvalidElemSol{}); // material law derivatives const auto insideSw = insideVolVars.saturation(0); @@ -366,8 +366,8 @@ public: // old material law interface is deprecated: Replace this by // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto insideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, insideScv, InvalidElemSol{}); - const auto outsideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, outsideScv, InvalidElemSol{}); + const auto insideFluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, insideScv, InvalidElemSol{}); + const auto outsideFluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, outsideScv, InvalidElemSol{}); // material law derivatives const auto insideSw = insideVolVars.saturation(0); @@ -452,7 +452,7 @@ public: // old material law interface is deprecated: Replace this by // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto insideFluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, insideScv, InvalidElemSol{}); + const auto insideFluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, insideScv, InvalidElemSol{}); // some quantities to be reused (rho & mu are constant and thus equal for all cells) static const auto rho = insideVolVars.density(0); diff --git a/dumux/porousmediumflow/richards/newtonsolver.hh b/dumux/porousmediumflow/richards/newtonsolver.hh index 002ccc62e6..007506df95 100644 --- a/dumux/porousmediumflow/richards/newtonsolver.hh +++ b/dumux/porousmediumflow/richards/newtonsolver.hh @@ -90,7 +90,7 @@ private: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.1, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, spatialParams, element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, spatialParams, element, scv, elemSol); const Scalar pcMin = fluidMatrixInteraction.pc(1.0); const Scalar pw = uLastIter[dofIdxGlobal][pressureIdx]; diff --git a/dumux/porousmediumflow/richards/volumevariables.hh b/dumux/porousmediumflow/richards/volumevariables.hh index d98769bc84..3410489549 100644 --- a/dumux/porousmediumflow/richards/volumevariables.hh +++ b/dumux/porousmediumflow/richards/volumevariables.hh @@ -111,7 +111,7 @@ public: // old material law interface is deprecated: Replace this by // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto& priVars = elemSol[scv.localDofIndex()]; const auto phasePresence = priVars.state(); @@ -255,7 +255,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto& priVars = elemSol[scv.localDofIndex()]; diff --git a/dumux/porousmediumflow/richardsnc/volumevariables.hh b/dumux/porousmediumflow/richardsnc/volumevariables.hh index 63de8e17d1..1ebae93f9a 100644 --- a/dumux/porousmediumflow/richardsnc/volumevariables.hh +++ b/dumux/porousmediumflow/richardsnc/volumevariables.hh @@ -99,7 +99,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); relativePermeabilityWetting_ = fluidMatrixInteraction.krw(fluidState_.saturation(0)); @@ -159,7 +159,7 @@ public: // old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported - const auto fluidMatrixInteraction = Deprecated::makeDeprecationPcKrSwHelper(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); const auto& priVars = elemSol[scv.localDofIndex()]; -- GitLab From 1ea77ebb452fd90acc8d868dbb4991702c92fcbd Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Wed, 14 Oct 2020 19:00:34 +0200 Subject: [PATCH 38/99] [fixup][cleanup][2pia] Remove moved headers from CMakeLists --- dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt b/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt index 4e84fedb46..4040d3bc88 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt +++ b/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt @@ -11,10 +11,4 @@ awnsurfacepolynomialedgezero2ndorder.hh awnsurfacepolynomialedgezero2ndorderparams.hh efftoabslawia.hh efftoabslawiaparams.hh -interfacialarea.hh -interfacialareaexponential.hh -interfacialareaexponentialcubic.hh -interfacialareapcmax.hh -interfacialareapolynomial2ndorder.hh -interfacialareapolynomialedgezero2ndorder.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/material/fluidmatrixinteractions/2pia) -- GitLab From e6807694c4c4e56b0e4caaa879a42ed2d51f1c34 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Wed, 14 Oct 2020 19:02:08 +0200 Subject: [PATCH 39/99] [doc][deprecation] Add deprecation comment to 2pia folder --- dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt b/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt index 4040d3bc88..5d3da0acb3 100644 --- a/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt +++ b/dumux/material/fluidmatrixinteractions/2pia/CMakeLists.txt @@ -1,3 +1,4 @@ +# this folder is deprecated. Use headers in 2p/interfacialarea/ install(FILES awnsurfaceexpfct.hh awnsurfaceexpfctparams.hh -- GitLab From d3a6db698a43d306b5a03121f57b93384ccf09ad Mon Sep 17 00:00:00 2001 From: Katharina Heck Date: Mon, 19 Oct 2020 15:23:47 +0200 Subject: [PATCH 40/99] [test][2pnc] update spatialparams according to changes in materiallaw --- .../2pnc/implicit/diffusion/params.input | 6 +++ .../2pnc/implicit/diffusion/spatialparams.hh | 41 ++++++----------- .../2pnc/implicit/fuelcell/params.input | 6 +++ .../2pnc/implicit/fuelcell/spatialparams.hh | 46 ++++++------------- 4 files changed, 39 insertions(+), 60 deletions(-) diff --git a/test/porousmediumflow/2pnc/implicit/diffusion/params.input b/test/porousmediumflow/2pnc/implicit/diffusion/params.input index b658cedc13..49248e5f84 100644 --- a/test/porousmediumflow/2pnc/implicit/diffusion/params.input +++ b/test/porousmediumflow/2pnc/implicit/diffusion/params.input @@ -9,3 +9,9 @@ Cells = 50 5 [Problem] Name = 2pnc_diffusion EnableGravity = false + +[SpatialParams] +BrooksCoreyPcEntry = 1e2 +BrooksCoreyLambda = 1.3 +Swr = 0.02 +Snr = 0.0 diff --git a/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh b/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh index dcbcfce6cf..d2bfb0e874 100644 --- a/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh +++ b/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh @@ -28,10 +28,7 @@ #include #include -#include -#include -#include -#include +#include namespace Dumux { /*! @@ -55,33 +52,22 @@ class TwoPNCDiffusionSpatialParams using DimWorldMatrix = Dune::FieldMatrix; - using EffectiveLaw = RegularizedBrooksCorey; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; public: using PermeabilityType = DimWorldMatrix; - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; - TwoPNCDiffusionSpatialParams(std::shared_ptr gridGeometry) - : ParentType(gridGeometry), K_(0) + : ParentType(gridGeometry) + , K_(0) + , pcKrSwCurve_("SpatialParams") { // intrinsic permeabilities K_[0][0] = 5e-11; K_[1][1] = 5e-11; - - // porosities - porosity_ = 0.2; - - // residual saturations - materialParams_.setSwr(0.02); - materialParams_.setSnr(0.0); - - // parameters for the vanGenuchten law - materialParams_.setPe(1e2); // alpha = 1/pcb - materialParams_.setLambda(1.3); } + /*! * \brief Returns the hydraulic conductivity \f$[m^2]\f$ * @@ -99,13 +85,15 @@ public: { return 0.2; } /*! - * \brief Returns the parameter object for the Brooks-Corey material law - * which depends on the position. + * \brief Returns the parameters for the material law at a given location * - * \param globalPos The global position + * This method is not actually required by the Richards model, but provided + * for the convenience of the RichardsLensProblem + * + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { return materialParams_; } + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const + { return makeFluidMatrixInteraction(pcKrSwCurve_); } /*! * \brief Function for defining which phase is to be considered as the wetting phase. @@ -119,9 +107,8 @@ public: private: DimWorldMatrix K_; - Scalar porosity_; static constexpr Scalar eps_ = 1e-6; - MaterialLawParams materialParams_; + const PcKrSwCurve pcKrSwCurve_; }; } // end namespace Dumux diff --git a/test/porousmediumflow/2pnc/implicit/fuelcell/params.input b/test/porousmediumflow/2pnc/implicit/fuelcell/params.input index 39d050f5a1..e26db822b1 100644 --- a/test/porousmediumflow/2pnc/implicit/fuelcell/params.input +++ b/test/porousmediumflow/2pnc/implicit/fuelcell/params.input @@ -42,3 +42,9 @@ SurfaceIncreasingFactor = 60 TransportNumberH20 = 0.2327 # [-] account for osmotic H20 transport term from membrane, value Lena Walter pO2Inlet = 0.3e5 # [Pa] partial pressure of oxygen at gas channel inlet MaxIterations = 300 # [-] Maximum number for iterations for solving electrochemical system + +[SpatialParams] +VanGenuchtenN = 3.652 +VanGenuchtenAlpha = 6.66e-5 +Swr = 0.12 +Snr = 0.0 diff --git a/test/porousmediumflow/2pnc/implicit/fuelcell/spatialparams.hh b/test/porousmediumflow/2pnc/implicit/fuelcell/spatialparams.hh index 33c29ca340..6efbf239cb 100644 --- a/test/porousmediumflow/2pnc/implicit/fuelcell/spatialparams.hh +++ b/test/porousmediumflow/2pnc/implicit/fuelcell/spatialparams.hh @@ -28,10 +28,7 @@ #include #include -#include -#include -#include -#include +#include namespace Dumux { /*! @@ -55,30 +52,19 @@ class FuelCellSpatialParams using DimWorldMatrix = Dune::FieldMatrix; - using EffectiveLaw = RegularizedVanGenuchten; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = DimWorldMatrix; FuelCellSpatialParams(std::shared_ptr gridGeometry) - : ParentType(gridGeometry), K_(0) + : ParentType(gridGeometry) + , K_(0) + , pcKrSwCurve_("SpatialParams") { // intrinsic permeabilities K_[0][0] = 5e-11; K_[1][1] = 5e-11; - - // porosities - porosity_ = 0.2; - - // residual saturations - materialParams_.setSwr(0.12); // air is wetting phase - materialParams_.setSnr(0.0); // water is nonwetting - - //parameters for the vanGenuchten law - materialParams_.setVgAlpha(6.66e-5); // alpha = 1/pcb - materialParams_.setVgn(3.652); } /*! @@ -95,21 +81,16 @@ public: * \param globalPos The global position */ Scalar porosityAtPos(const GlobalPosition& globalPos) const - { - if (globalPos[1] < eps_) - return porosity_; - else - return 0.2; - } + { return 0.2; } /*! - * \brief Returns the parameter object for the Brooks-Corey material law - * which depends on the position. - * - * \param globalPos The global position + * \brief Returns the parameters for the material law at a given location + * \param globalPos A global coordinate vector */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { return materialParams_; } + auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const + { + return makeFluidMatrixInteraction(pcKrSwCurve_); + } /*! * \brief Function for defining which phase is to be considered as the wetting phase. @@ -124,9 +105,8 @@ public: private: DimWorldMatrix K_; - Scalar porosity_; static constexpr Scalar eps_ = 1e-6; - MaterialLawParams materialParams_; + const PcKrSwCurve pcKrSwCurve_; }; } // end namespace Dumux -- GitLab From 6b0bf0744e4591160b5c5b01f3c288eb70b7bd17 Mon Sep 17 00:00:00 2001 From: Katharina Heck Date: Mon, 19 Oct 2020 16:01:39 +0200 Subject: [PATCH 41/99] [tests][2pncmin] update spatialparams materiallaws --- .../2pncmin/implicit/isothermal/params.input | 8 ++-- .../implicit/isothermal/spatialparams.hh | 40 ++++++------------ .../implicit/nonisothermal/params.input | 8 ++-- .../implicit/nonisothermal/spatialparams.hh | 41 ++++++------------- 4 files changed, 33 insertions(+), 64 deletions(-) diff --git a/test/porousmediumflow/2pncmin/implicit/isothermal/params.input b/test/porousmediumflow/2pncmin/implicit/isothermal/params.input index 0fd2372265..94578dd96b 100644 --- a/test/porousmediumflow/2pncmin/implicit/isothermal/params.input +++ b/test/porousmediumflow/2pncmin/implicit/isothermal/params.input @@ -37,10 +37,10 @@ InitPrecipitatedSaltBlock = 0.05 # [-] initial precipitated salt in the b SolubilityLimit = 0.26 # [-] solubility limit of salt in brine referencePorosity = 0.11 # [-] initial porosity referencePermeability = 2.23e-14 -IrreducibleLiqSat = 0.2 # [-] irreducible liquid saturation -IrreducibleGasSat = 0.001 # [-] irreducible gas saturation -Pentry1 = 500 # [Pa] -BCLambda1 = 2 # [-] +Swr = 0.2 # [-] irreducible liquid saturation +Snr = 0.001 # [-] irreducible gas saturation +BrooksCoreyPcEntry = 500 # [Pa] +BrooksCoreyLambda = 2 # [-] [Vtk] AddVelocity = 1 # Add extra information diff --git a/test/porousmediumflow/2pncmin/implicit/isothermal/spatialparams.hh b/test/porousmediumflow/2pncmin/implicit/isothermal/spatialparams.hh index bcdb15a870..c0a59da7da 100644 --- a/test/porousmediumflow/2pncmin/implicit/isothermal/spatialparams.hh +++ b/test/porousmediumflow/2pncmin/implicit/isothermal/spatialparams.hh @@ -27,9 +27,7 @@ #define DUMUX_INJECTION_SPATIAL_PARAMETERS_HH #include -#include -#include -#include +#include #include #include @@ -53,35 +51,21 @@ class DissolutionSpatialParams using ParentType = FVSpatialParams>; - using EffectiveLaw = RegularizedBrooksCorey; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; using GlobalPosition = typename SubControlVolume::GlobalPosition; public: // type used for the permeability (i.e. tensor or scalar) using PermeabilityType = Scalar; - //! Export the material law type used - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; DissolutionSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { solubilityLimit_ = getParam("SpatialParams.SolubilityLimit", 0.26); referencePorosity_ = getParam("SpatialParams.referencePorosity", 0.11); referencePermeability_ = getParam("SpatialParams.referencePermeability", 2.23e-14); - irreducibleLiqSat_ = getParam("SpatialParams.IrreducibleLiqSat", 0.2); - irreducibleGasSat_ = getParam("SpatialParams.IrreducibleGasSat", 1e-3); - pEntry1_ = getParam("SpatialParams.Pentry1", 500); - bcLambda1_ = getParam("SpatialParams.BCLambda1", 2); - - // residual saturations - materialParams_.setSwr(irreducibleLiqSat_); - materialParams_.setSnr(irreducibleGasSat_); - - // parameters of Brooks & Corey Law - materialParams_.setPe(pEntry1_); - materialParams_.setLambda(bcLambda1_); } /*! @@ -144,9 +128,14 @@ public: Scalar theta(const SubControlVolume &scv) const { return 10.0; } - // return the brooks-corey context depending on the position - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { return materialParams_; } + /*! + * \brief Returns the parameters for the material law at a given location + * \param globalPos A global coordinate vector + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const + { + return makeFluidMatrixInteraction(pcKrSwCurve_); + } // define which phase is to be considered as the wetting phase template @@ -155,17 +144,12 @@ public: private: - MaterialLawParams materialParams_; - PermeabilityKozenyCarman permLaw_; Scalar solubilityLimit_; Scalar referencePorosity_; PermeabilityType referencePermeability_ = 0.0; - Scalar irreducibleLiqSat_; - Scalar irreducibleGasSat_; - Scalar pEntry1_; - Scalar bcLambda1_; + const PcKrSwCurve pcKrSwCurve_; }; } // end namespace Dumux diff --git a/test/porousmediumflow/2pncmin/implicit/nonisothermal/params.input b/test/porousmediumflow/2pncmin/implicit/nonisothermal/params.input index b8eecf0438..51d63dc04c 100644 --- a/test/porousmediumflow/2pncmin/implicit/nonisothermal/params.input +++ b/test/porousmediumflow/2pncmin/implicit/nonisothermal/params.input @@ -40,10 +40,10 @@ RefTemperature = 299 # [K] temperature in the air abo SolubilityLimit = 0.26 # [-] solubility limit of NaCl in brine referencePorosity = 0.4 # [-] initial porosity referencePermeability = 1e-13 # [m²] initial permeability -VGAlpha = 0.00015 # Van Genuchten parameter -VGn = 14.0 # Van Genuchten parameter -IrreducibleLiqSat = 0.25 # [-] irreducible liquid saturation -IrreducibleGasSat = 0.025 # [-] irreducible gas saturation +VanGenuchtenAlpha = 0.00015 # Van Genuchten parameter +VanGenuchtenN = 14.0 # Van Genuchten parameter +Swr = 0.25 # [-] irreducible liquid saturation +Snr = 0.025 # [-] irreducible gas saturation [Vtk] AddVelocity = 1 # Add extra information diff --git a/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh b/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh index 276f8764c3..201941ae5b 100644 --- a/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh +++ b/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh @@ -29,9 +29,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -55,38 +53,23 @@ class SalinizationSpatialParams using ParentType = FVSpatialParams>; - using EffectiveLaw = RegularizedVanGenuchten; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; using GlobalPosition = typename SubControlVolume::GlobalPosition; public: // type used for the permeability (i.e. tensor or scalar) using PermeabilityType = Scalar; - //! Export the material law type used - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; SalinizationSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { solubilityLimit_ = getParam("SpatialParams.SolubilityLimit", 0.26); referencePorosity_ = getParam("SpatialParams.referencePorosity", 0.11); referencePermeability_ = getParam("SpatialParams.referencePermeability", 2.23e-14); - irreducibleLiqSat_ = getParam("SpatialParams.IrreducibleLiqSat", 0.2); - irreducibleGasSat_ = getParam("SpatialParams.IrreducibleGasSat", 1e-3); - vgAlpha_ = getParam("SpatialParams.VGAlpha", 1.5); - vgn_ = getParam("SpatialParams.VGn", 4.0); plotFluidMatrixInteractions_ = getParam("Output.PlotFluidMatrixInteractions"); - - //Van Genuchen parameters - // residual saturations - materialParams_.setSwr(irreducibleLiqSat_); - materialParams_.setSnr(irreducibleGasSat_); - - //Van Genuchen parameters - materialParams_.setVgAlpha(vgAlpha_ ); - materialParams_.setVgn(vgn_); } /*! @@ -150,9 +133,14 @@ public: Scalar theta(const SubControlVolume &scv) const { return 10.0; } - // return the brooks-corey context depending on the position - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { return materialParams_; } + /*! + * \brief Returns the parameters for the material law at a given location + * \param globalPos A global coordinate vector + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const + { + return makeFluidMatrixInteraction(pcKrSwCurve_); + } // define which phase is to be considered as the wetting phase template @@ -161,17 +149,14 @@ public: private: - MaterialLawParams materialParams_; + const PcKrSwCurve pcKrSwCurve_; PermeabilityKozenyCarman permLaw_; Scalar solubilityLimit_; Scalar referencePorosity_; PermeabilityType referencePermeability_ = 0.0; - Scalar irreducibleLiqSat_; - Scalar irreducibleGasSat_; - Scalar vgAlpha_; - Scalar vgn_ ; + bool plotFluidMatrixInteractions_; }; -- GitLab From d960f656aa3e6748c065f4ace64d1ca212def44e Mon Sep 17 00:00:00 2001 From: Katharina Heck Date: Mon, 19 Oct 2020 17:11:25 +0200 Subject: [PATCH 42/99] [tests][co2] update spatialparams due to change in materiallaw --- .../co2/implicit/params.input | 6 ++++ .../co2/implicit/paramsni.input | 6 ++++ .../co2/implicit/spatialparams.hh | 31 ++++++------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/test/porousmediumflow/co2/implicit/params.input b/test/porousmediumflow/co2/implicit/params.input index 5569a89c4c..cac8bfa421 100644 --- a/test/porousmediumflow/co2/implicit/params.input +++ b/test/porousmediumflow/co2/implicit/params.input @@ -22,3 +22,9 @@ InjectionRate = 3e-3 # [kg/sq/s] [Brine] Salinity = 1e-1 + +[SpatialParams] +BrooksCoreyPcEntry = 1e4 +BrooksCoreyLambda = 2.0 +Swr = 0.05 +Snr = 0.0 diff --git a/test/porousmediumflow/co2/implicit/paramsni.input b/test/porousmediumflow/co2/implicit/paramsni.input index 427e46671b..ae75655a2e 100644 --- a/test/porousmediumflow/co2/implicit/paramsni.input +++ b/test/porousmediumflow/co2/implicit/paramsni.input @@ -29,3 +29,9 @@ InjectionTemperature = 305 # [K] SolidDensity = 2700 SolidThermalConductivity = 2.8 SolidHeatCapacity = 790 + +[SpatialParams] +BrooksCoreyPcEntry = 1e4 +BrooksCoreyLambda = 2.0 +Swr = 0.05 +Snr = 0.0 diff --git a/test/porousmediumflow/co2/implicit/spatialparams.hh b/test/porousmediumflow/co2/implicit/spatialparams.hh index d858b2dab7..43d2c5016a 100644 --- a/test/porousmediumflow/co2/implicit/spatialparams.hh +++ b/test/porousmediumflow/co2/implicit/spatialparams.hh @@ -29,8 +29,7 @@ #include #include -#include -#include +#include #include @@ -57,18 +56,17 @@ class HeterogeneousSpatialParams using GlobalPosition = typename SubControlVolume::GlobalPosition; - using EffectiveLaw = RegularizedBrooksCorey; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; HeterogeneousSpatialParams(std::shared_ptr gridGeometry, std::shared_ptr> gridData) - : ParentType(gridGeometry), gridData_(gridData) + : ParentType(gridGeometry) + , gridData_(gridData) + , pcKrSwCurve_("SpatialParams") { - // Set the permeability for the layers barrierTopK_ = 1e-17; //sqm barrierMiddleK_ = 1e-15; //sqm @@ -78,12 +76,6 @@ public: barrierTopPorosity_ = 0.001; barrierMiddlePorosity_ = 0.05; reservoirPorosity_ = 0.2; - - // Same material parameters for every layer - materialParams_.setSwr(0.2); - materialParams_.setSwr(0.05); - materialParams_.setLambda(2.0); - materialParams_.setPe(1e4); } /*! @@ -175,15 +167,12 @@ public: /*! - * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). + * \brief Returns the parameters for the material law at a given location * - * \param globalPos The position of the center of the element - * \return The material parameters object + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { - return materialParams_; - } + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const + { return makeFluidMatrixInteraction(pcKrSwCurve_); } /*! * \brief Function for defining which phase is to be considered as the wetting phase. @@ -211,8 +200,8 @@ private: Scalar barrierMiddleK_; Scalar reservoirK_; - MaterialLawParams materialParams_; std::vector paramIdx_; + const PcKrSwCurve pcKrSwCurve_; }; } // end namespace Dumux -- GitLab From eb4dd0d691123b200d8c7b1b5aef6a95e222508c Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Mon, 26 Oct 2020 08:55:51 +0100 Subject: [PATCH 43/99] [2p][sequential] Adapt headers --- dumux/material/spatialparams/sequentialfv.hh | 20 +++++--- .../diffusion/cellcentered/pressure.hh | 36 +++++++++----- .../diffusion/cellcentered/velocity.hh | 21 ++++++--- .../sequential/diffusion/mimetic/mimetic.hh | 14 ++++-- .../diffusion/mimetic/mimeticadaptive.hh | 14 ++++-- .../sequential/diffusion/mimetic/operator.hh | 14 ++++-- .../diffusion/mimetic/operatoradaptive.hh | 14 ++++-- .../sequential/diffusion/mimetic/pressure.hh | 16 ++++--- .../diffusion/mimetic/pressureadaptive.hh | 16 ++++--- .../diffusion/mpfa/lmethod/2dpressure.hh | 31 +++++++----- .../mpfa/lmethod/2dpressureadaptive.hh | 33 +++++++------ .../mpfa/lmethod/2dpressurevelocity.hh | 19 +++++--- .../lmethod/2dpressurevelocityadaptive.hh | 19 +++++--- .../diffusion/mpfa/lmethod/2dvelocity.hh | 20 ++++---- .../mpfa/lmethod/2dvelocityadaptive.hh | 1 - .../diffusion/mpfa/lmethod/3dpressure.hh | 28 +++++++---- .../mpfa/lmethod/3dpressureadaptive.hh | 1 - .../mpfa/lmethod/3dpressurevelocity.hh | 19 +++++--- .../lmethod/3dpressurevelocityadaptive.hh | 19 +++++--- .../diffusion/mpfa/lmethod/3dvelocity.hh | 18 +++---- .../mpfa/lmethod/3dvelocityadaptive.hh | 1 - .../diffusion/mpfa/omethod/2dpressure.hh | 33 +++++++------ .../mpfa/omethod/2dpressurevelocity.hh | 19 +++++--- .../diffusion/mpfa/omethod/2dvelocity.hh | 20 ++++---- .../cellcentered/capillarydiffusion.hh | 25 +++++++--- .../cellcentered/evalcflfluxcoats.hh | 47 ++++++++++++------- .../cellcentered/evalcflfluxdefault.hh | 15 ++++-- .../transport/cellcentered/gravitypart.hh | 25 +++++++--- .../transport/cellcentered/saturation.hh | 29 ++++++++---- 29 files changed, 368 insertions(+), 219 deletions(-) diff --git a/dumux/material/spatialparams/sequentialfv.hh b/dumux/material/spatialparams/sequentialfv.hh index d491465768..4dedf42b25 100644 --- a/dumux/material/spatialparams/sequentialfv.hh +++ b/dumux/material/spatialparams/sequentialfv.hh @@ -53,9 +53,6 @@ class SequentialFVSpatialParams: public SequentialFVSpatialParamsOneP using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - /// @cond false - using MaterialLawParams = typename GetPropType::Params; - /// @endcond public: SequentialFVSpatialParams(const Problem& problem) @@ -63,15 +60,26 @@ public: { } + + // make sure we get a deprecation warning (remove this after release 3.3) + template + [[deprecated("Use the new style material laws. Old material laws and this interface will no longer be supported after release 3.3")]] + decltype(auto) materialLawParamsDeprecated(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { + return this->asImp_().materialLawParams(element); + } + /*! * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). * * \return the material parameters object * \param element The element */ - const MaterialLawParams& materialLawParams(const Element &element) const + const auto& materialLawParams(const Element &element) const { - return asImp_().materialLawParamsAtPos(element.geometry().center()); + return asImp_().materialLawParamsAtPos(element.geometry().center()); } /*! @@ -80,7 +88,7 @@ public: * \return the material parameters object * \param globalPos The position of the center of the element */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + const auto& materialLawParamsAtPos(const GlobalPosition& globalPos) const { DUNE_THROW(Dune::InvalidStateException, "The spatial parameters do not provide " diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/cellcentered/pressure.hh b/dumux/porousmediumflow/2p/sequential/diffusion/cellcentered/pressure.hh index b3c867d583..d68266be0d 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/cellcentered/pressure.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/cellcentered/pressure.hh @@ -30,6 +30,8 @@ #include #include +#include + namespace Dumux { /*! * \ingroup SequentialTwoPModel @@ -121,7 +123,6 @@ template class FVPressure2P: public FVPressure using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -920,13 +921,20 @@ const Intersection& intersection, const CellData& cellData, const bool first) satW = cellData.saturation(wPhaseIdx); satNw = cellData.saturation(nPhaseIdx); } - Scalar temperature = problem_.temperature(element); + + const Scalar temperature = problem_.temperature(element); // get Dirichlet pressure boundary condition - Scalar pressBound = boundValues[pressureIdx]; + const Scalar pressBound = boundValues[pressureIdx]; //calculate constitutive relations depending on the kind of saturation used - Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pcBound = fluidMatrixInteraction.pc(satW); // determine phase pressures from primary pressure variable Scalar pressW = 0; @@ -967,9 +975,9 @@ const Intersection& intersection, const CellData& cellData, const bool first) rhoMeanNw = 0.5 * (cellData.density(nPhaseIdx) + densityNwBound); } - Scalar lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) + Scalar lambdaWBound = fluidMatrixInteraction.krw(satW) / viscosityWBound; - Scalar lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) + Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW) / viscosityNwBound; Scalar fractionalWBound = lambdaWBound / (lambdaWBound + lambdaNwBound); @@ -1095,13 +1103,17 @@ void FVPressure2P::updateMaterialLaws() CellData& cellData = problem_.variables().cellData(eIdxGlobal); - Scalar temperature = problem_.temperature(element); + const Scalar temperature = problem_.temperature(element); // determine phase saturations from primary saturation variable + const Scalar satW = cellData.saturation(wPhaseIdx); - Scalar satW = cellData.saturation(wPhaseIdx); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); - Scalar pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + const Scalar pc = fluidMatrixInteraction.pc(satW); // determine phase pressures from primary pressure variable Scalar pressW = 0; @@ -1151,8 +1163,8 @@ void FVPressure2P::updateMaterialLaws() } // initialize mobilities - Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) / viscosity_[wPhaseIdx]; - Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) / viscosity_[nPhaseIdx]; + Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; if (compressibility_) { @@ -1168,7 +1180,7 @@ void FVPressure2P::updateMaterialLaws() cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNw)); cellData.setFracFlowFunc(nPhaseIdx, mobilityNw / (mobilityW + mobilityNw)); - Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_; + const Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_; Scalar potW = pressW + gravityDiff * density_[wPhaseIdx]; Scalar potNw = pressNw + gravityDiff * density_[nPhaseIdx]; diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/cellcentered/velocity.hh b/dumux/porousmediumflow/2p/sequential/diffusion/cellcentered/velocity.hh index 7bd5b3f8a9..337358c6c6 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/cellcentered/velocity.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/cellcentered/velocity.hh @@ -28,6 +28,8 @@ #include #include +#include + namespace Dumux { /*! @@ -64,7 +66,6 @@ class FVVelocity2P using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -564,8 +565,14 @@ void FVVelocity2P::calculateVelocityOnBoundary(const Intersection& inte satNw = cellData.saturation(nPhaseIdx); } - Scalar pressBound = boundValues[pressureIdx]; - Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + const Scalar pressBound = boundValues[pressureIdx]; + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pcBound = fluidMatrixInteraction.pc(satW); // determine phase pressures from primary pressure variable Scalar pressWBound = 0; @@ -582,7 +589,7 @@ void FVVelocity2P::calculateVelocityOnBoundary(const Intersection& inte } // get temperature at current position - Scalar temperature = problem_.temperature(element); + const Scalar temperature = problem_.temperature(element); Scalar densityWBound = density_[wPhaseIdx]; Scalar densityNwBound = density_[nPhaseIdx]; @@ -604,9 +611,9 @@ void FVVelocity2P::calculateVelocityOnBoundary(const Intersection& inte viscosityNwBound = FluidSystem::viscosity(fluidState, nPhaseIdx) / densityNwBound; } - Scalar lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) + Scalar lambdaWBound = fluidMatrixInteraction.krw(satW) / viscosityWBound; - Scalar lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) + Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW) / viscosityNwBound; Scalar potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndex); @@ -657,7 +664,7 @@ void FVVelocity2P::calculateVelocityOnBoundary(const Intersection& inte (Dune::FloatCmp::eq(potentialDiffNw, 0.0, 1.0e-30)) ? 0.5 * (cellData.density(nPhaseIdx) + densityNwBound) : density_[nPhaseIdx]; } - Scalar scalarPerm = permeability.two_norm(); + const Scalar scalarPerm = permeability.two_norm(); // calculate the gravity term Dune::FieldVector velocityW(unitOuterNormal); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/mimetic.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/mimetic.hh index 4056d8f703..c457759256 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/mimetic.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/mimetic.hh @@ -42,6 +42,8 @@ #include +#include + namespace Dumux { /*! @@ -96,7 +98,6 @@ class MimeticTwoPLocalStiffness: public LocalStiffness using CellData = GetPropType; using FluidSystem = GetPropType; using FluidState = GetPropType; - using MaterialLaw = GetPropType; public: // define the number of components of your system, this is used outside @@ -682,10 +683,13 @@ void MimeticTwoPLocalStiffness::assembleElementMatrices(const Element& PrimaryVariables boundValues(0.0); problem_.dirichlet(boundValues, intersection); - Scalar krw = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), - boundValues[saturationIdx]); - Scalar krn = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), - boundValues[saturationIdx]); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar krw = fluidMatrixInteraction.krw(boundValues[saturationIdx]); + const Scalar krn = fluidMatrixInteraction.krn(boundValues[saturationIdx]); switch (pressureType) { diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/mimeticadaptive.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/mimeticadaptive.hh index 60585c6ccc..3de77fd91c 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/mimeticadaptive.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/mimeticadaptive.hh @@ -44,6 +44,8 @@ #include #include +#include + namespace Dumux { /*! @@ -98,7 +100,6 @@ class MimeticTwoPLocalStiffnessAdaptive: public LocalStiffness using CellData = GetPropType; using FluidSystem = GetPropType; using FluidState = GetPropType; - using MaterialLaw = GetPropType; using IntersectionMapper = Dumux::IntersectionMapper; @@ -701,10 +702,13 @@ void MimeticTwoPLocalStiffnessAdaptive::assembleElementMatrices(const E PrimaryVariables boundValues(0.0); problem_.dirichlet(boundValues, intersection); - Scalar krw = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), - boundValues[saturationIdx]); - Scalar krn = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), - boundValues[saturationIdx]); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar krw = fluidMatrixInteraction.krw(boundValues[saturationIdx]); + const Scalar krn = fluidMatrixInteraction.krn(boundValues[saturationIdx]); switch (pressureType) { diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/operator.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/operator.hh index ca84c4a800..d4d10fbc0a 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/operator.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/operator.hh @@ -28,6 +28,8 @@ #include #include +#include + namespace Dumux { /*! @@ -57,7 +59,6 @@ class MimeticOperatorAssemblerTwoP: public CROperatorAssemblerTwoP using Element = typename GridView::template Codim<0>::Entity; using CellData = GetPropType; - using MaterialLaw = GetPropType; using FluidSystem = GetPropType; using FluidState = GetPropType; using BoundaryTypes = GetPropType; @@ -247,14 +248,18 @@ public: PrimaryVariables boundValues(0.0); problem.dirichlet(boundValues, intersection); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element); + if (velocityW[idxInInside] >= 0.) { mobilityW = cellData.mobility(wPhaseIdx); } else { - mobilityW = MaterialLaw::krw(problem.spatialParams().materialLawParams(element), - boundValues[saturationIdx]) / viscosityW; + mobilityW = fluidMatrixInteraction.krw(boundValues[saturationIdx]) / viscosityW; } if (velocityNw[idxInInside] >= 0.) @@ -263,8 +268,7 @@ public: } else { - mobilityNw = MaterialLaw::krn(problem.spatialParams().materialLawParams(element), - boundValues[saturationIdx]) / viscosityNw; + mobilityNw = fluidMatrixInteraction.krn(boundValues[saturationIdx]) / viscosityNw; } } else diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/operatoradaptive.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/operatoradaptive.hh index d204e8af45..32135a2b63 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/operatoradaptive.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/operatoradaptive.hh @@ -28,6 +28,8 @@ #include #include +#include + namespace Dumux { /*! @@ -59,7 +61,6 @@ class MimeticOperatorAssemblerTwoPAdaptive : public CROperatorAssemblerTwoPAdapt using Element = typename GridView::template Codim<0>::Entity; using CellData = GetPropType; - using MaterialLaw = GetPropType; using FluidSystem = GetPropType; using FluidState = GetPropType; using BoundaryTypes = GetPropType; @@ -255,14 +256,18 @@ public: PrimaryVariables boundValues(0.0); problem.dirichlet(boundValues, intersection); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element); + if (velocityW[intersectionIdx] >= 0.) { mobilityW = cellData.mobility(wPhaseIdx); } else { - mobilityW = MaterialLaw::krw(problem.spatialParams().materialLawParams(element), - boundValues[saturationIdx]) / viscosityW; + mobilityW = fluidMatrixInteraction.krw(boundValues[saturationIdx]) / viscosityW; } if (velocityNw[intersectionIdx] >= 0.) @@ -271,8 +276,7 @@ public: } else { - mobilityNw = MaterialLaw::krn(problem.spatialParams().materialLawParams(element), - boundValues[saturationIdx]) / viscosityNw; + mobilityNw = fluidMatrixInteraction.krn(boundValues[saturationIdx]) / viscosityNw; } } else diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/pressure.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/pressure.hh index 92fa2c1259..9da440fb95 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/pressure.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/pressure.hh @@ -32,6 +32,8 @@ #include #include +#include + namespace Dumux { /*! @@ -67,7 +69,6 @@ template class MimeticPressure2P using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -515,13 +516,16 @@ void MimeticPressure2P::updateMaterialLaws() CellData& cellData = problem_.variables().cellData(eIdxGlobal); - Scalar satW = cellData.saturation(wPhaseIdx); + const Scalar satW = cellData.saturation(wPhaseIdx); + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); // initialize mobilities - Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; // initialize mobilities cellData.setMobility(wPhaseIdx, mobilityW); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/pressureadaptive.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/pressureadaptive.hh index fb0f271f81..7ecf0b8839 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/pressureadaptive.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mimetic/pressureadaptive.hh @@ -32,6 +32,8 @@ #include #include +#include + namespace Dumux { /*! @@ -67,7 +69,6 @@ template class MimeticPressure2PAdaptive using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -532,13 +533,16 @@ void MimeticPressure2PAdaptive::updateMaterialLaws() CellData& cellData = problem_.variables().cellData(eIdxGlobal); - Scalar satW = cellData.saturation(wPhaseIdx); + const Scalar satW = cellData.saturation(wPhaseIdx); + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); // initialize mobilities - Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; // initialize mobilities cellData.setMobility(wPhaseIdx, mobilityW); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressure.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressure.hh index 34c6c1fabb..d5491eaa97 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressure.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressure.hh @@ -29,6 +29,8 @@ #include #include "2dtransmissibilitycalculator.hh" +#include + namespace Dumux { /*! @@ -82,7 +84,6 @@ class FvMpfaL2dPressure2p: public FVPressure using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -1664,19 +1665,20 @@ void FvMpfaL2dPressure2p::assemble() } - Scalar pcBound = MaterialLaw::pc( - problem_.spatialParams().materialLawParams(element), satWBound); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + Scalar pcBound = fluidMatrixInteraction.pc(satWBound); Scalar gravityDiffBound = (problem_.bBoxMax() - globalPosFace) * gravity_ * (density_[nPhaseIdx] - density_[wPhaseIdx]); pcBound += gravityDiffBound; - Dune::FieldVector lambdaBound( - MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), - satWBound)); - lambdaBound[nPhaseIdx] = MaterialLaw::krn( - problem_.spatialParams().materialLawParams(element), satWBound); + Dune::FieldVector lambdaBound(fluidMatrixInteraction.krw(satWBound)); + lambdaBound[nPhaseIdx] = fluidMatrixInteraction.krn(satWBound); lambdaBound[wPhaseIdx] /= viscosity_[wPhaseIdx]; lambdaBound[nPhaseIdx] /= viscosity_[nPhaseIdx]; @@ -1840,15 +1842,18 @@ void FvMpfaL2dPressure2p::updateMaterialLaws() Scalar satW = cellData.saturation(wPhaseIdx); - Scalar pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pc = fluidMatrixInteraction.pc(satW); cellData.setCapillaryPressure(pc); // initialize mobilities - Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; // initialize mobilities cellData.setMobility(wPhaseIdx, mobilityW); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressureadaptive.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressureadaptive.hh index e19b8d1740..6813decae3 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressureadaptive.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressureadaptive.hh @@ -30,6 +30,8 @@ #include #include "2dtransmissibilitycalculator.hh" +#include + namespace Dumux { /*! @@ -85,7 +87,6 @@ class FvMpfaL2dPressure2pAdaptive: public FVPressure using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -2383,19 +2384,20 @@ void FvMpfaL2dPressure2pAdaptive::assemble() } - Scalar pcBound = MaterialLaw::pc( - problem_.spatialParams().materialLawParams(element), satWBound); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + Scalar pcBound = fluidMatrixInteraction.pc(satWBound); Scalar gravityDiffBound = (problem_.bBoxMax() - globalPosFace) * gravity_ * (density_[nPhaseIdx] - density_[wPhaseIdx]); pcBound += gravityDiffBound; - Dune::FieldVector lambdaBound( - MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), - satWBound)); - lambdaBound[nPhaseIdx] = MaterialLaw::krn( - problem_.spatialParams().materialLawParams(element), satWBound); + Dune::FieldVector lambdaBound(fluidMatrixInteraction.krw(satWBound)); + lambdaBound[nPhaseIdx] = fluidMatrixInteraction.krn(satWBound); lambdaBound[wPhaseIdx] /= viscosity_[wPhaseIdx]; lambdaBound[nPhaseIdx] /= viscosity_[nPhaseIdx]; @@ -2556,17 +2558,20 @@ void FvMpfaL2dPressure2pAdaptive::updateMaterialLaws() CellData& cellData = problem_.variables().cellData(eIdxGlobal); - Scalar satW = cellData.saturation(wPhaseIdx); + const Scalar satW = cellData.saturation(wPhaseIdx); + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); - Scalar pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + const Scalar pc = fluidMatrixInteraction.pc(satW); cellData.setCapillaryPressure(pc); // initialize mobilities - Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; // initialize mobilities cellData.setMobility(wPhaseIdx, mobilityW); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressurevelocity.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressurevelocity.hh index 59b4039824..15b59fadef 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressurevelocity.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressurevelocity.hh @@ -27,6 +27,8 @@ #include "2dpressure.hh" #include "2dvelocity.hh" +#include + namespace Dumux { /*! @@ -61,7 +63,6 @@ template class FvMpfaL2dPressureVelocity2p: public FvMpfaL2dPress using PrimaryVariables = typename SolutionTypes::PrimaryVariables; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -453,8 +454,14 @@ void FvMpfaL2dPressureVelocity2p::calculateVelocityOnBoundary(const Int satW = cellData.saturation(wPhaseIdx); } - Scalar pressBound = boundValues[pressureIdx]; - Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + const Scalar pressBound = boundValues[pressureIdx]; + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pcBound = fluidMatrixInteraction.pc(satW); //determine phase pressures from primary pressure variable Scalar pressWBound = 0; @@ -470,10 +477,8 @@ void FvMpfaL2dPressureVelocity2p::calculateVelocityOnBoundary(const Int pressNwBound = pressBound; } - Scalar lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar lambdaWBound = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; Scalar potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndex); Scalar potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndex); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressurevelocityadaptive.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressurevelocityadaptive.hh index d4a7418692..87b3176ead 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressurevelocityadaptive.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dpressurevelocityadaptive.hh @@ -27,6 +27,8 @@ #include "2dpressureadaptive.hh" #include "2dvelocityadaptive.hh" +#include + namespace Dumux { /*! @@ -63,7 +65,6 @@ template class FvMpfaL2dPressureVelocity2pAdaptive: public FvMpfa using PrimaryVariables = typename SolutionTypes::PrimaryVariables; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -589,8 +590,14 @@ void FvMpfaL2dPressureVelocity2pAdaptive::calculateVelocityOnBoundary(c satW = cellData.saturation(wPhaseIdx); } - Scalar pressBound = boundValues[pressureIdx]; - Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + const Scalar pressBound = boundValues[pressureIdx]; + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pcBound = fluidMatrixInteraction.pc(satW); //determine phase pressures from primary pressure variable Scalar pressWBound = 0; @@ -606,10 +613,8 @@ void FvMpfaL2dPressureVelocity2pAdaptive::calculateVelocityOnBoundary(c pressNwBound = pressBound; } - Scalar lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar lambdaWBound = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; Scalar potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndex); Scalar potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndex); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dvelocity.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dvelocity.hh index 269960826c..0e6df329cd 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dvelocity.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dvelocity.hh @@ -30,6 +30,8 @@ #include #include "2dtransmissibilitycalculator.hh" +#include + namespace Dumux { /*! @@ -66,7 +68,6 @@ template class FvMpfaL2dVelocity2p using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -786,21 +787,20 @@ void FvMpfaL2dVelocity2p::calculateBoundaryInteractionVolumeVelocity(In } - Scalar pcBound = MaterialLaw::pc( - problem_.spatialParams().materialLawParams(element), satWBound); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + Scalar pcBound = fluidMatrixInteraction.pc(satWBound); Scalar gravityDiffBound = (problem_.bBoxMax() - globalPosFace) * gravity_ * (density_[nPhaseIdx] - density_[wPhaseIdx]); pcBound += gravityDiffBound; - Dune::FieldVector < Scalar, numPhases - > lambdaBound( - MaterialLaw::krw( - problem_.spatialParams().materialLawParams(element), - satWBound)); - lambdaBound[nPhaseIdx] = MaterialLaw::krn( - problem_.spatialParams().materialLawParams(element), satWBound); + Dune::FieldVector lambdaBound(fluidMatrixInteraction.krw(satWBound)); + lambdaBound[nPhaseIdx] = fluidMatrixInteraction.krn(satWBound); lambdaBound[wPhaseIdx] /= viscosity_[wPhaseIdx]; lambdaBound[nPhaseIdx] /= viscosity_[nPhaseIdx]; diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dvelocityadaptive.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dvelocityadaptive.hh index 2fddf014ca..85cbc3586b 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dvelocityadaptive.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/2dvelocityadaptive.hh @@ -63,7 +63,6 @@ template class FvMpfaL2dVelocity2pAdaptive : public FvMpfaL2dVelo using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressure.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressure.hh index 68a418328f..8eefe30623 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressure.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressure.hh @@ -32,6 +32,8 @@ #include "3dinteractionvolumecontainer.hh" #include "3dtransmissibilitycalculator.hh" +#include + namespace Dumux { /*! @@ -85,7 +87,6 @@ class FvMpfaL3dPressure2p: public FVPressure using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -2351,18 +2352,20 @@ void FvMpfaL3dPressure2p::assembleBoundaryInteractionVolume(Interaction } - Scalar pcBound = MaterialLaw::pc( - problem_.spatialParams().materialLawParams(element), satWBound); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + Scalar pcBound = fluidMatrixInteraction.pc(satWBound); Scalar gravityDiffBound = (problem_.bBoxMax() - globalPosFace) * gravity_ * (density_[nPhaseIdx] - density_[wPhaseIdx]); pcBound += gravityDiffBound; - Dune::FieldVector - lambdaBound(MaterialLaw::krw(problem_.spatialParams().materialLawParams(element),satWBound)); - lambdaBound[nPhaseIdx] = MaterialLaw::krn( - problem_.spatialParams().materialLawParams(element), satWBound); + Dune::FieldVector lambdaBound(fluidMatrixInteraction.krw(satWBound)); + lambdaBound[nPhaseIdx] = fluidMatrixInteraction.krn(satWBound); lambdaBound[wPhaseIdx] /= viscosity_[wPhaseIdx]; lambdaBound[nPhaseIdx] /= viscosity_[nPhaseIdx]; @@ -2489,14 +2492,19 @@ void FvMpfaL3dPressure2p::updateMaterialLaws() Scalar satW = cellData.saturation(wPhaseIdx); - Scalar pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pc = fluidMatrixInteraction.pc(satW); cellData.setCapillaryPressure(pc); // initialize mobilities - Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) + Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; - Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) + Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; // initialize mobilities diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressureadaptive.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressureadaptive.hh index a5129ed870..ef2aef01af 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressureadaptive.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressureadaptive.hh @@ -89,7 +89,6 @@ class FvMpfaL3dPressure2pAdaptive: public FvMpfaL3dPressure2p using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressurevelocity.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressurevelocity.hh index 025df282e2..595ff582d9 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressurevelocity.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressurevelocity.hh @@ -28,6 +28,8 @@ #include "3dpressure.hh" #include "3dvelocity.hh" +#include + namespace Dumux { /*! * \ingroup SequentialTwoPModel @@ -77,7 +79,6 @@ template class FvMpfaL3dPressureVelocity2p: public FvMpfaL3dPress using SolutionTypes = GetProp; using PrimaryVariables = typename SolutionTypes::PrimaryVariables; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using InteractionVolume = GetPropType; using Intersection = typename GridView::Intersection; @@ -452,8 +453,14 @@ void FvMpfaL3dPressureVelocity2p::calculateVelocityOnBoundary(const Int satW = cellData.saturation(wPhaseIdx); } - Scalar pressBound = boundValues[pressureIdx]; - Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + const Scalar pressBound = boundValues[pressureIdx]; + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pcBound = fluidMatrixInteraction.pc(satW); //determine phase pressures from primary pressure variable Scalar pressWBound = 0; @@ -469,10 +476,8 @@ void FvMpfaL3dPressureVelocity2p::calculateVelocityOnBoundary(const Int pressNwBound = pressBound; } - Scalar lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar lambdaWBound = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; Scalar potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndex); Scalar potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndex); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressurevelocityadaptive.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressurevelocityadaptive.hh index 5782b15acf..84a8ba579a 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressurevelocityadaptive.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dpressurevelocityadaptive.hh @@ -27,6 +27,8 @@ #include "3dpressureadaptive.hh" #include "3dvelocityadaptive.hh" +#include + namespace Dumux { /*! @@ -79,7 +81,6 @@ template class FvMpfaL3dPressureVelocity2pAdaptive: public FvMpfa using SolutionTypes = GetProp; using PrimaryVariables = typename SolutionTypes::PrimaryVariables; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using InteractionVolume = GetPropType; using Intersection = typename GridView::Intersection; @@ -553,8 +554,14 @@ void FvMpfaL3dPressureVelocity2pAdaptive::calculateVelocityOnBoundary(c satW = cellData.saturation(wPhaseIdx); } - Scalar pressBound = boundValues[pressureIdx]; - Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + const Scalar pressBound = boundValues[pressureIdx]; + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pcBound = fluidMatrixInteraction.pc(satW); //determine phase pressures from primary pressure variable Scalar pressWBound = 0; @@ -570,10 +577,8 @@ void FvMpfaL3dPressureVelocity2pAdaptive::calculateVelocityOnBoundary(c pressNwBound = pressBound; } - Scalar lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar lambdaWBound = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; Scalar potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndex); Scalar potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndex); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dvelocity.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dvelocity.hh index 8aef1f4cb8..818f50b71b 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dvelocity.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dvelocity.hh @@ -29,6 +29,8 @@ #include #include "3dtransmissibilitycalculator.hh" +#include + namespace Dumux { /*! @@ -63,7 +65,6 @@ template class FvMpfaL3dVelocity2p using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -1972,19 +1973,20 @@ void FvMpfaL3dVelocity2p::calculateBoundaryInteractionVolumeVelocity(In } - Scalar pcBound = MaterialLaw::pc( - problem_.spatialParams().materialLawParams(element), satWBound); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + Scalar pcBound = fluidMatrixInteraction.pc(satWBound); Scalar gravityDiffBound = (problem_.bBoxMax() - globalPosFace) * gravity_ * (density_[nPhaseIdx] - density_[wPhaseIdx]); pcBound += gravityDiffBound; - Dune::FieldVector lambdaBound( - MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), - satWBound)); - lambdaBound[nPhaseIdx] = MaterialLaw::krn( - problem_.spatialParams().materialLawParams(element), satWBound); + Dune::FieldVector lambdaBound(fluidMatrixInteraction.krw(satWBound)); + lambdaBound[nPhaseIdx] = fluidMatrixInteraction.krn(satWBound); lambdaBound[wPhaseIdx] /= viscosity_[wPhaseIdx]; lambdaBound[nPhaseIdx] /= viscosity_[nPhaseIdx]; diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dvelocityadaptive.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dvelocityadaptive.hh index 9aa9447370..1afe847c7f 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dvelocityadaptive.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/lmethod/3dvelocityadaptive.hh @@ -65,7 +65,6 @@ template class FvMpfaL3dVelocity2pAdaptive: public FvMpfaL3dVeloc using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dpressure.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dpressure.hh index fe1b2e9970..97f3be5fe5 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dpressure.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dpressure.hh @@ -28,6 +28,8 @@ #include #include +#include + namespace Dumux { /*! * \ingroup SequentialTwoPModel @@ -77,7 +79,6 @@ class FvMpfaO2dPressure2p: public FVPressure using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -1763,19 +1764,20 @@ void FvMpfaO2dPressure2p::assemble() } - Scalar pcBound = MaterialLaw::pc( - problem_.spatialParams().materialLawParams(element), satWBound); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + Scalar pcBound = fluidMatrixInteraction.pc(satWBound); Scalar gravityDiffBound = (problem_.bBoxMax() - globalPosFace) * gravity_ * (density_[nPhaseIdx] - density_[wPhaseIdx]); pcBound += gravityDiffBound; - Dune::FieldVector lambdaBound( - MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), - satWBound)); - lambdaBound[nPhaseIdx] = MaterialLaw::krn( - problem_.spatialParams().materialLawParams(element), satWBound); + Dune::FieldVector lambdaBound(fluidMatrixInteraction.krw(satWBound)); + lambdaBound[nPhaseIdx] = fluidMatrixInteraction.krn(satWBound); lambdaBound[wPhaseIdx] /= viscosity_[wPhaseIdx]; lambdaBound[nPhaseIdx] /= viscosity_[nPhaseIdx]; @@ -1938,17 +1940,20 @@ void FvMpfaO2dPressure2p::updateMaterialLaws() CellData& cellData = problem_.variables().cellData(eIdxGlobal); - Scalar satW = cellData.saturation(wPhaseIdx); + const Scalar satW = cellData.saturation(wPhaseIdx); + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); - Scalar pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + const Scalar pc = fluidMatrixInteraction.pc(satW); cellData.setCapillaryPressure(pc); // initialize mobilities - Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; // initialize mobilities cellData.setMobility(wPhaseIdx, mobilityW); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dpressurevelocity.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dpressurevelocity.hh index a38f5e39d1..eb00f5a077 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dpressurevelocity.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dpressurevelocity.hh @@ -27,6 +27,8 @@ #include "2dpressure.hh" #include "2dvelocity.hh" +#include + namespace Dumux { /*! * \ingroup SequentialTwoPModel @@ -60,7 +62,6 @@ template class FvMpfaO2dPressureVelocity2p: public FvMpfaO2dPress using PrimaryVariables = typename SolutionTypes::PrimaryVariables; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using FluidSystem = GetPropType; using FluidState = GetPropType; @@ -454,8 +455,14 @@ void FvMpfaO2dPressureVelocity2p::calculateVelocityOnBoundary(const Int satW = cellData.saturation(wPhaseIdx); } - Scalar pressBound = boundValues[pressureIdx]; - Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + const Scalar pressBound = boundValues[pressureIdx]; + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pcBound = fluidMatrixInteraction.pc(satW); //determine phase pressures from primary pressure variable Scalar pressWBound = 0; @@ -471,10 +478,8 @@ void FvMpfaO2dPressureVelocity2p::calculateVelocityOnBoundary(const Int pressNwBound = pressBound; } - Scalar lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[wPhaseIdx]; - Scalar lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) - / viscosity_[nPhaseIdx]; + const Scalar lambdaWBound = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; Scalar potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndex); Scalar potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndex); diff --git a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dvelocity.hh b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dvelocity.hh index b9ede8717a..36a08b2bd7 100644 --- a/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dvelocity.hh +++ b/dumux/porousmediumflow/2p/sequential/diffusion/mpfa/omethod/2dvelocity.hh @@ -30,6 +30,8 @@ #include #include +#include + namespace Dumux { /*! * \ingroup SequentialTwoPModel @@ -65,7 +67,6 @@ template class FvMpfaO2dVelocity2P using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -619,21 +620,20 @@ void FvMpfaO2dVelocity2P::calculateBoundaryInteractionVolumeVelocity(In } - Scalar pcBound = MaterialLaw::pc( - problem_.spatialParams().materialLawParams(element), satWBound); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + Scalar pcBound = fluidMatrixInteraction.pc(satWBound); Scalar gravityDiffBound = (problem_.bBoxMax() - globalPosFace) * gravity_ * (density_[nPhaseIdx] - density_[wPhaseIdx]); pcBound += gravityDiffBound; - Dune::FieldVector < Scalar, numPhases - > lambdaBound( - MaterialLaw::krw( - problem_.spatialParams().materialLawParams(element), - satWBound)); - lambdaBound[nPhaseIdx] = MaterialLaw::krn( - problem_.spatialParams().materialLawParams(element), satWBound); + Dune::FieldVector < Scalar, numPhases> lambdaBound(fluidMatrixInteraction.krw(satWBound)); + lambdaBound[nPhaseIdx] = fluidMatrixInteraction.krn(satWBound); lambdaBound[wPhaseIdx] /= viscosity_[wPhaseIdx]; lambdaBound[nPhaseIdx] /= viscosity_[nPhaseIdx]; diff --git a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/capillarydiffusion.hh b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/capillarydiffusion.hh index 4e50446756..dfdc2b3ae0 100644 --- a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/capillarydiffusion.hh +++ b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/capillarydiffusion.hh @@ -27,6 +27,8 @@ #include #include "properties.hh" +#include + namespace Dumux { /*! * \ingroup SequentialTwoPModel @@ -54,7 +56,6 @@ private: using Indices = typename GetPropType::Indices; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using FluidSystem = GetPropType; using FluidState = GetPropType; @@ -112,6 +113,11 @@ public: Scalar mobilityWI = 0; Scalar mobilityNwI = 0; + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + if (preComput_) { mobilityWI = CellDataI.mobility(wPhaseIdx); @@ -123,9 +129,9 @@ public: fluidState.setPressure(wPhaseIdx, referencePressure); fluidState.setPressure(nPhaseIdx, referencePressure); fluidState.setTemperature(temperature); - mobilityWI = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satI); + mobilityWI = fluidMatrixInteraction.krw(satI); mobilityWI /= FluidSystem::viscosity(fluidState, wPhaseIdx); - mobilityNwI = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satI); + mobilityNwI = fluidMatrixInteraction.krn(satI); mobilityNwI /= FluidSystem::viscosity(fluidState, nPhaseIdx); } @@ -172,9 +178,14 @@ public: fluidState.setPressure(nPhaseIdx, referencePressure); fluidState.setTemperature(temperature); - mobilityWJ = MaterialLaw::krw(problem_.spatialParams().materialLawParams(neighbor), satJ); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteractionNeighbor = spatialParams.fluidMatrixInteractionAtPos(neighbor.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteractionNeighbor = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), neighbor); + + mobilityWJ = fluidMatrixInteractionNeighbor.krw(satJ); mobilityWJ /= FluidSystem::viscosity(fluidState, wPhaseIdx); - mobilityNwJ = MaterialLaw::krn(problem_.spatialParams().materialLawParams(neighbor), satJ); + mobilityNwJ = fluidMatrixInteractionNeighbor.krn(satJ); mobilityNwJ /= FluidSystem::viscosity(fluidState, nPhaseIdx); } Scalar mobilityWMean = 0.5*(mobilityWI + mobilityWJ); @@ -207,9 +218,9 @@ public: fluidState.setPressure(wPhaseIdx, referencePressure); fluidState.setPressure(nPhaseIdx, referencePressure); fluidState.setTemperature(temperature); - mobilityWJ = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satJ); + mobilityWJ = fluidMatrixInteraction.krw(satJ); mobilityWJ /= FluidSystem::viscosity(fluidState, wPhaseIdx); - mobilityNwJ = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satJ); + mobilityNwJ = fluidMatrixInteraction.krn(satJ); mobilityNwJ /= FluidSystem::viscosity(fluidState, nPhaseIdx); Scalar mobWMean = 0.5 * (mobilityWI + mobilityWJ); diff --git a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/evalcflfluxcoats.hh b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/evalcflfluxcoats.hh index 0f43ac4153..4750fe67ab 100644 --- a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/evalcflfluxcoats.hh +++ b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/evalcflfluxcoats.hh @@ -28,6 +28,8 @@ #include #include "evalcflflux.hh" +#include + namespace Dumux { /*! * \ingroup SequentialTwoPModel @@ -44,7 +46,6 @@ private: using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using FluidSystem = GetPropType; using FluidState = GetPropType; using Indices = typename GetPropType::Indices; @@ -357,7 +358,12 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, Scalar lambdaWI = cellDataI.mobility(wPhaseIdx); Scalar lambdaNwI = cellDataI.mobility(nPhaseIdx); - Scalar dpc_dsI = MaterialLaw::dpc_dsw(problem_.spatialParams().materialLawParams(element), satI); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar dpc_dsI = fluidMatrixInteraction.dpc_dsw(satI); const GlobalPosition& unitOuterNormal = intersection.centerUnitOuterNormal(); @@ -407,7 +413,12 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, Scalar lambdaWJ = cellDataI.mobility(wPhaseIdx); Scalar lambdaNwJ = cellDataI.mobility(nPhaseIdx); - Scalar dpc_dsJ = MaterialLaw::dpc_dsw(problem_.spatialParams().materialLawParams(neighbor), satJ); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(neighbor.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteractionNeighbor = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), neighbor); + + const Scalar dpc_dsJ = fluidMatrixInteractionNeighbor.dpc_dsw(satJ); // compute vectorized permeabilities DimVector permeability(0); @@ -448,8 +459,8 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, ds += epsDerivative_; } - Scalar dLambdaWDs = MaterialLaw::krw(problem_.spatialParams().materialLawParams(neighbor), abs(satPlus)) / viscosityW; - dLambdaWDs -= MaterialLaw::krw(problem_.spatialParams().materialLawParams(neighbor), abs(satMinus)) / viscosityW; + Scalar dLambdaWDs = fluidMatrixInteractionNeighbor.krw(abs(satPlus)) / viscosityW; + dLambdaWDs -= fluidMatrixInteractionNeighbor.krw(abs(satMinus)) / viscosityW; dLambdaWDs /= (ds); if (upwindNwI) @@ -471,8 +482,8 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, ds += epsDerivative_; } - Scalar dLambdaNwDs = MaterialLaw::krn(problem_.spatialParams().materialLawParams(neighbor), satPlus) / viscosityNw; - dLambdaNwDs -= MaterialLaw::krn(problem_.spatialParams().materialLawParams(neighbor), satMinus) / viscosityNw; + Scalar dLambdaNwDs = fluidMatrixInteractionNeighbor.krn(satPlus) / viscosityNw; + dLambdaNwDs -= fluidMatrixInteractionNeighbor.krn(satMinus) / viscosityNw; dLambdaNwDs /= (ds); Scalar lambdaWCap = 0.5 * (lambdaWI + lambdaWJ); @@ -559,13 +570,13 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, case pw: { potWBound = bcValues[eqIdxPress] + density_[wPhaseIdx] * gdeltaZ; - potNwBound = bcValues[eqIdxPress] + MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satWBound) + potNwBound = bcValues[eqIdxPress] + fluidMatrixInteraction.pc(satWBound) + density_[nPhaseIdx] * gdeltaZ; break; } case pn: { - potWBound = bcValues[eqIdxPress] - MaterialLaw::pc(problem_.spatialParams().materialLawParams(element),satWBound) + potWBound = bcValues[eqIdxPress] - fluidMatrixInteraction.pc(satWBound) + density_[wPhaseIdx] * gdeltaZ; potNwBound = bcValues[eqIdxPress] + density_[nPhaseIdx] * gdeltaZ; break; @@ -602,12 +613,12 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, if (hasPotWBound && !hasPotNwBound) { - potNwBound = potWBound + MaterialLaw::pc(problem_.spatialParams().materialLawParams(element),satWBound) + potNwBound = potWBound + fluidMatrixInteraction.pc(satWBound) + (density_[nPhaseIdx] - density_[wPhaseIdx]) * gdeltaZ; } else if (!hasPotWBound && hasPotNwBound) { - potWBound = potNwBound - MaterialLaw::pc(problem_.spatialParams().materialLawParams(element),satWBound) + potWBound = potNwBound - fluidMatrixInteraction.pc(satWBound) + (density_[nPhaseIdx] - density_[wPhaseIdx]) * gdeltaZ; } } @@ -651,7 +662,7 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, return; } - Scalar dpc_dsBound = MaterialLaw::dpc_dsw(problem_.spatialParams().materialLawParams(element), satWBound); + const Scalar dpc_dsBound = fluidMatrixInteraction.dpc_dsw(satWBound); Scalar lambdaWBound = 0; Scalar lambdaNwBound = 0; @@ -666,8 +677,8 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, Scalar viscosityWBound = FluidSystem::viscosity(fluidState, wPhaseIdx); Scalar viscosityNwBound = FluidSystem::viscosity(fluidState, nPhaseIdx); - lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satWBound) / viscosityWBound; - lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satWBound) / viscosityNwBound; + lambdaWBound = fluidMatrixInteraction.krw(satWBound) / viscosityWBound; + lambdaNwBound = fluidMatrixInteraction.krn(satWBound) / viscosityNwBound; Scalar satUpw = 0; using std::max; @@ -690,8 +701,8 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, ds += epsDerivative_; } - Scalar dLambdaWDs = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satPlus) / viscosityW; - dLambdaWDs -= MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satMinus) / viscosityW; + Scalar dLambdaWDs = fluidMatrixInteraction.krw(satPlus) / viscosityW; + dLambdaWDs -= fluidMatrixInteraction.krw(satMinus) / viscosityW; dLambdaWDs /= (ds); if (cellDataI.fluxData().isUpwindCell(nPhaseIdx, indexInInside)) @@ -713,8 +724,8 @@ void EvalCflFluxCoats::addCoatsFlux(Scalar& lambdaW, Scalar& lambdaNw, ds += epsDerivative_; } - Scalar dLambdaNwDs = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satPlus) / viscosityNw; - dLambdaNwDs -= MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satMinus) / viscosityNw; + Scalar dLambdaNwDs = fluidMatrixInteraction.krn(satPlus) / viscosityNw; + dLambdaNwDs -= fluidMatrixInteraction.krn(satMinus) / viscosityNw; dLambdaNwDs /= (ds); Scalar lambdaWCap = 0.5 * (lambdaWI + lambdaWBound); diff --git a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/evalcflfluxdefault.hh b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/evalcflfluxdefault.hh index ae2e2ac4ec..d249715a25 100644 --- a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/evalcflfluxdefault.hh +++ b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/evalcflfluxdefault.hh @@ -27,6 +27,8 @@ #include #include "evalcflflux.hh" +#include + namespace Dumux { /*! * \ingroup SequentialTwoPModel @@ -234,11 +236,16 @@ private: template typename EvalCflFluxDefault::Scalar EvalCflFluxDefault::getCflFluxFunction(const Element& element) { - Scalar residualSatW = problem_.spatialParams().materialLawParams(element).swr(); - Scalar residualSatNw = problem_.spatialParams().materialLawParams(element).snr(); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar residualSatW = fluidMatrixInteraction.pcSwCurve().effToAbsParams().swr(); + const Scalar residualSatNw = fluidMatrixInteraction.pcSwCurve().effToAbsParams().snr(); // compute dt restriction - Scalar volumeCorrectionFactor = 1 - residualSatW - residualSatNw; + const Scalar volumeCorrectionFactor = 1 - residualSatW - residualSatNw; Scalar volumeCorrectionFactorOutW = 0; Scalar volumeCorrectionFactorOutNw = 0; @@ -273,7 +280,7 @@ typename EvalCflFluxDefault::Scalar EvalCflFluxDefault::getCfl } //determine timestep - Scalar cFLFluxFunction = min(cFLFluxIn, cFLFluxOut); + const Scalar cFLFluxFunction = min(cFLFluxIn, cFLFluxOut); return cFLFluxFunction; } diff --git a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/gravitypart.hh b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/gravitypart.hh index 59cb77ff6a..2e2eab7375 100644 --- a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/gravitypart.hh +++ b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/gravitypart.hh @@ -27,6 +27,8 @@ #include #include "properties.hh" +#include + namespace Dumux { /*! * \ingroup SequentialTwoPModel @@ -54,7 +56,6 @@ private: using Indices = typename GetPropType::Indices; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using FluidSystem = GetPropType; using FluidState = GetPropType; @@ -100,6 +101,11 @@ public: Scalar lambdaWJ = 0; Scalar lambdaNwJ = 0; + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + if (preComput_) { lambdaWI=cellDataI.mobility(wPhaseIdx); @@ -107,9 +113,9 @@ public: } else { - lambdaWI = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satI); + lambdaWI = fluidMatrixInteraction.krw(satI); lambdaWI /= viscosity_[wPhaseIdx]; - lambdaNwI = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satI); + lambdaNwI = fluidMatrixInteraction.krn(satI); lambdaNwI /= viscosity_[nPhaseIdx]; } @@ -144,9 +150,14 @@ public: } else { - lambdaWJ = MaterialLaw::krw(problem_.spatialParams().materialLawParams(neighbor), satJ); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(neighbor.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteractionNeighbor = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), neighbor); + + lambdaWJ = fluidMatrixInteractionNeighbor.krw(satJ); lambdaWJ /= viscosity_[wPhaseIdx]; - lambdaNwJ = MaterialLaw::krn(problem_.spatialParams().materialLawParams(neighbor), satJ); + lambdaNwJ = fluidMatrixInteractionNeighbor.krn(satJ); lambdaNwJ /= viscosity_[nPhaseIdx]; } @@ -164,9 +175,9 @@ public: distVec = intersection.geometry().center() - element.geometry().center(); //calculate lambda_n*f_w at the boundary - lambdaWJ = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satJ); + lambdaWJ = fluidMatrixInteraction.krw(satJ); lambdaWJ /= viscosity_[wPhaseIdx]; - lambdaNwJ = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satJ); + lambdaNwJ = fluidMatrixInteraction.krn(satJ); lambdaNwJ /= viscosity_[nPhaseIdx]; //If potential is zero always take value from the boundary! diff --git a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/saturation.hh b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/saturation.hh index d8331db506..da29f8af87 100644 --- a/dumux/porousmediumflow/2p/sequential/transport/cellcentered/saturation.hh +++ b/dumux/porousmediumflow/2p/sequential/transport/cellcentered/saturation.hh @@ -27,6 +27,8 @@ #include #include +#include + namespace Dumux { /*! @@ -92,7 +94,6 @@ class FVSaturation2P: public FVTransport using GravityFlux = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; @@ -803,7 +804,12 @@ void FVSaturation2P::getFluxOnBoundary(Scalar& update, const Intersecti } } - Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(elementI), satWBound); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(elementI.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), elementI); + + const Scalar pcBound = fluidMatrixInteraction.pc(satWBound); Scalar lambdaW = 0; Scalar lambdaNw = 0; @@ -821,12 +827,12 @@ void FVSaturation2P::getFluxOnBoundary(Scalar& update, const Intersecti { if (compressibility_) { - lambdaW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(elementI), satWBound) + lambdaW = fluidMatrixInteraction.krw(satWBound) / FluidSystem::viscosity(cellDataI.fluidState(), wPhaseIdx); } else { - lambdaW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(elementI), satWBound) + lambdaW = fluidMatrixInteraction.krw(satWBound) / viscosity_[wPhaseIdx]; } } @@ -843,12 +849,12 @@ void FVSaturation2P::getFluxOnBoundary(Scalar& update, const Intersecti { if (compressibility_) { - lambdaNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(elementI), satWBound) + lambdaNw = fluidMatrixInteraction.krn(satWBound) / FluidSystem::viscosity(cellDataI.fluidState(), nPhaseIdx); } else { - lambdaNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(elementI), satWBound) + lambdaNw = fluidMatrixInteraction.krn(satWBound) / viscosity_[nPhaseIdx]; } } @@ -1196,13 +1202,18 @@ void FVSaturation2P::updateMaterialLaws() //determine phase saturations from primary saturation variable Scalar satW = cellData.saturation(wPhaseIdx); - Scalar pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(elementI.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + + const Scalar pc = fluidMatrixInteraction.pc(satW); cellData.setCapillaryPressure(pc); // initialize mobilities - Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) / viscosity_[wPhaseIdx]; - Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) / viscosity_[nPhaseIdx]; + const Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx]; + const Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx]; // initialize mobilities cellData.setMobility(wPhaseIdx, mobilityW); -- GitLab From 85ef0f1d293cfc68e4651b68588b426de237f863 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Mon, 26 Oct 2020 11:23:03 +0100 Subject: [PATCH 44/99] [2p2c][sequential] Adapt headers --- .../2p2c/sequential/fv2dtransportadaptive.hh | 11 ++++- .../2p2c/sequential/fv3dpressureadaptive.hh | 1 - .../2p2c/sequential/fv3dtransportadaptive.hh | 12 +++-- .../2p2c/sequential/fvpressure.hh | 30 +++++++----- .../sequential/fvpressurecompositional.hh | 25 +++++----- .../2p2c/sequential/fvpressuremultiphysics.hh | 45 +++++++++-------- .../2p2c/sequential/fvtransport.hh | 49 ++++++++++++------- 7 files changed, 105 insertions(+), 68 deletions(-) diff --git a/dumux/porousmediumflow/2p2c/sequential/fv2dtransportadaptive.hh b/dumux/porousmediumflow/2p2c/sequential/fv2dtransportadaptive.hh index b7937fb722..37754d5bde 100644 --- a/dumux/porousmediumflow/2p2c/sequential/fv2dtransportadaptive.hh +++ b/dumux/porousmediumflow/2p2c/sequential/fv2dtransportadaptive.hh @@ -33,6 +33,8 @@ #include "adaptiveproperties.hh" #include "fvtransport.hh" +#include + namespace Dumux { /*! * \ingroup SequentialTwoPTwoCModel @@ -366,13 +368,18 @@ void FV2dTransport2P2CAdaptive::getMpfaFlux(Dune::FieldVector class FV3dPressure2P2CAdaptive using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; using BoundaryTypes = GetPropType; diff --git a/dumux/porousmediumflow/2p2c/sequential/fv3dtransportadaptive.hh b/dumux/porousmediumflow/2p2c/sequential/fv3dtransportadaptive.hh index 4e505d0e70..e18141fe40 100644 --- a/dumux/porousmediumflow/2p2c/sequential/fv3dtransportadaptive.hh +++ b/dumux/porousmediumflow/2p2c/sequential/fv3dtransportadaptive.hh @@ -33,6 +33,8 @@ #include "adaptiveproperties.hh" #include "fvtransport.hh" +#include + namespace Dumux { /*! * \ingroup SequentialTwoPTwoCModel @@ -57,7 +59,6 @@ class FV3dTransport2P2CAdaptive : public FVTransport2P2C using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; using BoundaryTypes = GetPropType; @@ -364,13 +365,18 @@ void FV3dTransport2P2CAdaptive::getMpfaFlux(Dune::FieldVector #include +#include + namespace Dumux { /*! * \ingroup SequentialTwoPTwoCModel @@ -79,7 +81,6 @@ template class FVPressure2P2C using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; using BoundaryTypes = GetPropType; @@ -677,6 +678,11 @@ void FVPressure2P2C::getFluxOnBoundary(Dune::FieldVector& en PhaseVector pressBC(0.); Scalar pcBound (0.); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = problem().spatialParams.fluidMatrixInteractionAtPos(elementI.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem().spatialParams(), elementI); + /********** Dirichlet Boundary *************/ if (bcType.isDirichlet(Indices::pressureEqIdx)) { @@ -754,11 +760,9 @@ void FVPressure2P2C::getFluxOnBoundary(Dune::FieldVector& en else if(getPropValue() == Indices::permDependent) { lambdaWBound - = MaterialLaw::krw(problem().spatialParams().materialLawParams(elementI), - BCfluidState.saturation(wPhaseIdx)) / viscosityWBound; + = fluidMatrixInteraction.krw(BCfluidState.saturation(wPhaseIdx)) / viscosityWBound; lambdaNWBound - = MaterialLaw::krn(problem().spatialParams().materialLawParams(elementI), - BCfluidState.saturation(wPhaseIdx)) / viscosityNWBound; + = fluidMatrixInteraction.krn(BCfluidState.saturation(wPhaseIdx)) / viscosityNWBound; } // get average density Scalar rhoMeanW = 0.5 * (cellDataI.density(wPhaseIdx) + densityWBound); @@ -953,6 +957,13 @@ void FVPressure2P2C::updateMaterialLawsInElement(const Element& element PhaseVector pressure; CompositionalFlash flashSolver; + + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = problem().spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem().spatialParams(), element); + + if(getPropValue()) // iterate capillary pressure and saturation { unsigned int maxiter = 6; @@ -981,8 +992,7 @@ void FVPressure2P2C::updateMaterialLawsInElement(const Element& element // calculate new pc Scalar oldPc = pc; - pc = MaterialLaw::pc(problem().spatialParams().materialLawParams(element), - fluidState.saturation(wPhaseIdx)); + pc = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); if (fabs(oldPc-pc)<10 && iter != 0) break; @@ -999,11 +1009,9 @@ void FVPressure2P2C::updateMaterialLawsInElement(const Element& element } // initialize mobilities - cellData.setMobility(wPhaseIdx, MaterialLaw::krw(problem().spatialParams().materialLawParams(element), - fluidState.saturation(wPhaseIdx)) + cellData.setMobility(wPhaseIdx, fluidMatrixInteraction.krw(fluidState.saturation(wPhaseIdx)) / cellData.viscosity(wPhaseIdx)); - cellData.setMobility(nPhaseIdx, MaterialLaw::krn(problem().spatialParams().materialLawParams(element), - fluidState.saturation(wPhaseIdx)) + cellData.setMobility(nPhaseIdx, fluidMatrixInteraction.krn(fluidState.saturation(wPhaseIdx)) / cellData.viscosity(nPhaseIdx)); // determine volume mismatch between actual fluid volume and pore volume diff --git a/dumux/porousmediumflow/2p2c/sequential/fvpressurecompositional.hh b/dumux/porousmediumflow/2p2c/sequential/fvpressurecompositional.hh index f99bd8dad9..e0734b718f 100644 --- a/dumux/porousmediumflow/2p2c/sequential/fvpressurecompositional.hh +++ b/dumux/porousmediumflow/2p2c/sequential/fvpressurecompositional.hh @@ -34,6 +34,8 @@ #include #include +#include + namespace Dumux { /*! * \ingroup SequentialTwoPTwoCModel @@ -78,9 +80,6 @@ template class FVPressureCompositional using FluidSystem = GetPropType; using FluidState = GetPropType; - ///@cond false - using MaterialLaw = typename GetPropType::MaterialLaw; - ///@endcond using CellData = GetPropType; enum @@ -547,6 +546,11 @@ void FVPressureCompositional::initialMaterialLaws(bool compositional) FluidState& fluidState = cellData.manipulateFluidState(); CompositionalFlash flashSolver; + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element); + // initial conditions PhaseVector pressure(0.); Scalar sat_0=0.; @@ -579,8 +583,7 @@ void FVPressureCompositional::initialMaterialLaws(bool compositional) Scalar pc=0.; if(getPropValue()) { - pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), - sat_0); + pc = fluidMatrixInteraction.pc(sat_0); } else pc = 0.; @@ -640,16 +643,14 @@ void FVPressureCompositional::initialMaterialLaws(bool compositional) Scalar oldPc = pc; //update with better pressures flashSolver.concentrationFlash2p2c(fluidState, Z0, pressure, problem_.temperatureAtPos(globalPos)); - pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), - fluidState.saturation(wPhaseIdx)); + pc = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); // TODO: get right criterion, do output for evaluation //converge criterion using std::abs; if (abs(oldPc - pc) < 10.0) iter = maxiter; - pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), - fluidState.saturation(wPhaseIdx)); + pc = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx)); } } else // capillary pressure neglected @@ -667,11 +668,9 @@ void FVPressureCompositional::initialMaterialLaws(bool compositional) problem_.transportModel().totalConcentration(nCompIdx,eIdxGlobal) = cellData.massConcentration(nCompIdx); // initialize mobilities - cellData.setMobility(wPhaseIdx, MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), - fluidState.saturation(wPhaseIdx)) + cellData.setMobility(wPhaseIdx, fluidMatrixInteraction.krw(fluidState.saturation(wPhaseIdx)) / cellData.viscosity(wPhaseIdx)); - cellData.setMobility(nPhaseIdx, MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), - fluidState.saturation(wPhaseIdx)) + cellData.setMobility(nPhaseIdx, fluidMatrixInteraction.krn(fluidState.saturation(wPhaseIdx)) / cellData.viscosity(nPhaseIdx)); // calculate perimeter used as weighting factor diff --git a/dumux/porousmediumflow/2p2c/sequential/fvpressuremultiphysics.hh b/dumux/porousmediumflow/2p2c/sequential/fvpressuremultiphysics.hh index ed873d286d..2b6540239f 100644 --- a/dumux/porousmediumflow/2p2c/sequential/fvpressuremultiphysics.hh +++ b/dumux/porousmediumflow/2p2c/sequential/fvpressuremultiphysics.hh @@ -31,6 +31,8 @@ #include #include +#include + namespace Dumux { /*! * \ingroup SequentialTwoPTwoCModel @@ -75,7 +77,6 @@ class FVPressure2P2CMultiPhysics : public FVPressure2P2C using Problem = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; using BoundaryTypes = GetPropType; @@ -700,23 +701,23 @@ void FVPressure2P2CMultiPhysics::get1pFluxOnBoundary(Dune::FieldVector< Scalar lambdaBound = 0.; switch (getPropValue()) { - case Indices::satDependent: + case Indices::satDependent: { - lambdaBound = BCfluidState.saturation(phaseIdx) - / viscosityBound; - break; + lambdaBound = BCfluidState.saturation(phaseIdx) / viscosityBound; + break; } - case Indices::permDependent: + case Indices::permDependent: { - if (phaseIdx == wPhaseIdx) - lambdaBound = MaterialLaw::krw( - problem().spatialParams().materialLawParams(elementI), BCfluidState.saturation(wPhaseIdx)) - / viscosityBound; - else - lambdaBound = MaterialLaw::krn( - problem().spatialParams().materialLawParams(elementI), BCfluidState.saturation(wPhaseIdx)) - / viscosityBound; - break; + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = problem().spatialParams.fluidMatrixInteractionAtPos(elementI.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem().spatialParams(), elementI); + + if (phaseIdx == wPhaseIdx) + lambdaBound = fluidMatrixInteraction.krw(BCfluidState.saturation(wPhaseIdx)) / viscosityBound; + else + lambdaBound = fluidMatrixInteraction.krn(BCfluidState.saturation(wPhaseIdx)) / viscosityBound; + break; } } Scalar rhoMean = 0.5 * (cellDataI.density(phaseIdx) + densityBound); @@ -931,14 +932,18 @@ void FVPressure2P2CMultiPhysics::update1pMaterialLawsInElement(const El // acess the simple fluid state and prepare for manipulation auto& pseudoFluidState = cellData.manipulateSimpleFluidState(); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = problem().spatialParams.fluidMatrixInteractionAtPos(elementI.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem().spatialParams(), elementI); + // prepare phase pressure for fluid state // both phase pressures are necessary for the case 1p domain is assigned for // the next 2p subdomain PhaseVector pressure(0.); Scalar pc = 0; if(getPropValue()) - pc = MaterialLaw::pc(problem().spatialParams().materialLawParams(elementI), - ((presentPhaseIdx == wPhaseIdx) ? 1. : 0.)); // assign sw = 1 if wPhase present, else 0 + pc = fluidMatrixInteraction.pc(((presentPhaseIdx == wPhaseIdx) ? 1. : 0.)); // assign sw = 1 if wPhase present, else 0 if(pressureType == wPhaseIdx) { pressure[wPhaseIdx] = this->pressure(eIdxGlobal); @@ -970,15 +975,13 @@ void FVPressure2P2CMultiPhysics::update1pMaterialLawsInElement(const El if(presentPhaseIdx == wPhaseIdx) { cellData.setMobility(wPhaseIdx, - MaterialLaw::krw(problem().spatialParams().materialLawParams(elementI), pseudoFluidState.saturation(wPhaseIdx)) - / cellData.viscosity(wPhaseIdx)); + fluidMatrixInteraction.krw(pseudoFluidState.saturation(wPhaseIdx)) / cellData.viscosity(wPhaseIdx)); cellData.setMobility(nPhaseIdx, 0.); } else { cellData.setMobility(nPhaseIdx, - MaterialLaw::krn(problem().spatialParams().materialLawParams(elementI), pseudoFluidState.saturation(wPhaseIdx)) - / cellData.viscosity(nPhaseIdx)); + fluidMatrixInteraction.krn(pseudoFluidState.saturation(wPhaseIdx)) / cellData.viscosity(nPhaseIdx)); cellData.setMobility(wPhaseIdx, 0.); } diff --git a/dumux/porousmediumflow/2p2c/sequential/fvtransport.hh b/dumux/porousmediumflow/2p2c/sequential/fvtransport.hh index 3bd9aa0be4..eff7ac11f3 100644 --- a/dumux/porousmediumflow/2p2c/sequential/fvtransport.hh +++ b/dumux/porousmediumflow/2p2c/sequential/fvtransport.hh @@ -35,6 +35,8 @@ #include #include +#include + namespace Dumux { /*! * \ingroup SequentialTwoPTwoCModel @@ -64,7 +66,6 @@ class FVTransport2P2C using Implementation = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; using Indices = typename GetPropType::Indices; using BoundaryTypes = GetPropType; @@ -598,13 +599,18 @@ void FVTransport2P2C::getFlux(ComponentVector& fluxEntries, Scalar pcI = cellDataI.capillaryPressure(); DimMatrix K_I(problem().spatialParams().intrinsicPermeability(elementI)); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = problem().spatialParams.fluidMatrixInteractionAtPos(elementI.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem().spatialParams(), elementI); + PhaseVector SmobI(0.); using std::max; SmobI[wPhaseIdx] = max((cellDataI.saturation(wPhaseIdx) - - problem().spatialParams().materialLawParams(elementI).swr()) + - fluidMatrixInteraction.pcSwCurve().effToAbsParams().swr()) , 1e-2); SmobI[nPhaseIdx] = max((cellDataI.saturation(nPhaseIdx) - - problem().spatialParams().materialLawParams(elementI).snr()) + - fluidMatrixInteraction.pcSwCurve().effToAbsParams().snr()) , 1e-2); Scalar densityWI (0.), densityNWI(0.); @@ -909,11 +915,16 @@ void FVTransport2P2C::getFluxOnBoundary(ComponentVector& fluxEntries, K_I[axis][axis] = minimalBoundaryPermeability; } + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = problem().spatialParams.fluidMatrixInteractionAtPos(elementI.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem().spatialParams(), elementI); + Scalar SwmobI = max((cellDataI.saturation(wPhaseIdx) - - problem().spatialParams().materialLawParams(elementI).swr()) + - fluidMatrixInteraction.pcSwCurve().effToAbsParams().swr()) , 1e-2); Scalar SnmobI = max((cellDataI.saturation(nPhaseIdx) - - problem().spatialParams().materialLawParams(elementI).snr()) + - fluidMatrixInteraction.pcSwCurve().effToAbsParams().snr()) , 1e-2); Scalar densityWI (0.), densityNWI(0.); @@ -1001,6 +1012,11 @@ void FVTransport2P2C::getFluxOnBoundary(ComponentVector& fluxEntries, potential[wPhaseIdx] *= fabs(K * unitOuterNormal); potential[nPhaseIdx] *= fabs(K * unitOuterNormal); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = problem().spatialParams.fluidMatrixInteractionAtPos(elementI.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem().spatialParams(), elementI); + // do upwinding for lambdas PhaseVector lambda(0.); if (potential[wPhaseIdx] >= 0.) @@ -1010,9 +1026,7 @@ void FVTransport2P2C::getFluxOnBoundary(ComponentVector& fluxEntries, if(getPropValue()==Indices::satDependent) lambda[wPhaseIdx] = BCfluidState.saturation(wPhaseIdx) / viscosityWBound; else - lambda[wPhaseIdx] = MaterialLaw::krw( - problem().spatialParams().materialLawParams(elementI), BCfluidState.saturation(wPhaseIdx)) - / viscosityWBound; + lambda[wPhaseIdx] = fluidMatrixInteraction.krw(BCfluidState.saturation(wPhaseIdx)) / viscosityWBound; } if (potential[nPhaseIdx] >= 0.) lambda[nPhaseIdx] = cellDataI.mobility(nPhaseIdx); @@ -1021,9 +1035,7 @@ void FVTransport2P2C::getFluxOnBoundary(ComponentVector& fluxEntries, if(getPropValue()==Indices::satDependent) lambda[nPhaseIdx] = BCfluidState.saturation(nPhaseIdx) / viscosityNWBound; else - lambda[nPhaseIdx] = MaterialLaw::krn( - problem().spatialParams().materialLawParams(elementI), BCfluidState.saturation(wPhaseIdx)) - / viscosityNWBound; + lambda[nPhaseIdx] = fluidMatrixInteraction.krn(BCfluidState.saturation(wPhaseIdx)) / viscosityNWBound; } // calculate and standardized velocity @@ -1117,16 +1129,21 @@ void FVTransport2P2C::evalBoundary(GlobalPosition globalPosFace, PrimaryVariables primaryVariablesOnBoundary(0.); problem().dirichlet(primaryVariablesOnBoundary, intersection); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteraction = problem().spatialParams.fluidMatrixInteractionAtPos(element.geometry().center()); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem().spatialParams(), element); + // read boundary type typename Indices::BoundaryFormulation bcType; problem().boundaryFormulation(bcType, intersection); if (bcType == Indices::saturation) { Scalar satBound = primaryVariablesOnBoundary[contiWEqIdx]; + if(getPropValue()) { - Scalar pcBound = MaterialLaw::pc(problem().spatialParams().materialLawParams(element), - satBound); + Scalar pcBound = fluidMatrixInteraction.pc(satBound); switch (pressureType) { case pw: @@ -1159,8 +1176,7 @@ void FVTransport2P2C::evalBoundary(GlobalPosition globalPosFace, if(getPropValue()) { - Scalar pcBound = MaterialLaw::pc(problem().spatialParams().materialLawParams(element), - BCfluidState.saturation(wPhaseIdx)); + Scalar pcBound = fluidMatrixInteraction.pc(BCfluidState.saturation(wPhaseIdx)); int maxiter = 3; //start iteration loop for(int iter=0; iter < maxiter; iter++) @@ -1189,8 +1205,7 @@ void FVTransport2P2C::evalBoundary(GlobalPosition globalPosFace, //update with better pressures flashSolver.concentrationFlash2p2c(BCfluidState, Z0Bound, pressBound, problem().temperatureAtPos(globalPosFace)); - pcBound = MaterialLaw::pc(problem().spatialParams().materialLawParams(element), - BCfluidState.saturation(wPhaseIdx)); + pcBound = fluidMatrixInteraction.pc(BCfluidState.saturation(wPhaseIdx)); // TODO: get right criterion, do output for evaluation //converge criterion using std::abs; -- GitLab From 0cae115f22f808d98702a03003b1c3d6028f8baf Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Mon, 26 Oct 2020 12:29:34 +0100 Subject: [PATCH 45/99] [test][2p][sequential] Adapt spatialParams --- .../buckleyleverettanalyticsolution.hh | 69 +++-------- .../sequential/mcwhorteranalyticsolution.hh | 19 ++- .../2p/sequential/test_3d2pspatialparams.hh | 58 +++------- .../2p/sequential/test_impes.input | 6 + .../2p/sequential/test_impesadaptive.input | 5 + .../test_impesadaptiverestart.input | 6 + .../test_impesadaptivespatialparams.hh | 52 +++------ .../2p/sequential/test_impesspatialparams.hh | 53 +++------ .../2p/sequential/test_impeswithamg.input | 8 +- .../2p/sequential/test_mpfa2pproblem.hh | 6 - .../2p/sequential/test_mpfa2pspatialparams.hh | 109 +++++++----------- .../2p/sequential/test_transport.input | 6 + .../sequential/test_transportspatialparams.hh | 43 +++---- 13 files changed, 151 insertions(+), 289 deletions(-) diff --git a/test/porousmediumflow/2p/sequential/buckleyleverettanalyticsolution.hh b/test/porousmediumflow/2p/sequential/buckleyleverettanalyticsolution.hh index 8a8114bb62..e54f31ba0d 100644 --- a/test/porousmediumflow/2p/sequential/buckleyleverettanalyticsolution.hh +++ b/test/porousmediumflow/2p/sequential/buckleyleverettanalyticsolution.hh @@ -24,9 +24,6 @@ #define DUMUX_BUCKLEYLEVERETT_ANALYTICAL_HH #include -#include -#include - namespace Dumux { @@ -36,33 +33,6 @@ namespace Dumux * the Buckley-Leverett problem */ -template -struct CheckMaterialLaw -{ - static bool isLinear() - { - return false; - } -}; - -template -struct CheckMaterialLaw > -{ - static bool isLinear() - { - return true; - } -}; - -template -struct CheckMaterialLaw > > -{ - static bool isLinear() - { - return true; - } -}; - /** * \file * \brief Analytical solution of the buckley-leverett problem @@ -74,8 +44,6 @@ template class BuckleyLeverettAnalytic using Scalar = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; - using MaterialLawParams = typename MaterialLaw::Params; using FluidSystem = GetPropType; using FluidState = GetPropType; @@ -119,10 +87,10 @@ private: void prepareAnalytic() { const auto& dummyElement = *problem_.gridView().template begin<0>(); - const MaterialLawParams& materialLawParams(problem_.spatialParams().materialLawParams(dummyElement)); + const auto& fluidMatrixInteraction = problem_->spatialParams().fluidMatrixInteractionAtPos(dummyElement.geometry().center()); - swr_ = materialLawParams.swr(); - snr_ = materialLawParams.snr(); + swr_ = fluidMatrixInteraction.effToAbsParams().swr(); + snr_ = fluidMatrixInteraction.effToAbsParams().snr(); Scalar porosity = problem_.spatialParams().porosity(dummyElement); FluidState fluidState; @@ -132,8 +100,7 @@ private: Scalar viscosityW = FluidSystem::viscosity(fluidState, wPhaseIdx); Scalar viscosityNW = FluidSystem::viscosity(fluidState, nPhaseIdx); - - if (CheckMaterialLaw::isLinear() && viscosityW == viscosityNW) + if constexpr (SpatialParams::pcSwCurveIsLinear() && viscosityW == viscosityNW) { std::pair entry; entry.first = 1 - snr_; @@ -145,32 +112,32 @@ private: else { Scalar sw0 = swr_; - Scalar fw0 = MaterialLaw::krw(materialLawParams, sw0)/viscosityW; - fw0 /= (fw0 + MaterialLaw::krn(materialLawParams, sw0)/viscosityNW); + Scalar fw0 = fluidMatrixInteraction.krw(sw0)/viscosityW; + fw0 /= (fw0 + fluidMatrixInteraction.krn(sw0)/viscosityNW); Scalar sw1 = sw0 + deltaS_; - Scalar fw1 = MaterialLaw::krw(materialLawParams, sw1)/viscosityW; - fw1 /= (fw1 + MaterialLaw::krn(materialLawParams, sw1)/viscosityNW); + Scalar fw1 = fluidMatrixInteraction.krw(sw1)/viscosityW; + fw1 /= (fw1 + fluidMatrixInteraction.krn(sw1)/viscosityNW); Scalar tangentSlopeOld = (fw1 - fw0)/(sw1 - sw0); sw1 += deltaS_; - fw1 = MaterialLaw::krw(materialLawParams, sw1)/viscosityW; - fw1 /= (fw1 + MaterialLaw::krn(materialLawParams, sw1)/viscosityNW); + fw1 = fluidMatrixInteraction.krw(sw1)/viscosityW; + fw1 /= (fw1 + fluidMatrixInteraction.krn(sw1)/viscosityNW); Scalar tangentSlopeNew = (fw1 - fw0)/(sw1 - sw0); while (tangentSlopeNew >= tangentSlopeOld && sw1 < (1.0 - snr_)) { tangentSlopeOld = tangentSlopeNew; sw1 += deltaS_; - fw1 = MaterialLaw::krw(materialLawParams, sw1)/viscosityW; - fw1 /= (fw1 + MaterialLaw::krn(materialLawParams, sw1)/viscosityNW); + fw1 = fluidMatrixInteraction.krw(sw1)/viscosityW; + fw1 /= (fw1 + fluidMatrixInteraction.krn(sw1)/viscosityNW); tangentSlopeNew = (fw1 - fw0)/(sw1 - sw0); } sw0 = sw1 - deltaS_; - fw0 = MaterialLaw::krw(materialLawParams, sw0)/viscosityW; - fw0 /= (fw0 + MaterialLaw::krn(materialLawParams, sw0)/viscosityNW); + fw0 = fluidMatrixInteraction.krw(sw0)/viscosityW; + fw0 /= (fw0 + fluidMatrixInteraction.krn(sw0)/viscosityNW); Scalar sw2 = sw1 + deltaS_; - Scalar fw2 = MaterialLaw::krw(materialLawParams, sw2)/viscosityW; - fw2 /= (fw2 + MaterialLaw::krn(materialLawParams, sw2)/viscosityNW); + Scalar fw2 = fluidMatrixInteraction.krw(sw2)/viscosityW; + fw2 /= (fw2 + fluidMatrixInteraction.krn(sw2)/viscosityNW); while (sw1 <= (1.0 - snr_)) { std::pair entry; @@ -188,8 +155,8 @@ private: fw1 = fw2; sw2 += deltaS_; - fw2 = MaterialLaw::krw(materialLawParams, sw2)/viscosityW; - fw2 /= (fw2 + MaterialLaw::krn(materialLawParams, sw2)/viscosityNW); + fw2 = fluidMatrixInteraction.krw(sw2)/viscosityW; + fw2 /= (fw2 + fluidMatrixInteraction.krn(sw2)/viscosityNW); } } diff --git a/test/porousmediumflow/2p/sequential/mcwhorteranalyticsolution.hh b/test/porousmediumflow/2p/sequential/mcwhorteranalyticsolution.hh index f2e9fe4caf..311dc2479c 100644 --- a/test/porousmediumflow/2p/sequential/mcwhorteranalyticsolution.hh +++ b/test/porousmediumflow/2p/sequential/mcwhorteranalyticsolution.hh @@ -47,8 +47,6 @@ class McWhorterAnalytic using Scalar = GetPropType; using SpatialParams = GetPropType; - using MaterialLaw = typename SpatialParams::MaterialLaw; - using MaterialLawParams = typename MaterialLaw::Params; using FluidSystem = GetPropType; using FluidState = GetPropType; @@ -132,10 +130,10 @@ private: void prepareAnalytic() { const auto& dummyElement = *problem_.gridView().template begin<0>(); - const MaterialLawParams& materialLawParams(problem_.spatialParams().materialLawParams(dummyElement)); + const auto& fluidMatrixInteraction = problem_->spatialParams().fluidMatrixInteractionAtPos(dummyElement.geometry().center()); - swr_ = materialLawParams.swr(); - snr_ = materialLawParams.snr(); + swr_ = fluidMatrixInteraction.effToAbsParams().swr(); + snr_ = fluidMatrixInteraction.effToAbsParams().snr(); porosity_ = problem_.spatialParams().porosity(dummyElement); permeability_ = problem_.spatialParams().intrinsicPermeability(dummyElement)[0][0]; PrimaryVariables initVec; @@ -165,17 +163,15 @@ private: // get fractional flow function vector for (int i=0; i #include -#include -#include -#include +#include namespace Dumux { @@ -48,16 +46,6 @@ struct TestIMPESSpatialParams {}; template struct SpatialParams { using type = TestIMPESSpatialParams; }; -// Set the material law -template -struct MaterialLaw -{ -private: - using Scalar = GetPropType; - using RawMaterialLaw = RegularizedBrooksCorey; -public: - using type = EffToAbsLaw; -}; } /*! @@ -80,10 +68,9 @@ class TestIMPESSpatialParams: public SequentialFVSpatialParams using GlobalPosition = typename Element::Geometry::GlobalCoordinate; -public: - using MaterialLaw = GetPropType; - using MaterialLawParams = typename MaterialLaw::Params; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; +public: Scalar intrinsicPermeability (const Element& element) const { @@ -95,36 +82,22 @@ public: return 0.2; } - - // return the parameter object for the Brooks-Corey material law which depends on the position -// const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - const MaterialLawParams& materialLawParams(const Element& element) const + /*! + * \brief Returns the parameters for the material law at a given location + * + * \param globalPos The global coordinates for the given location + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialLawParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } - TestIMPESSpatialParams(const Problem& problem) - : ParentType(problem) - { - // residual saturations - materialLawParams_.setSwr(0.2); - materialLawParams_.setSnr(0.2); - -// // parameters for the Brooks-Corey Law -// // entry pressures - materialLawParams_.setPe(0); -// // Brooks-Corey shape parameters - materialLawParams_.setLambda(2); - - // parameters for the linear - // entry pressures function -// materialLawParams_.setEntryPc(0); -// materialLawParams_.setMaxPc(0); - } + : ParentType(problem), pcKrSwCurve_("SpatialParams") + {} private: - MaterialLawParams materialLawParams_; + const PcKrSwCurve pcKrSwCurve_; }; } // end namespace diff --git a/test/porousmediumflow/2p/sequential/test_impeswithamg.input b/test/porousmediumflow/2p/sequential/test_impeswithamg.input index b28fbd28a0..60f65f7ee1 100644 --- a/test/porousmediumflow/2p/sequential/test_impeswithamg.input +++ b/test/porousmediumflow/2p/sequential/test_impeswithamg.input @@ -13,4 +13,10 @@ Name = test_impeswithamg # name passed to the output routines EnableGravity = 0 [Vtk] -OutputLevel = 0 \ No newline at end of file +OutputLevel = 0 + +[SpatialParams] +Swr = 0.2 +Snr = 0.2 +BrooksCoreyPcEntry = 0 +BrooksCoreyLambda = 2 diff --git a/test/porousmediumflow/2p/sequential/test_mpfa2pproblem.hh b/test/porousmediumflow/2p/sequential/test_mpfa2pproblem.hh index 964e6e2c67..7f7598a1d9 100644 --- a/test/porousmediumflow/2p/sequential/test_mpfa2pproblem.hh +++ b/test/porousmediumflow/2p/sequential/test_mpfa2pproblem.hh @@ -71,12 +71,6 @@ struct FVAdaptiveTwoPTest { using InheritsFrom = std::tuple; }; struct MPFALTwoPTest { using InheritsFrom = std::tuple; }; struct MPFALAdaptiveTwoPTest { using InheritsFrom = std::tuple; }; -// NEW_TYPE_TAG(FVTwoPTest, INHERITS_FROM(FVPressureTwoP, FVTransportTwoP, IMPESTwoP, MPFATwoPTest)); -// NEW_TYPE_TAG(FVAdaptiveTwoPTest, INHERITS_FROM(FVPressureTwoPAdaptive, FVTransportTwoP, IMPESTwoPAdaptive, MPFATwoPTest)); -// NEW_TYPE_TAG(MPFAOTwoPTest, INHERITS_FROM(FvMpfaO2dPressureTwoP, FVTransportTwoP, IMPESTwoP, MPFATwoPTest)); -// NEW_TYPE_TAG(MPFALTwoPTest, INHERITS_FROM(FvMpfaL2dPressureTwoP, FVTransportTwoP, IMPESTwoP, MPFATwoPTest)); -// NEW_TYPE_TAG(MPFALAdaptiveTwoPTest, INHERITS_FROM(FvMpfaL2dPressureTwoPAdaptive, FVTransportTwoP, IMPESTwoPAdaptive, MPFATwoPTest)); - } // end namespace TTag diff --git a/test/porousmediumflow/2p/sequential/test_mpfa2pspatialparams.hh b/test/porousmediumflow/2p/sequential/test_mpfa2pspatialparams.hh index ada177a294..9b52441ba2 100644 --- a/test/porousmediumflow/2p/sequential/test_mpfa2pspatialparams.hh +++ b/test/porousmediumflow/2p/sequential/test_mpfa2pspatialparams.hh @@ -25,9 +25,7 @@ #include #include -#include -#include - +#include namespace Dumux { @@ -46,18 +44,13 @@ struct Test2PSpatialParams {}; template struct SpatialParams { using type = Test2PSpatialParams; }; -// Set the material law -template -struct MaterialLaw -{ -private: - using Scalar = GetPropType; - using RawMaterialLaw = RegularizedBrooksCorey; -public: - using type = EffToAbsLaw; -}; } +// forward declaration +template +class LinearMaterialDefault; +class LinearMaterial; + /*! * \ingroup SequentialTwoPTests * \brief Test problem for the sequential 2p models @@ -81,9 +74,14 @@ class Test2PSpatialParams: public SequentialFVSpatialParams using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using FieldMatrix = Dune::FieldMatrix; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; + public: - using MaterialLaw = GetPropType; - using MaterialLawParams = typename MaterialLaw::Params; + + static constexpr bool pcSwCurveIsLinear() + { + return std::is_same_v || std::is_same_v; + } const FieldMatrix& intrinsicPermeabilityAtPos(const GlobalPosition& globalPos) const { @@ -108,17 +106,17 @@ public: #endif } - // return the brooks-corey context depending on the position - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + /*! + * \brief Returns the parameters for the material law at a given location + * + * \param globalPos The global coordinates for the given location + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - if (isLensOne(globalPos)) - return materialLawParamsLenses_; - else if (isLensTwo(globalPos)) - return materialLawParamsLenses_; - else if (isLensThree(globalPos)) - return materialLawParamsLenses_; + if (isLensOne(globalPos) || isLensTwo(globalPos) || isLensThree(globalPos)) + return makeFluidMatrixInteraction(*pcKrSwCurveLenses_); else - return materialLawParamsBackground_; + return makeFluidMatrixInteraction(*pcKrSwCurveBackground_); } Test2PSpatialParams(const Problem& problem) : @@ -126,53 +124,25 @@ public: lensOneLowerLeft_(0), lensOneUpperRight_(0), lensTwoLowerLeft_(0), lensTwoUpperRight_(0), lensThreeLowerLeft_(0), lensThreeUpperRight_(0) { #if PROBLEM == 0 - // residual saturations - materialLawParamsBackground_.setSwr(0.2); - materialLawParamsBackground_.setSnr(0.2); - - materialLawParamsLenses_.setSwr(0.2); - materialLawParamsLenses_.setSnr(0.2); - - //parameters for Brooks-Corey law + typename PcKrSwCurve::BasicParams params(0/*pe*/, 2/*lambda*/); + typename PcKrSwCurve::EffToAbsParams effToAbsParams(0.2/*swr*/, 0.2/*snr*/); + pcKrSwCurveBackground_ = std::make_unique(params, effToAbsParams); + pcKrSwCurveLenses_ = std::make_unique(params, effToAbsParams); - // entry pressures function - materialLawParamsBackground_.setPe(0.); - materialLawParamsLenses_.setPe(0.); #elif PROBLEM == 1 - // residual saturations - materialLawParamsBackground_.setSwr(0.); - materialLawParamsBackground_.setSnr(0.); + typename PcKrSwCurve::BasicParams params(5000/*pe*/, 2/*lambda*/); + typename PcKrSwCurve::EffToAbsParams effToAbsParams(0/*swr*/, 0/*snr*/); + pcKrSwCurveBackground_ = std::make_unique(params, effToAbsParams); + pcKrSwCurveLenses_ = std::make_unique(params, effToAbsParams); - materialLawParamsLenses_.setSwr(0.); - materialLawParamsLenses_.setSnr(0.); - - //parameters for Brooks-Corey law - - // entry pressures function - materialLawParamsBackground_.setPe(5000.); - materialLawParamsLenses_.setPe(5000.); #else - // residual saturations - materialLawParamsBackground_.setSwr(0.); - materialLawParamsBackground_.setSnr(0.); - - materialLawParamsLenses_.setSwr(0.); - materialLawParamsLenses_.setSnr(0.); - - //parameters for Brooks-Corey law - - // entry pressures - materialLawParamsBackground_.setPe(getParam("SpatialParams.BackgroundEntryPressure", 0.0)); - materialLawParamsLenses_.setPe(getParam("SpatialParams.LenseEntryPressure", 0.0)); -#endif - - // Brooks-Corey shape parameters -#if PROBLEM == 2 - materialLawParamsBackground_.setLambda(getParam("SpatialParams.BackgroundLambda", 3.0)); - materialLawParamsLenses_.setLambda(getParam("SpatialParams.LenseLambda", 2.0)); -#else - materialLawParamsBackground_.setLambda(2.0); - materialLawParamsLenses_.setLambda(2.0); + typename PcKrSwCurve::BasicParams paramsBackground(getParam("SpatialParams.BackgroundEntryPressure", 0.0), + getParam("SpatialParams.BackgroundLambda", 3.0)); + typename PcKrSwCurve::BasicParams paramsLenses(getParam("SpatialParams.LenseEntryPressure", 0.0), + getParam("SpatialParams.LenseLambda", 2.0)); + typename PcKrSwCurve::EffToAbsParams effToAbsParams(0/*swr*/, 0/*snr*/); + pcKrSwCurveBackground_ = std::make_unique(paramsBackground, effToAbsParams); + pcKrSwCurveLenses_ = std::make_unique(paramsLenses, effToAbsParams); #endif #if PROBLEM == 0 @@ -240,8 +210,9 @@ private: return true; } - MaterialLawParams materialLawParamsBackground_; - MaterialLawParams materialLawParamsLenses_; + std::unique_ptr pcKrSwCurveBackground_; + std::unique_ptr pcKrSwCurveLenses_; + FieldMatrix permBackground_; FieldMatrix permLenses_; GlobalPosition lensOneLowerLeft_; diff --git a/test/porousmediumflow/2p/sequential/test_transport.input b/test/porousmediumflow/2p/sequential/test_transport.input index 2c59caec82..fd79b3f2eb 100644 --- a/test/porousmediumflow/2p/sequential/test_transport.input +++ b/test/porousmediumflow/2p/sequential/test_transport.input @@ -11,3 +11,9 @@ LiquidKinematicViscosity = 1.0 [Grid] File = ./grids/test_transport.dgf + +[SpatialParams] +Swr = 0 +Snr = 0 +LinearPcEntry = 0 +LinearPcMax = 0 diff --git a/test/porousmediumflow/2p/sequential/test_transportspatialparams.hh b/test/porousmediumflow/2p/sequential/test_transportspatialparams.hh index ef1d19dd80..77a915c561 100644 --- a/test/porousmediumflow/2p/sequential/test_transportspatialparams.hh +++ b/test/porousmediumflow/2p/sequential/test_transportspatialparams.hh @@ -27,8 +27,6 @@ #include #include #include -#include -#include namespace Dumux { @@ -51,16 +49,6 @@ struct TestTransportSpatialParams {}; template struct SpatialParams { using type = TestTransportSpatialParams; }; -// Set the material law -template -struct MaterialLaw -{ -private: - using Scalar = GetPropType; - using RawMaterialLaw = LinearMaterial; -public: - using type = EffToAbsLaw; -}; } /*! @@ -77,10 +65,12 @@ class TestTransportSpatialParams: public SequentialFVSpatialParams using Scalar = GetPropType; using Element = typename Grid::Traits::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + using PcKrSwCurve = FluidMatrix::LinearMaterialDefault; public: - using MaterialLaw = GetPropType; - using MaterialLawParams = typename MaterialLaw::Params; + Scalar intrinsicPermeability (const Element& element) const { @@ -92,28 +82,21 @@ public: return 0.2; } - - // return the parameter object for the Brooks-Corey material law which depends on the position - const MaterialLawParams& materialLawParams(const Element &element) const + /*! + * \brief Returns the parameters for the material law at a given location + * \param globalPos A global coordinate vector + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const { - return materialLawParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } - TestTransportSpatialParams(const Problem& problem) - : ParentType(problem) - { - // residual saturations - materialLawParams_.setSwr(0.0); - materialLawParams_.setSnr(0.0); - - // parameters for the linear entry pressures function - materialLawParams_.setEntryPc(0); - materialLawParams_.setMaxPc(0); - } + : ParentType(problem), pcKrSwCurve_("SpatialParams") + {} private: - MaterialLawParams materialLawParams_; + const PcKrSwCurve pcKrSwCurve_; }; } // end namespace -- GitLab From e6d6df3ac6f683095bbae7ffdc50e4298c733668 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Mon, 26 Oct 2020 12:56:54 +0100 Subject: [PATCH 46/99] [test][2p2c][sequential] Adapt spatialParams --- .../2p2c/implicit/waterair/spatialparams.hh | 6 +-- .../sequential/test_dec2p2c_spatialparams.hh | 43 +++++++------------ .../2pnc/implicit/diffusion/spatialparams.hh | 3 -- 3 files changed, 18 insertions(+), 34 deletions(-) diff --git a/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh b/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh index fa6f8a26b9..f39d59d99c 100644 --- a/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh @@ -136,10 +136,8 @@ public: /*! - * \brief Returns the parameter object for the Brooks-Corey material law - * which depends on the position - * - * \param globalPos The global position + * \brief Returns the parameters for the material law at a given location + * \param globalPos The global coordinates for the given location */ const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { diff --git a/test/porousmediumflow/2p2c/sequential/test_dec2p2c_spatialparams.hh b/test/porousmediumflow/2p2c/sequential/test_dec2p2c_spatialparams.hh index 5aea20656e..1843367baf 100644 --- a/test/porousmediumflow/2p2c/sequential/test_dec2p2c_spatialparams.hh +++ b/test/porousmediumflow/2p2c/sequential/test_dec2p2c_spatialparams.hh @@ -28,7 +28,6 @@ #include #include #include -#include namespace Dumux { @@ -47,16 +46,6 @@ struct Test2P2CSpatialParams {}; template struct SpatialParams { using type = Test2P2CSpatialParams; }; -// Set the material law -template -struct MaterialLaw -{ -private: - using Scalar = GetPropType; - using RawMaterialLaw = LinearMaterial; -public: - using type = EffToAbsLaw; -}; } /*! @@ -72,12 +61,13 @@ class Test2P2CSpatialParams : public SequentialFVSpatialParams enum { dim = GridView::dimension }; using Element = typename GridView::Traits::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using FieldMatrix = Dune::FieldMatrix; + using PcKrSwCurve = FluidMatrix::LinearMaterialDefault; + public: - using MaterialLaw = GetPropType; - using MaterialLawParams = typename MaterialLaw::Params; const FieldMatrix& intrinsicPermeability (const Element& element) const { @@ -89,23 +79,22 @@ public: return 0.2; } - - // return the parameter object for the Brooks-Corey material law which depends on the position - const MaterialLawParams& materialLawParams(const Element &element) const + /*! + * \brief Returns the parameters for the material law at a given location + * + * \param globalPos The global coordinates for the given location + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialLawParams_; + return makeFluidMatrixInteraction(*pcKrSwCurve_); } - - Test2P2CSpatialParams(const Problem& problem) : SequentialFVSpatialParams(problem), - constPermeability_(0) + Test2P2CSpatialParams(const Problem& problem) + : SequentialFVSpatialParams(problem) + , constPermeability_(0) { - // residual saturations - materialLawParams_.setSwr(0); - materialLawParams_.setSnr(0); - - materialLawParams_.setEntryPc(0); - materialLawParams_.setMaxPc(10000); + typename PcKrSwCurve::BasicParams params(0/*pcEntry*/, 10000/*pcMax*/); + pcKrSwCurve_ = std::make_unique(params); for(int i = 0; i < dim; i++) { @@ -114,8 +103,8 @@ public: } private: - MaterialLawParams materialLawParams_; FieldMatrix constPermeability_; + std::unique_ptr pcKrSwCurve_; }; diff --git a/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh b/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh index d2bfb0e874..71cf16416c 100644 --- a/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh +++ b/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh @@ -87,9 +87,6 @@ public: /*! * \brief Returns the parameters for the material law at a given location * - * This method is not actually required by the Richards model, but provided - * for the convenience of the RichardsLensProblem - * * \param globalPos The global coordinates for the given location */ auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const -- GitLab From b28bc9a7f953bc42e3f07f436463ad6a414aaba6 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 13:29:04 +0100 Subject: [PATCH 47/99] [test][1p][sequential] Adapt spatial params --- .../1p/sequential/test_diffusion.input | 4 ++ .../1p/sequential/test_diffusion3d.input | 4 ++ .../test_diffusion3d_reference.input | 4 ++ .../sequential/test_diffusionspatialparams.hh | 43 +++++++------------ .../test_diffusionspatialparams3d.hh | 40 ++++++----------- 5 files changed, 40 insertions(+), 55 deletions(-) diff --git a/test/porousmediumflow/1p/sequential/test_diffusion.input b/test/porousmediumflow/1p/sequential/test_diffusion.input index bb3e7d6221..11347cafdf 100644 --- a/test/porousmediumflow/1p/sequential/test_diffusion.input +++ b/test/porousmediumflow/1p/sequential/test_diffusion.input @@ -13,3 +13,7 @@ LiquidKinematicViscosity = 1.0 [LinearSolver.Preconditioner] Iterations = 2 + +[SpatialParams] +LinearPcEntry = 0 +LinearPcMax = 0 diff --git a/test/porousmediumflow/1p/sequential/test_diffusion3d.input b/test/porousmediumflow/1p/sequential/test_diffusion3d.input index 86a65843f1..a524d48095 100644 --- a/test/porousmediumflow/1p/sequential/test_diffusion3d.input +++ b/test/porousmediumflow/1p/sequential/test_diffusion3d.input @@ -15,3 +15,7 @@ RefinementRatio = 0 GMResRestart = 80 MaxIterations = 1000 ResidualReduction = 1e-8 + +[SpatialParams] +LinearPcEntry = 0 +LinearPcMax = 0 diff --git a/test/porousmediumflow/1p/sequential/test_diffusion3d_reference.input b/test/porousmediumflow/1p/sequential/test_diffusion3d_reference.input index 69a160a2f3..b17075925c 100644 --- a/test/porousmediumflow/1p/sequential/test_diffusion3d_reference.input +++ b/test/porousmediumflow/1p/sequential/test_diffusion3d_reference.input @@ -14,3 +14,7 @@ RefinementRatio = 0 GMResRestart = 80 MaxIterations = 1000 ResidualReduction = 1e-8 + +[SpatialParams] +LinearPcEntry = 0 +LinearPcMax = 0 diff --git a/test/porousmediumflow/1p/sequential/test_diffusionspatialparams.hh b/test/porousmediumflow/1p/sequential/test_diffusionspatialparams.hh index 7fd27e7dc2..0cb1c59956 100644 --- a/test/porousmediumflow/1p/sequential/test_diffusionspatialparams.hh +++ b/test/porousmediumflow/1p/sequential/test_diffusionspatialparams.hh @@ -28,7 +28,6 @@ #include #include #include -#include namespace Dumux { @@ -48,16 +47,6 @@ struct TestDiffusionSpatialParams {}; template struct SpatialParams { using type = TestDiffusionSpatialParams; }; -// Set the material law -template -struct MaterialLaw -{ -private: - using Scalar = GetPropType; - using RawMaterialLaw = LinearMaterial; -public: - using type = EffToAbsLaw; -}; } /*! @@ -84,9 +73,9 @@ class TestDiffusionSpatialParams: public SequentialFVSpatialParams using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using FieldMatrix = Dune::FieldMatrix; + using PcKrSwCurve = FluidMatrix::LinearMaterialDefault; + public: - using MaterialLaw = GetPropType; - using MaterialLawParams = typename MaterialLaw::Params; const FieldMatrix& intrinsicPermeability (const Element& element) const { @@ -98,11 +87,14 @@ public: return 0.2; } - - // return the parameter object for the Brooks-Corey material law which depends on the position - const MaterialLawParams& materialLawParams(const Element &element) const + /*! + * \brief Returns the parameters for the material law at a given location + * + * \param globalPos The global coordinates for the given location + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialLawParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } void initialize(const double delta) @@ -140,16 +132,11 @@ public: } TestDiffusionSpatialParams(const Problem& problem) - : ParentType(problem),gridView_(problem.gridView()), indexSet_(problem.gridView().indexSet()), permeability_(0) - { - // residual saturations - materialLawParams_.setSwr(0.0); - materialLawParams_.setSnr(0.0); - - // parameters for the linear entry pressure function - materialLawParams_.setEntryPc(0); - materialLawParams_.setMaxPc(0); - } + : ParentType(problem),gridView_(problem.gridView()) + , indexSet_(problem.gridView().indexSet()) + , pcKrSwCurve_("SpatialParams") + , permeability_(0) + {} private: void perm (FieldMatrix& perm, const GlobalPosition& globalPos) const @@ -163,7 +150,7 @@ private: const GridView gridView_; const IndexSet& indexSet_; - MaterialLawParams materialLawParams_; + const PcKrSwCurve pcKrSwCurve_; std::vector permeability_; double delta_; }; diff --git a/test/porousmediumflow/1p/sequential/test_diffusionspatialparams3d.hh b/test/porousmediumflow/1p/sequential/test_diffusionspatialparams3d.hh index 58fee09815..11694890da 100644 --- a/test/porousmediumflow/1p/sequential/test_diffusionspatialparams3d.hh +++ b/test/porousmediumflow/1p/sequential/test_diffusionspatialparams3d.hh @@ -27,7 +27,6 @@ #include #include #include -#include namespace Dumux { @@ -47,16 +46,6 @@ struct TestDiffusionSpatialParams3d {}; template struct SpatialParams { using type = TestDiffusionSpatialParams3d; }; -// Set the material law -template -struct MaterialLaw -{ -private: - using Scalar = GetPropType; - using RawMaterialLaw = LinearMaterial; -public: - using type = EffToAbsLaw; -}; } /*! @@ -80,9 +69,9 @@ class TestDiffusionSpatialParams3d: public SequentialFVSpatialParams using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using FieldMatrix = Dune::FieldMatrix; + using PcKrSwCurve = FluidMatrix::LinearMaterialDefault; + public: - using MaterialLaw = GetPropType; - using MaterialLawParams = typename MaterialLaw::Params; const FieldMatrix& intrinsicPermeabilityAtPos (const GlobalPosition& globalPos) const { @@ -94,31 +83,28 @@ public: return 1.0; } - - // return the parameter object for the Brooks-Corey material law which depends on the position - const MaterialLawParams& materialLawParams(const Element &element) const + /*! + * \brief Returns the parameters for the material law at a given location + * + * \param globalPos The global coordinates for the given location + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialLawParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } TestDiffusionSpatialParams3d(const Problem& problem) - : ParentType(problem), permeability_(0) + : ParentType(problem) + , pcKrSwCurve_("SpatialParams") + , permeability_(0) { - // residual saturations - materialLawParams_.setSwr(0.0); - materialLawParams_.setSnr(0.0); - - // parameters for the linear entry pressure function - materialLawParams_.setEntryPc(0); - materialLawParams_.setMaxPc(0); - // permeability values permeability_[0][0] = permeability_[1][1] = permeability_[2][2] = 1.0; permeability_[0][1] = permeability_[1][0] = permeability_[1][2] = permeability_[2][1] = 0.5; } private: - MaterialLawParams materialLawParams_; + const PcKrSwCurve pcKrSwCurve_; FieldMatrix permeability_; }; -- GitLab From d933487d6a87cff27509c314e3300e756796251f Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 15:07:23 +0100 Subject: [PATCH 48/99] [test][2p][cmake] Use correct executable --- test/porousmediumflow/2p/implicit/incompressible/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/porousmediumflow/2p/implicit/incompressible/CMakeLists.txt b/test/porousmediumflow/2p/implicit/incompressible/CMakeLists.txt index 3175b589b7..4ba02c91be 100644 --- a/test/porousmediumflow/2p/implicit/incompressible/CMakeLists.txt +++ b/test/porousmediumflow/2p/implicit/incompressible/CMakeLists.txt @@ -55,7 +55,7 @@ dumux_add_test(NAME test_2p_incompressible_box_analytic CMD_ARGS --script fuzzy --files ${CMAKE_SOURCE_DIR}/test/references/test_2p_incompressible_box-reference.vtu ${CMAKE_CURRENT_BINARY_DIR}/test_2p_incompressible_box_analytic-00007.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_2p_incompressible_box params.input -Problem.Name test_2p_incompressible_box_analytic -Newton.EnablePartialReassembly false") + --command "${CMAKE_CURRENT_BINARY_DIR}/test_2p_incompressible_box_analytic params.input -Problem.Name test_2p_incompressible_box_analytic -Newton.EnablePartialReassembly false") # using box with interface solver dumux_add_test(NAME test_2p_incompressible_box_ifsolver -- GitLab From e7e9c978eb30f474f2feb1708975416020274d1e Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 15:08:12 +0100 Subject: [PATCH 49/99] [2p][incompressiblelocalresidual] Adapt to new material law --- .../2p/incompressiblelocalresidual.hh | 102 ++++++++++++------ 1 file changed, 71 insertions(+), 31 deletions(-) diff --git a/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh b/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh index 5cd473eaf8..06779218e9 100644 --- a/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh +++ b/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh @@ -38,6 +38,8 @@ #include #include +#include + namespace Dumux { /*! @@ -169,7 +171,6 @@ public: static_assert(ModelTraits::priVarFormulation() == TwoPFormulation::p0s1, "2p/incompressiblelocalresidual.hh: Analytic differentiation has to be checked for p1-s0 formulation!"); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; using AdvectionType = GetPropType; // evaluate the current wetting phase Darcy flux and resulting upwind weights @@ -189,12 +190,23 @@ public: const auto& outsideScv = fvGeometry.scv(outsideScvIdx); const auto& insideVolVars = curElemVolVars[insideScvIdx]; const auto& outsideVolVars = curElemVolVars[outsideScvIdx]; - const auto& insideMaterialParams = problem.spatialParams().materialLawParams(element, - insideScv, - elementSolution(insideVolVars.priVars())); - const auto& outsideMaterialParams = problem.spatialParams().materialLawParams(outsideElement, - outsideScv, - elementSolution(outsideVolVars.priVars())); + + // old material law interface is deprecated: Replace this by + // const auto& insidefluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, + // insideScv, + // elementSolution(insideVolVars.priVars())); + // const auto& outsidefluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(outsideElement, + // outsideScv, + // elementSolution(outsideVolVars.priVars())); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto& insidefluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), + element, + insideScv, + elementSolution(insideVolVars.priVars())); + const auto& outsidefluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), + outsideElement, + outsideScv, + elementSolution(outsideVolVars.priVars())); // get references to the two participating derivative matrices auto& dI_dI = derivativeMatrices[insideScvIdx]; @@ -213,12 +225,12 @@ public: // derivative w.r.t. to Sn is the negative of the one w.r.t. Sw const auto insideSw = insideVolVars.saturation(0); const auto outsideSw = outsideVolVars.saturation(0); - const auto dKrw_dSn_inside = -1.0*MaterialLaw::dkrw_dsw(insideMaterialParams, insideSw); - const auto dKrw_dSn_outside = -1.0*MaterialLaw::dkrw_dsw(outsideMaterialParams, outsideSw); - const auto dKrn_dSn_inside = -1.0*MaterialLaw::dkrn_dsw(insideMaterialParams, insideSw); - const auto dKrn_dSn_outside = -1.0*MaterialLaw::dkrn_dsw(outsideMaterialParams, outsideSw); - const auto dpc_dSn_inside = -1.0*MaterialLaw::dpc_dsw(insideMaterialParams, insideSw); - const auto dpc_dSn_outside = -1.0*MaterialLaw::dpc_dsw(outsideMaterialParams, outsideSw); + const auto dKrw_dSn_inside = -1.0*insidefluidMatrixInteraction.dkrw_dsw(insideSw); + const auto dKrw_dSn_outside = -1.0*outsidefluidMatrixInteraction.dkrw_dsw(outsideSw); + const auto dKrn_dSn_inside = -1.0*insidefluidMatrixInteraction.dkrn_dsw(insideSw); + const auto dKrn_dSn_outside = -1.0*outsidefluidMatrixInteraction.dkrn_dsw(outsideSw); + const auto dpc_dSn_inside = -1.0*insidefluidMatrixInteraction.dpc_dsw(insideSw); + const auto dpc_dSn_outside = -1.0*outsidefluidMatrixInteraction.dpc_dsw(outsideSw); const auto tij = elemFluxVarsCache[scvf].advectionTij(); @@ -288,7 +300,6 @@ public: static_assert(ModelTraits::priVarFormulation() == TwoPFormulation::p0s1, "2p/incompressiblelocalresidual.hh: Analytic differentiation has to be checked for p0-s1 formulation!"); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; using AdvectionType = GetPropType; // evaluate the current wetting phase Darcy flux and resulting upwind weights @@ -310,8 +321,22 @@ public: const auto elemSol = elementSolution(element, curElemVolVars, fvGeometry); - const auto& insideMaterialParams = problem.spatialParams().materialLawParams(element, insideScv, elemSol); - const auto& outsideMaterialParams = problem.spatialParams().materialLawParams(element, outsideScv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& insidefluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, + // insideScv, + // elemSol); + // const auto& outsidefluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, + // outsideScv, + // elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto& insidefluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), + element, + insideScv, + elemSol); + const auto& outsidefluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), + element, + outsideScv, + elemSol); // some quantities to be reused (rho & mu are constant and thus equal for all cells) static const auto rho_w = insideVolVars.density(0); @@ -366,19 +391,19 @@ public: { // partial derivative of the wetting phase flux w.r.t. S_n const auto insideSw = insideVolVars.saturation(0); - const auto dKrw_dSn_inside = -1.0*MaterialLaw::dkrw_dsw(insideMaterialParams, insideSw); + const auto dKrw_dSn_inside = -1.0*insidefluidMatrixInteraction.dkrw_dsw(insideSw); const auto dFluxW_dSnJ = rho_mu_flux_w*dKrw_dSn_inside*insideWeight_w; dI_dJ_inside[globalJ][conti0EqIdx+0][saturationIdx] += dFluxW_dSnJ; dI_dJ_outside[globalJ][conti0EqIdx+0][saturationIdx] -= dFluxW_dSnJ; // partial derivative of the nonwetting phase flux w.r.t. S_n (k_rn contribution) - const auto dKrn_dSn_inside = -1.0*MaterialLaw::dkrn_dsw(insideMaterialParams, insideSw); + const auto dKrn_dSn_inside = -1.0*insidefluidMatrixInteraction.dkrn_dsw(insideSw); const auto dFluxN_dSnJ_krn = rho_mu_flux_n*dKrn_dSn_inside*insideWeight_n; dI_dJ_inside[globalJ][conti0EqIdx+1][saturationIdx] += dFluxN_dSnJ_krn; dI_dJ_outside[globalJ][conti0EqIdx+1][saturationIdx] -= dFluxN_dSnJ_krn; // partial derivative of the nonwetting phase flux w.r.t. S_n (p_c contribution) - const auto dFluxN_dSnJ_pc = -1.0*tj_up_n*MaterialLaw::dpc_dsw(insideMaterialParams, insideSw); + const auto dFluxN_dSnJ_pc = -1.0*tj_up_n*insidefluidMatrixInteraction.dpc_dsw(insideSw); dI_dJ_inside[globalJ][conti0EqIdx+1][saturationIdx] += dFluxN_dSnJ_pc; dI_dJ_outside[globalJ][conti0EqIdx+1][saturationIdx] -= dFluxN_dSnJ_pc; } @@ -386,25 +411,34 @@ public: { // see comments for (globalJ == insideScvIdx) const auto outsideSw = outsideVolVars.saturation(0); - const auto dKrw_dSn_outside = -1.0*MaterialLaw::dkrw_dsw(outsideMaterialParams, outsideSw); + const auto dKrw_dSn_outside = -1.0*outsidefluidMatrixInteraction.dkrw_dsw(outsideSw); const auto dFluxW_dSnJ = rho_mu_flux_w*dKrw_dSn_outside*outsideWeight_w; dI_dJ_inside[globalJ][conti0EqIdx+0][saturationIdx] += dFluxW_dSnJ; dI_dJ_outside[globalJ][conti0EqIdx+0][saturationIdx] -= dFluxW_dSnJ; - const auto dKrn_dSn_outside = -1.0*MaterialLaw::dkrn_dsw(outsideMaterialParams, outsideSw); + const auto dKrn_dSn_outside = -1.0*outsidefluidMatrixInteraction.dkrn_dsw(outsideSw); const auto dFluxN_dSnJ_krn = rho_mu_flux_n*dKrn_dSn_outside*outsideWeight_n; dI_dJ_inside[globalJ][conti0EqIdx+1][saturationIdx] += dFluxN_dSnJ_krn; dI_dJ_outside[globalJ][conti0EqIdx+1][saturationIdx] -= dFluxN_dSnJ_krn; - const auto dFluxN_dSnJ_pc = -1.0*tj_up_n*MaterialLaw::dpc_dsw(outsideMaterialParams, outsideSw); + const auto dFluxN_dSnJ_pc = -1.0*tj_up_n*outsidefluidMatrixInteraction.dpc_dsw(outsideSw); dI_dJ_inside[globalJ][conti0EqIdx+1][saturationIdx] += dFluxN_dSnJ_pc; dI_dJ_outside[globalJ][conti0EqIdx+1][saturationIdx] -= dFluxN_dSnJ_pc; } else { - const auto& paramsJ = problem.spatialParams().materialLawParams(element, scvJ, elemSol); + // old material law interface is deprecated: Replace this by + // const auto& fluidMatrixInteractionJ = problem.spatialParams().fluidMatrixInteraction(element, + // scvJ, + // elemSol); + + // after the release of 3.3, when the deprecated interface is no longer supported + const auto& fluidMatrixInteractionJ = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), + element, + scvJ, + elemSol); const auto swJ = curElemVolVars[scvJ].saturation(0); - const auto dFluxN_dSnJ_pc = tj_up_n*MaterialLaw::dpc_dsw(paramsJ, swJ); + const auto dFluxN_dSnJ_pc = tj_up_n*fluidMatrixInteractionJ.dpc_dsw(swJ); dI_dJ_inside[globalJ][conti0EqIdx+1][saturationIdx] -= dFluxN_dSnJ_pc; dI_dJ_outside[globalJ][conti0EqIdx+1][saturationIdx] += dFluxN_dSnJ_pc; } @@ -434,7 +468,6 @@ public: const ElementFluxVariablesCache& elemFluxVarsCache, const SubControlVolumeFace& scvf) const { - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; using AdvectionType = GetPropType; // evaluate the current wetting phase Darcy flux and resulting upwind weights @@ -451,9 +484,16 @@ public: const auto& insideScv = fvGeometry.scv(insideScvIdx); const auto& insideVolVars = curElemVolVars[insideScvIdx]; const auto& outsideVolVars = curElemVolVars[scvf.outsideScvIdx()]; - const auto& insideMaterialParams = problem.spatialParams().materialLawParams(element, - insideScv, - elementSolution(insideVolVars.priVars())); + + // old material law interface is deprecated: Replace this by + // const auto& insidefluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, + // insideScv, + // elementSolution(insideVolVars.priVars())); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto& insidefluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), + element, + insideScv, + elementSolution(insideVolVars.priVars())); // some quantities to be reused (rho & mu are constant and thus equal for all cells) static const auto rho_w = insideVolVars.density(0); @@ -470,9 +510,9 @@ public: // derivative w.r.t. to Sn is the negative of the one w.r.t. Sw const auto insideSw = insideVolVars.saturation(0); - const auto dKrw_dSn_inside = -1.0*MaterialLaw::dkrw_dsw(insideMaterialParams, insideSw); - const auto dKrn_dSn_inside = -1.0*MaterialLaw::dkrn_dsw(insideMaterialParams, insideSw); - const auto dpc_dSn_inside = -1.0*MaterialLaw::dpc_dsw(insideMaterialParams, insideSw); + const auto dKrw_dSn_inside = -1.0*insidefluidMatrixInteraction.dkrw_dsw(insideSw); + const auto dKrn_dSn_inside = -1.0*insidefluidMatrixInteraction.dkrn_dsw(insideSw); + const auto dpc_dSn_inside = -1.0*insidefluidMatrixInteraction.dpc_dsw(insideSw); const auto tij = elemFluxVarsCache[scvf].advectionTij(); // partial derivative of the wetting phase flux w.r.t. p_w -- GitLab From cbfb44d7656604da3c6daa3518fc7ab204d965db Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Mon, 26 Oct 2020 17:28:56 +0100 Subject: [PATCH 50/99] [io] Add header to help plotting new-style pcKrSw curves --- dumux/io/plotpckrsw.hh | 223 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 dumux/io/plotpckrsw.hh diff --git a/dumux/io/plotpckrsw.hh b/dumux/io/plotpckrsw.hh new file mode 100644 index 0000000000..75bd4f2119 --- /dev/null +++ b/dumux/io/plotpckrsw.hh @@ -0,0 +1,223 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup InputOutput + * \brief Interface for plotting the two-phase fluid-matrix-interaction laws + */ +#ifndef DUMUX_IO_PLOT_PC_KR_SW_HH +#define DUMUX_IO_PLOT_PC_KR_SW_HH + +#include +#include +#include +#include + +namespace Dumux { + +namespace Detail { +template +Range evalFunctionForRange(const Function& f, const Range& range) +{ + Range result = range; + std::transform(range.begin(), range.end(), result.begin(), [&](auto x){ return f(x); }); + return result; +} +} // end namespace Detail + +/*! + * \ingroup InputOutput + * \brief sample the pc-sw curve + */ +template +auto samplePcSw(const PcKrSw& curve, const V& sw) +{ + return Detail::evalFunctionForRange([&](const auto s){ return curve.pc(s); }, sw); +} + +/*! + * \ingroup InputOutput + * \brief sample the pc-sw curve derivative wrt sw + */ +template +auto samplePcSwDerivative(const PcKrSw& curve, const V& sw) +{ + return Detail::evalFunctionForRange([&](const auto s){ return curve.dpc_dsw(s); }, sw); +} + +/*! + * \ingroup InputOutput + * \brief sample the sw-pc curve derivative wrt pc + */ +template +auto samplePcSwInverseDerivative(const PcKrSw& curve, const V& pc) +{ + return Detail::evalFunctionForRange([&](const auto p){ return curve.dsw_dpc(p); }, pc); +} + +/*! + * \ingroup InputOutput + * \brief sample sw-pc curve but return the log10 of the capillary pressure + */ +template +auto sampleLog10PcSw(const PcKrSw& curve, const V& sw) +{ + return Detail::evalFunctionForRange([&](const auto s){ using std::log10; return log10(curve.pc(s)); }, sw); +} + +/*! + * \ingroup InputOutput + * \brief sample krw-sw and krn-sw curves + */ +template +auto sampleRelPerms(const PcKrSw& curve, const V& sw) +{ + return std::make_tuple( + Detail::evalFunctionForRange([&](const auto s){ return curve.krw(s); }, sw), + Detail::evalFunctionForRange([&](const auto s){ return curve.krn(s); }, sw) + ); +} + +/*! + * \ingroup InputOutput + * \brief sample the derivatives of the krw-sw and krn-sw curves + */ +template +auto sampleRelPermDerivatives(const PcKrSw& curve, const V& sw) +{ + return std::make_tuple( + Detail::evalFunctionForRange([&](const auto s){ return curve.dkrw_dsw(s); }, sw), + Detail::evalFunctionForRange([&](const auto s){ return curve.dkrn_dsw(s); }, sw) + ); +} + +// forward declaration +template class GnuplotInterface; + +namespace Detail { +template +void addDataSetToGnuplot(GnuplotInterface& gnuplot, + const V& x, const V& y, + const std::string& curveName, + const std::string& curveOptions, + const std::string& xLabel, + const std::string& yLabel) +{ + gnuplot.setXlabel(xLabel); + gnuplot.setYlabel(yLabel); + gnuplot.addDataSetToPlot(x, y, curveName, curveOptions); +} +} // end namespace Detail + +/*! + * \ingroup InputOutput + * \brief Helper functions related to gnuplot + */ +namespace Gnuplot { + +/*! + * \ingroup InputOutput + * \brief Convenience function for adding material law quantities to gnuplot + */ +template +void addPcSw(GnuplotInterface& gnuplot, const V& sw, const V& pc, + const std::string& curveName = "pc-sw", + const std::string& curveOptions = "w l", + const std::string& xLabel = "wetting phase saturation [-]", + const std::string& yLabel = "capillary pressure [Pa]") +{ + Detail::addDataSetToGnuplot(gnuplot, sw, pc, curveName, curveOptions, xLabel, yLabel); +} + +/*! + * \ingroup InputOutput + * \brief Convenience function for adding material law quantities to gnuplot + */ +template +void addPcSwDerivative(GnuplotInterface& gnuplot, const V& sw, const V& dpc_dsw, + const std::string& curveName = "dpc-dsw", + const std::string& curveOptions = "w l", + const std::string& xLabel = "wetting phase saturation [-]", + const std::string& yLabel = "derivative of capillary pressure [Pa]") +{ + Detail::addDataSetToGnuplot(gnuplot, sw, dpc_dsw, curveName, curveOptions, xLabel, yLabel); +} + +/*! + * \ingroup InputOutput + * \brief Convenience function for adding material law quantities to gnuplot + */ +template +void addPcSwInverseDerivative(GnuplotInterface& gnuplot, const V& sw, const V& dpc_dsw, + const std::string& curveName = "dsw-dpc", + const std::string& curveOptions = "w l", + const std::string& xLabel = "capillary pressure [Pa]", + const std::string& yLabel = "derivative of saturation [1/Pa]") +{ + Detail::addDataSetToGnuplot(gnuplot, sw, dpc_dsw, curveName, curveOptions, xLabel, yLabel); +} + +/*! + * \ingroup InputOutput + * \brief Convenience function for adding material law quantities to gnuplot + */ +template +void addLog10PcSw(GnuplotInterface& gnuplot, const V& sw, const V& log10pc, + const std::string& curveName = "log10-pc-sw", + const std::string& curveOptions = "w l", + const std::string& xLabel = "wetting phase saturation [-]", + const std::string& yLabel = "log10 of capillary pressure [Pa]") +{ + Detail::addDataSetToGnuplot(gnuplot, sw, log10pc, curveName, curveOptions, xLabel, yLabel); +} + +/*! + * \ingroup InputOutput + * \brief Convenience function for adding material law quantities to gnuplot + */ +template +void addRelPerms(GnuplotInterface& gnuplot, const V& sw, const V& krw, const V& krn, + const std::string& curveName = "relperm", + const std::string& curveOptions = "w l", + const std::string& xLabel = "wetting phase saturation [-]", + const std::string& yLabel = "relative permeability [-]") +{ + Detail::addDataSetToGnuplot(gnuplot, sw, krw, curveName + "_krw", curveOptions, xLabel, yLabel); + Detail::addDataSetToGnuplot(gnuplot, sw, krn, curveName + "_krn", curveOptions, xLabel, yLabel); +} + +/*! + * \ingroup InputOutput + * \brief Convenience function for adding material law quantities to gnuplot + */ +template +void addRelPermDerivatives(GnuplotInterface& gnuplot, const V& sw, const V& krw, const V& krn, + const std::string& curveName = "relperm_dsw", + const std::string& curveOptions = "w l", + const std::string& xLabel = "wetting phase saturation [-]", + const std::string& yLabel = "derivative of the relative permeability [-]") +{ + Detail::addDataSetToGnuplot(gnuplot, sw, krw, curveName + "_krw", curveOptions, xLabel, yLabel); + Detail::addDataSetToGnuplot(gnuplot, sw, krn, curveName + "_krn", curveOptions, xLabel, yLabel); +} + +} // end namespace Gnuplot +} // end namespace Dumux + +#endif -- GitLab From 2ad2bd3454fc5f55d917305fb45d0e1489e38ad0 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Mon, 26 Oct 2020 17:29:52 +0100 Subject: [PATCH 51/99] [test][2p2c][waterair] Use new-style laws and plot function --- .../2p2c/implicit/waterair/params.input | 6 +++ .../2p2c/implicit/waterair/problem.hh | 5 +- .../2p2c/implicit/waterair/spatialparams.hh | 49 +++++++------------ 3 files changed, 26 insertions(+), 34 deletions(-) diff --git a/test/porousmediumflow/2p2c/implicit/waterair/params.input b/test/porousmediumflow/2p2c/implicit/waterair/params.input index 14fd8b7359..d9191a92bb 100644 --- a/test/porousmediumflow/2p2c/implicit/waterair/params.input +++ b/test/porousmediumflow/2p2c/implicit/waterair/params.input @@ -24,3 +24,9 @@ MaxRelativeShift = 1e-13 SolidDensity = 2700 SolidThermalConductivity = 2.8 SolidHeatCapacity = 790 + +[SpatialParams] +BrooksCoreyPcEntry = 1e4 +BrooksCoreyLambda = 2 +Swr = 0.2 +Snr = 0.0 diff --git a/test/porousmediumflow/2p2c/implicit/waterair/problem.hh b/test/porousmediumflow/2p2c/implicit/waterair/problem.hh index 3cdd37b7fb..89dd1fdf7f 100644 --- a/test/porousmediumflow/2p2c/implicit/waterair/problem.hh +++ b/test/porousmediumflow/2p2c/implicit/waterair/problem.hh @@ -266,9 +266,8 @@ public: values[contiN2EqIdx] = useMoles ? -1e-3/FluidSystem::molarMass(N2Idx) : -1e-3; // kg/(m^2*s) or mole/(m^2*s) const auto initialValues = initial_(globalPos); - const auto& mParams = this->spatialParams().materialLawParamsAtPos(globalPos); - using MaterialLaw = typename ParentType::SpatialParams::MaterialLaw; - const auto pn = initialValues[pressureIdx] + MaterialLaw::endPointPc(mParams); + const auto& fluidMatrixInteraction = this->spatialParams().fluidMatrixInteractionAtPos(globalPos); + const auto pn = initialValues[pressureIdx] + fluidMatrixInteraction.endPointPc(); const auto t = initialValues[temperatureIdx]; // note: energy equation is always formulated in terms of mass specific quantities, not per mole diff --git a/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh b/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh index f39d59d99c..138079d15f 100644 --- a/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh @@ -24,14 +24,14 @@ #ifndef DUMUX_WATER_AIR_SPATIAL_PARAMS_HH #define DUMUX_WATER_AIR_SPATIAL_PARAMS_HH +#include #include #include -#include +#include #include #include #include -#include -#include +#include namespace Dumux { @@ -52,15 +52,16 @@ class WaterAirSpatialParams static constexpr int dimWorld = GridView::dimensionworld; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; + public: //! Export the type used for the permeability using PermeabilityType = Scalar; - //! Export the type used for the material law - using MaterialLaw = EffToAbsLaw>; - using MaterialLawParams = typename MaterialLaw::Params; + WaterAirSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { layerBottom_ = 22.0; @@ -72,18 +73,6 @@ public: finePorosity_ = 0.3; coarsePorosity_ = 0.3; - // residual saturations - fineMaterialParams_.setSwr(0.2); - fineMaterialParams_.setSnr(0.0); - coarseMaterialParams_.setSwr(0.2); - coarseMaterialParams_.setSnr(0.0); - - // parameters for the Brooks-Corey law - fineMaterialParams_.setPe(1e4); - coarseMaterialParams_.setPe(1e4); - fineMaterialParams_.setLambda(2.0); - coarseMaterialParams_.setLambda(2.0); - plotFluidMatrixInteractions_ = getParam("Output.PlotFluidMatrixInteractions"); } @@ -93,18 +82,21 @@ public: */ void plotMaterialLaw() { - PlotMaterialLaw plotMaterialLaw; GnuplotInterface gnuplot(plotFluidMatrixInteractions_); gnuplot.setOpenPlotWindow(plotFluidMatrixInteractions_); - plotMaterialLaw.addpcswcurve(gnuplot, fineMaterialParams_, 0.2, 1.0, "fine", "w lp"); - plotMaterialLaw.addpcswcurve(gnuplot, coarseMaterialParams_, 0.2, 1.0, "coarse", "w l"); + + const auto sw = linspace(0.2, 1.0, 1000); + + const auto pc = samplePcSw(pcKrSwCurve_, sw); + Gnuplot::addPcSw(gnuplot, sw, pc, "pc-Sw", "w lp"); gnuplot.setOption("set xrange [0:1]"); gnuplot.setOption("set label \"residual\\nsaturation\" at 0.1,100000 center"); gnuplot.plot("pc-Sw"); gnuplot.resetAll(); - plotMaterialLaw.addkrcurves(gnuplot, fineMaterialParams_, 0.2, 1.0, "fine"); - plotMaterialLaw.addkrcurves(gnuplot, coarseMaterialParams_, 0.2, 1.0, "coarse"); + + const auto [krw, krn] = sampleRelPerms(makeFluidMatrixInteraction(pcKrSwCurve_), sw); // test wrapped law + Gnuplot::addRelPerms(gnuplot, sw, krw, krn, "kr-Sw", "w lp"); gnuplot.plot("kr"); } @@ -134,17 +126,13 @@ public: return coarsePorosity_; } - /*! * \brief Returns the parameters for the material law at a given location * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - if (isFineMaterial_(globalPos)) - return fineMaterialParams_; - else - return coarseMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } /*! @@ -168,8 +156,7 @@ private: Scalar finePorosity_; Scalar coarsePorosity_; - MaterialLawParams fineMaterialParams_; - MaterialLawParams coarseMaterialParams_; + const PcKrSwCurve pcKrSwCurve_; bool plotFluidMatrixInteractions_; }; -- GitLab From 239bc8221de80ed47292ae690ff466af1efd9fae Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Mon, 26 Oct 2020 17:30:22 +0100 Subject: [PATCH 52/99] [test][2pncmin] Remove unused header --- .../2pncmin/implicit/nonisothermal/spatialparams.hh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh b/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh index 201941ae5b..e3985f9e08 100644 --- a/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh +++ b/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh @@ -26,8 +26,6 @@ #ifndef DUMUX_SALINIZATION_SPATIAL_PARAMETERS_HH #define DUMUX_SALINIZATION_SPATIAL_PARAMETERS_HH -#include -#include #include #include #include @@ -68,8 +66,6 @@ public: solubilityLimit_ = getParam("SpatialParams.SolubilityLimit", 0.26); referencePorosity_ = getParam("SpatialParams.referencePorosity", 0.11); referencePermeability_ = getParam("SpatialParams.referencePermeability", 2.23e-14); - - plotFluidMatrixInteractions_ = getParam("Output.PlotFluidMatrixInteractions"); } /*! @@ -156,9 +152,6 @@ private: Scalar solubilityLimit_; Scalar referencePorosity_; PermeabilityType referencePermeability_ = 0.0; - - - bool plotFluidMatrixInteractions_; }; } // end namespace Dumux -- GitLab From ecd949df9669ef47c0d232df28e3a7197556db30 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Mon, 26 Oct 2020 17:30:36 +0100 Subject: [PATCH 53/99] [test][ichardsnc] Remove unused header --- test/porousmediumflow/richardsnc/implicit/spatialparams.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/porousmediumflow/richardsnc/implicit/spatialparams.hh b/test/porousmediumflow/richardsnc/implicit/spatialparams.hh index a1ce847777..eca361a854 100644 --- a/test/porousmediumflow/richardsnc/implicit/spatialparams.hh +++ b/test/porousmediumflow/richardsnc/implicit/spatialparams.hh @@ -31,9 +31,6 @@ #include -#include -#include - namespace Dumux { /*! -- GitLab From a2f7cff4fd21c2e5e3aac1ac5935e9dd1607a067 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Tue, 27 Oct 2020 15:11:25 +0100 Subject: [PATCH 54/99] [io] Deprecated plot tools for old material law --- dumux/io/plotmateriallaw.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dumux/io/plotmateriallaw.hh b/dumux/io/plotmateriallaw.hh index 92488748d5..cf2ff58006 100644 --- a/dumux/io/plotmateriallaw.hh +++ b/dumux/io/plotmateriallaw.hh @@ -24,6 +24,8 @@ #ifndef DUMUX_PLOT_FLUID_MATRIX_LAW_HH #define DUMUX_PLOT_FLUID_MATRIX_LAW_HH +#warning "This header is deprecated and will be removed after 3.3. Use new 2p material laws and plot tools from io/plotpckrsw.hh" + #include #include #include -- GitLab From c199687e1be2f481d327d7d27d5409ac7a759f50 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Tue, 27 Oct 2020 18:12:59 +0100 Subject: [PATCH 55/99] [test][2p][boxdfm] Add new test label boxdfm --- .../2p/implicit/boxdfm/CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/porousmediumflow/2p/implicit/boxdfm/CMakeLists.txt b/test/porousmediumflow/2p/implicit/boxdfm/CMakeLists.txt index 8384582b8d..3abbc2e238 100644 --- a/test/porousmediumflow/2p/implicit/boxdfm/CMakeLists.txt +++ b/test/porousmediumflow/2p/implicit/boxdfm/CMakeLists.txt @@ -2,7 +2,7 @@ dune_symlink_to_source_files(FILES "params.input" "grids") # quadrilaterals alu grid dumux_add_test(NAME test_2p_boxdfm_quads_alu - LABELS porousmediumflow 2p + LABELS porousmediumflow 2p boxdfm SOURCES main.cc CMAKE_GUARD dune-alugrid_FOUND CMAKE_GUARD dune-foamgrid_FOUND @@ -16,7 +16,7 @@ dumux_add_test(NAME test_2p_boxdfm_quads_alu # quadrilaterals ug grid dumux_add_test(NAME test_2p_boxdfm_quads_ug - LABELS porousmediumflow 2p + LABELS porousmediumflow 2p boxdfm SOURCES main.cc CMAKE_GUARD dune-uggrid_FOUND CMAKE_GUARD dune-foamgrid_FOUND @@ -30,7 +30,7 @@ dumux_add_test(NAME test_2p_boxdfm_quads_ug # triangles alu dumux_add_test(NAME test_2p_boxdfm_trias_alu - LABELS porousmediumflow 2p + LABELS porousmediumflow 2p boxdfm TIMEOUT 1500 SOURCES main.cc CMAKE_GUARD dune-foamgrid_FOUND @@ -45,7 +45,7 @@ dumux_add_test(NAME test_2p_boxdfm_trias_alu # triangles ug dumux_add_test(NAME test_2p_boxdfm_trias_ug - LABELS porousmediumflow 2p + LABELS porousmediumflow 2p boxdfm TIMEOUT 1500 SOURCES main.cc CMAKE_GUARD dune-uggrid_FOUND @@ -60,7 +60,7 @@ dumux_add_test(NAME test_2p_boxdfm_trias_ug # tetrahedra alu dumux_add_test(NAME test_2p_boxdfm_tets_alu - LABELS porousmediumflow 2p + LABELS porousmediumflow 2p boxdfm SOURCES main.cc CMAKE_GUARD dune-foamgrid_FOUND CMAKE_GUARD dune-alugrid_FOUND @@ -74,7 +74,7 @@ dumux_add_test(NAME test_2p_boxdfm_tets_alu # tetrahedra ug dumux_add_test(NAME test_2p_boxdfm_tets_ug - LABELS porousmediumflow 2p + LABELS porousmediumflow 2p boxdfm SOURCES main.cc CMAKE_GUARD dune-uggrid_FOUND CMAKE_GUARD dune-foamgrid_FOUND -- GitLab From 33cfd00aa53016258cf18524377a62aec116e9ff Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Tue, 27 Oct 2020 18:14:01 +0100 Subject: [PATCH 56/99] [box][2p] Use new fluid matrix interface for box interface solver. Update tests. --- CHANGELOG.md | 1 + ...faceparams.hh => boxmaterialinterfaces.hh} | 65 +++++++++---------- .../2p/saturationreconstruction.hh | 26 ++++---- .../2p/implicit/boxdfm/main.cc | 2 +- .../2p/implicit/boxdfm/params.input | 10 +++ .../2p/implicit/boxdfm/spatialparams.hh | 62 +++++++----------- .../2p/implicit/incompressible/main.cc | 2 +- .../2p/implicit/incompressible/params.input | 10 +++ .../implicit/incompressible/spatialparams.hh | 56 ++++++---------- 9 files changed, 114 insertions(+), 120 deletions(-) rename dumux/porousmediumflow/2p/{boxmaterialinterfaceparams.hh => boxmaterialinterfaces.hh} (66%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dfadefcaa..14bdc03df9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ An additional new option is `Vtk.CoordPrecision` which changes the precision of - __Van Genuchten__: Corrected VanGenuchten-Mualem exponent in the nonwetting saturation formula (`1/3` instead of `1/2` (or `l`, see above)) - __Van Genuchten__: Corrected VanGenuchten-Mualem implementation of `dkrn/dSw` - __Brooks-Corey__: Corrected Brooks-Corey implementation of `dkrn/dSw` and added the derivatives for the regularized version +- __Box interface solver__: The box interface solver immediately requires the new material law interface without deprecation period. Use the new class `BoxMaterialInterfaces` and update your spatial params to use the new fluidmatrixinteraction interface to be able to use the box interface solver in version 3.3. - __AMGBackend__: The internal structure of the AMGBackend and the ParallelISTLHelper has been overhauled, as only used by the AMG, we did not make the changes backwards-compatible - The global default parameters for linear solvers have been removed and moved to the class `LinearSolver`. This only affects users that directly obtain this parameter via `getParam` somewhere in the code. diff --git a/dumux/porousmediumflow/2p/boxmaterialinterfaceparams.hh b/dumux/porousmediumflow/2p/boxmaterialinterfaces.hh similarity index 66% rename from dumux/porousmediumflow/2p/boxmaterialinterfaceparams.hh rename to dumux/porousmediumflow/2p/boxmaterialinterfaces.hh index 5dcb9055d4..3296cd5444 100644 --- a/dumux/porousmediumflow/2p/boxmaterialinterfaceparams.hh +++ b/dumux/porousmediumflow/2p/boxmaterialinterfaces.hh @@ -22,8 +22,8 @@ * \copydoc Dumux::BoxMaterialInterfaceParams */ -#ifndef DUMUX_2P_BOX_MATERIAL_INTERFACE_PARAMS_HH -#define DUMUX_2P_BOX_MATERIAL_INTERFACE_PARAMS_HH +#ifndef DUMUX_2P_BOX_MATERIAL_INTERFACES_HH +#define DUMUX_2P_BOX_MATERIAL_INTERFACES_HH #include @@ -42,11 +42,19 @@ namespace Dumux { * of freedom. On the basis of these parameters, the saturations in the * remaining sub-control volumes connected to the vertex can be reconstructed. */ -template -class BoxMaterialInterfaceParams +template +class BoxMaterialInterfaces { + using SubControlVolume = typename GridGeometry::SubControlVolume; + public: - using MaterialLawParams = typename SpatialParams::MaterialLaw::Params; + template + BoxMaterialInterfaces(const GridGeometry& gridGeometry, + const SpatialParams& spatialParams, + const SolutionVector& x) + { + update(gridGeometry, spatialParams, x); + } /*! * \brief Updates the scv -> dofparameter map @@ -55,30 +63,18 @@ public: * \param spatialParams Class encapsulating the spatial parameters * \param x The current state of the solution vector */ - template + template void update(const GridGeometry& gridGeometry, const SpatialParams& spatialParams, const SolutionVector& x) { - using MaterialLaw = typename SpatialParams::MaterialLaw; - - // Make sure the spatial params return a const ref and no copy! - using Elem = typename GridGeometry::GridView::template Codim<0>::Entity; - using ElemSol = decltype( elementSolution(Elem(), x, gridGeometry) ); - using Scv = typename GridGeometry::SubControlVolume; - using ReturnType = decltype(spatialParams.materialLawParams(Elem(), Scv(), ElemSol())); - static_assert(std::is_lvalue_reference::value, - "In order to use the box-interface solver please provide access " - "to the material law parameters via returning (const) references"); - // make sure this is only called for geometries of the box method! if (GridGeometry::discMethod != DiscretizationMethod::box) DUNE_THROW(Dune::InvalidStateException, "Determination of the interface material parameters with " "this class only makes sense when using the box method!"); - isUpdated_ = true; isOnMaterialInterface_.resize(gridGeometry.numDofs(), false); - dofParams_.resize(gridGeometry.numDofs(), nullptr); + pcSwAtDof_.resize(gridGeometry.numDofs(), nullptr); for (const auto& element : elements(gridGeometry.gridView())) { const auto elemSol = elementSolution(element, x, gridGeometry); @@ -87,40 +83,43 @@ public: fvGeometry.bind(element); for (const auto& scv : scvs(fvGeometry)) { - const auto& params = spatialParams.materialLawParams(element, scv, elemSol); + const auto fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); + const auto& pcKrSw = fluidMatrixInteraction.pcSwCurve(); + + // assert current preconditions on requiring the spatial params to store the pckrSw curve + static_assert(std::is_lvalue_reference::PcKrSwType>::value, + "In order to use the box-interface solver please provide access " + "to the material law parameters via returning (const) references"); // if no parameters had been set, set them now - if (dofParams_[scv.dofIndex()] == nullptr) - dofParams_[scv.dofIndex()] = ¶ms; + if (!pcSwAtDof_[scv.dofIndex()]) + pcSwAtDof_[scv.dofIndex()] = &pcKrSw; // otherwise only use the current ones if endPointPc (e.g. Brooks-Corey entry pressure) is lower - else if (MaterialLaw::endPointPc( params ) < MaterialLaw::endPointPc( *(dofParams_[scv.dofIndex()]) )) + else if (pcKrSw.endPointPc() < pcSwAtDof_[scv.dofIndex()]->endPointPc()) { - dofParams_[scv.dofIndex()] = ¶ms; + pcSwAtDof_[scv.dofIndex()] = &pcKrSw; isOnMaterialInterface_[scv.dofIndex()] = true; } // keep track of material interfaces in any case - else if ( !(params == *(dofParams_[scv.dofIndex()])) ) + else if ( !(pcKrSw == *(pcSwAtDof_[scv.dofIndex()])) ) isOnMaterialInterface_[scv.dofIndex()] = true; } } } //! Returns if this scv is connected to a material interface - template - bool isOnMaterialInterface(const Scv& scv) const - { assert(isUpdated_); return isOnMaterialInterface_[scv.dofIndex()]; } + bool isOnMaterialInterface(const SubControlVolume& scv) const + { return isOnMaterialInterface_[scv.dofIndex()]; } //! Returns the material parameters associated with the dof - template - const MaterialLawParams& getDofParams(const Scv& scv) const - { assert(isUpdated_); return *(dofParams_[scv.dofIndex()]); } + const PcKrSw& pcSwAtDof(const SubControlVolume& scv) const + { return *(pcSwAtDof_[scv.dofIndex()]); } private: - bool isUpdated_{false}; std::vector isOnMaterialInterface_; - std::vector dofParams_; + std::vector pcSwAtDof_; }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/2p/saturationreconstruction.hh b/dumux/porousmediumflow/2p/saturationreconstruction.hh index ef2b49216b..10a49b2644 100644 --- a/dumux/porousmediumflow/2p/saturationreconstruction.hh +++ b/dumux/porousmediumflow/2p/saturationreconstruction.hh @@ -61,8 +61,8 @@ public: const Element& element, const Scv& scv, const ElemSol& elemSol, - typename ElemSol::PrimaryVariables::value_type Sn) - { return Sn; } + typename ElemSol::PrimaryVariables::value_type sn) + { return sn; } }; //! Specialization for the box scheme with the interface solver enabled @@ -85,23 +85,25 @@ public: const Element& element, const Scv& scv, const ElemSol& elemSol, - typename ElemSol::PrimaryVariables::value_type Sn) + typename ElemSol::PrimaryVariables::value_type sn) { // if this dof doesn't lie on a material interface, simply return Sn - if (!spatialParams.materialInterfaceParams().isOnMaterialInterface(scv)) - return Sn; + const auto& materialInterfaces = spatialParams.materialInterfaces(); + if (!materialInterfaces.isOnMaterialInterface(scv)) + return sn; - using MaterialLaw = typename SpatialParams::MaterialLaw; // compute capillary pressure using material parameters associated with the dof - const auto& ifMaterialParams = spatialParams.materialInterfaceParams().getDofParams(scv); - const auto pc = MaterialLaw::pc(ifMaterialParams, /*Sw=*/1.0 - Sn); + const auto& interfacePcSw = materialInterfaces.pcSwAtDof(scv); + const auto pc = interfacePcSw.pc(/*ww=*/1.0 - sn); // reconstruct by inverting the pc-sw curve - const auto& materialLawParams = spatialParams.materialLawParams(element, scv, elemSol); - const auto pcMin = MaterialLaw::endPointPc(materialLawParams); + const auto& pcSw = spatialParams.fluidMatrixInteraction(element, scv, elemSol).pcSwCurve(); + const auto pcMin = pcSw.endPointPc(); - if (pc < pcMin && pcMin > 0.0) return 0.0; - else return 1.0 - MaterialLaw::sw(materialLawParams, pc); + if (pc < pcMin && pcMin > 0.0) + return 0.0; + else + return 1.0 - pcSw.sw(pc); } }; diff --git a/test/porousmediumflow/2p/implicit/boxdfm/main.cc b/test/porousmediumflow/2p/implicit/boxdfm/main.cc index 6fe43aa027..e59caef33e 100644 --- a/test/porousmediumflow/2p/implicit/boxdfm/main.cc +++ b/test/porousmediumflow/2p/implicit/boxdfm/main.cc @@ -131,7 +131,7 @@ int main(int argc, char** argv) auto xOld = x; // update the interface parameters - problem->spatialParams().updateMaterialInterfaceParams(x); + problem->spatialParams().updateMaterialInterfaces(x); // the grid variables using GridVariables = GetPropType; diff --git a/test/porousmediumflow/2p/implicit/boxdfm/params.input b/test/porousmediumflow/2p/implicit/boxdfm/params.input index 18cb950644..6705416a25 100644 --- a/test/porousmediumflow/2p/implicit/boxdfm/params.input +++ b/test/porousmediumflow/2p/implicit/boxdfm/params.input @@ -9,6 +9,16 @@ File = grids/durlofsky.msh [SpatialParams] FractureAperture = 1e-3 +[SpatialParams.Matrix] +Swr = 0.18 +BrooksCoreyPcEntry = 1e4 +BrooksCoreyLambda = 2 + +[SpatialParams.Fracture] +Swr = 0.05 +BrooksCoreyPcEntry = 1e3 +BrooksCoreyLambda = 2 + [Problem] Name = 2pboxdfm EnableGravity = false diff --git a/test/porousmediumflow/2p/implicit/boxdfm/spatialparams.hh b/test/porousmediumflow/2p/implicit/boxdfm/spatialparams.hh index 5d0455254f..8183314ecb 100644 --- a/test/porousmediumflow/2p/implicit/boxdfm/spatialparams.hh +++ b/test/porousmediumflow/2p/implicit/boxdfm/spatialparams.hh @@ -28,11 +28,9 @@ #include #include -#include -#include -#include +#include -#include +#include namespace Dumux { @@ -41,7 +39,8 @@ namespace Dumux { * \brief The spatial params for the incompressible 2p test. */ template -class TwoPTestSpatialParams : public FVSpatialParams< GridGeometry, Scalar, TwoPTestSpatialParams > +class TwoPTestSpatialParams +: public FVSpatialParams< GridGeometry, Scalar, TwoPTestSpatialParams > { using ThisType = TwoPTestSpatialParams; using ParentType = FVSpatialParams; @@ -55,25 +54,16 @@ class TwoPTestSpatialParams : public FVSpatialParams< GridGeometry, Scalar, TwoP static constexpr int dimWorld = GridView::dimensionworld; + using PcKrSw = FluidMatrix::BrooksCoreyDefault; + using MaterialInterfaces = BoxMaterialInterfaces; public: - using MaterialLaw = EffToAbsLaw< RegularizedBrooksCorey >; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; - TwoPTestSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) - { - // residual saturations - matrixMaterialParams_.setSwr(0.18); - matrixMaterialParams_.setSnr(0.0); - fractureMaterialParams_.setSwr(0.05); - fractureMaterialParams_.setSnr(0.0); - - // parameters for the Brooks-Corey law - matrixMaterialParams_.setPe(1e4); - matrixMaterialParams_.setLambda(2); - fractureMaterialParams_.setPe(1e3); - fractureMaterialParams_.setLambda(2); - } + TwoPTestSpatialParams(std::shared_ptr gridGeometry) + : ParentType(gridGeometry) + , pcKrSwMatrix_("SpatialParams.Matrix") + , pcKrSwFracture_("SpatialParams.Fracture") + {} /*! * \brief Function for defining the (intrinsic) permeability \f$[m^2]\f$. @@ -115,24 +105,23 @@ public: } /*! - * \brief Returns the parameter object for the Brooks-Corey material law. + * \brief Returns the fluid-matrix interaction law. * * In this test, we use element-wise distributed material parameters. * * \param element The current element * \param scv The sub-control volume inside the element. * \param elemSol The solution at the dofs connected to the element. - * \return The material parameters object */ template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + auto fluidMatrixInteraction(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { if (scv.isOnFracture()) - return fractureMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwFracture_); else - return matrixMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwMatrix_); } /*! @@ -147,21 +136,18 @@ public: //! Updates the map of which material parameters are associated with a nodal dof. template - void updateMaterialInterfaceParams(const SolutionVector& x) - { - materialInterfaceParams_.update(this->gridGeometry(), *this, x); - } + void updateMaterialInterfaces(const SolutionVector& x) + { materialInterfaces_ = std::make_unique(this->gridGeometry(), *this, x); } //! Returns the material parameters associated with a nodal dof - const BoxMaterialInterfaceParams& materialInterfaceParams() const - { return materialInterfaceParams_; } + const MaterialInterfaces& materialInterfaces() const + { return *materialInterfaces_; } private: - MaterialLawParams matrixMaterialParams_; - MaterialLawParams fractureMaterialParams_; + PcKrSw pcKrSwMatrix_; + PcKrSw pcKrSwFracture_; - // Determines the parameters associated with the dofs at material interfaces - BoxMaterialInterfaceParams materialInterfaceParams_; + std::unique_ptr materialInterfaces_; static constexpr Scalar eps_ = 1.5e-7; }; diff --git a/test/porousmediumflow/2p/implicit/incompressible/main.cc b/test/porousmediumflow/2p/implicit/incompressible/main.cc index 0d7c8192bb..3824474246 100644 --- a/test/porousmediumflow/2p/implicit/incompressible/main.cc +++ b/test/porousmediumflow/2p/implicit/incompressible/main.cc @@ -151,7 +151,7 @@ int main(int argc, char** argv) // maybe update the interface parameters if (ENABLEINTERFACESOLVER) - problem->spatialParams().updateMaterialInterfaceParams(x); + problem->spatialParams().updateMaterialInterfaces(x); // the grid variables using GridVariables = GetPropType; diff --git a/test/porousmediumflow/2p/implicit/incompressible/params.input b/test/porousmediumflow/2p/implicit/incompressible/params.input index 336df6cf83..17b87d2465 100644 --- a/test/porousmediumflow/2p/implicit/incompressible/params.input +++ b/test/porousmediumflow/2p/implicit/incompressible/params.input @@ -11,6 +11,16 @@ Cells = 48 32 LensLowerLeft = 1.0 2.0 # [m] coordinates of the lower left lens corner LensUpperRight = 4.0 3.0 # [m] coordinates of the upper right lens corner +[SpatialParams.Lens] +Swr = 0.18 +VanGenuchtenAlpha = 0.00045 +VanGenuchtenN = 7.3 + +[SpatialParams.Outer] +Swr = 0.05 +VanGenuchtenAlpha = 0.0037 +VanGenuchtenN = 4.7 + [Problem] Name = 2p EnableGravity = true diff --git a/test/porousmediumflow/2p/implicit/incompressible/spatialparams.hh b/test/porousmediumflow/2p/implicit/incompressible/spatialparams.hh index 1232ca5d2b..fdb750dcb2 100644 --- a/test/porousmediumflow/2p/implicit/incompressible/spatialparams.hh +++ b/test/porousmediumflow/2p/implicit/incompressible/spatialparams.hh @@ -26,10 +26,8 @@ #define DUMUX_INCOMPRESSIBLE_TWOP_TEST_SPATIAL_PARAMS_HH #include -#include -#include - -#include +#include +#include namespace Dumux { @@ -51,36 +49,24 @@ class TwoPTestSpatialParams static constexpr int dimWorld = GridView::dimensionworld; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using EffectiveLaw = RegularizedVanGenuchten; + using PcKrSw = FluidMatrix::VanGenuchtenDefault; + using MaterialInterfaces = BoxMaterialInterfaces; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; TwoPTestSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , lensPcKrSw_("SpatialParams.Lens") + , outerPcKrSw_("SpatialParams.Outer") { lensIsOilWet_ = getParam("SpatialParams.LensIsOilWet", false); lensLowerLeft_ = getParam("SpatialParams.LensLowerLeft"); lensUpperRight_ = getParam("SpatialParams.LensUpperRight"); - // residual saturations - lensMaterialParams_.setSwr(0.18); - lensMaterialParams_.setSnr(0.0); - outerMaterialParams_.setSwr(0.05); - outerMaterialParams_.setSnr(0.0); - - // parameters for the Van Genuchten law - // alpha and n - lensMaterialParams_.setVgAlpha(0.00045); - lensMaterialParams_.setVgn(7.3); - outerMaterialParams_.setVgAlpha(0.0037); - outerMaterialParams_.setVgn(4.7); - - lensK_ = getParam("SpatialParams.lensK", 9.05e-12); - outerK_ = getParam("SpatialParams.outerK", 4.6e-10); + lensK_ = getParam("SpatialParams.Lens.Permeability", 9.05e-12); + outerK_ = getParam("SpatialParams.Outer.Permeability", 4.6e-10); } /*! @@ -123,14 +109,14 @@ public: * \return The material parameters object */ template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + auto fluidMatrixInteraction(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { // do not use different parameters in the test with inverted wettability if (isInLens_(element.geometry().center()) && !lensIsOilWet_) - return lensMaterialParams_; - return outerMaterialParams_; + return makeFluidMatrixInteraction(lensPcKrSw_); + return makeFluidMatrixInteraction(outerPcKrSw_); } /*! @@ -149,15 +135,15 @@ public: //! Updates the map of which material parameters are associated with a nodal dof. template - void updateMaterialInterfaceParams(const SolutionVector& x) + void updateMaterialInterfaces(const SolutionVector& x) { if (GridGeometry::discMethod == DiscretizationMethod::box) - materialInterfaceParams_.update(this->gridGeometry(), *this, x); + materialInterfaces_ = std::make_unique(this->gridGeometry(), *this, x); } //! Returns the material parameters associated with a nodal dof - const BoxMaterialInterfaceParams& materialInterfaceParams() const - { return materialInterfaceParams_; } + const MaterialInterfaces& materialInterfaces() const + { return *materialInterfaces_; } //! Returns whether or not the lens is oil wet bool lensIsOilWet() const { return lensIsOilWet_; } @@ -178,11 +164,11 @@ private: Scalar lensK_; Scalar outerK_; - MaterialLawParams lensMaterialParams_; - MaterialLawParams outerMaterialParams_; - // Determines the parameters associated with the dofs at material interfaces - BoxMaterialInterfaceParams materialInterfaceParams_; + const PcKrSw lensPcKrSw_; + const PcKrSw outerPcKrSw_; + + std::unique_ptr materialInterfaces_; static constexpr Scalar eps_ = 1.5e-7; }; -- GitLab From a87c15858a425146cb66403e8f9669b9bd729db0 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 29 Oct 2020 20:03:32 +0100 Subject: [PATCH 57/99] [material][flash] Use new material laws in flashes --- .../constraintsolvers/immiscibleflash.hh | 35 +++++----- dumux/material/constraintsolvers/ncpflash.hh | 31 ++++----- .../test_compositionalflash.cc | 65 +++++++------------ .../immiscibleflash/test_immiscibleflash.cc | 54 ++++++--------- test/material/ncpflash/test_ncpflash.cc | 50 ++++++-------- .../pengrobinson/test_pengrobinson.cc | 37 ++++------- 6 files changed, 108 insertions(+), 164 deletions(-) diff --git a/dumux/material/constraintsolvers/immiscibleflash.hh b/dumux/material/constraintsolvers/immiscibleflash.hh index b04e524534..1c3a934be8 100644 --- a/dumux/material/constraintsolvers/immiscibleflash.hh +++ b/dumux/material/constraintsolvers/immiscibleflash.hh @@ -29,6 +29,7 @@ #include #include +#include namespace Dumux { @@ -117,15 +118,15 @@ public: * \param fluidState Thermodynamic state of the fluids * \param paramCache Container for cache parameters * \param globalMolarities - * \param matParams The material law object + * \param material The material law object * * The phase's fugacities must already be set. */ template - void solve(FluidState &fluidState, - ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams, - const ComponentVector &globalMolarities) + void solve(FluidState& fluidState, + ParameterCache& paramCache, + const MaterialLaw& material, + const ComponentVector& globalMolarities) { ///////////////////////// // Check if all fluid phases are incompressible @@ -164,12 +165,12 @@ public: // right hand side Vector b; - completeFluidState_(fluidState, paramCache, matParams); + completeFluidState_(fluidState, paramCache, material); const int nMax = 50; // <- maximum number of newton iterations for (int nIdx = 0; nIdx < nMax; ++nIdx) { // calculate Jacobian matrix and right hand side - linearize_(J, b, fluidState, paramCache, matParams, globalMolarities); + linearize_(J, b, fluidState, paramCache, material, globalMolarities); // Solve J*x = b deltaX = 0; @@ -207,7 +208,7 @@ public: */ // update the fluid quantities. - Scalar relError = update_(fluidState, paramCache, matParams, deltaX); + Scalar relError = update_(fluidState, paramCache, material, deltaX); if (relError < 1e-9) return; @@ -263,7 +264,7 @@ protected: Vector &b, FluidState &fluidState, ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams, + const MaterialLaw& material, const ComponentVector &globalMolarities) { FluidState origFluidState(fluidState); @@ -287,7 +288,7 @@ protected: // deviate the mole fraction of the i-th component Scalar x_i = getQuantity_(fluidState, pvIdx); const Scalar eps = 1e-10/quantityWeight_(fluidState, pvIdx); - setQuantity_(fluidState, paramCache, matParams, pvIdx, x_i + eps); + setQuantity_(fluidState, paramCache, material, pvIdx, x_i + eps); // compute derivative of the defect calculateDefect_(tmp, origFluidState, fluidState, globalMolarities); @@ -325,7 +326,7 @@ protected: template Scalar update_(FluidState &fluidState, ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams, + const MaterialLaw& material, const Vector &deltaX) { Scalar relError = 0; @@ -351,7 +352,7 @@ protected: setQuantityRaw_(fluidState, pvIdx, tmp - delta); } - completeFluidState_(fluidState, paramCache, matParams); + completeFluidState_(fluidState, paramCache, material); return relError; } @@ -359,7 +360,7 @@ protected: template void completeFluidState_(FluidState &fluidState, ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams) + const MaterialLaw& material) { // calculate the saturation of the last phase as a function of // the other saturations @@ -384,8 +385,7 @@ protected: // update the pressures using the material law (saturations // and first pressure are already set because it is implicitly // solved for.) - ComponentVector pc; - MaterialLaw::capillaryPressures(pc, matParams, fluidState, wettingPhaseIdx_); + const auto pc = material.capillaryPressures(fluidState, wettingPhaseIdx_); for (int phaseIdx = 1; phaseIdx < numPhases; ++phaseIdx) fluidState.setPressure(phaseIdx, fluidState.pressure(0) @@ -432,7 +432,7 @@ protected: template void setQuantity_(FluidState &fs, ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams, + const MaterialLaw& material, int pvIdx, Scalar value) { @@ -470,8 +470,7 @@ protected: // update all fluid pressures using the capillary pressure // law - ComponentVector pc; - MaterialLaw::capillaryPressures(pc, matParams, fs, wettingPhaseIdx_); + const auto pc = material.capillaryPressures(fs, wettingPhaseIdx_); for (int phaseIdx = 1; phaseIdx < numPhases; ++phaseIdx) fs.setPressure(phaseIdx, fs.pressure(0) diff --git a/dumux/material/constraintsolvers/ncpflash.hh b/dumux/material/constraintsolvers/ncpflash.hh index 652ba0a9a9..f5567a629e 100644 --- a/dumux/material/constraintsolvers/ncpflash.hh +++ b/dumux/material/constraintsolvers/ncpflash.hh @@ -29,6 +29,7 @@ #include #include +#include namespace Dumux { @@ -143,14 +144,14 @@ public: * \param fluidState Thermodynamic state of the fluids * \param paramCache Container for cache parameters * \param globalMolarities - * \param matParams The material law object + * \param material The material law object * * The phase's fugacities must already be set. */ template void solve(FluidState &fluidState, ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams, + const MaterialLaw& material, const ComponentVector &globalMolarities) { ///////////////////////// @@ -165,9 +166,7 @@ public: Vector b; // make the fluid state consistent with the fluid system. - completeFluidState_(fluidState, - paramCache, - matParams); + completeFluidState_(fluidState, paramCache, material); /* std::cout << "--------------------\n"; @@ -180,7 +179,7 @@ public: const int nMax = 50; // <- maximum number of newton iterations for (int nIdx = 0; nIdx < nMax; ++nIdx) { // calculate Jacobian matrix and right hand side - linearize_(J, b, fluidState, paramCache, matParams, globalMolarities); + linearize_(J, b, fluidState, paramCache, material, globalMolarities); // Solve J*x = b deltaX = 0; @@ -236,7 +235,7 @@ public: */ // update the fluid quantities. - Scalar relError = update_(fluidState, paramCache, matParams, deltaX); + Scalar relError = update_(fluidState, paramCache, material, deltaX); if (relError < 1e-9) return; @@ -313,7 +312,7 @@ protected: Vector &b, FluidState &fluidState, ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams, + const MaterialLaw& material, const ComponentVector &globalMolarities) { FluidState origFluidState(fluidState); @@ -337,7 +336,7 @@ protected: // deviate the mole fraction of the i-th component Scalar x_i = getQuantity_(fluidState, pvIdx); const Scalar eps = 1e-8/quantityWeight_(fluidState, pvIdx); - setQuantity_(fluidState, paramCache, matParams, pvIdx, x_i + eps); + setQuantity_(fluidState, paramCache, material, pvIdx, x_i + eps); // compute derivative of the defect calculateDefect_(tmp, origFluidState, fluidState, globalMolarities); @@ -418,7 +417,7 @@ protected: template Scalar update_(FluidState &fluidState, ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams, + const MaterialLaw& material, const Vector &deltaX) { Scalar relError = 0; @@ -486,7 +485,7 @@ protected: } } - completeFluidState_(fluidState, paramCache, matParams); + completeFluidState_(fluidState, paramCache, material); return relError; } @@ -494,7 +493,7 @@ protected: template void completeFluidState_(FluidState &fluidState, ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams) + const MaterialLaw& material) { // calculate the saturation of the last phase as a function of // the other saturations @@ -506,8 +505,7 @@ protected: // update the pressures using the material law (saturations // and first pressure are already set because it is implicitly // solved for.) - ComponentVector pc; - MaterialLaw::capillaryPressures(pc, matParams, fluidState, wettingPhaseIdx_); + const auto pc = material.capillaryPressures(fluidState, wettingPhaseIdx_); for (int phaseIdx = 1; phaseIdx < numPhases; ++phaseIdx) fluidState.setPressure(phaseIdx, fluidState.pressure(0) @@ -569,7 +567,7 @@ protected: template void setQuantity_(FluidState &fs, ParameterCache ¶mCache, - const typename MaterialLaw::Params &matParams, + const MaterialLaw& material, int pvIdx, Scalar value) { @@ -608,8 +606,7 @@ protected: // update all fluid pressures using the capillary pressure // law - ComponentVector pc; - MaterialLaw::capillaryPressures(pc, matParams, fs, wettingPhaseIdx_); + const auto pc = material.capillaryPressures(fs, wettingPhaseIdx_); for (int phaseIdx = 1; phaseIdx < numPhases; ++phaseIdx) fs.setPressure(phaseIdx, fs.pressure(0) diff --git a/test/material/compositionalflash/test_compositionalflash.cc b/test/material/compositionalflash/test_compositionalflash.cc index f7eeafed72..50f24900c9 100644 --- a/test/material/compositionalflash/test_compositionalflash.cc +++ b/test/material/compositionalflash/test_compositionalflash.cc @@ -39,10 +39,7 @@ #include #include -#include -#include -#include -#include +#include #include @@ -91,7 +88,7 @@ void checkSame(const FluidState1 &fsRef, const FluidState2 &fsFlash) } } -template +template void checkCompositionalFlash(const FluidState &fsRef) { enum { numPhases = FluidSystem::numPhases }; @@ -122,7 +119,7 @@ void checkCompositionalFlash(const FluidState &fsRef) checkSame(fsRef, fsFlash); } -template +template void checkCompositionalFlashSequential(const FluidState &fsRef, int refPhaseIdx) { enum { numPhases = FluidSystem::numPhases }; @@ -154,13 +151,12 @@ void checkCompositionalFlashSequential(const FluidState &fsRef, int refPhaseIdx) template void completeReferenceFluidState(FluidState &fs, - typename MaterialLaw::Params &matParams, + const MaterialLaw& material, int refPhaseIdx) { enum { numPhases = FluidSystem::numPhases }; using ComputeFromReferencePhase = Dumux::ComputeFromReferencePhase; - using PhaseVector = Dune::FieldVector; int otherPhaseIdx = 1 - refPhaseIdx; @@ -168,8 +164,7 @@ void completeReferenceFluidState(FluidState &fs, fs.setSaturation(otherPhaseIdx, 1.0 - fs.saturation(refPhaseIdx)); // calulate the capillary pressure - PhaseVector pc; - MaterialLaw::capillaryPressures(pc, matParams, fs, /*liquidPhaseIdx=*/0); + const auto pc = material.capillaryPressures(fs, /*liquidPhaseIdx=*/0); fs.setPressure(otherPhaseIdx, fs.pressure(refPhaseIdx) + (pc[otherPhaseIdx] - pc[refPhaseIdx])); @@ -184,7 +179,7 @@ void completeReferenceFluidState(FluidState &fs, template void completeReferenceFluidStateSequential(FluidState &fs, - typename MaterialLaw::Params &matParams, + const MaterialLaw& material, int refPhaseIdx) { enum { numPhases = FluidSystem::numPhases }; @@ -200,8 +195,7 @@ void completeReferenceFluidStateSequential(FluidState &fs, (1. - fs.moleFraction(refPhaseIdx, 0)) * FluidSystem::molarMass(1)); // calulate the capillary pressure - PhaseVector pc; - MaterialLaw::capillaryPressures(pc, matParams, fs, /*liquidPhaseIdx=*/0); + const auto pc = material.capillaryPressures(fs, /*liquidPhaseIdx=*/0); PhaseVector phasePressures(0.0); phasePressures[refPhaseIdx] = fs.pressure(refPhaseIdx); @@ -230,10 +224,8 @@ int main() enum { H2OIdx = FluidSystem::H2OIdx }; enum { N2Idx = FluidSystem::N2Idx }; - using EffMaterialLaw = Dumux::RegularizedBrooksCorey; - using MaterialLaw = Dumux::EffToAbsLaw; - using MaterialLawParams = MaterialLaw::Params; - using MPAdapter = Dumux::MPAdapter; + using MaterialLaw = Dumux::FluidMatrix::BrooksCoreyDefault; + using MPAdapter = Dumux::FluidMatrix::MPAdapter; Scalar T = 273.15 + 25; @@ -249,11 +241,8 @@ int main() FluidSystem::init(Tmin, Tmax, nT, pmin, pmax, np); // set the parameters for the capillary pressure law - MaterialLawParams matParams; - matParams.setSwr(0.0); - matParams.setSnr(0.0); - matParams.setPe(0); - matParams.setLambda(2.0); + MaterialLaw pcKrSw(typename MaterialLaw::BasicParams{/*pe*/0.0, /*lambda*/2.0}); + MPAdapter material(pcKrSw); CompositionalFluidState fsRef; FluidState1p2c fsRefSeq; @@ -287,18 +276,18 @@ int main() fsRef.setWettingPhase(wPhaseIdx); // "complete" the fluid state - completeReferenceFluidState(fsRef, matParams, liquidPhaseIdx); + completeReferenceFluidState(fsRef, material, liquidPhaseIdx); // check the flash calculation - checkCompositionalFlash(fsRef); + checkCompositionalFlash(fsRef); std::cout << "testing single-phase liquid for consistency with other sequential routines\n"; // "complete" the fluid state - completeReferenceFluidStateSequential(fsRefSeq, matParams, liquidPhaseIdx); + completeReferenceFluidStateSequential(fsRefSeq, material, liquidPhaseIdx); // check the flash calculation - checkCompositionalFlashSequential(fsRefSeq, liquidPhaseIdx); + checkCompositionalFlashSequential(fsRefSeq, liquidPhaseIdx); //////////////// // only gas @@ -319,18 +308,18 @@ int main() fsRefSeq.setMoleFraction(gasPhaseIdx, H2OIdx, 0.001); // "complete" the fluid state - completeReferenceFluidState(fsRef, matParams, gasPhaseIdx); + completeReferenceFluidState(fsRef, material, gasPhaseIdx); // check the flash calculation - checkCompositionalFlash(fsRef); + checkCompositionalFlash(fsRef); std::cout << "testing single-phase gas for consistency with other sequential routines\n"; // "complete" the fluid state - completeReferenceFluidStateSequential(fsRefSeq, matParams, gasPhaseIdx); + completeReferenceFluidStateSequential(fsRefSeq, material, gasPhaseIdx); // check the flash calculation - checkCompositionalFlashSequential(fsRefSeq, gasPhaseIdx); + checkCompositionalFlashSequential(fsRefSeq, gasPhaseIdx); //////////////// // both phases @@ -350,7 +339,7 @@ int main() MiscibleMultiPhaseComposition::solve(fsRef, paramCache); // check the flash calculation - checkCompositionalFlash(fsRef); + checkCompositionalFlash(fsRef); std::cout << "testing two-phase for consistency with other sequential routines\n"; @@ -363,18 +352,15 @@ int main() pressures, 0/*dummy*/, fsRef.temperature(0)); // check the flash calculation - checkCompositionalFlash(fsRef); + checkCompositionalFlash(fsRef); //////////////// // with capillary pressure //////////////// std::cout << "testing two-phase against implicit routines, including capillary pressure\n"; - MaterialLawParams matParams2; - matParams2.setSwr(0.0); - matParams2.setSnr(0.0); - matParams2.setPe(1e3); - matParams2.setLambda(2.0); + MaterialLaw pcKrS2(typename MaterialLaw::BasicParams{/*pe*/1e3, /*lambda*/2.0}); + MPAdapter material2(pcKrS2); // set gas saturation fsRef.setSaturation(gasPhaseIdx, 0.5); @@ -384,8 +370,7 @@ int main() fsRef.setPressure(liquidPhaseIdx, 1e6); // calulate the capillary pressure - PhaseVector pc; - MPAdapter::capillaryPressures(pc, matParams2, fsRef, /*wPhaseIdx=*/0); + const auto pc = material2.capillaryPressures(fsRef, /*wPhaseIdx=*/0); fsRef.setPressure(gasPhaseIdx, fsRef.pressure(liquidPhaseIdx) + (pc[gasPhaseIdx] - pc[liquidPhaseIdx])); @@ -395,7 +380,7 @@ int main() // check the flash calculation - checkCompositionalFlash(fsRef); + checkCompositionalFlash(fsRef); return 0; } diff --git a/test/material/immiscibleflash/test_immiscibleflash.cc b/test/material/immiscibleflash/test_immiscibleflash.cc index 6608553dd1..dff4e5f2a8 100644 --- a/test/material/immiscibleflash/test_immiscibleflash.cc +++ b/test/material/immiscibleflash/test_immiscibleflash.cc @@ -37,12 +37,8 @@ #include -#include #include -#include -#include -#include -#include +#include #include @@ -94,7 +90,7 @@ void checkSame(const FluidState &fsRef, const FluidState &fsFlash) template void checkImmiscibleFlash(const FluidState &fsRef, - typename MaterialLaw::Params &matParams) + const MaterialLaw& material) { enum { numPhases = FluidSystem::numPhases }; enum { numComponents = FluidSystem::numComponents }; @@ -120,7 +116,7 @@ void checkImmiscibleFlash(const FluidState &fsRef, // run the flash calculation typename FluidSystem::ParameterCache paramCache; flash.guessInitial(fsFlash, paramCache, globalMolarities); - flash.template solve(fsFlash, paramCache, matParams, globalMolarities); + flash.solve(fsFlash, paramCache, material, globalMolarities); // compare the "flashed" fluid state with the reference one checkSame(fsRef, fsFlash); @@ -129,21 +125,18 @@ void checkImmiscibleFlash(const FluidState &fsRef, template void completeReferenceFluidState(FluidState &fs, - typename MaterialLaw::Params &matParams, + const MaterialLaw& material, int refPhaseIdx) { enum { numPhases = FluidSystem::numPhases }; - using PhaseVector = Dune::FieldVector; - int otherPhaseIdx = 1 - refPhaseIdx; // calculate the other saturation fs.setSaturation(otherPhaseIdx, 1.0 - fs.saturation(refPhaseIdx)); // calulate the capillary pressure - PhaseVector pc; - MaterialLaw::capillaryPressures(pc, matParams, fs, /*wPhaseIdx=*/0); + const auto pc = material.capillaryPressures(fs, /*wPhaseIdx=*/0); fs.setPressure(otherPhaseIdx, fs.pressure(refPhaseIdx) + (pc[otherPhaseIdx] - pc[refPhaseIdx])); @@ -171,10 +164,7 @@ int main() enum { liquidPhaseIdx = FluidSystem::liquidPhaseIdx }; enum { gasPhaseIdx = FluidSystem::gasPhaseIdx }; - using EffMaterialLaw = Dumux::RegularizedBrooksCorey; - using MaterialLaw = Dumux::EffToAbsLaw; - using MPAdapter = Dumux::MPAdapter; - using MaterialLawParams = MaterialLaw::Params; + using PcKrSw = Dumux::FluidMatrix::BrooksCoreyDefault; Scalar T = 273.15 + 25; @@ -190,11 +180,9 @@ int main() FluidSystem::init(Tmin, Tmax, nT, pmin, pmax, np); // set the parameters for the capillary pressure law - MaterialLawParams matParams; - matParams.setSwr(0.0); - matParams.setSnr(0.0); - matParams.setPe(0); - matParams.setLambda(2.0); + typename PcKrSw::BasicParams bParams(/*pe*/0.0, /*lambda*/2.0); + auto pcKrSw = PcKrSw(bParams); + auto material = Dumux::FluidMatrix::MPAdapter(pcKrSw); ImmiscibleFluidState fsRef; @@ -213,10 +201,10 @@ int main() fsRef.setPressure(liquidPhaseIdx, 1e6); // set the remaining parameters of the reference fluid state - completeReferenceFluidState(fsRef, matParams, liquidPhaseIdx); + completeReferenceFluidState(fsRef, material, liquidPhaseIdx); // check the flash calculation - checkImmiscibleFlash(fsRef, matParams); + checkImmiscibleFlash(fsRef, material); //////////////// // only gas @@ -228,10 +216,10 @@ int main() fsRef.setPressure(gasPhaseIdx, 1e6); // set the remaining parameters of the reference fluid state - completeReferenceFluidState(fsRef, matParams, gasPhaseIdx); + completeReferenceFluidState(fsRef, material, gasPhaseIdx); // check the flash calculation - checkImmiscibleFlash(fsRef, matParams); + checkImmiscibleFlash(fsRef, material); //////////////// // both phases @@ -243,21 +231,19 @@ int main() fsRef.setPressure(liquidPhaseIdx, 1e6); // set the remaining parameters of the reference fluid state - completeReferenceFluidState(fsRef, matParams, liquidPhaseIdx); + completeReferenceFluidState(fsRef, material, liquidPhaseIdx); // check the flash calculation - checkImmiscibleFlash(fsRef, matParams); + checkImmiscibleFlash(fsRef, material); //////////////// // with capillary pressure //////////////// std::cout << "testing two-phase with capillary pressure\n"; - MaterialLawParams matParams2; - matParams2.setSwr(0.0); - matParams2.setSnr(0.0); - matParams2.setPe(1e3); - matParams2.setLambda(2.0); + typename PcKrSw::BasicParams bParams2(/*pe*/1e3, /*lambda*/2.0); + auto pcKrSw2 = PcKrSw(bParams2); + auto material2 = Dumux::FluidMatrix::MPAdapter(pcKrSw2); // set liquid saturation fsRef.setSaturation(liquidPhaseIdx, 0.5); @@ -266,10 +252,10 @@ int main() fsRef.setPressure(liquidPhaseIdx, 1e6); // set the remaining parameters of the reference fluid state - completeReferenceFluidState(fsRef, matParams2, liquidPhaseIdx); + completeReferenceFluidState(fsRef, material2, liquidPhaseIdx); // check the flash calculation - checkImmiscibleFlash(fsRef, matParams2); + checkImmiscibleFlash(fsRef, material2); return 0; } diff --git a/test/material/ncpflash/test_ncpflash.cc b/test/material/ncpflash/test_ncpflash.cc index d2e5001992..03603a686a 100644 --- a/test/material/ncpflash/test_ncpflash.cc +++ b/test/material/ncpflash/test_ncpflash.cc @@ -38,8 +38,7 @@ #include #include -#include -#include +#include #include @@ -90,7 +89,7 @@ void checkSame(const FluidState &fsRef, const FluidState &fsFlash) template void checkNcpFlash(const FluidState &fsRef, - typename MaterialLaw::Params &matParams) + const MaterialLaw& material) { enum { numPhases = FluidSystem::numPhases }; enum { numComponents = FluidSystem::numComponents }; @@ -116,7 +115,7 @@ void checkNcpFlash(const FluidState &fsRef, // run the flash calculation typename FluidSystem::ParameterCache paramCache; flash.guessInitial(fsFlash, paramCache, globalMolarities); - flash.template solve(fsFlash, paramCache, matParams, globalMolarities); + flash.solve(fsFlash, paramCache, material, globalMolarities); // compare the "flashed" fluid state with the reference one checkSame(fsRef, fsFlash); @@ -125,13 +124,12 @@ void checkNcpFlash(const FluidState &fsRef, template void completeReferenceFluidState(FluidState &fs, - typename MaterialLaw::Params &matParams, + const MaterialLaw& material, int refPhaseIdx) { enum { numPhases = FluidSystem::numPhases }; using ComputeFromReferencePhase = Dumux::ComputeFromReferencePhase; - using PhaseVector = Dune::FieldVector; int otherPhaseIdx = 1 - refPhaseIdx; @@ -139,8 +137,7 @@ void completeReferenceFluidState(FluidState &fs, fs.setSaturation(otherPhaseIdx, 1.0 - fs.saturation(refPhaseIdx)); // calulate the capillary pressure - PhaseVector pc; - MaterialLaw::capillaryPressures(pc, matParams, fs, /*wPhaseIdx=*/0); + const auto pc = material.capillaryPressures(fs, /*wPhaseIdx=*/0); fs.setPressure(otherPhaseIdx, fs.pressure(refPhaseIdx) + (pc[otherPhaseIdx] - pc[refPhaseIdx])); @@ -169,10 +166,7 @@ int main() enum { H2OIdx = FluidSystem::H2OIdx }; enum { N2Idx = FluidSystem::N2Idx }; - using EffMaterialLaw = Dumux::RegularizedBrooksCorey; - using MaterialLaw = Dumux::EffToAbsLaw; - using MaterialLawParams = MaterialLaw::Params; - using MPAdapter = Dumux::MPAdapter; + using PcKrSw = Dumux::FluidMatrix::BrooksCoreyDefault; Scalar T = 273.15 + 25; @@ -188,11 +182,9 @@ int main() FluidSystem::init(Tmin, Tmax, nT, pmin, pmax, np); // set the parameters for the capillary pressure law - MaterialLawParams matParams; - matParams.setSwr(0.0); - matParams.setSnr(0.0); - matParams.setPe(0); - matParams.setLambda(2.0); + typename PcKrSw::BasicParams bParams(/*pe*/0.0, /*lambda*/2.0); + auto pcKrSw = PcKrSw(bParams); + auto material = Dumux::FluidMatrix::MPAdapter(pcKrSw); CompositionalFluidState fsRef; @@ -219,10 +211,10 @@ int main() fsRef.setWettingPhase(wPhaseIdx); // "complete" the fluid state - completeReferenceFluidState(fsRef, matParams, liquidPhaseIdx); + completeReferenceFluidState(fsRef, material, liquidPhaseIdx); // check the flash calculation - checkNcpFlash(fsRef, matParams); + checkNcpFlash(fsRef, material); //////////////// // only gas @@ -239,10 +231,10 @@ int main() fsRef.setMoleFraction(gasPhaseIdx, H2OIdx, 0.001); // "complete" the fluid state - completeReferenceFluidState(fsRef, matParams, gasPhaseIdx); + completeReferenceFluidState(fsRef, material, gasPhaseIdx); // check the flash calculation - checkNcpFlash(fsRef, matParams); + checkNcpFlash(fsRef, material); //////////////// // both phases @@ -262,17 +254,15 @@ int main() MiscibleMultiPhaseComposition::solve(fsRef, paramCache); // check the flash calculation - checkNcpFlash(fsRef, matParams); + checkNcpFlash(fsRef, material); //////////////// // with capillary pressure //////////////// - MaterialLawParams matParams2; - matParams2.setSwr(0.0); - matParams2.setSnr(0.0); - matParams2.setPe(1e3); - matParams2.setLambda(2.0); + typename PcKrSw::BasicParams bParams2(/*pe*/1e3, /*lambda*/2.0); + auto pcKrSw2 = PcKrSw(bParams2); + auto material2 = Dumux::FluidMatrix::MPAdapter(pcKrSw2); // set gas saturation fsRef.setSaturation(gasPhaseIdx, 0.5); @@ -282,9 +272,7 @@ int main() fsRef.setPressure(liquidPhaseIdx, 1e6); // calulate the capillary pressure - using PhaseVector = Dune::FieldVector; - PhaseVector pc; - MPAdapter::capillaryPressures(pc, matParams2, fsRef, /*wPhaseIdx=*/0); + const auto pc = material2.capillaryPressures(fsRef, /*wPhaseIdx=*/0); fsRef.setPressure(gasPhaseIdx, fsRef.pressure(liquidPhaseIdx) + (pc[gasPhaseIdx] - pc[liquidPhaseIdx])); @@ -294,7 +282,7 @@ int main() // check the flash calculation - checkNcpFlash(fsRef, matParams2); + checkNcpFlash(fsRef, material2); return 0; } diff --git a/test/material/pengrobinson/test_pengrobinson.cc b/test/material/pengrobinson/test_pengrobinson.cc index e113c1648b..80865d29de 100644 --- a/test/material/pengrobinson/test_pengrobinson.cc +++ b/test/material/pengrobinson/test_pengrobinson.cc @@ -43,24 +43,19 @@ Scalar bringOilToSurface(FluidState &surfaceFluidState, Scalar alpha, const Flui numComponents = FluidSystem::numComponents }; - using MaterialLaw = Dumux::MpLinearMaterial; - using MaterialLawParams = typename MaterialLaw::Params; - using ComponentVector = Dune::FieldVector; - // create a flash Dumux::NcpFlash flash(/*wettingPhaseIdx=*/0); const Scalar refPressure = 1.0135e5; // [Pa] // set the parameters for the capillary pressure law - MaterialLawParams matParams; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - matParams.setPcMinSat(phaseIdx, 0.0); - matParams.setPcMaxSat(phaseIdx, 0.0); - } + using PcKrSw = Dumux::FluidMatrix::MPLinearMaterial; + typename PcKrSw::BasicParams params({}, {}); + PcKrSw pcKrSw(params); // retrieve the global volumetric component molarities surfaceFluidState.setTemperature(273.15 + 20); + using ComponentVector = Dune::FieldVector; ComponentVector molarities; for (int compIdx = 0; compIdx < numComponents; ++ compIdx) molarities[compIdx] = reservoirFluidState.molarity(oPhaseIdx, compIdx); @@ -95,7 +90,7 @@ Scalar bringOilToSurface(FluidState &surfaceFluidState, Scalar alpha, const Flui // calculate the deviation from the standard pressure tmpMolarities = molarities; tmpMolarities /= alpha; - flash.template solve(surfaceFluidState, paramCache, matParams, tmpMolarities); + flash.solve(surfaceFluidState, paramCache, pcKrSw, tmpMolarities); Scalar f = surfaceFluidState.pressure(gPhaseIdx) - refPressure; // calculate the derivative of the deviation from the standard @@ -103,7 +98,7 @@ Scalar bringOilToSurface(FluidState &surfaceFluidState, Scalar alpha, const Flui Scalar eps = alpha*1e-10; tmpMolarities = molarities; tmpMolarities /= alpha + eps; - flash.template solve(surfaceFluidState, paramCache, matParams, tmpMolarities); + flash.solve(surfaceFluidState, paramCache, pcKrSw, tmpMolarities); Scalar fStar = surfaceFluidState.pressure(gPhaseIdx) - refPressure; Scalar fPrime = (fStar - f)/eps; @@ -119,7 +114,7 @@ Scalar bringOilToSurface(FluidState &surfaceFluidState, Scalar alpha, const Flui // calculate the final result tmpMolarities = molarities; tmpMolarities /= alpha; - flash.template solve(surfaceFluidState, paramCache, matParams, tmpMolarities); + flash.solve(surfaceFluidState, paramCache, pcKrSw, tmpMolarities); return alpha; } @@ -144,12 +139,7 @@ int main(int argc, char** argv) C20Idx = FluidSystem::C20Idx }; - using ComponentVector = Dune::FieldVector; using FluidState = Dumux::CompositionalFluidState; - - using MaterialLaw = Dumux::MpLinearMaterial; - using MaterialLawParams = MaterialLaw::Params; - using ParameterCache = FluidSystem::ParameterCache; //////////// @@ -159,11 +149,9 @@ int main(int argc, char** argv) FluidSystem::init(); // set the parameters for the capillary pressure law - MaterialLawParams matParams; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - matParams.setPcMinSat(phaseIdx, 0.0); - matParams.setPcMaxSat(phaseIdx, 0.0); - } + using PcKrSw = Dumux::FluidMatrix::MPLinearMaterial; + typename PcKrSw::BasicParams params({}, {}); + PcKrSw pcKrSw(params); //////////// // Create a fluid state @@ -199,6 +187,7 @@ int main(int argc, char** argv) //////////// // Calculate the total molarities of the components //////////// + using ComponentVector = Dune::FieldVector; ComponentVector molarities; for (int compIdx = 0; compIdx < numComponents; ++ compIdx) molarities[compIdx] = fluidState.saturation(oPhaseIdx)*fluidState.molarity(oPhaseIdx, compIdx); @@ -213,7 +202,7 @@ int main(int argc, char** argv) FluidState flashFluidState, surfaceFluidState; flashFluidState.assign(fluidState); flash.guessInitial(flashFluidState, paramCache, molarities); - flash.solve(flashFluidState, paramCache, matParams, molarities); + flash.solve(flashFluidState, paramCache, pcKrSw, molarities); Scalar surfaceAlpha = 50; bringOilToSurface(surfaceFluidState, surfaceAlpha, flashFluidState, /*guessInitial=*/true); @@ -234,7 +223,7 @@ int main(int argc, char** argv) curMolarities /= alpha; // "flash" the modified reservoir oil - flash.solve(flashFluidState, paramCache, matParams, curMolarities); + flash.solve(flashFluidState, paramCache, pcKrSw, curMolarities); Scalar alphaSurface = bringOilToSurface(surfaceFluidState, surfaceAlpha, -- GitLab From e2eb7b40d1500b4c6b19dda3cedcbdd9c5b0da70 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 29 Oct 2020 23:50:26 +0100 Subject: [PATCH 58/99] [deprecated] Add deprecation helper for mp material laws --- dumux/common/deprecated.hh | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/dumux/common/deprecated.hh b/dumux/common/deprecated.hh index 15d3b9d2d1..047e82ed16 100644 --- a/dumux/common/deprecated.hh +++ b/dumux/common/deprecated.hh @@ -28,6 +28,7 @@ #include #include #include +#include namespace Dumux { @@ -188,6 +189,71 @@ auto makePcKrSw(const Scalar& scalar, } +/////////////////////////////////////////////////////////////// +// Deprecation warnings for the mp material law stuff // +/////////////////////////////////////////////////////////////// + +template +class PcKrSwMPHelper : public FluidMatrix::Adapter, FluidMatrix::MultiPhasePcKrSw> +{ + using MaterialLaw = typename SpatialParams::MaterialLaw; + using MPAdapter = Dumux::MPAdapter; +public: + using Scalar = ScalarT; + + // pass scalar so template arguments can all be deduced + PcKrSwMPHelper(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol, + const NumPhases& np) + : spatialParams_(sp), element_(element), scv_(scv), elemSol_(elemSol) + {} + + template + auto capillaryPressures(const FluidState& fs, int wPhaseIdx) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + Dune::FieldVector pc; + MPAdapter::capillaryPressures(pc, params, fs, wPhaseIdx); + return pc; + } + + template + auto relativePermeabilities(const FluidState& fs, int wPhaseIdx) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + Dune::FieldVector kr; + MPAdapter::capillaryPressures(kr, params, fs, wPhaseIdx); + return kr; + } + +private: + const SpatialParams& spatialParams_; + const Element& element_; + const Scv& scv_; + const ElemSol& elemSol_; +}; + +template +auto makeMPPcKrSw(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol, + const NumPhases& np) +{ + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + constexpr bool hasNew = decltype(isValid(HasNewFIAIF()).template check())::value; + constexpr bool hasNewAtPos = decltype(isValid(HasNewFIAIFAtPos()).template check())::value; + if constexpr (hasNew) + return sp.fluidMatrixInteraction(element, scv, elemSol); + else if constexpr (hasNewAtPos) + return sp.fluidMatrixInteractionAtPos(scv.center()); + else + return makeFluidMatrixInteraction(PcKrSwMPHelper(scalar, sp, element, scv, elemSol, np)); +} /////////////////////////////////////////////////////////////// // Deprecation warnings for the kinetic surface areas // -- GitLab From 0dc56527e6fa13ce878192478da77034cff5b41b Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 29 Oct 2020 23:51:48 +0100 Subject: [PATCH 59/99] [mpnc] Fix mpnc volume variables to support multiple phases again When using the old interface we hard code the MPAdapater like before in the volvars. When using new-sytle fluidmatrixinteractions we require the spatial params to return a MP-sytle material law. This can be acheived by simply wrapping a twop law using MPAdapter. --- .../porousmediumflow/mpnc/volumevariables.hh | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/dumux/porousmediumflow/mpnc/volumevariables.hh b/dumux/porousmediumflow/mpnc/volumevariables.hh index af207b8022..0ce2f71a60 100644 --- a/dumux/porousmediumflow/mpnc/volumevariables.hh +++ b/dumux/porousmediumflow/mpnc/volumevariables.hh @@ -34,7 +34,6 @@ #include #include #include -#include #include "pressureformulation.hh" namespace Dumux { @@ -74,6 +73,9 @@ class MPNCVolumeVariablesImplementation using EffDiffModel = typename Traits::EffectiveDiffusivityModel; using DiffusionCoefficients = typename Traits::DiffusionType::DiffusionCoefficientsContainer; + // remove this after deprecation period, i.e. after release 3.3 + static constexpr auto numPhases = std::integral_constant{}; + public: //! Export the type encapsulating primary variable indices using Indices = typename Traits::ModelTraits::Indices; @@ -115,13 +117,13 @@ public: // after the release of 3.3, when the deprecated interface is no longer supported. // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports // two phases anyway... - const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makeMPPcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol, numPhases); //calculate the remaining quantities const int wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); // relative permeabilities - using MPAdapter = FluidMatrix::MPAdapter; - MPAdapter::relativePermeabilities(relativePermeability_, fluidMatrixInteraction, fluidState_, wPhaseIdx); + const auto relPerm = fluidMatrixInteraction.relativePermeabilities(fluidState_, wPhaseIdx); + std::copy(relPerm.begin(), relPerm.end(), relativePermeability_.begin()); typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState_); @@ -192,11 +194,8 @@ public: // after the release of 3.3, when the deprecated interface is no longer supported. // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports // two phases anyway... - const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); - - std::array capPress; - using MPAdapter = FluidMatrix::MPAdapter; - MPAdapter::capillaryPressures(capPress, fluidMatrixInteraction, fluidState, wPhaseIdx); + const auto fluidMatrixInteraction = Deprecated::makeMPPcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol, numPhases); + const auto capPress = fluidMatrixInteraction.capillaryPressures(fluidState, wPhaseIdx); // add to the pressure of the first fluid phase // depending on which pressure is stored in the primary variables @@ -525,6 +524,9 @@ class MPNCVolumeVariablesImplementation using EffDiffModel = typename Traits::EffectiveDiffusivityModel; using DiffusionCoefficients = typename Traits::DiffusionType::DiffusionCoefficientsContainer; + // remove this after deprecation period, i.e. after release 3.3 + static constexpr auto numPhases = std::integral_constant{}; + public: //! Export the underlying fluid system using FluidSystem = typename Traits::FluidSystem; @@ -563,17 +565,14 @@ public: // calculate the remaining quantities const int wPhaseIdx = problem.spatialParams().template wettingPhase(element, scv, elemSol); - // relative permeabilities - using MPAdapter = FluidMatrix::MPAdapter; - // Old material law interface is deprecated: Replace this by // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol); // after the release of 3.3, when the deprecated interface is no longer supported. - // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports - // two phases anyway... - const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const auto fluidMatrixInteraction = Deprecated::makeMPPcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol, numPhases); + + const auto relPerm = fluidMatrixInteraction.relativePermeabilities(fluidState_, wPhaseIdx); + std::copy(relPerm.begin(), relPerm.end(), relativePermeability_.begin()); - MPAdapter::relativePermeabilities(relativePermeability_, fluidMatrixInteraction, fluidState_, wPhaseIdx); typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState_); @@ -639,11 +638,8 @@ public: // after the release of 3.3, when the deprecated interface is no longer supported. // We can safely use the two-p wrapper here without breaking compatibility because the MPAdapter only supports // two phases anyway... - const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol); - - std::vector capPress(numFluidPhases()); - using MPAdapter = FluidMatrix::MPAdapter; - MPAdapter::capillaryPressures(capPress, fluidMatrixInteraction, fluidState, wPhaseIdx); + const auto fluidMatrixInteraction = Deprecated::makeMPPcKrSw(Scalar{}, problem.spatialParams(), element, scv, elemSol, numPhases); + const auto capPress = fluidMatrixInteraction.capillaryPressures(fluidState, wPhaseIdx); // add to the pressure of the first fluid phase // depending on which pressure is stored in the primary variables -- GitLab From 2cf6ffb830f36bc1cb9136f6db8fdba18366629d Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Thu, 29 Oct 2020 23:52:23 +0100 Subject: [PATCH 60/99] [test][mpnc] Use new fluidmatrixinteraction interface --- .../mpnc/implicit/2p2ccomparison/params.input | 6 ++- .../mpnc/implicit/2p2ccomparison/problem.hh | 12 ++---- .../implicit/2p2ccomparison/spatialparams.hh | 43 +++++-------------- .../mpnc/implicit/kinetic/problem.hh | 6 +-- .../mpnc/implicit/kinetic/spatialparams.hh | 6 ++- .../mpnc/implicit/obstacle/problem.hh | 5 +-- .../mpnc/implicit/obstacle/spatialparams.hh | 4 +- .../implicit/thermalnonequilibrium/problem.hh | 5 +-- .../thermalnonequilibrium/spatialparams.hh | 4 +- 9 files changed, 35 insertions(+), 56 deletions(-) diff --git a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/params.input b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/params.input index 0ca290b167..2fe2cab440 100644 --- a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/params.input +++ b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/params.input @@ -6,9 +6,13 @@ TEnd = 1e4 # [s] UpperRight = 60 40 Cells = 24 16 +[SpatialParams] +Swr = 0.2 +BrooksCoreyPcEntry = 1e4 +BrooksCoreyLambda = 2.0 + [LinearSolver] ResidualReduction = 1e-12 [Problem] Name = obstacle - diff --git a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/problem.hh b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/problem.hh index b97fd347eb..14a844f864 100644 --- a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/problem.hh +++ b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/problem.hh @@ -261,20 +261,16 @@ private: // set pressure of the gas phase fs.setPressure(gasPhaseIdx, 1e5); // calulate the capillary pressure - const auto& matParams = - this->spatialParams().materialLawParamsAtPos(globalPos); - PhaseVector pc; - using MaterialLaw = typename ParentType::SpatialParams::MaterialLaw; - using MPAdapter = MPAdapter; - + const auto& fm = + this->spatialParams().fluidMatrixInteractionAtPos(globalPos); const int wPhaseIdx = this->spatialParams().template wettingPhaseAtPos(globalPos); - MPAdapter::capillaryPressures(pc, matParams, fs, wPhaseIdx); + const auto pc = fm.capillaryPressures(fs, wPhaseIdx); fs.setPressure(liquidPhaseIdx, fs.pressure(gasPhaseIdx) + pc[liquidPhaseIdx] - pc[gasPhaseIdx]); // make the fluid state consistent with local thermodynamic // equilibrium - using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition; + using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition; ParameterCache paramCache; MiscibleMultiPhaseComposition::solve(fs, paramCache); diff --git a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/spatialparams.hh b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/spatialparams.hh index b3697ee9d1..2478cbe98f 100644 --- a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/spatialparams.hh @@ -27,10 +27,8 @@ #include #include -#include -#include - -#include +#include +#include namespace Dumux { @@ -53,14 +51,16 @@ class MPNCComparisonSpatialParams MPNCComparisonSpatialParams>; using GlobalPosition = typename SubControlVolume::GlobalPosition; - using EffectiveLaw = RegularizedBrooksCorey; + + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; + using MPAdapter = Dumux::FluidMatrix::MPAdapter; public: using PermeabilityType = Scalar; - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; - MPNCComparisonSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + MPNCComparisonSpatialParams(std::shared_ptr gridGeometry) + : ParentType(gridGeometry) + , pcKrSw_("SpatialParams") { // intrinsic permeabilities coarseK_ = 1e-12; @@ -68,18 +68,6 @@ public: // the porosity porosity_ = 0.3; - - // residual saturations - fineMaterialParams_.setSwr(0.2); - fineMaterialParams_.setSnr(0.0); - coarseMaterialParams_.setSwr(0.2); - coarseMaterialParams_.setSnr(0.0); - - // parameters for the Brooks-Corey law - fineMaterialParams_.setPe(1e4); - coarseMaterialParams_.setPe(1e4); - fineMaterialParams_.setLambda(2.0); - coarseMaterialParams_.setLambda(2.0); } template @@ -95,7 +83,6 @@ public: /*! * \brief Defines the porosity \f$[-]\f$ of the soil - * * \param globalPos The global Position */ Scalar porosityAtPos(const GlobalPosition& globalPos) const @@ -105,23 +92,16 @@ public: /*! * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). - * * \param globalPos The global position of the sub-control volume. - * \return The material parameters object */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - if (isFineMaterial_(globalPos)) - return fineMaterialParams_; - else - return coarseMaterialParams_; + return makeFluidMatrixInteraction(MPAdapter(pcKrSw_)); } /*! * \brief Function for defining which phase is to be considered as the wetting phase. - * * \param globalPos The global position - * \return The wetting phase index */ template int wettingPhaseAtPos(const GlobalPosition& globalPos) const @@ -144,8 +124,7 @@ private: Scalar coarseK_; Scalar fineK_; Scalar porosity_; - MaterialLawParams fineMaterialParams_; - MaterialLawParams coarseMaterialParams_; + PcKrSwCurve pcKrSw_; static constexpr Scalar eps_ = 1e-6; }; diff --git a/test/porousmediumflow/mpnc/implicit/kinetic/problem.hh b/test/porousmediumflow/mpnc/implicit/kinetic/problem.hh index 8423989dd1..24ed4fb559 100644 --- a/test/porousmediumflow/mpnc/implicit/kinetic/problem.hh +++ b/test/porousmediumflow/mpnc/implicit/kinetic/problem.hh @@ -381,12 +381,10 @@ private: equilibriumFluidState.setTemperature(phaseIdx, TInitial_ ); } - std::vector capPress(numPhases); // obtain pc according to saturation - using MPAdapter = FluidMatrix::MPAdapter; - const int wPhaseIdx = this->spatialParams().template wettingPhaseAtPos(globalPos); - MPAdapter::capillaryPressures(capPress, this->spatialParams().fluidMatrixInteractionAtPos(globalPos), equilibriumFluidState, wPhaseIdx); + const auto& fm = this->spatialParams().fluidMatrixInteractionAtPos(globalPos); + const auto capPress = fm.capillaryPressures(equilibriumFluidState, wPhaseIdx); Scalar p[numPhases]; if (this->spatialParams().inPM_(globalPos)){ diff --git a/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh b/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh index 15c3c3863c..c1c2d0f1fc 100644 --- a/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh @@ -31,6 +31,7 @@ #include #include +#include #include @@ -62,6 +63,7 @@ class EvaporationAtmosphereSpatialParams static constexpr auto dimWorld = GridView::dimensionworld; using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; + using MPAdapter = Dumux::FluidMatrix::MPAdapter; using NonwettingSolidInterfacialArea = FluidMatrix::InterfacialArea Date: Fri, 30 Oct 2020 17:42:16 +0100 Subject: [PATCH 62/99] [changelog] Fix entry --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1544e1423..2c6e2137e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ Differences Between DuMux 3.3 and DuMux 3.2 ### Immediate interface changes not allowing/requiring a deprecation period: - __Flash/Constraintsolver__: The flashes depending on material laws are immediately required to use new-style material laws (fluidMatrixInteraction interface in spatialparams) - +- __Box interface solver__: The box interface solver immediately requires the new material law interface without deprecation period. Use the new class `BoxMaterialInterfaces` and update your spatial params to use the new fluidmatrixinteraction interface to be able to use the box interface solver in version 3.3. - For the "sequential" models, the property `BoundaryTypes` has been simply renamed to `SequentialBoundaryTypes` - __Quadmath__: Dumux::Quad has been removed without deprecation. Use Dune::Float128 instead. - Within the RANS group, two additional runtime parameters have been included 'IsFlatWallBounded' and 'WriteFlatWallBoundedFields'. @@ -72,7 +72,6 @@ An additional new option is `Vtk.CoordPrecision` which changes the precision of - __Van Genuchten__: Corrected VanGenuchten-Mualem exponent in the nonwetting saturation formula (`1/3` instead of `1/2` (or `l`, see above)) - __Van Genuchten__: Corrected VanGenuchten-Mualem implementation of `dkrn/dSw` - __Brooks-Corey__: Corrected Brooks-Corey implementation of `dkrn/dSw` and added the derivatives for the regularized version -- __Box interface solver__: The box interface solver immediately requires the new material law interface without deprecation period. Use the new class `BoxMaterialInterfaces` and update your spatial params to use the new fluidmatrixinteraction interface to be able to use the box interface solver in version 3.3. - __AMGBackend__: The internal structure of the AMGBackend and the ParallelISTLHelper has been overhauled, as only used by the AMG, we did not make the changes backwards-compatible - The global default parameters for linear solvers have been removed and moved to the class `LinearSolver`. This only affects users that directly obtain this parameter via `getParam` somewhere in the code. -- GitLab From 71fb1d0de891e26be3080dfe639e690126a3bc9a Mon Sep 17 00:00:00 2001 From: yue Date: Tue, 20 Oct 2020 12:38:10 +0200 Subject: [PATCH 63/99] [test][2p1c] new material law --- .../2p1c/implicit/params_box.input | 6 ++++++ .../2p1c/implicit/params_tpfa.input | 6 ++++++ .../2p1c/implicit/spatialparams.hh | 20 ++++++------------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/test/porousmediumflow/2p1c/implicit/params_box.input b/test/porousmediumflow/2p1c/implicit/params_box.input index 0cfbd646e1..c93fdeeb0c 100644 --- a/test/porousmediumflow/2p1c/implicit/params_box.input +++ b/test/porousmediumflow/2p1c/implicit/params_box.input @@ -13,3 +13,9 @@ Name = test_boxsteaminjection # name passed to the output routines SolidDensity = 2650 SolidThermalConductivity = 2.8 SolidHeatCapacity = 850.0 + +[SpatialParams] +Swr = 0.1 +Snr = 0 +VanGenuchtenAlpha = 0.0028 +VanGenuchtenN = 2.0 diff --git a/test/porousmediumflow/2p1c/implicit/params_tpfa.input b/test/porousmediumflow/2p1c/implicit/params_tpfa.input index 8d5fbbc7da..9b18fbb3c4 100644 --- a/test/porousmediumflow/2p1c/implicit/params_tpfa.input +++ b/test/porousmediumflow/2p1c/implicit/params_tpfa.input @@ -13,3 +13,9 @@ Name = test_ccsteaminjection # name passed to the output routines SolidDensity = 2650 SolidThermalConductivity = 2.8 SolidHeatCapacity = 850.0 + +[SpatialParams] +Swr = 0.1 +Snr = 0 +VanGenuchtenAlpha = 0.0028 +VanGenuchtenN = 2.0 diff --git a/test/porousmediumflow/2p1c/implicit/spatialparams.hh b/test/porousmediumflow/2p1c/implicit/spatialparams.hh index b298ab78a1..6046c2e3fa 100644 --- a/test/porousmediumflow/2p1c/implicit/spatialparams.hh +++ b/test/porousmediumflow/2p1c/implicit/spatialparams.hh @@ -27,8 +27,7 @@ #include #include -#include -#include +#include namespace Dumux { /*! @@ -53,23 +52,16 @@ class InjectionProblemSpatialParams using DimWorldMatrix = Dune::FieldMatrix; - using EffectiveLaw = RegularizedVanGenuchten; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = DimWorldMatrix; InjectionProblemSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { gasWetting_ = getParam("SpatialParams.GasWetting", false); - - // set Van Genuchten Parameters - materialParams_.setSwr(0.1); - materialParams_.setSnr(0.0); - materialParams_.setVgAlpha(0.0028); - materialParams_.setVgn(2.0); } /*! @@ -104,9 +96,9 @@ public: * * \param globalPos The global position */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } /*! @@ -126,7 +118,7 @@ public: private: bool gasWetting_; - MaterialLawParams materialParams_; + const PcKrSwCurve pcKrSwCurve_; }; } -- GitLab From cccc9e061735df6cc0c397e788f2173ff59b994a Mon Sep 17 00:00:00 2001 From: yue Date: Mon, 19 Oct 2020 19:57:44 +0200 Subject: [PATCH 64/99] [test][2p2c][injection] new material law --- .../2p2c/implicit/injection/params.input | 10 ++++++ .../2p2c/implicit/injection/spatialparams.hh | 32 ++++++------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/test/porousmediumflow/2p2c/implicit/injection/params.input b/test/porousmediumflow/2p2c/implicit/injection/params.input index 2a03857bf9..eba1e4ef07 100644 --- a/test/porousmediumflow/2p2c/implicit/injection/params.input +++ b/test/porousmediumflow/2p2c/implicit/injection/params.input @@ -24,3 +24,13 @@ TemperatureHigh = 314.15 # [Pa] upper temperature limit for tabularization PriVarNamesState1 = p_liq x^N2_liq PriVarNamesState2 = p_liq x^H2O_gas PriVarNamesState3 = p_liq S_gas + +[SpatialParams] +FineMaterial.Swr = 0.2 +FineMaterial.Snr = 0.0 +FineMaterial.BrooksCoreyPcEntry = 1e4 +FineMaterial.BrooksCoreyLambda = 2.0 +CoarseMaterial.Swr = 0.2 +CoarseMaterial.Snr = 0.0 +CoarseMaterial.BrooksCoreyPcEntry = 1e4 +CoarseMaterial.BrooksCoreyLambda = 2.0 diff --git a/test/porousmediumflow/2p2c/implicit/injection/spatialparams.hh b/test/porousmediumflow/2p2c/implicit/injection/spatialparams.hh index d23d12282e..5f74e016ad 100644 --- a/test/porousmediumflow/2p2c/implicit/injection/spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/injection/spatialparams.hh @@ -28,8 +28,7 @@ #include #include -#include -#include +#include namespace Dumux { @@ -51,19 +50,18 @@ class InjectionSpatialParams static constexpr int dimWorld = GridView::dimensionworld; - using EffectiveLaw = RegularizedBrooksCorey; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; public: //! Export the type used for the permeability using PermeabilityType = Scalar; - //! Export the material law type used - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; InjectionSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , finePcKrSwCurve_("SpatialParams.FineMaterial") + , coarsePcKrSwCurve_("SpatialParams.CoarseMaterial") { layerBottom_ = 22.5; @@ -74,18 +72,6 @@ public: // porosities finePorosity_ = 0.3; coarsePorosity_ = 0.3; - - // residual saturations - fineMaterialParams_.setSwr(0.2); - fineMaterialParams_.setSnr(0.0); - coarseMaterialParams_.setSwr(0.2); - coarseMaterialParams_.setSnr(0.0); - - // parameters for the Brooks-Corey law - fineMaterialParams_.setPe(1e4); - coarseMaterialParams_.setPe(1e4); - fineMaterialParams_.setLambda(2.0); - coarseMaterialParams_.setLambda(2.0); } /*! @@ -119,11 +105,11 @@ public: * * \param globalPos The global position */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + const auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { if (isFineMaterial_(globalPos)) - return fineMaterialParams_; - return coarseMaterialParams_; + return makeFluidMatrixInteraction(finePcKrSwCurve_); + return makeFluidMatrixInteraction(coarsePcKrSwCurve_); } /*! @@ -147,8 +133,8 @@ private: Scalar finePorosity_; Scalar coarsePorosity_; - MaterialLawParams fineMaterialParams_; - MaterialLawParams coarseMaterialParams_; + const PcKrSwCurve finePcKrSwCurve_; + const PcKrSwCurve coarsePcKrSwCurve_; }; } // end namespace Dumux -- GitLab From dd74aaed18ddfabe9bc6e4e958c27761e78671fa Mon Sep 17 00:00:00 2001 From: yue Date: Mon, 19 Oct 2020 20:06:13 +0200 Subject: [PATCH 65/99] [test][2p2c][mpnccomparison] new material law --- .../2p2c/implicit/mpnccomparison/params.input | 10 +++++ .../implicit/mpnccomparison/spatialparams.hh | 40 ++++++------------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/test/porousmediumflow/2p2c/implicit/mpnccomparison/params.input b/test/porousmediumflow/2p2c/implicit/mpnccomparison/params.input index 740e5317e7..7dbea708ca 100644 --- a/test/porousmediumflow/2p2c/implicit/mpnccomparison/params.input +++ b/test/porousmediumflow/2p2c/implicit/mpnccomparison/params.input @@ -11,3 +11,13 @@ ResidualReduction = 1e-12 [Problem] Name = obstacle_2p + +[SpatialParams] +FineMaterial.Swr = 0.2 +FineMaterial.Snr = 0.0 +FineMaterial.BrooksCoreyPcEntry = 1e4 +FineMaterial.BrooksCoreyLambda = 2.0 +CoarseMaterial.Swr = 0.2 +CoarseMaterial.Snr = 0.0 +CoarseMaterial.BrooksCoreyPcEntry = 1e4 +CoarseMaterial.BrooksCoreyLambda = 2.0 diff --git a/test/porousmediumflow/2p2c/implicit/mpnccomparison/spatialparams.hh b/test/porousmediumflow/2p2c/implicit/mpnccomparison/spatialparams.hh index d984c54cb9..4720777dba 100644 --- a/test/porousmediumflow/2p2c/implicit/mpnccomparison/spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/mpnccomparison/spatialparams.hh @@ -27,10 +27,7 @@ #include #include -#include -#include - -#include +#include namespace Dumux { @@ -55,17 +52,16 @@ class TwoPTwoCComparisonSpatialParams enum {dimWorld=GridView::dimensionworld}; - using EffectiveLaw = RegularizedBrooksCorey; + using PcKrSwCurve =FluidMatrix::BrooksCoreyDefault; public: //! Export permeability type using PermeabilityType = Scalar; - //! Export the type used for the material law - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; - - TwoPTwoCComparisonSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + TwoPTwoCComparisonSpatialParams(std::shared_ptr gridGeometry) + : ParentType(gridGeometry) + , finePcKrSwCurve_("SpatialParams.FineMaterial") + , coarsePcKrSwCurve_("SpatialParams.CoarseMaterial") { // intrinsic permeabilities coarseK_ = 1e-12; @@ -73,18 +69,6 @@ public: // the porosity porosity_ = 0.3; - - // residual saturations - fineMaterialParams_.setSwr(0.2); - fineMaterialParams_.setSnr(0.0); - coarseMaterialParams_.setSwr(0.2); - coarseMaterialParams_.setSnr(0.0); - - // parameters for the Brooks-Corey law - fineMaterialParams_.setPe(1e4); - coarseMaterialParams_.setPe(1e4); - fineMaterialParams_.setLambda(2.0); - coarseMaterialParams_.setLambda(2.0); } template @@ -115,12 +99,11 @@ public: * \param globalPos The global position of the sub-control volume. * \return The material parameters object */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { if (isFineMaterial_(globalPos)) - return fineMaterialParams_; - else - return coarseMaterialParams_; + return makeFluidMatrixInteraction(finePcKrSwCurve_); + return makeFluidMatrixInteraction(coarsePcKrSwCurve_); } /*! @@ -149,8 +132,9 @@ private: Scalar coarseK_; Scalar fineK_; Scalar porosity_; - MaterialLawParams fineMaterialParams_; - MaterialLawParams coarseMaterialParams_; + + const PcKrSwCurve finePcKrSwCurve_; + const PcKrSwCurve coarsePcKrSwCurve_; static constexpr Scalar eps_ = 1e-6; }; -- GitLab From 38b469b3a3aec5a071a777cdcc845d2aea3e1eae Mon Sep 17 00:00:00 2001 From: yue Date: Tue, 20 Oct 2020 12:55:58 +0200 Subject: [PATCH 66/99] [test][2p] new material law --- .../2p/implicit/adaptive/params.input | 10 +++++++ .../2p/implicit/cornerpoint/params.input | 6 +++++ .../2p/implicit/cornerpoint/spatialparams.hh | 21 ++++++--------- .../2p/implicit/fracture/params.input | 6 +++++ .../2p/implicit/fracture/spatialparams.hh | 27 +++++-------------- .../2p/implicit/nonisothermal/params.input | 10 +++++++ .../2p/implicit/rotationsymmetry/params.input | 6 +++++ .../rotationsymmetry/spatialparams.hh | 23 +++++----------- .../tracer/2ptracer/params.input | 14 ++++++++-- 9 files changed, 72 insertions(+), 51 deletions(-) diff --git a/test/porousmediumflow/2p/implicit/adaptive/params.input b/test/porousmediumflow/2p/implicit/adaptive/params.input index a650f89187..3f474517c3 100644 --- a/test/porousmediumflow/2p/implicit/adaptive/params.input +++ b/test/porousmediumflow/2p/implicit/adaptive/params.input @@ -13,6 +13,16 @@ ClosureType = Green LensLowerLeft = 1.0 2.0 # [m] coordinates of the lower left lens corner LensUpperRight = 4.0 3.0 # [m] coordinates of the upper right lens corner +[SpatialParams.Lens] +Swr = 0.18 +VanGenuchtenAlpha = 0.00045 +VanGenuchtenN = 7.3 + +[SpatialParams.Outer] +Swr = 0.05 +VanGenuchtenAlpha = 0.0037 +VanGenuchtenN = 4.7 + [Problem] Name = 2padaptive # name passed to the output routines diff --git a/test/porousmediumflow/2p/implicit/cornerpoint/params.input b/test/porousmediumflow/2p/implicit/cornerpoint/params.input index b4e0ef3e37..b9ecbd3a17 100644 --- a/test/porousmediumflow/2p/implicit/cornerpoint/params.input +++ b/test/porousmediumflow/2p/implicit/cornerpoint/params.input @@ -10,3 +10,9 @@ Name = cc2pcornerpoint # name passed to the output routines Homogeneous = 0 # use a homogeneous permeablity/porosity distribution InjectionElement = 0 # index of the element where injection should take place InjectionRate = 0.1 # injection rate in kg/s + +[SpatialParams] +Swr = 0.0 +Snr = 0.0 +VanGenuchtenAlpha = 0.00045 +VanGenuchtenN = 7.3; diff --git a/test/porousmediumflow/2p/implicit/cornerpoint/spatialparams.hh b/test/porousmediumflow/2p/implicit/cornerpoint/spatialparams.hh index 22d56066ea..f036ee2534 100644 --- a/test/porousmediumflow/2p/implicit/cornerpoint/spatialparams.hh +++ b/test/porousmediumflow/2p/implicit/cornerpoint/spatialparams.hh @@ -29,8 +29,7 @@ #include #include -#include -#include +#include namespace Dumux { @@ -52,19 +51,18 @@ class TwoPCornerPointTestSpatialParams static constexpr int dimWorld = GridView::dimensionworld; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using EffectiveLaw = RegularizedVanGenuchten; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; using DimWorldMatrix = Dune::FieldMatrix; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = DimWorldMatrix; TwoPCornerPointTestSpatialParams(std::shared_ptr gridGeometry, std::shared_ptr deck) : ParentType(gridGeometry) , deck_(deck) + , pcCurve_("SpatialParams") { homogeneous_ = getParam("Problem.Homogeneous"); @@ -115,9 +113,6 @@ public: permZ_ = permX_; } - // parameters for the Van Genuchten law - materialParams_.setVgAlpha(0.00045); - materialParams_.setVgn(7.3); } /*! @@ -170,11 +165,11 @@ public: * \return The material parameters object */ template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + auto fluidMatrixInteraction(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { - return materialParams_; + return makeFluidMatrixInteraction(pcCurve_); } /*! @@ -197,7 +192,7 @@ public: private: std::shared_ptr deck_; //!< the eclipse deck - MaterialLawParams materialParams_; + PcKrSwCurve pcCurve_; std::vector porosity_; std::vector permX_; std::vector permZ_; diff --git a/test/porousmediumflow/2p/implicit/fracture/params.input b/test/porousmediumflow/2p/implicit/fracture/params.input index 666a5013f6..fa2fb1f686 100644 --- a/test/porousmediumflow/2p/implicit/fracture/params.input +++ b/test/porousmediumflow/2p/implicit/fracture/params.input @@ -15,3 +15,9 @@ ResidualReduction = 1e-16 [Newton] MaxRelativeShift = 1e-10 + +[SpatialParams] +Swr = 0.05 +Snr = 0.0 +VanGenuchtenN = 4.7 +VanGenuchtenAlpha = 0.0037 diff --git a/test/porousmediumflow/2p/implicit/fracture/spatialparams.hh b/test/porousmediumflow/2p/implicit/fracture/spatialparams.hh index d9d13cedc8..66adff4cd3 100644 --- a/test/porousmediumflow/2p/implicit/fracture/spatialparams.hh +++ b/test/porousmediumflow/2p/implicit/fracture/spatialparams.hh @@ -27,9 +27,7 @@ #define DUMUX_TWOP_FRACTURE_TEST_SPATIALPARAMS_HH #include -#include -#include -#include +#include #include @@ -54,27 +52,16 @@ class FractureSpatialParams using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using EffectiveLaw = RegularizedVanGenuchten; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; public: //! export permeability type using PermeabilityType = Scalar; - //! export the type used for the material law - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; FractureSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) - { - // residual saturations - materialParams_.setSwr(0.05); - materialParams_.setSnr(0.0); - - // parameters for the Van Genuchten law - // alpha and n - materialParams_.setVgAlpha(0.0037); - materialParams_.setVgn(4.7); - } + , pcKrSwCurve_("SpatialParams") + {} /*! * \brief Returns the scalar intrinsic permeability \f$[m^2]\f$ @@ -97,8 +84,8 @@ public: * * \param globalPos The position at which we evaluate */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { return materialParams_; } + auto fluidMatrixInteractionAtPos (const GlobalPosition& globalPos) const + { return makeFluidMatrixInteraction(pcKrSwCurve_); } /*! * \brief Function for defining which phase is to be considered as the wetting phase. @@ -111,7 +98,7 @@ public: { return FluidSystem::phase0Idx; } private: - MaterialLawParams materialParams_; + PcKrSwCurve pcKrSwCurve_; }; } // end namespace Dumux diff --git a/test/porousmediumflow/2p/implicit/nonisothermal/params.input b/test/porousmediumflow/2p/implicit/nonisothermal/params.input index e30e238016..246559beea 100644 --- a/test/porousmediumflow/2p/implicit/nonisothermal/params.input +++ b/test/porousmediumflow/2p/implicit/nonisothermal/params.input @@ -17,3 +17,13 @@ WriteConvergence = 1 # write convergence behaviour to disk? SolidDensity = 2700 SolidThermalConductivity = 2.8 SolidHeatCapacity = 790 + +[SpatialParams] +FineMaterial.Swr = 0.2 +FineMaterial.Snr = 0.0 +FineMaterial.BrooksCoreyPcEntry = 1e4 +FineMaterial.BrooksCoreyLambda = 2.0 +CoarseMaterial.Swr = 0.2 +CoarseMaterial.Snr = 0.0 +CoarseMaterial.BrooksCoreyPcEntry = 1e4 +CoarseMaterial.BrooksCoreyLambda = 2.0 diff --git a/test/porousmediumflow/2p/implicit/rotationsymmetry/params.input b/test/porousmediumflow/2p/implicit/rotationsymmetry/params.input index efe4baef16..49bd7c80bb 100644 --- a/test/porousmediumflow/2p/implicit/rotationsymmetry/params.input +++ b/test/porousmediumflow/2p/implicit/rotationsymmetry/params.input @@ -12,3 +12,9 @@ EnableGravity = true [Vtk] OutputInterval = 50 + +[SpatialParams] +Swr = 0.0 +Snr = 0.0 +BrooksCoreyPcEntry = 0.0 +BrooksCoreyLambda = 2.0 diff --git a/test/porousmediumflow/2p/implicit/rotationsymmetry/spatialparams.hh b/test/porousmediumflow/2p/implicit/rotationsymmetry/spatialparams.hh index da0361a7f8..fb0346fb2c 100644 --- a/test/porousmediumflow/2p/implicit/rotationsymmetry/spatialparams.hh +++ b/test/porousmediumflow/2p/implicit/rotationsymmetry/spatialparams.hh @@ -24,8 +24,7 @@ #define DUMUX_TEST_TWOP_ROTATIONALSYMMETRY_SPATIAL_PARAMS_HH #include -#include -#include +#include namespace Dumux { @@ -38,22 +37,14 @@ class TwoPRotationalSymmetrySpatialParams using Element = typename GridGeometry::GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; public: - using MaterialLaw = EffToAbsLaw>; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; TwoPRotationalSymmetrySpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) - { - // residual saturations - materialLawParams_.setSwr(0.0); - materialLawParams_.setSnr(0.0); - - // parameters for the material law - materialLawParams_.setPe(0.0); - materialLawParams_.setLambda(2.0); - } + ,pcKrSwCurve_("SpatialParams") + {} PermeabilityType permeabilityAtPos(const GlobalPosition& globalPos) const { return 1e-11; } @@ -61,15 +52,15 @@ public: Scalar porosityAtPos(const GlobalPosition& globalPos) const { return 0.4; } - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { return materialLawParams_; } + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const + { return makeFluidMatrixInteraction(pcKrSwCurve_); } template int wettingPhaseAtPos(const GlobalPosition& globalPos) const { return FluidSystem::phase0Idx; } private: - MaterialLawParams materialLawParams_; + const PcKrSwCurve pcKrSwCurve_; }; } // end namespace Dumux diff --git a/test/porousmediumflow/tracer/2ptracer/params.input b/test/porousmediumflow/tracer/2ptracer/params.input index bf62610a95..ea81574f6b 100644 --- a/test/porousmediumflow/tracer/2ptracer/params.input +++ b/test/porousmediumflow/tracer/2ptracer/params.input @@ -10,8 +10,18 @@ Cells = 48 32 [SpatialParams] LensLowerLeft = 1.0 2.0 # [m] coordinates of the lower left lens corner LensUpperRight = 4.0 3.0 # [m] coordinates of the upper right lens corner -outerK = 1e-09 # [m^2] -lensK = 1e-12 # [m^2] + +[SpatialParams.Lens] +Swr = 0.18 +VanGenuchtenAlpha = 0.00045 +VanGenuchtenN = 7.3 +Permeability = 1e-12 # [m^2] + +[SpatialParams.Outer] +Swr = 0.05 +VanGenuchtenAlpha = 0.0037 +VanGenuchtenN = 4.7 +Permeability = 1e-09 # [m^2] [Problem] Name = test_2ptracer_lens_tpfa -- GitLab From ed7b8202d2bca8eed45064bad3af1b22029f0cd0 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 20:44:18 +0100 Subject: [PATCH 67/99] [test][2ptracer] Use constexr if --- test/porousmediumflow/tracer/2ptracer/main.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/porousmediumflow/tracer/2ptracer/main.cc b/test/porousmediumflow/tracer/2ptracer/main.cc index ddb9ec50e5..cb08ccc40a 100644 --- a/test/porousmediumflow/tracer/2ptracer/main.cc +++ b/test/porousmediumflow/tracer/2ptracer/main.cc @@ -107,8 +107,8 @@ int main(int argc, char** argv) auto pOld = p; // maybe update the interface parameters - if (ENABLEINTERFACESOLVER) - twoPProblem->spatialParams().updateMaterialInterfaceParams(p); + if constexpr (ENABLEINTERFACESOLVER) + twoPProblem->spatialParams().updateMaterialInterfaces(p); // the grid variables using TwoPGridVariables = GetPropType; -- GitLab From f4179c680a475c0a980c0f1cc42fc54216cfd486 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 17:59:26 +0100 Subject: [PATCH 68/99] [test][2p2c/chemicalnonq] New material law --- .../chemicalnonequilibrium/params.input | 4 + .../chemicalnonequilibrium/spatialparams.hh | 122 ++++-------------- 2 files changed, 32 insertions(+), 94 deletions(-) diff --git a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/params.input b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/params.input index 353c491f26..75971a389a 100644 --- a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/params.input +++ b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/params.input @@ -17,6 +17,10 @@ WettingNonwettingAreaA2 = 1.429e-05 WettingNonwettingAreaA3 = 1.915e-01 MeanPoreSize = 5e-4 MassTransferFactor = 0.5 +BrooksCoreyPcEntry = 1e4 +BrooksCoreyLambda = 2.0 +Swr = 0.2 +Snr = 0.1 [Component] SolidDensity = 2700 diff --git a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh index 50f229a158..415d821956 100644 --- a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh @@ -28,16 +28,11 @@ #include #include #include -#include -#include -#include +#include +#include +#include -// material laws for interfacial area -#include -#include -#include -#include namespace Dumux { /** @@ -61,49 +56,34 @@ class TwoPTwoCChemicalNonequilibriumSpatialParams enum {dimWorld=GridView::dimensionworld}; - using EffectiveLaw = RegularizedBrooksCorey; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; + using WettingNonwettingInterfacialArea = FluidMatrix::InterfacialArea; public: //! Export permeability type using PermeabilityType = Scalar; - //! Export the type used for the material law - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; - using EffectiveIALawAwn = AwnSurfacePcMaxFct; - using AwnSurface = EffToAbsLawIA; - using AwnSurfaceParams = typename AwnSurface::Params; TwoPTwoCChemicalNonequilibriumSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , permeability_(1e-11) + , porosity_(0.4) + , pcKrSwCurve_("SpatialParams") { - // intrinsic permeabilities - coarseK_ = 1e-11; - - // the porosity - porosity_ = 0.4; - - // residual saturations - coarseMaterialParams_.setSwr(0.2); - coarseMaterialParams_.setSnr(0.1); - - // parameters for the Brooks-Corey law - coarseMaterialParams_.setPe(1e4); - coarseMaterialParams_.setLambda(2.0); + characteristicLength_ = getParam("SpatialParams.MeanPoreSize"); + factorMassTransfer_ = getParam("SpatialParams.MassTransferFactor"); - aWettingNonwettingA1_ = getParam("SpatialParams.WettingNonwettingAreaA1"); - aWettingNonwettingA2_ = getParam("SpatialParams.WettingNonwettingAreaA2"); - aWettingNonwettingA3_ = getParam("SpatialParams.WettingNonwettingAreaA3"); + using WettingNonwettingInterfacialAreaParams = typename WettingNonwettingInterfacialArea::BasicParams; + WettingNonwettingInterfacialAreaParams anwParams; + anwParams.setA1(getParam("SpatialParams.WettingNonwettingAreaA1")); + anwParams.setA2(getParam("SpatialParams.WettingNonwettingAreaA2")); + anwParams.setA3(getParam("SpatialParams.WettingNonwettingAreaA3")); - // wetting-non wetting: surface which goes to zero on the edges, but is a polynomial - aWettingNonwettingSurfaceParams_.setA1(aWettingNonwettingA1_); - aWettingNonwettingSurfaceParams_.setA2(aWettingNonwettingA2_); - aWettingNonwettingSurfaceParams_.setA3(aWettingNonwettingA3_); // determine maximum capillary pressure for wetting-nonwetting surface - using TwoPLaw = EffToAbsLaw>; - pcMax_ = TwoPLaw::pc(coarseMaterialParams_, /*sw = */0.0); - aWettingNonwettingSurfaceParams_.setPcMax(pcMax_); - characteristicLength_ =getParam("SpatialParams.MeanPoreSize"); - factorMassTransfer_ = getParam("SpatialParams.MassTransferFactor"); + anwParams.setPcMax(pcKrSwCurve_.pc(/*sw = */0.0)); + + aNw_ = std::make_unique(anwParams); } template @@ -111,7 +91,7 @@ public: const SubControlVolume& scv, const ElementSolution& elemSol) const { - return coarseK_; + return permeability_; } /*! @@ -126,53 +106,13 @@ public: } /*! - * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). - * - * \param globalPos The global position of the sub-control volume. - * \return The material parameters object - */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { - return coarseMaterialParams_; - } - - /*!\brief Returns a reference to the container object for the - * parametrization of the surface between wetting and nonwetting phase. - * - * The position is determined based on the coordinate of - * the vertex belonging to the considered sub-control volume. - * - * \param element The finite element - * \param scv The sub-control volume - * \param elemSol The element solution + * \brief Returns the parameters for the material law at a given location */ - template - const AwnSurfaceParams& aWettingNonwettingSurfaceParams(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return aWettingNonwettingSurfaceParams_ ; + return makeFluidMatrixInteraction(pcKrSwCurve_, *aNw_); } - /*!\brief Returns the maximum capillary pressure for the given pc-Sw curve - * - * Of course physically there is no such thing as a maximum capillary pressure. - * The parametrization (VG/BC) goes to infinity and physically there is only one pressure - * for single phase conditions. - * Here, this is used for fitting the interfacial area surface: the capillary pressure, - * where the interfacial area is zero. - * Technically this value is obtained as the capillary pressure of saturation zero. - * This value of course only exists for the case of a regularized pc-Sw relation. - * \param element The finite element - * \param scv The sub-control volume - * \param elemSol The element solution - */ - template - const Scalar pcMax(const Element &element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const - { return aWettingNonwettingSurfaceParams_.pcMax() ; } - /*! * \brief Returns the characteristic length for the mass transfer. * @@ -201,18 +141,12 @@ public: private: - Scalar coarseK_; - Scalar porosity_; - MaterialLawParams coarseMaterialParams_; + const Scalar permeability_; + const Scalar porosity_; static constexpr Scalar eps_ = 1e-6; - AwnSurfaceParams aWettingNonwettingSurfaceParams_; - Scalar pcMax_ ; - - // interfacial area parameters - Scalar aWettingNonwettingA1_ ; - Scalar aWettingNonwettingA2_ ; - Scalar aWettingNonwettingA3_ ; + const PcKrSwCurve pcKrSwCurve_; + std::unique_ptr aNw_; Scalar factorMassTransfer_ ; Scalar characteristicLength_ ; -- GitLab From 79fbcd2c15ee7f4ac42ecdc3f2a9fbfb9e579669 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 18:34:48 +0100 Subject: [PATCH 69/99] [fluidmatrixinteraction][2pmateriallaw] Add make functions for parameters --- .../fluidmatrixinteractions/2p/materiallaw.hh | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2p/materiallaw.hh b/dumux/material/fluidmatrixinteractions/2p/materiallaw.hh index 6a9b098725..f08fbbf2b4 100644 --- a/dumux/material/fluidmatrixinteractions/2p/materiallaw.hh +++ b/dumux/material/fluidmatrixinteractions/2p/materiallaw.hh @@ -88,8 +88,8 @@ public: * \note This will give you nice error messages if a mandatory parameter is missing */ explicit TwoPMaterialLaw(const std::string& paramGroup) - : basicParams_(BaseLaw::template makeParams(paramGroup)) - , effToAbsParams_(EffToAbs::template makeParams(paramGroup)) + : basicParams_(makeBasicParams(paramGroup)) + , effToAbsParams_(makeEffToAbsParams(paramGroup)) { if constexpr (isRegularized()) regularization_.init(this, paramGroup); @@ -261,9 +261,33 @@ public: && regularization_ == o.regularization_; } + /*! + * \brief Create the base law's parameters using + * input file parameters + */ + static BasicParams makeBasicParams(const std::string& paramGroup) + { + return BaseLaw::template makeParams(paramGroup); + } + + /*! + * \brief Return the base law's parameters + */ const BasicParams& basicParams() const { return basicParams_; } + /*! + * \brief Create the parameters of the EffToAbs policy using + * input file parameters + */ + static EffToAbsParams makeEffToAbsParams(const std::string& paramGroup) + { + return EffToAbs::template makeParams(paramGroup); + } + + /*! + * \brief Return the parameters of the EffToAbs policy + */ const EffToAbsParams& effToAbsParams() const { return effToAbsParams_; } -- GitLab From 796bd902ac477d7bd822d1f2cadd3411952eb288 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 18:35:07 +0100 Subject: [PATCH 70/99] [fluidmatrixinteraction][2pinterfacialarea] Add make functions for parameters --- .../2p/interfacialarea/interfacialarea.hh | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/interfacialarea.hh b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/interfacialarea.hh index 722c8caaec..afd05170b7 100644 --- a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/interfacialarea.hh +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/interfacialarea.hh @@ -80,10 +80,9 @@ public: * \note This will give you nice error messages if a mandatory parameter is missing */ explicit InterfacialArea(const std::string& paramGroup) + : basicParams_(makeBasicParams(paramGroup)) + , effToAbsParams_(makeEffToAbsParams(paramGroup)) { - basicParams_ = BaseLaw::template makeParams(paramGroup); - effToAbsParams_ = EffToAbs::template makeParams(paramGroup); - if constexpr (isRegularized()) regularization_.init(this, paramGroup); } @@ -161,9 +160,33 @@ public: && regularization_ == o.regularization_; } + /*! + * \brief Create the base law's parameters using + * input file parameters + */ + static BasicParams makeBasicParams(const std::string& paramGroup) + { + return BaseLaw::template makeParams(paramGroup); + } + + /*! + * \brief Return the base law's parameters + */ const BasicParams& basicParams() const { return basicParams_; } + /*! + * \brief Create the parameters of the EffToAbs policy using + * input file parameters + */ + static EffToAbsParams makeEffToAbsParams(const std::string& paramGroup) + { + return EffToAbs::template makeParams(paramGroup); + } + + /*! + * \brief Return the parameters of the EffToAbs policy + */ const EffToAbsParams& effToAbsParams() const { return effToAbsParams_; } -- GitLab From 4fd1506404ae4b47c62d0eb0e9eeb96faf17eebe Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 18:35:46 +0100 Subject: [PATCH 71/99] [test][2p/chemicalnoneq] Use new make function --- .../2p2c/implicit/chemicalnonequilibrium/params.input | 7 ++++--- .../2p2c/implicit/chemicalnonequilibrium/spatialparams.hh | 6 +----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/params.input b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/params.input index 75971a389a..1b6a94cf71 100644 --- a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/params.input +++ b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/params.input @@ -12,9 +12,10 @@ Name = chemicalnonequilibrium EnableGravity = false [SpatialParams] -WettingNonwettingAreaA1 = -1.603e-01 -WettingNonwettingAreaA2 = 1.429e-05 -WettingNonwettingAreaA3 = 1.915e-01 +WettingNonwettingArea.PcMax = 0 # will be overwritten internally +WettingNonwettingArea.A1 = -1.603e-01 +WettingNonwettingArea.A2 = 1.429e-05 +WettingNonwettingArea.A3 = 1.915e-01 MeanPoreSize = 5e-4 MassTransferFactor = 0.5 BrooksCoreyPcEntry = 1e4 diff --git a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh index 415d821956..73efbc3e0a 100644 --- a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh @@ -74,11 +74,7 @@ public: characteristicLength_ = getParam("SpatialParams.MeanPoreSize"); factorMassTransfer_ = getParam("SpatialParams.MassTransferFactor"); - using WettingNonwettingInterfacialAreaParams = typename WettingNonwettingInterfacialArea::BasicParams; - WettingNonwettingInterfacialAreaParams anwParams; - anwParams.setA1(getParam("SpatialParams.WettingNonwettingAreaA1")); - anwParams.setA2(getParam("SpatialParams.WettingNonwettingAreaA2")); - anwParams.setA3(getParam("SpatialParams.WettingNonwettingAreaA3")); + auto anwParams = WettingNonwettingInterfacialArea::makeBasicParams("SpatialParams.WettingNonwettingArea"); // determine maximum capillary pressure for wetting-nonwetting surface anwParams.setPcMax(pcKrSwCurve_.pc(/*sw = */0.0)); -- GitLab From 2c97131c451fa2bbd0cc761a5af10137a9173734 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 18:43:44 +0100 Subject: [PATCH 72/99] [test][richardsni] New material law --- .../nonisothermal/conduction/params.input | 6 +++ .../nonisothermal/convection/params.input | 6 +++ .../nonisothermal/evaporation/params.input | 6 +++ .../implicit/nonisothermal/spatialparams.hh | 39 ++++++------------- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/test/porousmediumflow/richards/implicit/nonisothermal/conduction/params.input b/test/porousmediumflow/richards/implicit/nonisothermal/conduction/params.input index 0304a8a780..03be824f3d 100644 --- a/test/porousmediumflow/richards/implicit/nonisothermal/conduction/params.input +++ b/test/porousmediumflow/richards/implicit/nonisothermal/conduction/params.input @@ -19,3 +19,9 @@ EnableChop = false # chop for better convergence SolidDensity = 2700 SolidThermalConductivity = 2.8 SolidHeatCapacity = 790 + +[SpatialParams] +Swr = 0.05 +Snr = 0.0 +VanGenuchtenAlpha = 0.0037 +VanGenuchtenN = 4.7 diff --git a/test/porousmediumflow/richards/implicit/nonisothermal/convection/params.input b/test/porousmediumflow/richards/implicit/nonisothermal/convection/params.input index a286867c03..e0841d4f4a 100644 --- a/test/porousmediumflow/richards/implicit/nonisothermal/convection/params.input +++ b/test/porousmediumflow/richards/implicit/nonisothermal/convection/params.input @@ -20,3 +20,9 @@ EnableChop = false # chop for better convergence SolidDensity = 2700 SolidThermalConductivity = 2.8 SolidHeatCapacity = 790 + +[SpatialParams] +Swr = 0.05 +Snr = 0.0 +VanGenuchtenAlpha = 0.0037 +VanGenuchtenN = 4.7 diff --git a/test/porousmediumflow/richards/implicit/nonisothermal/evaporation/params.input b/test/porousmediumflow/richards/implicit/nonisothermal/evaporation/params.input index 1f6701d4ef..49e1c6baa0 100644 --- a/test/porousmediumflow/richards/implicit/nonisothermal/evaporation/params.input +++ b/test/porousmediumflow/richards/implicit/nonisothermal/evaporation/params.input @@ -20,3 +20,9 @@ EnableChop = false # chop for better convergence SolidDensity = 2700 SolidThermalConductivity = 2.8 SolidHeatCapacity = 790 + +[SpatialParams] +Swr = 0.05 +Snr = 0.0 +VanGenuchtenAlpha = 0.0037 +VanGenuchtenN = 4.7 diff --git a/test/porousmediumflow/richards/implicit/nonisothermal/spatialparams.hh b/test/porousmediumflow/richards/implicit/nonisothermal/spatialparams.hh index 6b6da0eb44..7afce1ac6a 100644 --- a/test/porousmediumflow/richards/implicit/nonisothermal/spatialparams.hh +++ b/test/porousmediumflow/richards/implicit/nonisothermal/spatialparams.hh @@ -26,9 +26,7 @@ #define DUMUX_RICHARDSNI_SPATIAL_PARAMS_HH #include -#include -#include -#include +#include #include namespace Dumux { @@ -47,33 +45,20 @@ class RichardsNISpatialParams enum { dimWorld=GridView::dimensionworld }; - using EffectiveLaw = RegularizedVanGenuchten; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; + public: // export permeability type using PermeabilityType = Scalar; - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; - RichardsNISpatialParams(std::shared_ptr gridGeometry) - : ParentType(gridGeometry) + : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { permeability_ = 1e-10; porosity_ = 0.4; - - - // residual saturations - materialParams_.setSwr(0.05); - materialParams_.setSnr(0.0); - - // parameters for the Van Genuchten law - // alpha and n - - materialParams_.setVgAlpha(0.0037); - materialParams_.setVgn(4.7); } /*! @@ -96,20 +81,18 @@ public: return porosity_; } - /*! - * \brief Returns the parameter object for the Brooks-Corey material law - * which depends on the position - * - * \param globalPos The global position where we evaluate + /*! + * \brief Returns the parameters for the material law at a given location + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition &globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } private: - MaterialLawParams materialParams_; + const PcKrSwCurve pcKrSwCurve_; Scalar permeability_; Scalar porosity_; }; -- GitLab From 16d51024fee90489dc7fe97b65a6c880bc302ef2 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 18:51:35 +0100 Subject: [PATCH 73/99] [test][richardsnc] New material law --- .../richardsnc/implicit/params.input | 10 +++++ .../richardsnc/implicit/problem.hh | 5 +-- .../richardsnc/implicit/spatialparams.hh | 40 ++++++------------- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/test/porousmediumflow/richardsnc/implicit/params.input b/test/porousmediumflow/richardsnc/implicit/params.input index ebded49d42..366a917b75 100644 --- a/test/porousmediumflow/richardsnc/implicit/params.input +++ b/test/porousmediumflow/richardsnc/implicit/params.input @@ -25,3 +25,13 @@ AddVelocity = true [Newton] EnableChop = false + +[SpatialParams] +Lens.Swr = 0.18 +Lens.Snr = 0.0 +Lens.VanGenuchtenAlpha = 0.00045 +Lens.VanGenuchtenN = 7.3 +OuterDomain.Swr = 0.05 +OuterDomain.Snr = 0.0 +OuterDomain.VanGenuchtenAlpha = 0.0037 +OuterDomain.VanGenuchtenN = 4.7 diff --git a/test/porousmediumflow/richardsnc/implicit/problem.hh b/test/porousmediumflow/richardsnc/implicit/problem.hh index 4986d23678..2f2a70d73f 100644 --- a/test/porousmediumflow/richardsnc/implicit/problem.hh +++ b/test/porousmediumflow/richardsnc/implicit/problem.hh @@ -144,9 +144,8 @@ public: pumpRate_ = getParam("Problem.PumpRate"); // in kg/s // for initial conditions - const Scalar sw = 0.4; // start with 80% saturation on top - using MaterialLaw = typename ParentType::SpatialParams::MaterialLaw; - pcTop_ = MaterialLaw::pc(this->spatialParams().materialLawParamsAtPos(this->gridGeometry().bBoxMax()), sw); + const Scalar sw = 0.4; // start with 40% saturation on top + pcTop_ = this->spatialParams().fluidMatrixInteractionAtPos(this->gridGeometry().bBoxMax()).pc(sw); // for post time step mass balance accumulatedSource_ = 0.0; diff --git a/test/porousmediumflow/richardsnc/implicit/spatialparams.hh b/test/porousmediumflow/richardsnc/implicit/spatialparams.hh index eca361a854..4e4434dd95 100644 --- a/test/porousmediumflow/richardsnc/implicit/spatialparams.hh +++ b/test/porousmediumflow/richardsnc/implicit/spatialparams.hh @@ -27,7 +27,6 @@ #include #include -#include #include @@ -51,37 +50,20 @@ class RichardsWellTracerSpatialParams using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using EffectiveLaw = VanGenuchten; + using PcKrSwCurve = FluidMatrix::VanGenuchtenNoReg; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; // export permeability type using PermeabilityType = Scalar; RichardsWellTracerSpatialParams(std::shared_ptr gridGeometry) - : ParentType(gridGeometry) + : ParentType(gridGeometry) + , lensPcKrSwCurve_("SpatialParams.Lens") + , outerPcKrSwCurve_("SpatialParams.OuterDomain") { - lensLowerLeft_ = getParam("Problem.LensLowerLeft"); lensUpperRight_ = getParam("Problem.LensUpperRight"); - // residual saturations - lensMaterialParams_.setSwr(0.18); - lensMaterialParams_.setSnr(0.0); - outerMaterialParams_.setSwr(0.05); - outerMaterialParams_.setSnr(0.0); - - // parameters for the Van Genuchten law - // alpha and n - lensMaterialParams_.setVgAlpha(0.00045); - lensMaterialParams_.setVgn(7.3); - outerMaterialParams_.setVgAlpha(0.0037); - outerMaterialParams_.setVgn(4.7); - - lensMaterialParams_.setVgn(7.3); - outerMaterialParams_.setVgAlpha(0.0037); - lensK_ = 1e-14; outerK_ = 5e-12; } @@ -113,13 +95,14 @@ public: /*! * \brief Returns the parameters for the material law at a given location * - * \param globalPos A global coordinate vector + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition &globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { if (isInLens_(globalPos)) - return lensMaterialParams_; - return outerMaterialParams_; + return makeFluidMatrixInteraction(lensPcKrSwCurve_); + else + return makeFluidMatrixInteraction(outerPcKrSwCurve_); } private: @@ -139,8 +122,9 @@ private: Scalar lensK_; Scalar outerK_; - MaterialLawParams lensMaterialParams_; - MaterialLawParams outerMaterialParams_; + + const PcKrSwCurve lensPcKrSwCurve_; + const PcKrSwCurve outerPcKrSwCurve_; }; } // end namespace Dumux -- GitLab From 89439a58d03453a624cd1321582d3c56f2cf1867 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 19:26:20 +0100 Subject: [PATCH 74/99] [test][md][stokesdarcy] New material law --- .../stokesdarcy/1p2c_2p2c/params.input | 4 +- .../1p2c_2p2c/params_nonisothermal.input | 4 +- .../stokesdarcy/1p2c_2p2c/spatialparams.hh | 39 ++++++------------- .../boundary/stokesdarcy/1p_2p/params.input | 4 +- .../stokesdarcy/1p_2p/spatialparams.hh | 39 ++++++------------- 5 files changed, 30 insertions(+), 60 deletions(-) diff --git a/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/params.input b/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/params.input index 5e94b99bb8..640ce27c38 100644 --- a/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/params.input +++ b/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/params.input @@ -39,8 +39,8 @@ Permeability = 2.65e-10 AlphaBJ = 1.0 Swr = 0.005 Snr = 0.01 -VgAlpha = 6.371e-4 -VgN = 6.9 +VanGenuchtenAlpha = 6.371e-4 +VanGenuchtenN = 6.9 [Problem] Name = test_stokes1p2cdarcy2p2chorizontal diff --git a/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/params_nonisothermal.input b/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/params_nonisothermal.input index 2b8814c19e..d210df63f9 100644 --- a/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/params_nonisothermal.input +++ b/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/params_nonisothermal.input @@ -39,8 +39,8 @@ Permeability = 2.65e-10 AlphaBJ = 1.0 Swr = 0.005 Snr = 0.01 -VgAlpha = 6.371e-4 -VgN = 6.9 +VanGenuchtenAlpha = 6.371e-4 +VanGenuchtenN = 6.9 [Problem] Name = test_stokes1p2cnidarcy2p2cnihorizontal diff --git a/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/spatialparams.hh b/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/spatialparams.hh index 8e63965ff1..389b3fff5e 100644 --- a/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/spatialparams.hh +++ b/test/multidomain/boundary/stokesdarcy/1p2c_2p2c/spatialparams.hh @@ -26,9 +26,7 @@ #define DUMUX_CONSERVATION_SPATIAL_PARAMS_HH #include -#include -#include -#include +#include namespace Dumux { @@ -49,26 +47,19 @@ class TwoPTwoCSpatialParams using ParentType = FVSpatialParams>; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using EffectiveLaw = RegularizedVanGenuchten; + + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; TwoPTwoCSpatialParams(std::shared_ptr gridGeometry) - : ParentType(gridGeometry) + : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { permeability_ = getParam("SpatialParams.Permeability"); porosity_ = getParam("SpatialParams.Porosity"); alphaBJ_ = getParam("SpatialParams.AlphaBJ"); - - // residual saturations - params_.setSwr(getParam("SpatialParams.Swr")); - params_.setSnr(getParam("SpatialParams.Snr")); - // parameters for the vanGenuchten law - params_.setVgAlpha(getParam("SpatialParams.VgAlpha")); - params_.setVgn(getParam("SpatialParams.VgN")); } /*! @@ -95,20 +86,14 @@ public: { return alphaBJ_; } /*! - * \brief Returns the parameter object for the Brooks-Corey material law. - * - * In this test, we use element-wise distributed material parameters. + * \brief Returns the parameters for the material law at a given location * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - * \return The material parameters object + * \param globalPos The global coordinates for the given location */ - template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolutionVector& elemSol) const - { return params_; } + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const + { + return makeFluidMatrixInteraction(pcKrSwCurve_); + } /*! * \brief Function for defining which phase is to be considered as the wetting phase. @@ -124,7 +109,7 @@ private: Scalar permeability_; Scalar porosity_; Scalar alphaBJ_; - MaterialLawParams params_; + const PcKrSwCurve pcKrSwCurve_; static constexpr Scalar eps_ = 1.0e-7; }; diff --git a/test/multidomain/boundary/stokesdarcy/1p_2p/params.input b/test/multidomain/boundary/stokesdarcy/1p_2p/params.input index a5532ea868..513cf67522 100644 --- a/test/multidomain/boundary/stokesdarcy/1p_2p/params.input +++ b/test/multidomain/boundary/stokesdarcy/1p_2p/params.input @@ -30,8 +30,8 @@ Permeability = 2.65e-10 AlphaBJ = 1.0 Swr = 0.005 Snr = 0.01 -VgAlpha = 6.371e-4 -VgN = 8.0 +VanGenuchtenAlpha = 6.371e-4 +VanGenuchtenN = 8.0 [Problem] EnableGravity = false diff --git a/test/multidomain/boundary/stokesdarcy/1p_2p/spatialparams.hh b/test/multidomain/boundary/stokesdarcy/1p_2p/spatialparams.hh index e78d2f634a..d218d2e90d 100644 --- a/test/multidomain/boundary/stokesdarcy/1p_2p/spatialparams.hh +++ b/test/multidomain/boundary/stokesdarcy/1p_2p/spatialparams.hh @@ -26,9 +26,7 @@ #define DUMUX_CONSERVATION_SPATIAL_PARAMS_HH #include -#include -#include -#include +#include namespace Dumux { @@ -51,26 +49,19 @@ class ConservationSpatialParams using ParentType = FVSpatialParams; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using EffectiveLaw = RegularizedVanGenuchten; + + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; ConservationSpatialParams(std::shared_ptr gridGeometry) - : ParentType(gridGeometry) + : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { permeability_ = getParam("SpatialParams.Permeability"); porosity_ = getParam("SpatialParams.Porosity"); alphaBJ_ = getParam("SpatialParams.AlphaBJ"); - - // residual saturations - params_.setSwr(getParam("SpatialParams.Swr")); - params_.setSnr(getParam("SpatialParams.Snr")); - // parameters for the vanGenuchten law - params_.setVgAlpha(getParam("SpatialParams.VgAlpha")); - params_.setVgn(getParam("SpatialParams.VgN")); } /*! @@ -97,20 +88,14 @@ public: { return alphaBJ_; } /*! - * \brief Returns the parameter object for the Brooks-Corey material law. - * - * In this test, we use element-wise distributed material parameters. + * \brief Returns the parameters for the material law at a given location * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - * \return The material parameters object + * \param globalPos The global coordinates for the given location */ - template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolutionVector& elemSol) const - { return params_; } + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const + { + return makeFluidMatrixInteraction(pcKrSwCurve_); + } /*! * \brief Function for defining which phase is to be considered as the wetting phase. @@ -126,7 +111,7 @@ private: Scalar permeability_; Scalar porosity_; Scalar alphaBJ_; - MaterialLawParams params_; + const PcKrSwCurve pcKrSwCurve_; static constexpr Scalar eps_ = 1.0e-7; }; -- GitLab From f156ac51a11586ade9a449a47fbb1b272e7cde0f Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 19:26:34 +0100 Subject: [PATCH 75/99] [test][md][darcydarcy] New material law --- .../boundary/darcydarcy/1p_2p/params.input | 6 +++++ .../darcydarcy/1p_2p/spatialparams.hh | 25 +++++++------------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/test/multidomain/boundary/darcydarcy/1p_2p/params.input b/test/multidomain/boundary/darcydarcy/1p_2p/params.input index 28d525347c..9721af3d35 100644 --- a/test/multidomain/boundary/darcydarcy/1p_2p/params.input +++ b/test/multidomain/boundary/darcydarcy/1p_2p/params.input @@ -20,3 +20,9 @@ Name = 2p LowerLeft = -2000 -2000 UpperRight = 2000 2000 Cells = 50 50 + +[SpatialParams] +Swr = 0.05 +Snr = 0.0 +VanGenuchtenAlpha = 0.0037 +VanGenuchtenN = 4.7 diff --git a/test/multidomain/boundary/darcydarcy/1p_2p/spatialparams.hh b/test/multidomain/boundary/darcydarcy/1p_2p/spatialparams.hh index 7cf67002da..ba0442cbbe 100644 --- a/test/multidomain/boundary/darcydarcy/1p_2p/spatialparams.hh +++ b/test/multidomain/boundary/darcydarcy/1p_2p/spatialparams.hh @@ -27,7 +27,6 @@ #include #include -#include namespace Dumux { @@ -50,20 +49,15 @@ class TestSpatialParams static constexpr int dimWorld = GridView::dimensionworld; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; -public: - using MaterialLaw = EffToAbsLaw>; - using MaterialLawParams = typename MaterialLaw::Params; + using PcKrSwCurve = FluidMatrix::VanGenuchtenNoReg; +public: using PermeabilityType = Scalar; TestSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) - { - materialParams_.setSwr(0.05); - materialParams_.setSnr(0.0); - materialParams_.setVgAlpha(0.0037); - materialParams_.setVgn(4.7); - } + , pcKrSwCurve_("SpatialParams") + {} /*! * \brief Function for defining the (intrinsic) permeability \f$[m^2]\f$. @@ -85,14 +79,13 @@ public: } /*! - * \brief Returns the parameter object for the Brooks-Corey material law. + * \brief Returns the parameters for the material law at a given location * - * In this test, we use element-wise distributed material parameters. - * \return the material parameters object + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } /*! @@ -108,7 +101,7 @@ public: } private: - MaterialLawParams materialParams_; + const PcKrSwCurve pcKrSwCurve_; }; } // end namespace Dumux -- GitLab From 4514e277524bfc7d7f1eab3bcca7944a440d7ead Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 19:27:01 +0100 Subject: [PATCH 76/99] [test][md][el2p] New material law --- .../poromechanics/el2p/params.input | 4 ++ .../poromechanics/el2p/spatialparams_2p.hh | 52 +++++++------------ 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/test/multidomain/poromechanics/el2p/params.input b/test/multidomain/poromechanics/el2p/params.input index 7c96b619fa..addf0055f2 100644 --- a/test/multidomain/poromechanics/el2p/params.input +++ b/test/multidomain/poromechanics/el2p/params.input @@ -21,6 +21,10 @@ Name = twop # name passed to the output routines [SpatialParams] Permeability = 1e-14 # [m^2] InitialPorosity = 0.2 # [-] +Swr = 0.3 +Snr = 0.05 +BrooksCoreyPcEntry = 1.99e4 +BrooksCoreyLambda = 0 # will be overwritten internally [LinearSolver] ResidualReduction = 1e-20 diff --git a/test/multidomain/poromechanics/el2p/spatialparams_2p.hh b/test/multidomain/poromechanics/el2p/spatialparams_2p.hh index 543c5660b0..ec9573bb9f 100644 --- a/test/multidomain/poromechanics/el2p/spatialparams_2p.hh +++ b/test/multidomain/poromechanics/el2p/spatialparams_2p.hh @@ -28,8 +28,7 @@ #include #include -#include -#include +#include #include #include #include @@ -52,10 +51,9 @@ class TwoPSpatialParams : public FVSpatialParams; using ParentType = FVSpatialParams; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; + public: - using EffectiveLaw = RegularizedBrooksCorey; - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; // export permeability type using PermeabilityType = Scalar; @@ -67,18 +65,16 @@ public: , initPorosity_(getParam("SpatialParams.InitialPorosity")) { // given Van Genuchten m - Scalar m = 0.457; + const Scalar m = 0.457; // Brooks Corey lambda using std::pow; - Scalar brooksCoreyLambda = m / (1 - m) * (1 - pow(0.5, 1/m)); + const Scalar brooksCoreyLambda = m / (1 - m) * (1 - pow(0.5, 1/m)); - // residual saturations - myMaterialParams_.setSwr(0.3); - myMaterialParams_.setSnr(0.05); + auto baseParams = PcKrSwCurve::makeBasicParams("SpatialParams"); + baseParams.setLambda(brooksCoreyLambda); + const auto effToAbsParams = PcKrSwCurve::makeEffToAbsParams("SpatialParams"); - // parameters for the Brooks Corey law - myMaterialParams_.setPe(1.99e4); - myMaterialParams_.setLambda(brooksCoreyLambda); + pcKrSwCurve_ = std::make_unique(baseParams, effToAbsParams); } //! Returns the porosity for a sub-control volume. @@ -106,24 +102,15 @@ public: return permLaw.evaluatePermeability(initPermeability_, initPorosity_, porosity(element, scv, elemSol)); } - /*! - * \brief Returns the parameter object for the Brooks-Corey material law. - * - * In this test, we use element-wise distributed material parameters. - * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - * \return The material parameters object - */ - template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - // do not use different parameters in the test with inverted wettability - return myMaterialParams_; - } + /*! + * \brief Returns the parameters for the material law at a given location + * + * \param globalPos The global coordinates for the given location + */ + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const + { + return makeFluidMatrixInteraction(*pcKrSwCurve_); + } /*! * \brief Function for defining which phase is to be considered as the wetting phase. @@ -145,8 +132,7 @@ private: std::shared_ptr couplingManagerPtr_; Scalar initPermeability_; Scalar initPorosity_; - - MaterialLawParams myMaterialParams_; + std::unique_ptr pcKrSwCurve_; }; } // end namespace Dumux -- GitLab From 570e4422bf3d9388983f4e89b6a91790d64013c4 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 19:35:59 +0100 Subject: [PATCH 77/99] [test][md][embedded] New material law --- .../1d3d/1p2c_richards2c/params.input | 3 ++ .../1d3d/1p2c_richards2c/problem_soil.hh | 3 +- .../1p2c_richards2c/spatialparams_soil.hh | 32 ++++++------------- .../embedded/1d3d/1p_richards/params.input | 3 ++ .../1d3d/1p_richards/spatialparams_soil.hh | 32 ++++++------------- 5 files changed, 27 insertions(+), 46 deletions(-) diff --git a/test/multidomain/embedded/1d3d/1p2c_richards2c/params.input b/test/multidomain/embedded/1d3d/1p2c_richards2c/params.input index 48d97f0393..003bc1edb6 100644 --- a/test/multidomain/embedded/1d3d/1p2c_richards2c/params.input +++ b/test/multidomain/embedded/1d3d/1p2c_richards2c/params.input @@ -28,6 +28,9 @@ InitTopSaturation = 0.3 [Soil] SpatialParams.Permeability = 2.57e-12 # [m^2] SpatialParams.Porosity = 0.4 # [-] +SpatialParams.Swr = 0.05 +SpatialParams.VanGenuchtenAlpha = 2.956e-4 +SpatialParams.VanGenuchtenN = 1.5 Problem.Name = 3d [Root] diff --git a/test/multidomain/embedded/1d3d/1p2c_richards2c/problem_soil.hh b/test/multidomain/embedded/1d3d/1p2c_richards2c/problem_soil.hh index 7459221af5..7b67f2eb3d 100644 --- a/test/multidomain/embedded/1d3d/1p2c_richards2c/problem_soil.hh +++ b/test/multidomain/embedded/1d3d/1p2c_richards2c/problem_soil.hh @@ -158,8 +158,7 @@ public: // for initial conditions const Scalar sw = getParam("Problem.InitTopSaturation", 0.3); // start with 30% saturation on top - using MaterialLaw = typename GetPropType::MaterialLaw; - pcTop_ = MaterialLaw::pc(this->spatialParams().materialLawParamsAtPos(gridGeometry->bBoxMax()), sw); + pcTop_ = this->spatialParams().fluidMatrixInteractionAtPos(gridGeometry->bBoxMax()).pc(sw); } /*! diff --git a/test/multidomain/embedded/1d3d/1p2c_richards2c/spatialparams_soil.hh b/test/multidomain/embedded/1d3d/1p2c_richards2c/spatialparams_soil.hh index 342eb9079e..85f028d7b0 100644 --- a/test/multidomain/embedded/1d3d/1p2c_richards2c/spatialparams_soil.hh +++ b/test/multidomain/embedded/1d3d/1p2c_richards2c/spatialparams_soil.hh @@ -27,8 +27,7 @@ #include #include -#include -#include +#include namespace Dumux { @@ -47,26 +46,16 @@ class SoilSpatialParams using SubControlVolume = typename GridGeometry::SubControlVolume; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; + public: // export permeability type using PermeabilityType = Scalar; - // export material law type - using MaterialLaw = EffToAbsLaw>; - // export material law params - using MaterialLawParams = typename MaterialLaw::Params; SoilSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurve_("Soil.SpatialParams") { - // residual saturations - materialParams_.setSwr(0.05); - materialParams_.setSnr(0.0); - - // parameters for the Van Genuchten law - // alpha and n - materialParams_.setVgAlpha(2.956e-4); - materialParams_.setVgn(1.5); - // perm and poro permeability_ = getParam("Soil.SpatialParams.Permeability"); porosity_ = getParam("Soil.SpatialParams.Porosity"); @@ -105,16 +94,15 @@ public: /*! * \brief Returns the parameters for the material law at a given location * - * This method is not actually required by the Richards model, but provided - * for the convenience of the RichardsLensProblem - * - * \param globalPos A global coordinate vector + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition &globalPos) const - { return materialParams_; } + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const + { + return makeFluidMatrixInteraction(pcKrSwCurve_); + } private: - MaterialLawParams materialParams_; + const PcKrSwCurve pcKrSwCurve_; Scalar permeability_; Scalar porosity_; }; diff --git a/test/multidomain/embedded/1d3d/1p_richards/params.input b/test/multidomain/embedded/1d3d/1p_richards/params.input index fe09ff1a66..294a0d327a 100644 --- a/test/multidomain/embedded/1d3d/1p_richards/params.input +++ b/test/multidomain/embedded/1d3d/1p_richards/params.input @@ -24,6 +24,9 @@ OutputName = test_md_embedded1d3d_1p_richards [Soil] SpatialParams.Permeability = 2.57e-12 # [m^2] SpatialParams.Porosity = 0.3 # [-] +SpatialParams.Swr = 0.05 +SpatialParams.VanGenuchtenAlpha = 2.956e-4 +SpatialParams.VanGenuchtenN = 1.5 Problem.Name = 3d [Root] diff --git a/test/multidomain/embedded/1d3d/1p_richards/spatialparams_soil.hh b/test/multidomain/embedded/1d3d/1p_richards/spatialparams_soil.hh index f2baa36fd3..802e7cf4c8 100644 --- a/test/multidomain/embedded/1d3d/1p_richards/spatialparams_soil.hh +++ b/test/multidomain/embedded/1d3d/1p_richards/spatialparams_soil.hh @@ -27,8 +27,7 @@ #include #include -#include -#include +#include namespace Dumux { @@ -47,26 +46,16 @@ class SoilSpatialParams using SubControlVolume = typename GridGeometry::SubControlVolume; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; + public: // export permeability type using PermeabilityType = Scalar; - // export material law type - using MaterialLaw = EffToAbsLaw>; - // export material law params - using MaterialLawParams = typename MaterialLaw::Params; SoilSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurve_("Soil.SpatialParams") { - // residual saturations - materialParams_.setSwr(0.05); - materialParams_.setSnr(0.0); - - // parameters for the Van Genuchten law - // alpha and n - materialParams_.setVgAlpha(2.956e-4); - materialParams_.setVgn(1.5); - // perm and poro permeability_ = getParam("Soil.SpatialParams.Permeability"); porosity_ = getParam("Soil.SpatialParams.Porosity"); @@ -105,16 +94,15 @@ public: /*! * \brief Returns the parameters for the material law at a given location * - * This method is not actually required by the Richards model, but provided - * for the convenience of the RichardsLensProblem - * - * \param globalPos A global coordinate vector + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition &globalPos) const - { return materialParams_; } + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const + { + return makeFluidMatrixInteraction(pcKrSwCurve_); + } private: - MaterialLawParams materialParams_; + const PcKrSwCurve pcKrSwCurve_; Scalar permeability_; Scalar porosity_; }; -- GitLab From c2b357a96f449ae2754c40c9e5ed32f4167476c9 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Tue, 27 Oct 2020 20:44:02 +0100 Subject: [PATCH 78/99] [test][2pncmin] Add missing gnuplot include --- test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh b/test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh index ecb694b7a6..04d8d7df54 100644 --- a/test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh +++ b/test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh @@ -36,6 +36,7 @@ #include #include #include +#include #include #include -- GitLab From eca0e48655ed6f9cb77fab7e2898208bb862f8fa Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 19:33:27 +0100 Subject: [PATCH 79/99] [deprecated] Add helper for 3p pcSw --- dumux/common/deprecated.hh | 87 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/dumux/common/deprecated.hh b/dumux/common/deprecated.hh index 047e82ed16..9164b15ce1 100644 --- a/dumux/common/deprecated.hh +++ b/dumux/common/deprecated.hh @@ -120,7 +120,7 @@ public: return SpatialParams::MaterialLaw::sw(params, pc); } - Scalar dsw_dpc(const Scalar pc) const + Scalar dsw_dpc(const Scalar pc) const { const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); return SpatialParams::MaterialLaw::dsw_dpc(params, pc); @@ -151,8 +151,84 @@ private: const ElemSol& elemSol_; }; +template +class PcKrSwThreePHelper : public FluidMatrix::Adapter, FluidMatrix::ThreePhasePcKrSw> +{ +public: + using Scalar = ScalarT; + + // pass scalar so template arguments can all be deduced + PcKrSwThreePHelper(const Scalar& scalar, + const SpatialParams& sp, + const Element& element, + const Scv& scv, + const ElemSol& elemSol) + : spatialParams_(sp), element_(element), scv_(scv), elemSol_(elemSol) + {} + + Scalar pcgw(const Scalar sw, const Scalar /*dummySn*/) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::pcgw(params, sw); + } + + Scalar pcnw(const Scalar sw, const Scalar /*dummySn*/) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::pcnw(params, sw); + } + + Scalar pcgn(const Scalar sw, const Scalar sn) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::pcgn(params, sw + sn); + } + + Scalar pcAlpha(const Scalar /*dummySw*/, const Scalar sn) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::pcAlpha(params, sn); + } + + Scalar krw(const Scalar sw, const Scalar sn) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::krw(params, sw, sn); + } + + Scalar krn(const Scalar sw, const Scalar sn) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::krw(params, sw, sn); + } + + Scalar krg(const Scalar sw, const Scalar sn) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::krg(params, sw, sn); + } + + Scalar kr(const int phaseIdx, const Scalar sw, const Scalar sn) const + { + const auto& params = spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); + return SpatialParams::MaterialLaw::kr(params, phaseIdx, sw, sn, 1 - sw - sn); + } + + const auto& basicParams() const + { return spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); } + + const auto& effToAbsParams() const + { return spatialParams_.materialLawParamsDeprecated(element_, scv_, elemSol_); } + +private: + const SpatialParams& spatialParams_; + const Element& element_; + const Scv& scv_; + const ElemSol& elemSol_; +}; + // for implicit models -template +template auto makePcKrSw(const Scalar& scalar, const SpatialParams& sp, const Element& element, @@ -167,7 +243,12 @@ auto makePcKrSw(const Scalar& scalar, else if constexpr (hasNewAtPos) return sp.fluidMatrixInteractionAtPos(scv.center()); else - return makeFluidMatrixInteraction(PcKrSwHelper(scalar, sp, element, scv, elemSol)); + { + if constexpr (numPhases == 2) + return makeFluidMatrixInteraction(PcKrSwHelper(scalar, sp, element, scv, elemSol)); + else + return makeFluidMatrixInteraction(PcKrSwThreePHelper(scalar, sp, element, scv, elemSol)); + } } // for sequential models -- GitLab From d8c896a9bd96435b458e0cc53ebcd7933cd18f89 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 19:35:29 +0100 Subject: [PATCH 80/99] [3p] Add ParkerVanGenuchten class --- .../3p/parkervangenuchten.hh | 1349 +++++++++++++++++ 1 file changed, 1349 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/3p/parkervangenuchten.hh diff --git a/dumux/material/fluidmatrixinteractions/3p/parkervangenuchten.hh b/dumux/material/fluidmatrixinteractions/3p/parkervangenuchten.hh new file mode 100644 index 0000000000..b42c0d6759 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/3p/parkervangenuchten.hh @@ -0,0 +1,1349 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Implementation of van Genuchten's capillary pressure-saturation relation for three phases. + */ +#ifndef PARKER_VANGENUCHTEN_3P_HH +#define PARKER_VANGENUCHTEN_3P_HH + +#include +#include +#include +#include +#include + +namespace Dumux::FluidMatrix { + +struct ParkerVanGenuchten3PEffToAbsPolicy +{ + /*! + * \brief The parameter type + * \tparam Scalar The scalar type + * \note The efftoabs policy need two parameters: \f$\mathrm{S_{w,r}}, \mathrm{S_{n,r}}\f$. + * For the respective formulas check out the description of the free function. + */ + template + struct Params + { + Params(const Scalar swr = 0.0, const Scalar snr = 0.0, const Scalar sgr = 0.0) + : swr_(swr), snr_(snr), sgr_(sgr) + {} + + /*! + * \brief Return the residual wetting saturation. + */ + Scalar swr() const + { return swr_; } + + /*! + * \brief Set the residual wetting saturation. + */ + void setSwr(Scalar v) + { swr_ = v; } + + /*! + * \brief Return the residual non-wetting saturation. + */ + Scalar snr() const + { return snr_; } + + /*! + * \brief Set the residual non-wetting saturation. + */ + void setSnr(Scalar v) + { snr_ = v; } + /*! + + * \brief Return the residual gas phase saturation. + */ + Scalar sgr() const + { return sgr_; } + + /*! + * \brief Set the residual gas phase saturation. + */ + void setSgr(Scalar v) + { sgr_ = v; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(swr(), p.swr(), 1e-6) + && Dune::FloatCmp::eq(snr(), p.snr(), 1e-6) + && Dune::FloatCmp::eq(sgr(), p.sgr(), 1e-6); + } + private: + Scalar swr_; + Scalar snr_; + Scalar sgr_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + Params params; + params.setSwr(getParamFromGroup(paramGroup, "Swr", 0.0)); + params.setSnr(getParamFromGroup(paramGroup, "Snr", 0.0)); + params.setSgr(getParamFromGroup(paramGroup, "Sgr", 0.0)); + return params; + } + + /*! + * \brief Convert an absolute wetting saturation to an effective one. + * + * \param sw Absolute saturation of the wetting phase \f$\mathrm{[{S}_w]}\f$. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Effective saturation of the wetting phase. + */ + template + static Scalar swToSwe(const Scalar sw, const Params& params) + { + return (sw - params.swr())/(1.0 - params.swr()); // TODO other residual saturations? + } + + /*! + * \brief Convert an effective wetting saturation to an absolute one. + * + * \param swe Effective saturation of the non-wetting phase \f$\mathrm{[\overline{S}_n]}\f$. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Absolute saturation of the non-wetting phase. + */ + template + static Scalar sweToSw(const Scalar swe, const Params& params) + { + return swe*(1.0 - params.swr()) + params.swr(); // TODO other residual saturations? + } + + /*! + * \brief Derivative of the effective saturation w.r.t. the absolute saturation. + * + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Derivative of the effective saturation w.r.t. the absolute saturation. + */ + template + static Scalar dswe_dsw(const Params& params) + { + return 1.0/(1.0 - params.swr()); // TODO other residual saturations? + } + + /*! + * \brief Derivative of the absolute saturation w.r.t. the effective saturation. + * + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Derivative of the absolute saturation w.r.t. the effective saturation. + */ + template + static Scalar dsw_dswe(const Params& params) + { + return 1.0 - params.swr(); // TODO other residual saturations? + } + + /*! + * \brief Convert an absolute non-wetting saturation to an effective one. + * + * \param sn Absolute saturation of the non-wetting phase \f$\mathrm{[{S}_n]}\f$. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Effective saturation of the non-wetting phase. + */ + template + static Scalar snToSne(const Scalar sn, const Params& params) + { + return sn; // sne equals sn // TODO other residual saturations? + } + + /*! + * \brief Convert an absolute total liquid saturation to an effective one. + * + * \param st Absolute saturation of the total liquid phase (sw+sn) \f$\mathrm{[{S}_n]}\f$. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Effective saturation of the non-wetting phase. + */ + template + static Scalar stToSte(const Scalar st, const Params& params) + { + return (st-params.swr()) / (1-params.swr()); // TODO other residual saturations? + } + + /*! + * \brief Convert an effective wetting saturation to an absolute one. + * + * \param swe Effective saturation of the non-wetting phase \f$\mathrm{[\overline{S}_n]}\f$. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Absolute saturation of the non-wetting phase. + */ + template + static Scalar steToSt(const Scalar ste, const Params& params) + { + return ste*(1.0 - params.swr()) + params.swr(); // TODO other residual saturations? + } + + /*! + * \brief Derivative of the effective saturation w.r.t. the absolute saturation. + * + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Derivative of the effective saturation w.r.t. the absolute saturation. + */ + template + static Scalar dste_dst(const Params& params) + { + return 1.0/(1.0 - params.swr() /*- params.snr() - params.sgr()*/); // TODO other residual saturations? + } + + /*! + * \brief Derivative of the absolute saturation w.r.t. the effective saturation. + * + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, + * and then the params container is constructed accordingly. Afterwards the values are set there, too. + * \return Derivative of the absolute saturation w.r.t. the effective saturation. + */ + template + static Scalar dst_dste(const Params& params) + { + return 1.0 - params.swr(); // TODO other residual saturations? + } +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Implementation of van Genuchten's capillary pressure <-> + * saturation relation. This class bundles the "raw" curves + * as static members and doesn't concern itself converting + * absolute to effective saturations and vince versa. + * + * \sa VanGenuchten, VanGenuchtenThreephase + */ +class ParkerVanGenuchten3P +{ + +public: + /*! + * \brief The parameter type + * \tparam Scalar The scalar type + * \note The van Genuchten laws are parameterized with four parameters: \f$\mathrm{n, m, \alpha, l}\f$. + * + * - \f$\mathrm{\alpha}\f$ shape parameter \f$\mathrm{[1/Pa]}\f$ + * - \f$\mathrm{m}\f$ shape parameter \f$\mathrm{[-]}\f$ + * - \f$\mathrm{n}\f$ shape parameter \f$\mathrm{[-]}\f$ + * - \f$\mathrm{l}\f$ pore-connectivity parameter \f$\mathrm{[-]}\f$ of Mualem's relative permeability curve + * + */ + template + struct Params + { + Params(Scalar alpha, Scalar n, Scalar swr = 0.0, Scalar snr = 0.0, + Scalar betaNw = 1.0, Scalar betaGn = 1.0, Scalar betaGw = 1.0, bool regardSnr = false) + : alpha_(alpha), n_(n), m_(1.0 - 1.0/n), swr_(swr), snr_(snr) + , betaNw_(betaNw), betaGn_(betaGn), betaGw_(betaGw), regardSnr_(regardSnr) + {} + + Scalar alpha() const { return alpha_; } + void setAlpha(Scalar alpha) { alpha_ = alpha; } + + Scalar m() const { return m_; } + void setM(Scalar m) { m_ = m; n_ = 1.0/(1.0 - m); } + + Scalar n() const{ return n_; } + void setN(Scalar n){ n_ = n; m_ = 1.0 - 1.0/n; } + + Scalar swr() const { return swr_; } + void setSwr(Scalar swr) { swr_ = swr; } + + Scalar snr() const { return snr_; } + void setSnr(Scalar swr) { snr_ = swr; } + + Scalar betaNw() const { return betaNw_; } + void setBetaNw(Scalar betaNw) { betaNw_ = betaNw; } + + Scalar betaGn() const { return betaNw_; } + void setBetaGn(Scalar betaGn) { betaGn_ = betaGn; } + + Scalar betaGw() const { return betaGw_; } + void setBetaGw(Scalar betaGw) { betaGw_ = betaGw; } + + bool regardSnrForKrn() const { return regardSnr_; } + void setRegardSnrForKrn(bool v) {regardSnr_ = v; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(alpha_, p.alpha_, 1e-6) + && Dune::FloatCmp::eq(n_, p.n_, 1e-6) + && Dune::FloatCmp::eq(m_, p.m_, 1e-6) + && Dune::FloatCmp::eq(swr_, p.swr_, 1e-6) + && Dune::FloatCmp::eq(snr_, p.snr_, 1e-6) + && Dune::FloatCmp::eq(betaNw_, p.betaNw_, 1e-6) + && Dune::FloatCmp::eq(betaGn_, p.betaGn_, 1e-6) + && Dune::FloatCmp::eq(betaGw_, p.betaGw_, 1e-6) + && regardSnr_ == p.regardSnr_; + } + + private: + Scalar alpha_, n_, m_, swr_, snr_, betaNw_, betaGn_, betaGw_; + bool regardSnr_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + template + static Params makeParams(const std::string& paramGroup) + { + const auto n = getParamFromGroup(paramGroup, "ParkerVanGenuchtenN"); + const auto alpha = getParamFromGroup(paramGroup, "ParkerVanGenuchtenAlpha"); + const auto swr = getParamFromGroup(paramGroup, "Swr", 0.0); + const auto snr = getParamFromGroup(paramGroup, "Snr", 0.0); + const auto betaNw = getParamFromGroup(paramGroup, "ParkerVanGenuchtenBetaNw", 1.0); + const auto betaGn = getParamFromGroup(paramGroup, "ParkerVanGenuchtenBetaGn", 1.0); + const auto betaGw = getParamFromGroup(paramGroup, "ParkerVanGenuchtenBetaGw", 1.0); + const auto regardSnr = getParamFromGroup(paramGroup, "ParkerVanGenuchtenRegardSnrForKrn", false); + return Params(alpha, n, swr, snr, + betaNw, betaGn, betaGw, regardSnr ); + } + + + /*! + * \brief The capillary pressure-saturation curve for the gas and wetting phase + * \param params Array of parameters + * \param swe Effective wetting phase saturation + * + */ + template + static Scalar pcgw(Scalar swe, const Params& params) + { + assert(0 <= swe && swe <= 1); + return pc_(swe, params); + } + + /*! + * \brief The capillary pressure-saturation curve for the non-wettigng and wetting phase + * \param params Array of parameters + * \param swe Effective wetting phase saturation + */ + template + static Scalar pcnw(Scalar swe, const Params& params) + { + assert(0 <= swe && swe <= 1); + return pc_(swe, params)/params.betaNw(); + } + + /*! + * \brief The capillary pressure-saturation curve for the gas and non-wetting phase + * \param params Array of parameters + * \param ste Effective total liquid (wetting + non-wetting) saturation + */ + template + static Scalar pcgn(const Scalar ste, const Params& params) + { + assert(0 <= ste && ste <= 1); + return pc_(ste, params)/params.betaGn(); + } + + /*! + * \brief This function ensures a continuous transition from 2 to 3 phases and vice versa + * \param params Array of parameters + * \param sne Non-wetting liquid saturation + */ + template + static Scalar pcAlpha(Scalar sne, const Params& params) + { + /* regularization */ + if (sne <= 0.001) + sne = 0.0; + if (sne >= 1.0) + sne = 1.0; + + if (sne > params.snr()) + return 1.0; + else + { + if (params.snr() >= 0.001) + return sne/params.snr(); + else + return 0.0; + }; + } + + /*! + * \brief Returns the partial derivative of the capillary + * pressure to the effective saturation. + * \param params Array of parameters + * \param seRegu Effective wetting phase saturation for regularization + */ + template + static Scalar dpcgw_dswe(const Scalar swe, const Params& params) + { + using std::pow; + const Scalar powSeRegu = pow(swe, -1/params.m()); + return - 1.0/params.alpha() * pow(powSeRegu - 1, 1.0/params.n() - 1)/params.n() + * powSeRegu/swe/params.m()/params.betaGw(); + } + + /*! + * \brief Returns the partial derivative of the capillary + * pressure to the effective saturation. + * \param params Array of parameters + * \param seRegu Effective wetting phase saturation for regularization + */ + template + static Scalar dpcnw_dswe(const Scalar swe, const Params& params) + { + using std::pow; + const Scalar powSeRegu = pow(swe, -1/params.m()); + return - 1.0/params.alpha() * pow(powSeRegu - 1, 1.0/params.n() - 1)/params.n() + * powSeRegu/swe/params.m()/params.betaNw(); + } + + /*! + * \brief Returns the partial derivative of the capillary + * pressure to the effective saturation. + * \param params Array of parameters + * \param seRegu Effective wetting phase saturation for regularization + */ + template + static Scalar dpcgn_dste(const Scalar ste, const Params& params) + { + using std::pow; + const Scalar powSeRegu = pow(ste, -1/params.m()); + return - 1.0/params.alpha() * pow(powSeRegu - 1, 1.0/params.n() - 1)/params.n() + * powSeRegu/ste/params.m()/params.betaGn(); + } + + /*! + * \brief The relative permeability for the wetting phase of + * the medium implied by van Genuchten's + * parameterization. + * + * The permeability of water in a 3p system equals the standard 2p description. + * (see p61. in "Comparison of the Three-Phase Oil Relative Permeability Models" + * MOJDEH DELSHAD and GARY A. POPE, Transport in Porous Media 4 (1989), 59-83.) \cite delshad1989
+ * + * \param params Array of parameters. + * \param swe Effective wetting phase saturation + */ + template + static Scalar krw(const Scalar swe, const Params& params) + { + using std::pow; + using std::sqrt; + const Scalar r = 1.0 - pow(1 - pow(swe, 1/params.m()), params.m()); + return sqrt(swe)*r*r; + } + + /*! + * \brief The relative permeability for the non-wetting phase + * after the Model of Parker et al. (1987). + * + * See model 7 in "Comparison of the Three-Phase Oil Relative Permeability Models" + * MOJDEH DELSHAD and GARY A. POPE, Transport in Porous Media 4 (1989), 59-83 \cite delshad1989
+ * or more comprehensive in + * "Estimation of primary drainage three-phase relative permeability for organic + * liquid transport in the vadose zone", Leonardo I. Oliveira, Avery H. Demond, + * Journal of Contaminant Hydrology 66 (2003), 261-285 \cite oliveira2003
+ * + * + * \param params Array of parameters. + * \param swe Effective wetting phase saturation + * \param sn Absolute non-wetting liquid saturation + * \param ste Effective total liquid (wetting + non-wetting) saturation + */ + template + static Scalar krn(const Scalar swe, const Scalar sn, const Scalar ste, const Params& params) + { + Scalar krn; + using std::pow; + krn = pow(1 - pow(swe, 1/params.m()), params.m()); + krn -= pow(1 - pow(ste, 1/params.m()), params.m()); + krn *= krn; + + using std::clamp; + using std::sqrt; + if (params.regardSnrForKrn()) + { + // regard Snr in the permeability of the n-phase, see Helmig1997 + const Scalar resIncluded = clamp(sn - params.snr()/ (1-params.swr()), 0.0, 1.0); + krn *= sqrt(resIncluded); + } + else + krn *= sqrt(sn / (1 - params.swr())); // Hint: (ste - swe) = sn / (1-Swr) + + return krn; + } + + /*! + * \brief The relative permeability for the non-wetting phase + * of the medium implied by van Genuchten's + * parameterization. + * + * The permeability of gas in a 3p system equals the standard 2p description. + * (see p61. in "Comparison of the Three-Phase Oil Relative Permeability Models" + * MOJDEH DELSHAD and GARY A. POPE, Transport in Porous Media 4 (1989), 59-83.) \cite delshad1989
+ * + * \param params Array of parameters. + * \param ste Effective total liquid (wetting + non-wetting) saturation + */ + template + static Scalar krg(const Scalar ste, const Params& params) + { + assert(0 <= ste && ste <= 1); + using std::cbrt; + using std::pow; + return cbrt(1 - ste) * pow(1 - pow(ste, 1/params.m()), 2*params.m()); + } + + /*! + * \brief The derivative of the relative permeability for the + * gas phase in regard to the total liquid saturation of + * the medium as implied by the van Genuchten + * parameterization. + * + * \param ste The mobile total liquid saturation. + * \param params A container object that is populated with the appropriate coefficients for the respective law. + * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, and then the params container + * is constructed accordingly. Afterwards the values are set there, too. + */ + template + static Scalar dkrg_dste(const Scalar ste, const Params& params) + { + assert(0 < ste && ste <= 1); + + using std::pow; + const Scalar x = pow(ste, 1.0/params.m()); + return + -pow(1.0 - x, 2*params.m()) + *pow(1.0 - ste, -2.0/3) + *(1.0/3 + 2*x/ste); + } + + /*! + * \brief The relative permeability for a phase. + * \param params Array of parameters. + * \param phaseIdx Indicator, The saturation of all phases. + * \param swe Effective wetting phase saturation + * \param sn Absolute non-wetting liquid saturation + * \param ste Effective total liquid (wetting + non-wetting) saturation + */ + template + static Scalar kr(const int phaseIdx, const Scalar swe, const Scalar sne, const Params& params) + { + switch (phaseIdx) + { + case 0: + return krw(params, swe, sne); + case 1: + return krn(params, swe, sne); + case 2: + return krg(params, swe, sne); + } + DUNE_THROW(Dune::InvalidStateException, + "Invalid phase index "); + } + +private: + + /*! + * \brief The standard van Genuchten two-phase pc-S relation either with respect to + * the effective wetting phase saturation Swe or the effective total liquid saturation Ste. + * \param params Array of parameters. + * \param Se Effective wetting phase ortotal liquid saturation + */ + template + const static Scalar pc_(const Scalar se, const Params& params) + { + using std::pow; + return pow(pow(se, -1/params.m()) - 1, 1/params.n())/params.alpha(); + } + +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A regularization for the VanGenuchten material law + * \note Regularization can be turned of by setting the threshold parameters + * out of range (runtime) or by replacing + * this class by NoRegularization (compile time). + */ +template +class ParkerVanGenuchten3PRegularization +{ + using BaseLawParams = typename ParkerVanGenuchten3P::Params; + +public: + //! Regularization parameters + template + struct Params + { + /*! + * \brief Set the threshold saturation below which the capillary pressure is regularized. + * + * Most problems are very sensitive to this value (e.g. making it smaller might + * result in very high capillary pressures) + */ + void setPcLowSwe(Scalar pcLowSwe) + { pcLowSwe_ = pcLowSwe; } + + /*! + * \brief Threshold saturation below which the capillary pressure is regularized. + */ + Scalar pcLowSwe() const + { return pcLowSwe_; } + + /*! + * \brief Set the threshold saturation above which the capillary pressure is regularized. + */ + void setPcHighSwe(Scalar pcHighSwe) + { pcHighSwe_ = pcHighSwe; } + + /*! + * \brief Threshold saturation above which the capillary pressure is regularized. + * + * Most problems are very sensitive to this value (e.g. making it smaller might + * result in negative capillary pressures). + */ + Scalar pcHighSwe() const + { return pcHighSwe_; } + + /*! + * \brief Set the threshold saturation below which the relative + * permeability of the non-wetting phase gets regularized. + */ + void setKrnLowSwe(Scalar krnLowSwe) + { krnLowSwe_ = krnLowSwe; } + + /*! + * \brief Threshold saturation below which the relative + * permeability of the non-wetting phase gets regularized. + */ + Scalar krnLowSwe() const + { return krnLowSwe_; } + + /*! + * \brief Set the threshold saturation below which the relative + * permeability of the non-wetting phase gets regularized. + */ + void setKrgLowSte(Scalar krgLowSte) + { krgLowSte_ = krgLowSte; } + + /*! + * \brief Threshold saturation below which the relative + * permeability of the non-wetting phase gets regularized. + */ + Scalar krgLowSte() const + { return krgLowSte_; } + + /*! + * \brief Set the threshold saturation above which the relative + * permeability of the wetting phase gets regularized. + */ + void setKrwHighSwe(Scalar krwHighSwe) + { krwHighSwe_ = krwHighSwe; } + + /*! + * \brief Threshold saturation above which the relative + * permeability of the wetting phase gets regularized. + */ + Scalar krwHighSwe() const + { return krwHighSwe_; } + + + /*! + * \brief Choose whether to use a constant value for regularization of the + * pc-S curves or not + * \param input True or false + */ + void setConstRegularization(const bool input) + { constRegularization_ = input; } + + /*! + * \brief Returns whether to use a constant value for regularization of the + * pc-S curves or not + */ + bool constRegularization() const + { return constRegularization_; } + +private: + S pcLowSwe_ = 0.01; + S pcHighSwe_ = 0.99; + S krnLowSwe_ = 0.1; + S krwHighSwe_ = 0.9; + S krgLowSte_ = 1e-3; + bool constRegularization_ = false; + }; + + //! Initialize the spline + template + void init(const MaterialLaw* m, const std::string& paramGroup) + { + pcLowSwe_ = getParamFromGroup(paramGroup, "ParkerVanGenuchtenPcLowSweThreshold", 0.01); + pcHighSwe_ = getParamFromGroup(paramGroup, "ParkerVanGenuchtenPcHighSweThreshold", 0.99); + krwHighSwe_ = getParamFromGroup(paramGroup, "ParkerVanGenuchtenKrwHighSweThreshold", 0.9); + krnLowSwe_ = getParamFromGroup(paramGroup, "ParkerVanGenuchtenKrnLowSweThreshold", 0.1); + krgLowSte_ = getParamFromGroup(paramGroup, "ParkerVanGenuchtenKrgLowSteThreshold", 1e-3); + constRegularization_ = getParamFromGroup(paramGroup, "VanGenuchtenConstantRegularization", false); + + initPcParameters_(m, pcLowSwe_, pcHighSwe_); + initKrParameters_(m, krnLowSwe_, krwHighSwe_); + } + + template + void init(const MaterialLaw* m, const BaseParams& bp, const EffToAbsParams& etap, const Params& p) + { + pcLowSwe_ = p.pcLowSwe(); + pcHighSwe_ = p.pcHighSwe(); + krwHighSwe_ = p.krwHighSwe(); + krnLowSwe_ = p.krnLowSwe(); + krgLowSte_ = p.krgLowSte(); + constRegularization_ = p.constRegularization(); + + initPcParameters_(m, pcLowSwe_, pcHighSwe_); + initKrParameters_(m, krnLowSwe_, krwHighSwe_); + } + + /*! + * \brief Equality comparison with another instance + */ + bool operator== (const ParkerVanGenuchten3PRegularization& o) const + { + return Dune::FloatCmp::eq(pcLowSwe_, o.pcLowSwe_, 1e-6) + && Dune::FloatCmp::eq(pcHighSwe_, o.pcHighSwe_, 1e-6) + && Dune::FloatCmp::eq(krwHighSwe_, o.krwHighSwe_, 1e-6) + && Dune::FloatCmp::eq(krnLowSwe_, o.krnLowSwe_, 1e-6) + && constRegularization_ == o.constRegularization_; + } + + /*! + * \brief The regularized capillary pressure-saturation curve or the gas and wetting phase + * regularized part: + * - low saturation: extend the \f$\mathrm{p_c(S_w)}\f$ curve with the slope at the regularization point (i.e. no kink). + * - high saturation: connect the high regularization point with \f$\mathrm{\overline{S}_w =1}\f$ + * with a spline and continue linearly for \f$\mathrm{\overline{S}_w > 1}\f$ + */ + OptionalScalar pcgw(Scalar swe) const + { + // if specified, a constant value is used for regularization + using std::clamp; + if (constRegularization_) + swe = clamp(swe, 0.0, 1.0); + + // make sure that the capillary pressure observes a derivative + // != 0 for 'illegal' saturations. This is favourable for the + // newton solver (if the derivative is calculated numerically) + // in order to get the saturation moving to the right + // direction if it temporarily is in an 'illegal' range. + if (swe < pcLowSwe_) + return pcgwLowSwePcgwValue_ + pcgwDerivativeLowSw_*(swe - pcLowSwe_); + + else if (swe > 1.0) + return pcgwDerivativeHighSweEnd_*(swe - 1.0); + + else if (swe > pcHighSwe_) + return pcgwSpline_.eval(swe); + + else + return {}; // no regularization + } + + OptionalScalar pcnw(Scalar swe) const + { + // if specified, a constant value is used for regularization + using std::clamp; + if (constRegularization_) + swe = clamp(swe, 0.0, 1.0); + + // make sure that the capillary pressure observes a derivative + // != 0 for 'illegal' saturations. This is favourable for the + // newton solver (if the derivative is calculated numerically) + // in order to get the saturation moving to the right + // direction if it temporarily is in an 'illegal' range. + if (swe < pcLowSwe_) + return pcnwLowSwePcnwValue_ + pcnwDerivativeLowSw_*(swe - pcLowSwe_); + + else if (swe > pcHighSwe_) + return pcnwSpline_.eval(swe); + + else + return {}; // no regularization + } + + OptionalScalar pcgn(Scalar ste) const + { + // if specified, a constant value is used for regularization + using std::clamp; + if (constRegularization_) + ste = clamp(ste, 0.0, 1.0); + + + // make sure that the capillary pressure observes a derivative + // != 0 for 'illegal' saturations. This is favourable for the + // newton solver (if the derivative is calculated numerically) + // in order to get the saturation moving to the right + // direction if it temporarily is in an 'illegal' range. + const Scalar pcLowSte = pcLowSwe_; + const Scalar pcHighSte = pcHighSwe_; + if (ste < pcLowSte) + return pcgnLowStePcgnValue_ + pcgnDerivativeLowSt_*(ste - pcLowSte); + + else if (ste > pcHighSte) + return pcgnSpline_.eval(ste); + + else + return {}; // no regularization + } + + /*! + * \brief This function ensures a continuous transition from 2 to 3 phases and vice versa + * \param sne Effective non-wetting liquid saturation + */ + OptionalScalar pcAlpha(Scalar sne) const + { + // no regularization + return {}; + } + + /*! + * \brief The regularized relative permeability for the wetting phase + */ + OptionalScalar krw(const Scalar swe) const + { + if (swe < 0.0) + return 0.0; + else if (swe > 1.0 - std::numeric_limits::epsilon()) + return 1.0; + else + return {}; // no regularization + } + + + /*! + * \brief The regularized relative permeability for the non-wetting phase + */ + OptionalScalar krn(Scalar swe, const Scalar sn, Scalar ste) const + { + using std::clamp; + swe = clamp(swe, 0.0, 1.0); + ste = clamp(ste, 0.0, 1.0); + + if (ste - swe <= 0.0) + return 0.0; + else + return ParkerVanGenuchten3P::krn(swe, sn, ste, *baseLawParamsPtr_); + } + + /*! + * \brief The regularized relative permeability for the gas phase + */ + OptionalScalar krg(const Scalar ste) const + { + //return 0 if there is no gas + if (ste > 1.0 - std::numeric_limits::epsilon()) + return 0.0; + + // use linear regularization for very high gas saturations + // to avoid a kink in the curve and to maintain a slope for + // the Newton solver + if (ste <= krgLowSte_) + return krgLowStkrgValue_ + krgDerivativeLowSt_*(ste - krgLowSte_); + else + { + // For very low gas saturations: + // We use a scaling factor that decreases the gas phase permeability quite fast a very low gas phase + // saturations, thus making that phase virtually immobile. + // This prevents numerical issues related to the degeneration of the gas phase mass balance for the 3p3c model + // at very low gas phase saturations. + + // get the absolute gas phase saturation + const Scalar st = ste*(1 - swr_) + swr_; + const Scalar sg = 1.0 - st; + + // do not regularize + if (sg > 0.1) + return {}; + + // return original curve scaled by factor + using std::max; + const Scalar scalFact = max(0.0, (sg - sgr_)/(0.1 - sgr_)); + + return ParkerVanGenuchten3P::krg(ste, *baseLawParamsPtr_) * scalFact; + } + } + + /*! + * \brief The relative permeability for a phase. + * \param params Array of parameters. + * \param phaseIdx Indicator, The saturation of all phases. + * \param swe Effective wetting phase saturation + * \param sn Absolute non-wetting liquid saturation + * \param ste Effective total liquid (wetting + non-wetting) saturation + */ + OptionalScalar kr(const int phaseIdx, const Scalar swe, const Scalar sne) const + { + switch (phaseIdx) + { + case 0: + return krw(swe, sne); + case 1: + return krn(swe, sne); + case 2: + return krg(swe, sne); + } + DUNE_THROW(Dune::InvalidStateException, + "Invalid phase index "); + } + +private: + template + void initPcParameters_(const MaterialLaw* m, const Scalar lowSwe, const Scalar highSwe) + { + const auto lowSw = MaterialLaw::EffToAbs::sweToSw(lowSwe, m->effToAbsParams()); + const auto highSw = MaterialLaw::EffToAbs::sweToSw(highSwe, m->effToAbsParams()); + const auto dsw_dswe = MaterialLaw::EffToAbs::dsw_dswe(m->effToAbsParams()); + const auto dst_dste = MaterialLaw::EffToAbs::dst_dste(m->effToAbsParams()); + + baseLawParamsPtr_ = &m->basicParams(); + + + + // pcgw + pcgwLowSwePcgwValue_ = m->template pcgw(lowSw, 0.0); + pcgwDerivativeLowSw_ = m->template dpcgw_dsw(lowSw, 0.0)*dsw_dswe; + pcgwHighSwePcgwValue_ = m->template pcgw(highSw, 0.0); + pcgwDerivativeHighSweThreshold_ = m->template dpcgw_dsw(highSw, 0.0)*dsw_dswe; + pcgwDerivativeHighSweEnd_ = 2.0*(0.0 - m->template pcgw(highSw, 0.0))/(1.0 - highSwe); + pcgwSpline_ = Spline(highSwe, 1.0, // x0, x1 + pcgwHighSwePcgwValue_, 0, // y0, y1 + pcgwDerivativeHighSweThreshold_, pcgwDerivativeHighSweEnd_); // m0, m1 + + // pcnw + pcnwLowSwePcnwValue_ = m->template pcnw(lowSw, 0.0); + pcnwDerivativeLowSw_ = m->template dpcnw_dsw(lowSw, 0.0)*dsw_dswe; + pcnwHighSwePcnwValue_ = m->template pcnw(highSw, 0.0); + pcnwDerivativeHighSweThreshold_ = m->template dpcnw_dsw(highSw, 0.0); + pcnwDerivativeHighSweEnd_ = 2.0*(0.0 - m->template pcnw(highSw, 0.0))/(1.0 - highSwe); + pcnwSpline_ = Spline(highSwe, 1.0, // x0, x1 + pcnwHighSwePcnwValue_, 0, // y0, y1 + pcnwDerivativeHighSweThreshold_, pcnwDerivativeHighSweEnd_); // m0, m1 + + // pcgn + pcgnLowStePcgnValue_ = m->template pcgn(lowSw, 0.0); + pcgnDerivativeLowSt_ = m->template dpcgn_dst(lowSw, 0.0)*dst_dste; + pcgnHighSwePcgnValue_ = m->template pcgn(highSw, 0.0); + pcgnDerivativeHighSweThreshold_ = m->template dpcgn_dst(highSw, 0.0); + pcgnDerivativeHighSweEnd_ = 2.0*(0.0 - m->template pcgn(highSw, 0.0))/(1.0 - highSwe); + pcgnSpline_ = Spline(highSwe, 1.0, // x0, x1 + pcgnHighSwePcgnValue_, 0, // y0, y1 + pcgnDerivativeHighSweThreshold_, pcgnDerivativeHighSweEnd_); // m0, m1 + + } + + template + void initKrParameters_(const MaterialLaw* m, const Scalar lowSwe, const Scalar highSwe) + { + krgLowStkrgValue_ = ParkerVanGenuchten3P::krg(krgLowSte_, *baseLawParamsPtr_); + krgDerivativeLowSt_ = ParkerVanGenuchten3P::dkrg_dste(krgLowSte_, *baseLawParamsPtr_); + + swr_ = m->effToAbsParams().swr(); + sgr_ = m->effToAbsParams().sgr(); + } + + Scalar krgLowStkrgValue_; + Scalar krgDerivativeLowSt_; + + Scalar pcLowSwe_, pcHighSwe_; + Scalar krwHighSwe_, krnLowSwe_, krgLowSte_; + + // pcgw + Scalar pcgwLowSwePcgwValue_; + Scalar pcgwHighSwePcgwValue_; + Scalar pcgwDerivativeLowSw_; + Scalar pcgwDerivativeHighSweThreshold_; + Scalar pcgwDerivativeHighSweEnd_; + + // pcgn + Scalar pcgnLowStePcgnValue_; + Scalar pcgnHighSwePcgnValue_; + Scalar pcgnDerivativeLowSt_; + Scalar pcgnDerivativeHighSweThreshold_; + Scalar pcgnDerivativeHighSweEnd_; + + // pcnw + Scalar pcnwLowSwePcnwValue_; + Scalar pcnwHighSwePcnwValue_; + Scalar pcnwDerivativeLowSw_; + Scalar pcnwDerivativeHighSweThreshold_; + Scalar pcnwDerivativeHighSweEnd_; + + Spline pcgwSpline_; + Spline pcnwSpline_; + Spline pcgnSpline_; + Spline krwSpline_; + Spline krnSpline_; + + Scalar swr_, sgr_; + + bool constRegularization_; + + const BaseLawParams* baseLawParamsPtr_; +}; + +template +class ParkerVanGenuchtenMaterialLaw : public Adapter, ThreePhasePcKrSw> +{ +public: + + using Scalar = ScalarType; + + using BasicParams = typename BaseLaw::template Params; + using EffToAbsParams = typename EffToAbsPolicy::template Params; + using RegularizationParams = typename Regularization::template Params; + + using EffToAbs = EffToAbsPolicy; + + /*! + * \brief Return whether this law is regularized + */ + static constexpr bool isRegularized() + { return !std::is_same::value; } + + /*! + * \brief Deleted default constructor (so we are never in an undefined state) + * \note store owning pointers to laws instead if you need default-constructible objects + */ + ParkerVanGenuchtenMaterialLaw() = delete; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + explicit ParkerVanGenuchtenMaterialLaw(const std::string& paramGroup) + : basicParams_(makeBasicParams(paramGroup)) + , effToAbsParams_(makeEffToAbsParams(paramGroup)) + { + if constexpr (isRegularized()) + regularization_.init(this, paramGroup); + } + + /*! + * \brief Construct from parameter structs + * \note More efficient constructor but you need to ensure all parameters are initialized + */ + ParkerVanGenuchtenMaterialLaw(const BasicParams& baseParams, + const EffToAbsParams& effToAbsParams = {}, + const RegularizationParams& regParams = {}) + : basicParams_(baseParams) + , effToAbsParams_(effToAbsParams) + { + if constexpr (isRegularized()) + regularization_.init(this, baseParams, effToAbsParams, regParams); + } + + /*! + * \brief The capillary pressure-saturation curve for the gas and wetting phase + */ + template + Scalar pcgw(const Scalar sw, const Scalar /*dummySn*/) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.pcgw(swe); + if (regularized) + return regularized.value(); + } + + return BaseLaw::pcgw(swe, basicParams_); + } + + /*! + * \brief The capillary pressure-saturation curve for the non-wetting and wetting phase + */ + template + Scalar pcnw(const Scalar sw, const Scalar /*dummySn*/) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.pcnw(swe); + if (regularized) + return regularized.value(); + } + + return BaseLaw::pcnw(swe, basicParams_); + } + + /*! + * \brief The capillary pressure-saturation curve for the gas and non-wetting phase + */ + template + Scalar pcgn(const Scalar sw, const Scalar sn) const + { + const auto swe = EffToAbs::swToSwe(sw + sn, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.pcgn(swe); + if (regularized) + return regularized.value(); + } + + return BaseLaw::pcgn(swe, basicParams_); + } + + /*! + * \brief This function ensures a continuous transition from 2 to 3 phases and vice versa + * \param params Array of parameters + * \param sn Non-wetting liquid saturation + */ + template + Scalar pcAlpha(const Scalar /*dummySw*/, const Scalar sn) const + { + const auto sne = EffToAbs::snToSne(sn, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.pcAlpha(sne); + if (regularized) + return regularized.value(); + } + return BaseLaw::pcAlpha(sne, basicParams_); + } + + /*! + * \brief The partial derivative of the capillary pressure w.r.t. the saturation + */ + template + Scalar dpcgw_dsw(const Scalar sw, const Scalar /*dummyS*/) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.dpcgw_dswe(swe); + if (regularized) + return regularized.value()*EffToAbs::dswe_dsw(effToAbsParams_); + } + + return BaseLaw::dpcgw_dswe(swe, basicParams_)*EffToAbs::dswe_dsw(effToAbsParams_); + } + + /*! + * \brief The partial derivative of the capillary pressure w.r.t. the saturation + */ + template + Scalar dpcnw_dsw(const Scalar sw, const Scalar /*dummySw*/) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.dpcnw_dswe(swe); + if (regularized) + return regularized.value()*EffToAbs::dswe_dsw(effToAbsParams_); + } + + return BaseLaw::dpcnw_dswe(swe, basicParams_)*EffToAbs::dswe_dsw(effToAbsParams_); + } + + /*! + * \brief The partial derivative of the capillary pressure w.r.t. the saturation + */ + template + Scalar dpcgn_dst(const Scalar st, const Scalar /*dummySw*/) const + { + const auto ste = EffToAbs::stToSte(st, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.dpcgn_dste(ste); + if (regularized) + return regularized.value()*EffToAbs::dswte_dst(effToAbsParams_); + } + + return BaseLaw::dpcgn_dste(ste, basicParams_)*EffToAbs::dste_dst(effToAbsParams_); + } + + /*! + * \brief The relative permeability for the wetting phase + */ + template + Scalar krw(const Scalar sw, const Scalar sn) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.krw(swe); + if (regularized) + return regularized.value(); + } + + return BaseLaw::krw(swe, basicParams_); + } + + /*! + * \brief The relative permeability for the non-wetting phase + */ + template + Scalar krn(const Scalar sw, const Scalar sn) const + { + const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); + const auto ste = EffToAbs::stToSte(sw + sn, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.krn(swe, sn, ste); + if (regularized) + return regularized.value(); + } + + return BaseLaw::krn(swe, sn, ste, basicParams_); + } + + /*! + * \brief The relative permeability for the non-wetting phase + */ + template + Scalar krg(const Scalar sw, const Scalar sn) const + { + const auto ste = EffToAbs::stToSte(sw + sn, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.krg(ste); + if (regularized) + return regularized.value(); + } + + return BaseLaw::krg(ste, basicParams_); + } + + /*! + * \brief The relative permeability for the non-wetting phase + */ + template + Scalar kr(const int phaseIdx, const Scalar sw, const Scalar sn) const + { + switch (phaseIdx) + { + case 0: + return krw(sw, sn); + case 1: + return krn(sw, sn); + case 2: + return krg(sw, sn); + } + DUNE_THROW(Dune::InvalidStateException, + "Invalid phase index "); + } + + /*! + * \brief The derivative of the relative permeability for the non-wetting phase w.r.t. saturation + */ + template + Scalar dkrg_dst(const Scalar st) const + { + const auto ste = EffToAbs::stToSte(st, effToAbsParams_); + if constexpr (enableRegularization) + { + const auto regularized = regularization_.dkrg_dste(ste); + if (regularized) + return regularized.value()*EffToAbs::dste_dst(effToAbsParams_); + } + + return BaseLaw::dkrg_dste(ste, basicParams_)*EffToAbs::dste_dst(effToAbsParams_); + } + + /*! + * \brief Equality comparison with another instance + */ + bool operator== (const ParkerVanGenuchtenMaterialLaw& o) const + { + return basicParams_ == o.basicParams_ + && effToAbsParams_ == o.effToAbsParams_ + && regularization_ == o.regularization_; + } + + /*! + * \brief Create the base law's parameters using + * input file parameters + */ + static BasicParams makeBasicParams(const std::string& paramGroup) + { + return BaseLaw::template makeParams(paramGroup); + } + + /*! + * \brief Return the base law's parameters + */ + const BasicParams& basicParams() const + { return basicParams_; } + + /*! + * \brief Create the parameters of the EffToAbs policy using + * input file parameters + */ + static EffToAbsParams makeEffToAbsParams(const std::string& paramGroup) + { + return EffToAbs::template makeParams(paramGroup); + } + + /*! + * \brief Return the parameters of the EffToAbs policy + */ + const EffToAbsParams& effToAbsParams() const + { return effToAbsParams_; } + +private: + BasicParams basicParams_; + EffToAbsParams effToAbsParams_; + Regularization regularization_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A configuration for using the ParkerVanGenuchten material law without regularization + */ +template +using ParkerVanGenuchten3PNoReg = ParkerVanGenuchtenMaterialLaw; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief A default configuration for using the ParkerVanGenuchten material law + */ +template +using ParkerVanGenuchten3PDefault = ParkerVanGenuchtenMaterialLaw, ParkerVanGenuchten3PEffToAbsPolicy>; + +} // end namespace Dumux::FluidMatrix + +#endif -- GitLab From 5a36e312bd4b063090437f799e7b00659668ab39 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 19:36:43 +0100 Subject: [PATCH 81/99] [3p] Add ThreePNAPLAdsorption class --- .../3p/napladsorption.hh | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 dumux/material/fluidmatrixinteractions/3p/napladsorption.hh diff --git a/dumux/material/fluidmatrixinteractions/3p/napladsorption.hh b/dumux/material/fluidmatrixinteractions/3p/napladsorption.hh new file mode 100644 index 0000000000..689ceb4f67 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/3p/napladsorption.hh @@ -0,0 +1,88 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Fluidmatrixinteractions + * \brief Implementation of a NAPL adsorption model. + */ +#ifndef DUMUX_MATERIAL_FLUIDMATRIX_INTERACTIONS_3P_NAPL_ADSORPTION +#define DUMUX_MATERIAL_FLUIDMATRIX_INTERACTIONS_3P_NAPL_ADSORPTION + +#include +#include + +namespace Dumux::FluidMatrix { + +template +class ThreePNAPLAdsorption : Adapter, Adsorption> +{ +public: + + struct Params + { + Params(const Scalar rhoBulk, const Scalar kdNAPL) + : rhoBulk_(rhoBulk), kdNAPL_(kdNAPL) {} + + Scalar rhoBulk() const { return rhoBulk_; } + void setRhoBulk(const Scalar rhoBulk) { rhoBulk_ = rhoBulk; } + + Scalar kdNAPL() const { return kdNAPL_; } + void setKdNAPL(const Scalar kdNAPL) { kdNAPL_ = kdNAPL; } + + bool operator== (const Params& p) const + { + return Dune::FloatCmp::eq(kdNAPL(), p.kdNAPL(), 1e-6) + && Dune::FloatCmp::eq(rhoBulk(), p.rhoBulk(), 1e-6); + } + + private: + Scalar rhoBulk_, kdNAPL_; + }; + + /*! + * \brief Construct from a subgroup from the global parameter tree + * \note This will give you nice error messages if a mandatory parameter is missing + */ + static Params makeParams(const std::string& paramGroup) + { + const auto rhoBulk = getParamFromGroup(paramGroup, "ThreePNAPLAdsorptionRhoBulk"); + const auto kdNAPL = getParamFromGroup(paramGroup, "ThreePNAPLAdsorptionKdNAPL"); + return {rhoBulk, kdNAPL}; + } + + ThreePNAPLAdsorption(const Params& params): params_(params) {} + + ThreePNAPLAdsorption(const std::string& paramGroup) + : params_(makeParams(paramGroup)) {} + + /*! + * \brief the basis for calculating adsorbed NAPL in storage term + * \param params Array of parameters + */ + Scalar bulkDensTimesAdsorpCoeff () const + { + return params_.rhoBulk() * params_.kdNAPL(); + } + +private: + Params params_; +}; +} // end namespace Dumux::FluidMatrix + +#endif -- GitLab From e56630b23651691ebbf754fd5f9ad1613e6f8465 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 19:37:20 +0100 Subject: [PATCH 82/99] [fluidmatrixinteraction] Add wrapper for Adsorption --- .../fluidmatrixinteraction.hh | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh b/dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh index c5291d14f7..74abc3f422 100644 --- a/dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh +++ b/dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh @@ -249,6 +249,32 @@ private: template NonwettingSolidInterfacialAreaPcSw(T&&) -> NonwettingSolidInterfacialAreaPcSw; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Wrapper type for adsorption laws. + */ +template +class Adsorption +{ +public: + using value_type = T; + + Adsorption(T&& impl) : impl_(std::forward(impl)) {} + const T& adsorptionModel() const { return impl_; } +private: + const T impl_; +}; + +/*! + * \ingroup Fluidmatrixinteractions + * \brief Deduction guide for the Adsorption class. + * Makes sure that Adsorption stores a copy of T if + * the constructor is called with a temporary object. + */ +template +Adsorption(T&&) -> Adsorption; + } // end namespace Dumux::FluidMatrix #endif -- GitLab From 99669bfbd4b7207b2f79b8e5fe27ebbd2e7f9115 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 19:38:12 +0100 Subject: [PATCH 83/99] [3p] Adapt volVars --- dumux/porousmediumflow/3p/volumevariables.hh | 35 +++++++++++--------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/dumux/porousmediumflow/3p/volumevariables.hh b/dumux/porousmediumflow/3p/volumevariables.hh index 2f70cf36a6..8680f1cd61 100644 --- a/dumux/porousmediumflow/3p/volumevariables.hh +++ b/dumux/porousmediumflow/3p/volumevariables.hh @@ -31,6 +31,8 @@ #include #include +#include + namespace Dumux { /*! @@ -89,21 +91,21 @@ public: const Scv& scv) { ParentType::update(elemSol, problem, element, scv); + completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); - // capillary pressure parameters - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw<3>(Scalar{}, problem.spatialParams(), element, scv, elemSol); - completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_); + const auto sw = fluidState_.saturation(wPhaseIdx); + const auto sn = fluidState_.saturation(nPhaseIdx); // mobilities for (int phaseIdx = 0; phaseIdx < ParentType::numFluidPhases(); ++phaseIdx) { - mobility_[phaseIdx] = MaterialLaw::kr(materialParams, phaseIdx, - fluidState_.saturation(wPhaseIdx), - fluidState_.saturation(nPhaseIdx), - fluidState_.saturation(gPhaseIdx)) - / fluidState_.viscosity(phaseIdx); + mobility_[phaseIdx] = fluidMatrixInteraction.kr(phaseIdx, sw, sn) + / fluidState_.viscosity(phaseIdx); } // porosity @@ -136,9 +138,13 @@ public: { EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState); - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); const auto& priVars = elemSol[scv.localDofIndex()]; + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw<3>(Scalar{}, problem.spatialParams(), element, scv, elemSol); + const Scalar sw = priVars[swIdx]; const Scalar sn = priVars[snIdx]; const Scalar sg = 1.0 - sw - sn; @@ -151,12 +157,11 @@ public: const Scalar pg = priVars[pressureIdx]; // calculate capillary pressures - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const Scalar pcgw = MaterialLaw::pcgw(materialParams, sw); - const Scalar pcnw = MaterialLaw::pcnw(materialParams, sw); - const Scalar pcgn = MaterialLaw::pcgn(materialParams, sw + sn); + const Scalar pcgw = fluidMatrixInteraction.pcgw(sw, sn); + const Scalar pcnw = fluidMatrixInteraction.pcnw(sw, sn); + const Scalar pcgn = fluidMatrixInteraction.pcgn(sw, sn); - const Scalar pcAlpha = MaterialLaw::pcAlpha(materialParams, sn); + const Scalar pcAlpha = fluidMatrixInteraction.pcAlpha(sw, sn); const Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file const Scalar pn = pg- pcAlpha * pcgn - (1.0 - pcAlpha)*(pcgw - pcNW1); -- GitLab From 4383e75699a69ab6263ad034f4c9d47d3bd641cf Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 19:38:49 +0100 Subject: [PATCH 84/99] [3p3c] Adapt volVars --- .../porousmediumflow/3p3c/volumevariables.hh | 68 +++++++++++-------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/dumux/porousmediumflow/3p3c/volumevariables.hh b/dumux/porousmediumflow/3p3c/volumevariables.hh index 2bde2eec54..1eb6858fa2 100644 --- a/dumux/porousmediumflow/3p3c/volumevariables.hh +++ b/dumux/porousmediumflow/3p3c/volumevariables.hh @@ -33,11 +33,25 @@ #include #include #include +#include #include "primaryvariableswitch.hh" +#include + namespace Dumux { +namespace Detail { +// helper struct and function detecting if the fluid matrix interaction features a adsorptionModel() function +template +using AdsorptionModelDetector = decltype(std::declval().adsorptionModel()); + +template +static constexpr bool hasAdsorptionModel() +{ return Dune::Std::is_detected::value; } + +} + /*! * \ingroup ThreePThreeCModel * \brief Contains the quantities which are are constant within a @@ -123,11 +137,6 @@ public: constexpr bool useConstraintSolver = ModelTraits::useConstraintSolver(); - // capillary pressure parameters - const auto &materialParams = - problem.spatialParams().materialLawParams(element, scv, elemSol); - - EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState_, solidState_); /* first the saturations */ @@ -178,13 +187,18 @@ public: pg_ = priVars[pressureIdx]; // calculate capillary pressures - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - Scalar pcgw = MaterialLaw::pcgw(materialParams, sw_); - Scalar pcnw = MaterialLaw::pcnw(materialParams, sw_); - Scalar pcgn = MaterialLaw::pcgn(materialParams, sw_ + sn_); - Scalar pcAlpha = MaterialLaw::pcAlpha(materialParams, sn_); - Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw<3>(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + Scalar pcgw = fluidMatrixInteraction.pcgw(sw_, sn_); + Scalar pcnw = fluidMatrixInteraction.pcnw(sw_, sn_); + Scalar pcgn = fluidMatrixInteraction.pcgn(sw_, sn_); + + const Scalar pcAlpha = fluidMatrixInteraction.pcAlpha(sw_, sn_); + const Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file pn_ = pg_- pcAlpha * pcgn - (1.-pcAlpha)*(pcgw - pcNW1); pw_ = pn_ - pcAlpha * pcnw - (1.-pcAlpha)*pcNW1; @@ -528,29 +542,26 @@ public: } } else - { DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); - } - for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx) { - // Mobilities + for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx) + { + // mobilities const Scalar mu = FluidSystem::viscosity(fluidState_, paramCache, phaseIdx); fluidState_.setViscosity(phaseIdx,mu); - Scalar kr; - kr = MaterialLaw::kr(materialParams, phaseIdx, + const Scalar kr = fluidMatrixInteraction.kr(phaseIdx, fluidState_.saturation(wPhaseIdx), - fluidState_.saturation(nPhaseIdx), - fluidState_.saturation(gPhaseIdx)); + fluidState_.saturation(nPhaseIdx)); mobility_[phaseIdx] = kr / mu; } - // material dependent parameters for NAPL adsorption - bulkDensTimesAdsorpCoeff_ = - MaterialLaw::bulkDensTimesAdsorpCoeff(materialParams); + // material dependent parameters for NAPL adsorption (only if law is provided) + if constexpr (Detail::hasAdsorptionModel>()) + bulkDensTimesAdsorpCoeff_ = fluidMatrixInteraction.adsorptionModel().bulkDensTimesAdsorpCoeff(); /* compute the diffusion coefficient * \note This is the part of the diffusion coefficient determined by the fluid state, e.g. @@ -675,9 +686,7 @@ public: * \param phaseIdx The phase index */ Scalar mobility(const int phaseIdx) const - { - return mobility_[phaseIdx]; - } + { return mobility_[phaseIdx]; } /*! * \brief Returns the effective capillary pressure within the control volume. @@ -695,7 +704,12 @@ public: * \brief Returns the adsorption information. */ Scalar bulkDensTimesAdsorpCoeff() const - { return bulkDensTimesAdsorpCoeff_; } + { + if (bulkDensTimesAdsorpCoeff_) + return bulkDensTimesAdsorpCoeff_.value(); + else + DUNE_THROW(Dune::NotImplemented, "Your spatialParams do not provide an adsorption model"); + } /*! * \brief Returns the average permeability within the control volume in \f$[m^2]\f$. @@ -732,7 +746,7 @@ private: PermeabilityType permeability_; //!< Effective permeability within the control volume Scalar mobility_[ModelTraits::numFluidPhases()]; //!< Effective mobility within the control volume - Scalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL + OptionalScalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL DiffusionCoefficients effectiveDiffCoeff_; }; -- GitLab From bb04056f75c7a5e041cbd92289c5114166c44f65 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 20:13:20 +0100 Subject: [PATCH 85/99] [test][3p/infiltration] Adapt spatialParams --- .../3p/implicit/infiltration/params.input | 11 ++- .../3p/implicit/infiltration/problem.hh | 23 ++--- .../3p/implicit/infiltration/spatialparams.hh | 85 ++++++++++--------- 3 files changed, 64 insertions(+), 55 deletions(-) diff --git a/test/porousmediumflow/3p/implicit/infiltration/params.input b/test/porousmediumflow/3p/implicit/infiltration/params.input index 2fc97e822c..b313b40818 100644 --- a/test/porousmediumflow/3p/implicit/infiltration/params.input +++ b/test/porousmediumflow/3p/implicit/infiltration/params.input @@ -12,8 +12,15 @@ Name = infiltration3pcc [SpatialParams] permeability = 1.e-11 # m^2 porosity = 0.40 -vanGenuchtenAlpha = 0.0005 -vanGenuchtenN = 4.0 + +ParkerVanGenuchtenAlpha = 0.0005 +ParkerVanGenuchtenN = 4 +ParkerVanGenuchtenBetaNw = 1 +ParkerVanGenuchtenBetaGw = 1 +ParkerVanGenuchtenBetaGn = 1 +Swr = 0.12 +Snr = 0.07 +Sgr = 0.03 [Output] PlotFluidMatrixInteractions = false diff --git a/test/porousmediumflow/3p/implicit/infiltration/problem.hh b/test/porousmediumflow/3p/implicit/infiltration/problem.hh index 79cb2e8974..8dfc7cd19c 100644 --- a/test/porousmediumflow/3p/implicit/infiltration/problem.hh +++ b/test/porousmediumflow/3p/implicit/infiltration/problem.hh @@ -291,35 +291,36 @@ private: void initial_(PrimaryVariables &values, const GlobalPosition &globalPos) const { - Scalar y = globalPos[1]; - Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + const Scalar x = globalPos[0]; Scalar sw, swr=0.12, sgr=0.03; - if(y > (-1.E-3*x+5) - eps_) + if (y > (-1e-3*x + 5) - eps_) { - Scalar pc = 9.81 * 1000.0 * (y - (-5E-4*x+5)); + Scalar pc = 9.81 * 1000.0 * (y - (-5e-4*x + 5)); if (pc < 0.0) pc = 0.0; sw = invertPcgw_(pc, - this->spatialParams().materialLawParamsAtPos(globalPos)); + this->spatialParams().fluidMatrixInteractionAtPos(globalPos)); if (sw < swr) sw = swr; if (sw > 1.-sgr) sw = 1.-sgr; values[pressureIdx] = 1e5 ; values[swIdx] = sw; values[snIdx] = 0.; - }else { - values[pressureIdx] = 1e5 + 9.81 * 1000.0 * ((-5E-4*x+5) - y); + } + else + { + values[pressureIdx] = 1e5 + 9.81 * 1000.0 * ((-5e-4*x + 5) - y); values[swIdx] = 1.-sgr; values[snIdx] = 0.; } } // small solver inverting the pc curve - template - static Scalar invertPcgw_(Scalar pcIn, const MaterialLawParams &pcParams) + template + static Scalar invertPcgw_(Scalar pcIn, const FMInteraction& fluidMatrixInteraction) { - using MaterialLaw = typename ParentType::SpatialParams::MaterialLaw; Scalar lower,upper; int k; int maxIt = 50; @@ -329,7 +330,7 @@ private: for (k=1; k<=25; k++) { sw = 0.5*(upper+lower); - pcgw = MaterialLaw::pcgw(pcParams, sw); + pcgw = fluidMatrixInteraction.pcgw(sw, 0.0); Scalar delta = pcgw-pcIn; if (delta<0.) delta*=-1.; if (delta #include -#include -#include -#include +#include #include -#include +#include namespace Dumux { /*! @@ -53,18 +51,15 @@ class InfiltrationThreePSpatialParams using GlobalPosition = typename SubControlVolume::GlobalPosition; - using EffectiveLaw = RegularizedParkerVanGen3P; + using ThreePhasePcKrSw = FluidMatrix::ParkerVanGenuchten3PDefault; public: //! Export permeability type using PermeabilityType = Scalar; - //! Get the material law from the property system - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; - InfiltrationThreePSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { // intrinsic permeabilities fineK_ = getParam("SpatialParams.permeability"); @@ -72,22 +67,6 @@ public: // porosities porosity_ = getParam("SpatialParams.porosity"); - vGAlpha_ = getParam("SpatialParams.vanGenuchtenAlpha"); - vGN_ = getParam("SpatialParams.vanGenuchtenN"); - // residual saturations - materialParams_.setSwr(0.12); - materialParams_.setSnr(0.07); - materialParams_.setSgr(0.03); - - // parameters for the 3phase van Genuchten law - materialParams_.setVgAlpha(vGAlpha_); - materialParams_.setVgn(vGN_); - materialParams_.setKrRegardsSnr(false); - - // parameters for adsorption - materialParams_.setKdNAPL(0.); - materialParams_.setRhoBulk(1500.); - plotFluidMatrixInteractions_ = getParam("Output.PlotFluidMatrixInteractions"); } @@ -99,15 +78,40 @@ public: { GnuplotInterface gnuplot(plotFluidMatrixInteractions_); gnuplot.setOpenPlotWindow(plotFluidMatrixInteractions_); - PlotMaterialLaw plotMaterialLaw(plotFluidMatrixInteractions_); + + const Scalar sg = 0.2; // assume a fixed gas saturation + auto swRange = linspace(0.2, 1.0, 1000); + + // assume fixed sn = 0.2 for pcgw curve + auto pcgw = swRange; + std::transform(swRange.begin(), swRange.end(), pcgw.begin(), [&](auto x){ return this->pcKrSwCurve_.pcgw(x, 0.2); }); gnuplot.resetAll(); - plotMaterialLaw.addpc(gnuplot, materialParams_); - gnuplot.plot("pc"); + gnuplot.setXlabel("Sw"); + gnuplot.setYlabel("pcgw"); + gnuplot.addDataSetToPlot(swRange, pcgw, "pcgw", "w l"); + gnuplot.plot("pcgw-sw"); + + // plot kr + swRange = linspace(0.2, 0.8, 1000); + auto krw = swRange; + auto krn = swRange; + auto krg = swRange; + for (const auto& [i, sw] : enumerate(swRange)) + { + const Scalar sn = 1.0 - sg - sw; + krw[i] = pcKrSwCurve_.krw(sw, sn); + krn[i] = pcKrSwCurve_.krn(sw, sn); + krg[i] = pcKrSwCurve_.krg(sw, sn); + } gnuplot.resetAll(); - plotMaterialLaw.addkr(gnuplot, materialParams_); - gnuplot.plot("kr"); + gnuplot.setXlabel("Sw"); + gnuplot.setYlabel("kr"); + gnuplot.addDataSetToPlot(swRange, krw, "krw", "w l"); + gnuplot.addDataSetToPlot(swRange, krn, "krn", "w l"); + gnuplot.addDataSetToPlot(swRange, krg, "krg", "w l"); + gnuplot.plot("kr-sw"); } /*! @@ -139,29 +143,26 @@ public: } /*! - * \brief Returns the parameter object for the Brooks-Corey material law + * \brief Returns the parameters for the material law at a given location * - * \param globalPos The global position + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } + private: bool isFineMaterial_(const GlobalPosition &globalPos) const - { return - 70. - eps_ <= globalPos[0] && globalPos[0] <= 85. + eps_ && - 7.0 - eps_ <= globalPos[1] && globalPos[1] <= 7.50 + eps_; + { + return 70. - eps_ <= globalPos[0] && globalPos[0] <= 85. + eps_ && + 7.0 - eps_ <= globalPos[1] && globalPos[1] <= 7.50 + eps_; } Scalar fineK_; Scalar coarseK_; - Scalar porosity_; - Scalar vGN_; - Scalar vGAlpha_; - - MaterialLawParams materialParams_; + const ThreePhasePcKrSw pcKrSwCurve_; bool plotFluidMatrixInteractions_; -- GitLab From 79ccf27c04aa8399aa8cbd7c77bb755f1d014382 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 20:13:59 +0100 Subject: [PATCH 86/99] [test][3p3c/kuevette] Adapt spatialParams --- .../3p3c/implicit/kuevette/params.input | 10 ++++ .../3p3c/implicit/kuevette/spatialparams.hh | 60 +++++-------------- 2 files changed, 26 insertions(+), 44 deletions(-) diff --git a/test/porousmediumflow/3p3c/implicit/kuevette/params.input b/test/porousmediumflow/3p3c/implicit/kuevette/params.input index 757f876da7..06718dd5d1 100644 --- a/test/porousmediumflow/3p3c/implicit/kuevette/params.input +++ b/test/porousmediumflow/3p3c/implicit/kuevette/params.input @@ -22,3 +22,13 @@ SolidDensity = 2650 SolidThermalConductivity = 2.8 SolidHeatCapacity = 850 +[SpatialParams] +Swr = 0.12 +Snr = 0.07 +Sgr = 0.01 +ParkerVanGenuchtenN = 4 +ParkerVanGenuchtenRegardSnrForKrn = true +Fine.ParkerVanGenuchtenAlpha = 0.0005 +Coarse.ParkerVanGenuchtenAlpha = 0.005 +ThreePNAPLAdsorptionRhoBulk = 1500 +ThreePNAPLAdsorptionKdNAPL = 0 diff --git a/test/porousmediumflow/3p3c/implicit/kuevette/spatialparams.hh b/test/porousmediumflow/3p3c/implicit/kuevette/spatialparams.hh index 4f9bb865bb..b3ad2a6277 100644 --- a/test/porousmediumflow/3p3c/implicit/kuevette/spatialparams.hh +++ b/test/porousmediumflow/3p3c/implicit/kuevette/spatialparams.hh @@ -29,9 +29,9 @@ #include #include -#include -#include -#include + +#include +#include namespace Dumux { @@ -54,15 +54,17 @@ class KuevetteSpatialParams using GlobalPosition = typename SubControlVolume::GlobalPosition; - using EffectiveLaw = RegularizedParkerVanGen3P; + using ThreePhasePcKrSw = FluidMatrix::ParkerVanGenuchten3PDefault; + using AdsorptionModel = FluidMatrix::ThreePNAPLAdsorption; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; KuevetteSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurveFine_("SpatialParams.Fine") + , pcKrSwCurveCoarse_("SpatialParams.Coarse") + , adsorption_("SpatialParams") { // intrinsic permeabilities fineK_ = 6.28e-12; @@ -71,29 +73,6 @@ public: // porosities finePorosity_ = 0.42; coarsePorosity_ = 0.42; - - // residual saturations - fineMaterialParams_.setSwr(0.12); - fineMaterialParams_.setSnr(0.07); - fineMaterialParams_.setSgr(0.01); - coarseMaterialParams_.setSwr(0.12); - coarseMaterialParams_.setSnr(0.07); - coarseMaterialParams_.setSgr(0.01); - - // parameters for the 3phase van Genuchten law - fineMaterialParams_.setVgAlpha(0.0005); - coarseMaterialParams_.setVgAlpha(0.005); - fineMaterialParams_.setVgn(4.0); - coarseMaterialParams_.setVgn(4.0); - - coarseMaterialParams_.setKrRegardsSnr(true); - fineMaterialParams_.setKrRegardsSnr(true); - - // parameters for adsorption - coarseMaterialParams_.setKdNAPL(0.); - coarseMaterialParams_.setRhoBulk(1500.); - fineMaterialParams_.setKdNAPL(0.); - fineMaterialParams_.setRhoBulk(1500.); } /*! @@ -129,25 +108,17 @@ public: return coarsePorosity_; } - /*! - * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). + * \brief Returns the fluid-matrix interaction law at a given location * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - * \return The material parameters object + * \param globalPos The global coordinates for the given location */ - template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - const auto& globalPos = scv.dofPosition(); if (isFineMaterial_(globalPos)) - return fineMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwCurveFine_, adsorption_); else - return coarseMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwCurveCoarse_, adsorption_); } private: @@ -167,8 +138,9 @@ private: Scalar finePorosity_; Scalar coarsePorosity_; - MaterialLawParams fineMaterialParams_; - MaterialLawParams coarseMaterialParams_; + const ThreePhasePcKrSw pcKrSwCurveFine_; + const ThreePhasePcKrSw pcKrSwCurveCoarse_; + const AdsorptionModel adsorption_; }; -- GitLab From d27a7ea3ce85d186152434f5f63e4ab17a59be60 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 20:18:43 +0100 Subject: [PATCH 87/99] [3p] deprecate old material laws --- dumux/material/fluidmatrixinteractions/3p/efftoabslaw.hh | 2 ++ dumux/material/fluidmatrixinteractions/3p/efftoabslawparams.hh | 2 ++ dumux/material/fluidmatrixinteractions/3p/parkervangen3p.hh | 2 ++ .../material/fluidmatrixinteractions/3p/parkervangen3pparams.hh | 2 ++ .../fluidmatrixinteractions/3p/regularizedparkervangen3p.hh | 2 ++ .../3p/regularizedparkervangen3pparams.hh | 2 ++ 6 files changed, 12 insertions(+) diff --git a/dumux/material/fluidmatrixinteractions/3p/efftoabslaw.hh b/dumux/material/fluidmatrixinteractions/3p/efftoabslaw.hh index cdc4fa6435..ee92afb5fc 100644 --- a/dumux/material/fluidmatrixinteractions/3p/efftoabslaw.hh +++ b/dumux/material/fluidmatrixinteractions/3p/efftoabslaw.hh @@ -29,6 +29,8 @@ #include #include "efftoabslawparams.hh" +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! diff --git a/dumux/material/fluidmatrixinteractions/3p/efftoabslawparams.hh b/dumux/material/fluidmatrixinteractions/3p/efftoabslawparams.hh index 4fd831ccbd..495190741c 100644 --- a/dumux/material/fluidmatrixinteractions/3p/efftoabslawparams.hh +++ b/dumux/material/fluidmatrixinteractions/3p/efftoabslawparams.hh @@ -26,6 +26,8 @@ #ifndef DUMUX_EFF_TO_ABS_LAW_PARAMS_HH #define DUMUX_EFF_TO_ABS_LAW_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! diff --git a/dumux/material/fluidmatrixinteractions/3p/parkervangen3p.hh b/dumux/material/fluidmatrixinteractions/3p/parkervangen3p.hh index 1f7da16699..f5b8c86168 100644 --- a/dumux/material/fluidmatrixinteractions/3p/parkervangen3p.hh +++ b/dumux/material/fluidmatrixinteractions/3p/parkervangen3p.hh @@ -28,6 +28,8 @@ #include "parkervangen3pparams.hh" +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + namespace Dumux { /*! diff --git a/dumux/material/fluidmatrixinteractions/3p/parkervangen3pparams.hh b/dumux/material/fluidmatrixinteractions/3p/parkervangen3pparams.hh index 7e407ed4da..23dda11b0b 100644 --- a/dumux/material/fluidmatrixinteractions/3p/parkervangen3pparams.hh +++ b/dumux/material/fluidmatrixinteractions/3p/parkervangen3pparams.hh @@ -28,6 +28,8 @@ #ifndef PARKERVANGEN_PARAMS_3P_HH #define PARKERVANGEN_PARAMS_3P_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include #include diff --git a/dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3p.hh b/dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3p.hh index 231218d4d7..95726acdda 100644 --- a/dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3p.hh +++ b/dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3p.hh @@ -25,6 +25,8 @@ #ifndef REGULARIZED_PARKERVANGEN_3P_HH #define REGULARIZED_PARKERVANGEN_3P_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include #include "parkervangen3p.hh" diff --git a/dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3pparams.hh b/dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3pparams.hh index d9717cde8b..d83485540a 100644 --- a/dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3pparams.hh +++ b/dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3pparams.hh @@ -25,6 +25,8 @@ #ifndef DUMUX_REGULARIZED_PARKERVANGEN_3P_PARAMS_HH #define DUMUX_REGULARIZED_PARKERVANGEN_3P_PARAMS_HH +#warning "This header is deprecated. Removal after 3.3. Use new material laws." + #include "parkervangen3pparams.hh" namespace Dumux { -- GitLab From b9de103ee6ed314d426927b9573d23f2466ce45d Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 20:48:43 +0100 Subject: [PATCH 88/99] [test][3p/infiltration] Adapt spatialParams --- .../3pwateroil/volumevariables.hh | 115 ++++++++++-------- 1 file changed, 63 insertions(+), 52 deletions(-) diff --git a/dumux/porousmediumflow/3pwateroil/volumevariables.hh b/dumux/porousmediumflow/3pwateroil/volumevariables.hh index 06195036b0..bc46538779 100644 --- a/dumux/porousmediumflow/3pwateroil/volumevariables.hh +++ b/dumux/porousmediumflow/3pwateroil/volumevariables.hh @@ -37,12 +37,26 @@ #include #include +#include #include #include "primaryvariableswitch.hh" +#include + namespace Dumux { +namespace Detail { +// helper struct and function detecting if the fluid matrix interaction features a adsorptionModel() function +template +using AdsorptionModelDetector = decltype(std::declval().adsorptionModel()); + +template +static constexpr bool hasAdsorptionModel() +{ return Dune::Std::is_detected::value; } + +} + /*! * \ingroup ThreePWaterOilModel * \brief Contains the quantities which are are constant within a @@ -123,11 +137,7 @@ public: const auto& priVars = elemSol[scv.localDofIndex()]; const auto phasePresence = priVars.state(); - // capillary pressure parameters - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - - if(!onlyGasPhaseCanDisappear()) + if constexpr (!onlyGasPhaseCanDisappear()) { /* first the saturations */ if (phasePresence == threePhases) @@ -172,34 +182,29 @@ public: fluidState_.setSaturation(gPhaseIdx, sg_); fluidState_.setSaturation(nPhaseIdx, sn_); + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw<3>(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + // calculate capillary pressures + const Scalar pcgw = fluidMatrixInteraction.pcgw(sw_, sn_); + const Scalar pcnw = fluidMatrixInteraction.pcnw(sw_, sn_); + const Scalar pcgn = fluidMatrixInteraction.pcgn(sw_, sn_); + + const Scalar pcAlpha = fluidMatrixInteraction.pcAlpha(sw_, sn_); + const Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file + /* now the pressures */ if (phasePresence == threePhases || phasePresence == gnPhaseOnly || phasePresence == gPhaseOnly || phasePresence == wgPhaseOnly) { pg_ = priVars[pressureIdx]; - - // calculate capillary pressures - Scalar pcgw = MaterialLaw::pcgw(materialParams, sw_); - Scalar pcnw = MaterialLaw::pcnw(materialParams, sw_); - Scalar pcgn = MaterialLaw::pcgn(materialParams, sw_ + sn_); - - Scalar pcAlpha = MaterialLaw::pcAlpha(materialParams, sn_); - Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file - pn_ = pg_- pcAlpha * pcgn - (1.-pcAlpha)*(pcgw - pcNW1); pw_ = pn_ - pcAlpha * pcnw - (1.-pcAlpha)*pcNW1; } else if (phasePresence == wPhaseOnly || phasePresence == wnPhaseOnly) { pw_ = priVars[pressureIdx]; - - // calculate capillary pressures - Scalar pcgw = MaterialLaw::pcgw(materialParams, sw_); - Scalar pcnw = MaterialLaw::pcnw(materialParams, sw_); - Scalar pcgn = MaterialLaw::pcgn(materialParams, sw_ + sn_); - - Scalar pcAlpha = MaterialLaw::pcAlpha(materialParams, sn_); - Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file - pn_ = pw_ + pcAlpha * pcnw + (1.-pcAlpha)*pcNW1; pg_ = pn_ + pcAlpha * pcgn + (1.-pcAlpha)*(pcgw - pcNW1); } @@ -504,6 +509,7 @@ public: else assert(false); // unhandled phase state } // end of if(!UseSimpleModel), i.e. the more complex version with six phase states + else // use the simpler model with only two phase states { /* first the saturations */ @@ -525,34 +531,29 @@ public: fluidState_.setSaturation(gPhaseIdx, sg_); fluidState_.setSaturation(nPhaseIdx, sn_); + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw<3>(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + // calculate capillary pressures + const Scalar pcgw = fluidMatrixInteraction.pcgw(sw_, sn_); + const Scalar pcnw = fluidMatrixInteraction.pcnw(sw_, sn_); + const Scalar pcgn = fluidMatrixInteraction.pcgn(sw_, sn_); + + const Scalar pcAlpha = fluidMatrixInteraction.pcAlpha(sw_, sn_); + const Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file + /* now the pressures */ if (phasePresence == threePhases) { pg_ = priVars[pressureIdx]; - - // calculate capillary pressures - Scalar pcgw = MaterialLaw::pcgw(materialParams, sw_); - Scalar pcnw = MaterialLaw::pcnw(materialParams, sw_); - Scalar pcgn = MaterialLaw::pcgn(materialParams, sw_ + sn_); - - Scalar pcAlpha = MaterialLaw::pcAlpha(materialParams, sn_); - Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file - pn_ = pg_- pcAlpha * pcgn - (1.-pcAlpha)*(pcgw - pcNW1); pw_ = pn_ - pcAlpha * pcnw - (1.-pcAlpha)*pcNW1; } else if (phasePresence == wnPhaseOnly) { pw_ = priVars[pressureIdx]; - - // calculate capillary pressures - Scalar pcgw = MaterialLaw::pcgw(materialParams, sw_); - Scalar pcnw = MaterialLaw::pcnw(materialParams, sw_); - Scalar pcgn = MaterialLaw::pcgn(materialParams, sw_ + sn_); - - Scalar pcAlpha = MaterialLaw::pcAlpha(materialParams, sn_); - Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file - pn_ = pw_ + pcAlpha * pcnw + (1.-pcAlpha)*pcNW1; pg_ = pn_ + pcAlpha * pcgn + (1.-pcAlpha)*(pcgw - pcNW1); } @@ -723,25 +724,30 @@ public: fluidState_.setMolarDensity(nPhaseIdx, rhoNMolar); } else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); - } + } - for (int phaseIdx = 0; phaseIdx < numPs; ++phaseIdx) { + // old material law interface is deprecated: Replace this by + // const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); + // after the release of 3.3, when the deprecated interface is no longer supported + const auto fluidMatrixInteraction = Deprecated::makePcKrSw<3>(Scalar{}, problem.spatialParams(), element, scv, elemSol); + + for (int phaseIdx = 0; phaseIdx < numPs; ++phaseIdx) + { // Mobilities const Scalar mu = FluidSystem::viscosity(fluidState_, phaseIdx); fluidState_.setViscosity(phaseIdx,mu); - Scalar kr; - kr = MaterialLaw::kr(materialParams, phaseIdx, + const Scalar kr = fluidMatrixInteraction.kr(phaseIdx, fluidState_.saturation(wPhaseIdx), - fluidState_.saturation(nPhaseIdx), - fluidState_.saturation(gPhaseIdx)); + fluidState_.saturation(nPhaseIdx)); mobility_[phaseIdx] = kr / mu; } - // material dependent parameters for NAPL adsorption - bulkDensTimesAdsorpCoeff_ = MaterialLaw::bulkDensTimesAdsorpCoeff(materialParams); + // material dependent parameters for NAPL adsorption (only if law is provided) + if constexpr (Detail::hasAdsorptionModel>()) + bulkDensTimesAdsorpCoeff_ = fluidMatrixInteraction.adsorptionModel().bulkDensTimesAdsorpCoeff(); // porosity updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps); @@ -902,10 +908,15 @@ public: { return effectiveDiffCoeff_(phaseIdx, compIIdx, compJIdx); } /*! - * \brief Returns the adsorption information + * \brief Returns the adsorption information. */ Scalar bulkDensTimesAdsorpCoeff() const - { return bulkDensTimesAdsorpCoeff_; } + { + if (bulkDensTimesAdsorpCoeff_) + return bulkDensTimesAdsorpCoeff_.value(); + else + DUNE_THROW(Dune::NotImplemented, "Your spatialParams do not provide an adsorption model"); + } /*! * \brief Returns the total internal energy of a phase in the @@ -937,7 +948,7 @@ private: Scalar permeability_; //!< Effective porosity within the control volume Scalar mobility_[numPs]; //!< Effective mobility within the control volume - Scalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL + OptionalScalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL //!< Binary diffusion coefficients of the 3 components in the phases DiffusionCoefficients effectiveDiffCoeff_; -- GitLab From 90c3d57952ddb2d72e64aaace20d2764458a0a53 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 21:48:39 +0100 Subject: [PATCH 89/99] [test][3pni] Adapt spatial params --- .../3p/implicit/conduction/params.input | 8 +++++ .../3p/implicit/conduction/spatialparams.hh | 36 +++++-------------- .../3p/implicit/convection/params.input | 8 +++++ 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/test/porousmediumflow/3p/implicit/conduction/params.input b/test/porousmediumflow/3p/implicit/conduction/params.input index 4f9840b5f7..3d57f51512 100644 --- a/test/porousmediumflow/3p/implicit/conduction/params.input +++ b/test/porousmediumflow/3p/implicit/conduction/params.input @@ -19,3 +19,11 @@ AddVelocity = true #Enable velocity output SolidDensity = 2700 SolidThermalConductivity = 2.8 SolidHeatCapacity = 790 + +[SpatialParams] +Swr = 0.12 +Snr = 0.10 +Sgr = 0.01 +ParkerVanGenuchtenAlpha = 0.5 +ParkerVanGenuchtenN = 4 +ParkerVanGenuchtenRegardSnrForKrn = true diff --git a/test/porousmediumflow/3p/implicit/conduction/spatialparams.hh b/test/porousmediumflow/3p/implicit/conduction/spatialparams.hh index 6fa0971a8e..78f77d58c2 100644 --- a/test/porousmediumflow/3p/implicit/conduction/spatialparams.hh +++ b/test/porousmediumflow/3p/implicit/conduction/spatialparams.hh @@ -27,9 +27,7 @@ #include #include -#include -#include -#include +#include namespace Dumux { @@ -49,36 +47,20 @@ class ThreePNISpatialParams using ParentType = FVSpatialParams>; - using EffectiveLaw = RegularizedParkerVanGen3P; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using ThreePhasePcKrSw = FluidMatrix::ParkerVanGenuchten3PDefault; + public: //! Export permeability type using PermeabilityType = Scalar; - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; - ThreePNISpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { permeability_ = 1e-10; porosity_ = 0.4; - - // residual saturations - materialParams_.setSwr(0.12); - materialParams_.setSnr(0.10); - materialParams_.setSgr(0.01); - - // parameters for the 3phase van Genuchten law - materialParams_.setVgAlpha(0.5); - materialParams_.setVgn(4.0); - materialParams_.setKrRegardsSnr(true); - - // parameters for adsorption - materialParams_.setKdNAPL(0.); - materialParams_.setRhoBulk(1500.); } /*! @@ -102,18 +84,18 @@ public: } /*! - * \brief Returns the parameter object for the Brooks-Corey material law + * \brief Returns the fluid-matrix interaction law at a given location * - * \param globalPos The global position + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } private: - MaterialLawParams materialParams_; + const ThreePhasePcKrSw pcKrSwCurve_; Scalar permeability_; Scalar porosity_; }; diff --git a/test/porousmediumflow/3p/implicit/convection/params.input b/test/porousmediumflow/3p/implicit/convection/params.input index ddc172cec4..d2b95c9597 100644 --- a/test/porousmediumflow/3p/implicit/convection/params.input +++ b/test/porousmediumflow/3p/implicit/convection/params.input @@ -20,3 +20,11 @@ AddVelocity = true #Enable velocity output SolidDensity = 2700 SolidThermalConductivity = 2.8 SolidHeatCapacity = 790 + +[SpatialParams] +Swr = 0.12 +Snr = 0.10 +Sgr = 0.01 +ParkerVanGenuchtenAlpha = 0.5 +ParkerVanGenuchtenN = 4 +ParkerVanGenuchtenRegardSnrForKrn = true -- GitLab From a948c0231dec44ec6e12999e173ada2a694e5ce7 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 21:49:02 +0100 Subject: [PATCH 90/99] [test][3pwateroil] Adapt spatial params --- .../3pwateroil/implicit/params.input | 8 +++ .../3pwateroil/implicit/spatialparams.hh | 70 ++++--------------- 2 files changed, 21 insertions(+), 57 deletions(-) diff --git a/test/porousmediumflow/3pwateroil/implicit/params.input b/test/porousmediumflow/3pwateroil/implicit/params.input index 3eee8b7db6..e0656f7d1b 100644 --- a/test/porousmediumflow/3pwateroil/implicit/params.input +++ b/test/porousmediumflow/3pwateroil/implicit/params.input @@ -16,3 +16,11 @@ MaxSteps = 8 SolidDensity = 2650 SolidThermalConductivity = 2.8 SolidHeatCapacity = 850 + +[SpatialParams] +Swr = 0.1 +Snr = 0.09 +Sgr = 0.01 +ParkerVanGenuchtenN = 4 +ParkerVanGenuchtenAlpha = 1 +ParkerVanGenuchtenRegardSnrForKrn = false diff --git a/test/porousmediumflow/3pwateroil/implicit/spatialparams.hh b/test/porousmediumflow/3pwateroil/implicit/spatialparams.hh index 94790c0357..ba21820bbd 100644 --- a/test/porousmediumflow/3pwateroil/implicit/spatialparams.hh +++ b/test/porousmediumflow/3pwateroil/implicit/spatialparams.hh @@ -28,11 +28,7 @@ #include #include -#include - -#include -#include -#include +#include namespace Dumux { @@ -57,15 +53,15 @@ class SagdSpatialParams using ParentType = FVSpatialParams>; - using EffectiveLaw = RegularizedParkerVanGen3P; + using ThreePhasePcKrSw = FluidMatrix::ParkerVanGenuchten3PDefault; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; SagdSpatialParams(std::shared_ptr gridGeometry) - : ParentType(gridGeometry), eps_(1e-6) + : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") + , eps_(1e-6) { layerBottom_ = 35.0; @@ -76,23 +72,6 @@ public: // porosities finePorosity_ = 0.10; coarsePorosity_ = 0.1; - - // residual saturations - fineMaterialParams_.setSwr(0.1); - fineMaterialParams_.setSnr(0.09); //Residual of NAPL if there is no water - fineMaterialParams_.setSgr(0.01); - coarseMaterialParams_.setSwr(0.1); - coarseMaterialParams_.setSnr(0.09); - coarseMaterialParams_.setSgr(0.01); - - // parameters for the 3phase van Genuchten law - fineMaterialParams_.setVgn(4.0); - coarseMaterialParams_.setVgn(4.0); - fineMaterialParams_.setVgAlpha(1.); - coarseMaterialParams_.setVgAlpha(1.); - - coarseMaterialParams_.setKrRegardsSnr(false); - fineMaterialParams_.setKrRegardsSnr(false); } /*! @@ -136,41 +115,19 @@ public: } /*! - * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). - * - * \param element The current element - * \param scv The sub-control volume inside the element. - * \param elemSol The solution at the dofs connected to the element. - * \return The material parameters object - */ - template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const - { - return materialLawParamsAtPos(scv.dofPosition()); - } - - /*! - * \brief Returns the parameter object for the capillary-pressure/ - * saturation material law + * \brief Returns the fluid-matrix interaction law at a given location * - * \param globalPos The global position + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - if (isFineMaterial_(globalPos)) - return fineMaterialParams_; - else - return coarseMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } - private: - bool isFineMaterial_(const GlobalPosition &pos) const - { - return pos[dimWorld-1] > layerBottom_ - eps_; - }; + + bool isFineMaterial_(const GlobalPosition& pos) const + { return pos[dimWorld-1] > layerBottom_ - eps_; } Scalar layerBottom_; @@ -180,8 +137,7 @@ private: Scalar finePorosity_; Scalar coarsePorosity_; - MaterialLawParams fineMaterialParams_; - MaterialLawParams coarseMaterialParams_; + const ThreePhasePcKrSw pcKrSwCurve_; Scalar eps_; }; -- GitLab From 55126561afe97c5a26afbae71d900f3480f407c6 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Thu, 29 Oct 2020 21:50:04 +0100 Subject: [PATCH 91/99] [test][3p3c] Adapt spatial params --- .../3p3c/implicit/columnxylol/params.input | 9 +++ .../implicit/columnxylol/spatialparams.hh | 59 ++++++------------- .../3p3c/implicit/infiltration/params.input | 8 +++ .../3p3c/implicit/infiltration/problem.hh | 9 ++- .../implicit/infiltration/spatialparams.hh | 37 +++--------- 5 files changed, 47 insertions(+), 75 deletions(-) diff --git a/test/porousmediumflow/3p3c/implicit/columnxylol/params.input b/test/porousmediumflow/3p3c/implicit/columnxylol/params.input index f502ce89f7..0da3b34d3b 100644 --- a/test/porousmediumflow/3p3c/implicit/columnxylol/params.input +++ b/test/porousmediumflow/3p3c/implicit/columnxylol/params.input @@ -18,3 +18,12 @@ SolidDensity = 2650 SolidThermalConductivity = 2.8 SolidHeatCapacityFine = 850 SolidHeatCapacityCoarse = 84000 + +[SpatialParams] +Swr = 0.12 +Snr = 0.10 +Sgr = 0.01 +ParkerVanGenuchtenN = 4 +ParkerVanGenuchtenRegardSnrForKrn = true +Fine.ParkerVanGenuchtenAlpha = 0.0005 +Coarse.ParkerVanGenuchtenAlpha = 0.5 diff --git a/test/porousmediumflow/3p3c/implicit/columnxylol/spatialparams.hh b/test/porousmediumflow/3p3c/implicit/columnxylol/spatialparams.hh index 4de10b8032..3fade2a52b 100644 --- a/test/porousmediumflow/3p3c/implicit/columnxylol/spatialparams.hh +++ b/test/porousmediumflow/3p3c/implicit/columnxylol/spatialparams.hh @@ -26,9 +26,7 @@ #include #include -#include -#include -#include +#include namespace Dumux { @@ -50,15 +48,16 @@ class ColumnSpatialParams ColumnSpatialParams>; using GlobalPosition = typename SubControlVolume::GlobalPosition; - using EffectiveLaw = RegularizedParkerVanGen3P; + + using ThreePhasePcKrSw = FluidMatrix::ParkerVanGenuchten3PDefault; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; ColumnSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurveFine_("SpatialParams.Fine") + , pcKrSwCurveCoarse_("SpatialParams.Coarse") { // intrinsic permeabilities fineK_ = 1.4e-11; @@ -70,29 +69,6 @@ public: // specific heat capacities fineHeatCap_ = getParam("Component.SolidHeatCapacityFine", 850.0); coarseHeatCap_ = getParam("Component.SolidHeatCapacityCoarse", 84000.0); - - // residual saturations - fineMaterialParams_.setSwr(0.12); - fineMaterialParams_.setSnr(0.10); - fineMaterialParams_.setSgr(0.01); - coarseMaterialParams_.setSwr(0.12); - coarseMaterialParams_.setSnr(0.10); - coarseMaterialParams_.setSgr(0.01); - - // parameters for the 3phase van Genuchten law - fineMaterialParams_.setVgAlpha(0.0005); - coarseMaterialParams_.setVgAlpha(0.5); - fineMaterialParams_.setVgn(4.0); - coarseMaterialParams_.setVgn(4.0); - - coarseMaterialParams_.setKrRegardsSnr(true); - fineMaterialParams_.setKrRegardsSnr(true); - - // parameters for adsorption - coarseMaterialParams_.setKdNAPL(0.); - coarseMaterialParams_.setRhoBulk(1500.); - fineMaterialParams_.setKdNAPL(0.); - fineMaterialParams_.setRhoBulk(1500.); } /*! @@ -116,32 +92,31 @@ public: } /*! \brief Defines the porosity in [-]. - * - * \param globalPos The global position where we evaluate - */ + * + * \param globalPos The global position where we evaluate + */ Scalar porosityAtPos(const GlobalPosition& globalPos) const { return porosity_; } /*! - * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). + * \brief Returns the fluid-matrix interaction law. * * \param element The current element * \param scv The sub-control volume inside the element. * \param elemSol The solution at the dofs connected to the element. - * \return The material parameters object */ - template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + template + auto fluidMatrixInteraction(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { const auto& globalPos = scv.dofPosition(); if (isFineMaterial_(globalPos)) - return fineMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwCurveFine_); else - return coarseMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwCurveCoarse_); } /*! @@ -180,8 +155,8 @@ private: Scalar fineHeatCap_; Scalar coarseHeatCap_; - MaterialLawParams fineMaterialParams_; - MaterialLawParams coarseMaterialParams_; + const ThreePhasePcKrSw pcKrSwCurveFine_; + const ThreePhasePcKrSw pcKrSwCurveCoarse_; static constexpr Scalar eps_ = 1e-6; }; diff --git a/test/porousmediumflow/3p3c/implicit/infiltration/params.input b/test/porousmediumflow/3p3c/implicit/infiltration/params.input index d910fd4511..9a76b58299 100644 --- a/test/porousmediumflow/3p3c/implicit/infiltration/params.input +++ b/test/porousmediumflow/3p3c/implicit/infiltration/params.input @@ -14,3 +14,11 @@ NumericDifferenceMethod = 0 # -1 backward differences, 0: central differences, + [Newton] MaxRelativeShift = 1e-6 + +[SpatialParams] +Swr = 0.12 +Snr = 0.07 +Sgr = 0.03 +ParkerVanGenuchtenN = 4 +ParkerVanGenuchtenAlpha = 0.0005 +ParkerVanGenuchtenRegardSnrForKrn = false diff --git a/test/porousmediumflow/3p3c/implicit/infiltration/problem.hh b/test/porousmediumflow/3p3c/implicit/infiltration/problem.hh index c710cf2b9b..ba40089f11 100644 --- a/test/porousmediumflow/3p3c/implicit/infiltration/problem.hh +++ b/test/porousmediumflow/3p3c/implicit/infiltration/problem.hh @@ -274,7 +274,7 @@ private: Scalar pc = 9.81 * 1000.0 * (y - (-5E-4*x+5)); if (pc < 0.0) pc = 0.0; - sw = invertPcgw_(pc, this->spatialParams().materialLawParamsAtPos(globalPos)); + sw = invertPcgw_(pc, this->spatialParams().fluidMatrixInteractionAtPos(globalPos)); if (sw < swr) sw = swr; if (sw > 1.-sgr) sw = 1.-sgr; @@ -289,10 +289,9 @@ private: return values; } - template - static Scalar invertPcgw_(Scalar pcIn, const MaterialLawParams &pcParams) + template + static Scalar invertPcgw_(Scalar pcIn, const FluidMatrixInteraction& fluidmatrixinteraction) { - using MaterialLaw = typename ParentType::SpatialParams::MaterialLaw; Scalar lower,upper; int k; int maxIt = 50; @@ -302,7 +301,7 @@ private: for (k=1; k<=25; k++) { sw = 0.5*(upper+lower); - pcgw = MaterialLaw::pcgw(pcParams, sw); + pcgw = fluidmatrixinteraction.pcgw(sw, 0.0/*sn*/); Scalar delta = pcgw-pcIn; if (delta<0.) delta*=-1.; if (delta #include -#include -#include -#include -#include +#include namespace Dumux { @@ -51,17 +48,16 @@ class InfiltrationThreePThreeCSpatialParams using ParentType = FVSpatialParams>; - using EffectiveLaw = RegularizedParkerVanGen3P; - using GlobalPosition = typename SubControlVolume::GlobalPosition; + using ThreePhasePcKrSw = FluidMatrix::ParkerVanGenuchten3PDefault; + public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; InfiltrationThreePThreeCSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurve_("SpatialParams") { // intrinsic permeabilities fineK_ = 1.e-11; @@ -69,20 +65,6 @@ public: // porosities porosity_ = 0.40; - - // residual saturations - materialParams_.setSwr(0.12); - materialParams_.setSnr(0.07); - materialParams_.setSgr(0.03); - - // parameters for the 3phase van Genuchten law - materialParams_.setVgAlpha(0.0005); - materialParams_.setVgn(4.); - materialParams_.setKrRegardsSnr(false); - - // parameters for adsorption - materialParams_.setKdNAPL(0.); - materialParams_.setRhoBulk(1500.); } /*! @@ -115,15 +97,14 @@ public: return porosity_; } - /*! - * \brief Returns the parameter object for the material law which depends on the position + * \brief Returns the fluid-matrix interaction law at a given location * - * \param globalPos The position for which the material law should be evaluated + * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { - return materialParams_; + return makeFluidMatrixInteraction(pcKrSwCurve_); } private: @@ -138,7 +119,7 @@ private: Scalar porosity_; - MaterialLawParams materialParams_; + const ThreePhasePcKrSw pcKrSwCurve_; }; } // end namespace Dumux -- GitLab From 5769870d4e96c756acf7a76fd88dc7e41bb5497a Mon Sep 17 00:00:00 2001 From: Melanie Lipp Date: Wed, 28 Oct 2020 11:24:47 +0100 Subject: [PATCH 92/99] [doc][doxygen] Cleanup for new materiallaw. --- .../fluidmatrixinteractions/2p/datasplinemateriallaw.hh | 2 +- dumux/material/fluidmatrixinteractions/2p/heatpipelaw.hh | 2 -- .../2p/interfacialarea/exponential.hh | 6 +++--- .../2p/interfacialarea/polynomial2ndorder.hh | 6 +++--- .../fluidmatrixinteractions/2p/splinemateriallaw.hh | 2 +- dumux/material/fluidmatrixinteractions/2p/vangenuchten.hh | 1 + dumux/porousmediumflow/2p/boxmaterialinterfaces.hh | 2 +- dumux/porousmediumflow/2p/saturationreconstruction.hh | 4 ++-- 8 files changed, 12 insertions(+), 13 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/2p/datasplinemateriallaw.hh b/dumux/material/fluidmatrixinteractions/2p/datasplinemateriallaw.hh index 794fe36049..990e43fd09 100644 --- a/dumux/material/fluidmatrixinteractions/2p/datasplinemateriallaw.hh +++ b/dumux/material/fluidmatrixinteractions/2p/datasplinemateriallaw.hh @@ -36,7 +36,7 @@ namespace Dumux::FluidMatrix { * \ingroup Fluidmatrixinteractions * \brief Pc- and Kr-sw curves based on monotone splines through given data points * \tparam S the type for scalar numbers - * \tpraram approximatePcSwInverse if this is set true, the + * \tparam approximatePcSwInverse if this is set true, the * spline approximates sw(pc) and evaluating pc(sw) needs spline inversion. * if this is false, the spline approximates pc(sw) and evaluating * sw(pc) needs spline inversion. Spline inversion is rather expensive diff --git a/dumux/material/fluidmatrixinteractions/2p/heatpipelaw.hh b/dumux/material/fluidmatrixinteractions/2p/heatpipelaw.hh index 3a5437d690..43a96a6170 100644 --- a/dumux/material/fluidmatrixinteractions/2p/heatpipelaw.hh +++ b/dumux/material/fluidmatrixinteractions/2p/heatpipelaw.hh @@ -273,7 +273,6 @@ public: /*! * \brief The capillary pressure-saturation curve. * - }\f$ * \param swe Effective saturation of the wetting phase \f$\mathrm{\overline{S}_w}\f$ */ template @@ -305,7 +304,6 @@ public: /*! * \brief The partial derivative of the capillary * pressure w.r.t. the effective saturation. - * * \param swe Effective saturation of the wetting phase \f$\mathrm{\overline{S}_w}\f$ */ diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponential.hh b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponential.hh index 552922aaf5..4d3b6b2b81 100644 --- a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponential.hh +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/exponential.hh @@ -92,7 +92,7 @@ public: * \f$\mathrm{ a_{wn} = a_1 * (S_{wr}-S_w) .* (1-S_w) + a_2 * (S_{wr}-S_w) * (1-S_w) * \exp( a_3 * p_c) ; }\f$ - * \param sw Effective saturation of the wetting phase + * \param swe Effective saturation of the wetting phase * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ * \param params parameter container for the coefficients of the surface */ @@ -110,7 +110,7 @@ public: /*! \brief the derivative of specific interfacial area function w.r.t. capillary pressure * * \param params parameter container for the coefficients of the surface - * \param Sw Effective saturation of the wetting phase + * \param swe Effective saturation of the wetting phase * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ */ template @@ -126,7 +126,7 @@ public: /*! \brief the derivative of specific interfacial area function w.r.t. saturation * * \param params parameter container for the coefficients of the surface - * \param Sw Effective saturation of the wetting phase + * \param swe Effective saturation of the wetting phase * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ */ template diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomial2ndorder.hh b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomial2ndorder.hh index 1b0f44599c..05f4243a69 100644 --- a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomial2ndorder.hh +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/polynomial2ndorder.hh @@ -101,7 +101,7 @@ public: a_{wn} = a_{00} + a_{10}S_{w} + a_{20}S_{w}^2 + a_{11} S_{w} p_{c} + a_{01} p_{c} + a_{02}p_{c}^2 \f$] * \param params parameter container for the coefficients of the surface - * \param Sw Effective saturation of the wetting phase + * \param swe Effective saturation of the wetting phase * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ */ template @@ -121,7 +121,7 @@ public: * \brief the derivative of specific interfacial area function w.r.t. capillary pressure * * \param params parameter container for the coefficients of the surface - * \param Sw Effective saturation of the wetting phase + * \param swe Effective saturation of the wetting phase * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ */ template @@ -134,7 +134,7 @@ public: * \brief the derivative of specific interfacial area function w.r.t. saturation * * \param params parameter container for the coefficients of the surface - * \param Sw Effective saturation of the wetting phase + * \param swe Effective saturation of the wetting phase * \param pc Capillary pressure in \f$\mathrm{[Pa]}\f$ */ template diff --git a/dumux/material/fluidmatrixinteractions/2p/splinemateriallaw.hh b/dumux/material/fluidmatrixinteractions/2p/splinemateriallaw.hh index 59e54d6f51..78e1967384 100644 --- a/dumux/material/fluidmatrixinteractions/2p/splinemateriallaw.hh +++ b/dumux/material/fluidmatrixinteractions/2p/splinemateriallaw.hh @@ -37,7 +37,7 @@ namespace Dumux::FluidMatrix { * \ingroup Fluidmatrixinteractions * \brief A spline approximation wrapper for 2p material laws * \tparam TwoPMaterialLaw the type of material law to be wrapped - * \tpraram approximatePcSwInverse if this is set true, the + * \tparam approximatePcSwInverse if this is set true, the * spline approximates sw(pc) and evaluating pc(sw) needs spline inversion. * if this is false, the spline approximates pc(sw) and evaluating * sw(pc) needs spline inversion. Spline inversion is rather expensive diff --git a/dumux/material/fluidmatrixinteractions/2p/vangenuchten.hh b/dumux/material/fluidmatrixinteractions/2p/vangenuchten.hh index 323aac975d..69aeb71099 100644 --- a/dumux/material/fluidmatrixinteractions/2p/vangenuchten.hh +++ b/dumux/material/fluidmatrixinteractions/2p/vangenuchten.hh @@ -523,6 +523,7 @@ public: * parameterization. * * \param swe The mobile saturation of the wetting phase. + * \param params A container object that is populated with the appropriate coefficients for the respective law. * \note Instead of undefined behaviour if pc is not in the valid range, we return a valid number, * by clamping the input. */ diff --git a/dumux/porousmediumflow/2p/boxmaterialinterfaces.hh b/dumux/porousmediumflow/2p/boxmaterialinterfaces.hh index 3296cd5444..ab1e84f16d 100644 --- a/dumux/porousmediumflow/2p/boxmaterialinterfaces.hh +++ b/dumux/porousmediumflow/2p/boxmaterialinterfaces.hh @@ -19,7 +19,7 @@ /*! * \file * \ingroup TwoPModel - * \copydoc Dumux::BoxMaterialInterfaceParams + * \copydoc Dumux::BoxMaterialInterfaces */ #ifndef DUMUX_2P_BOX_MATERIAL_INTERFACES_HH diff --git a/dumux/porousmediumflow/2p/saturationreconstruction.hh b/dumux/porousmediumflow/2p/saturationreconstruction.hh index 10a49b2644..7a94627486 100644 --- a/dumux/porousmediumflow/2p/saturationreconstruction.hh +++ b/dumux/porousmediumflow/2p/saturationreconstruction.hh @@ -53,7 +53,7 @@ public: * \param element The finite element the scv is embedded in * \param scv The sub-control volume for which the saturation is computed * \param elemSol The solution at all dofs inside this element - * \param Sn The nonwetting phase saturation at the global dof + * \param sn The nonwetting phase saturation at the global dof */ template static typename ElemSol::PrimaryVariables::value_type @@ -77,7 +77,7 @@ public: * \param element The finite element the scv is embedded in * \param scv The sub-control volume for which the saturation is computed * \param elemSol The solution at all dofs inside this element - * \param Sn The nonwetting phase saturation at the global dof + * \param sn The nonwetting phase saturation at the global dof */ template static typename ElemSol::PrimaryVariables::value_type -- GitLab From a80634a4ccc3b0c9db55938aff8a61298cb73301 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Fri, 30 Oct 2020 01:32:26 +0100 Subject: [PATCH 93/99] [cmake] Add missing entries in CMakeLists for material laws --- dumux/io/CMakeLists.txt | 1 + dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt | 2 ++ .../2p/interfacialarea/CMakeLists.txt | 8 ++++++++ dumux/material/fluidmatrixinteractions/3p/CMakeLists.txt | 2 ++ dumux/porousmediumflow/2p/CMakeLists.txt | 2 +- 5 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 dumux/material/fluidmatrixinteractions/2p/interfacialarea/CMakeLists.txt diff --git a/dumux/io/CMakeLists.txt b/dumux/io/CMakeLists.txt index 6032f37994..2a491c8b78 100644 --- a/dumux/io/CMakeLists.txt +++ b/dumux/io/CMakeLists.txt @@ -14,6 +14,7 @@ name.hh ploteffectivediffusivitymodel.hh plotmateriallaw.hh plotmateriallaw3p.hh +plotpckrsw.hh plotthermalconductivitymodel.hh pointcloudvtkwriter.hh rasterimagereader.hh diff --git a/dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt b/dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt index 84bbb5107a..9c39155a73 100644 --- a/dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt +++ b/dumux/material/fluidmatrixinteractions/2p/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(interfacialarea) add_subdirectory(thermalconductivity) install(FILES @@ -12,6 +13,7 @@ heatpipelawparams.hh linearmaterial.hh linearmaterialparams.hh materiallaw.hh +noregularization.hh regularizedbrookscorey.hh regularizedbrookscoreyparams.hh regularizedlinearmaterial.hh diff --git a/dumux/material/fluidmatrixinteractions/2p/interfacialarea/CMakeLists.txt b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/CMakeLists.txt new file mode 100644 index 0000000000..f908e650e5 --- /dev/null +++ b/dumux/material/fluidmatrixinteractions/2p/interfacialarea/CMakeLists.txt @@ -0,0 +1,8 @@ +install(FILES +exponential.hh +exponentialcubic.hh +interfacialarea.hh +pcmax.hh +polynomial2ndorder.hh +polynomialedgezero2ndorder.hh +DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/material/fluidmatrixinteractions/2p/interfacialarea) diff --git a/dumux/material/fluidmatrixinteractions/3p/CMakeLists.txt b/dumux/material/fluidmatrixinteractions/3p/CMakeLists.txt index 63d05e3b03..3cb201ecc2 100644 --- a/dumux/material/fluidmatrixinteractions/3p/CMakeLists.txt +++ b/dumux/material/fluidmatrixinteractions/3p/CMakeLists.txt @@ -1,8 +1,10 @@ install(FILES efftoabslaw.hh efftoabslawparams.hh +napladsorption.hh parkervangen3p.hh parkervangen3pparams.hh +parkervangenuchten.hh regularizedparkervangen3p.hh regularizedparkervangen3pparams.hh thermalconductivitysomerton3p.hh diff --git a/dumux/porousmediumflow/2p/CMakeLists.txt b/dumux/porousmediumflow/2p/CMakeLists.txt index 5497ae6e4c..d7847edce0 100644 --- a/dumux/porousmediumflow/2p/CMakeLists.txt +++ b/dumux/porousmediumflow/2p/CMakeLists.txt @@ -1,7 +1,7 @@ add_subdirectory(sequential) install(FILES -boxmaterialinterfaceparams.hh +boxmaterialinterfaces.hh formulation.hh gridadaptindicator.hh griddatatransfer.hh -- GitLab From 4e24c4ed8c0bbf7205c08918acaef63ebfe319ae Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Fri, 30 Oct 2020 12:40:23 +0100 Subject: [PATCH 94/99] [examples] Use new material law interface --- examples/2pinfiltration/params.input | 10 +++++ examples/2pinfiltration/spatialparams.hh | 47 +++++++-------------- examples/biomineralization/params.input | 4 ++ examples/biomineralization/spatialparams.hh | 29 ++++--------- 4 files changed, 38 insertions(+), 52 deletions(-) diff --git a/examples/2pinfiltration/params.input b/examples/2pinfiltration/params.input index e49c6f4dd3..ba7188008a 100644 --- a/examples/2pinfiltration/params.input +++ b/examples/2pinfiltration/params.input @@ -11,6 +11,16 @@ Refinement = 1 LensLowerLeft = 1.0 2.0 # [m] coordinates of the lower left lens corner LensUpperRight = 4.0 3.0 # [m] coordinates of the upper right lens corner +[SpatialParams.Lens] +Swr = 0.18 +VanGenuchtenN = 7.3 +VanGenuchtenAlpha = 0.00045 + +[SpatialParams.Outer] +Swr = 0.05 +VanGenuchtenN = 4.7 +VanGenuchtenAlpha = 0.0037 + [Problem] Name = 2padaptive # name passed to the output routines diff --git a/examples/2pinfiltration/spatialparams.hh b/examples/2pinfiltration/spatialparams.hh index 7ef356def8..23bca1f22c 100644 --- a/examples/2pinfiltration/spatialparams.hh +++ b/examples/2pinfiltration/spatialparams.hh @@ -28,8 +28,7 @@ #include // We include all laws which are needed to define the interaction between the solid matrix and the fluids, e.g. laws for capillary pressure saturation relationships. -#include -#include +#include // ### The spatial parameters class // In the TwoPTestSpatialParams class we define all functions needed to describe the porous matrix, e.g. porosity and permeability. We inherit from the `FVSpatialParams` class, which is the base class for multiphase porous medium flow applications. @@ -51,11 +50,9 @@ class TwoPTestSpatialParams static constexpr int dimWorld = GridView::dimensionworld; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using EffectiveLaw = RegularizedVanGenuchten; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; public: - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; using PermeabilityType = Scalar; // [[/codeblock]] @@ -63,31 +60,18 @@ public: // [[codeblock]] TwoPTestSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwLens_("SpatialParams.Lens") // read params from input file + , pcKrSwOuter_("SpatialParams.Outer") // read params from input file { // We get the position of the lens from the params.input file. // The lens is defined by the position of the lower left and the upper right corner lensLowerLeft_ = getParam("SpatialParams.LensLowerLeft"); lensUpperRight_ = getParam("SpatialParams.LensUpperRight"); - // We set the parameters for the material law (here Van-Genuchten Law). - // First we set the residual saturations for the wetting phase and the nonwetting phase. - // lensMaterialParams_ define the material parameters for the lens while - // outerMaterialParams_ define material params for the rest of the domain. - lensMaterialParams_.setSwr(0.18); - lensMaterialParams_.setSnr(0.0); - outerMaterialParams_.setSwr(0.05); - outerMaterialParams_.setSnr(0.0); - - //We set the parameters for the Van Genuchten law alpha and n - lensMaterialParams_.setVgAlpha(0.00045); - lensMaterialParams_.setVgn(7.3); - outerMaterialParams_.setVgAlpha(0.0037); - outerMaterialParams_.setVgn(4.7); - - //Here, we get the permeabilities from the params.input file. - //In case that no parameter is set, the default parameters (9.05e-12 and 4.6e-10) are used - lensK_ = getParam("SpatialParams.lensK", 9.05e-12); - outerK_ = getParam("SpatialParams.outerK", 4.6e-10); + // Here, we get the permeabilities from the params.input file. + // In case that no parameter is set, the default parameters (9.05e-12 and 4.6e-10) are used + lensK_ = getParam("SpatialParams.Lens.Permeability", 9.05e-12); + outerK_ = getParam("SpatialParams.Outer.Permeability", 4.6e-10); } // [[/codeblock]] @@ -112,13 +96,13 @@ public: // We set the parameter object for the Van Genuchten material law. template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + auto fluidMatrixInteraction(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { if (isInLens_(element.geometry().center())) - return lensMaterialParams_; - return outerMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwLens_); + return makeFluidMatrixInteraction(pcKrSwOuter_); } @@ -147,8 +131,9 @@ private: Scalar lensK_; Scalar outerK_; - MaterialLawParams lensMaterialParams_; - MaterialLawParams outerMaterialParams_; + + const PcKrSwCurve pcKrSwLens_; + const PcKrSwCurve pcKrSwOuter_; static constexpr Scalar eps_ = 1.5e-7; }; diff --git a/examples/biomineralization/params.input b/examples/biomineralization/params.input index 9ec5f23397..4aaa2e64c4 100644 --- a/examples/biomineralization/params.input +++ b/examples/biomineralization/params.input @@ -44,6 +44,10 @@ Cells = 56 # [-] number of cells in x,y-di [SpatialParams] ReferencePorosity = 0.4 # [-] ReferencePermeability = 2e-10 # [m^2] +BrooksCoreyPcEntry = 1e4 # [Pa] +BrooksCoreyLambda = 2.0 # [-] +Swr = 0.2 # [-] +Snr = 0.05 # [-] [BioCoefficients] Ca1 = 8.3753e-8 # [1/s] fitted parameter, see Hommel et al. 2015 diff --git a/examples/biomineralization/spatialparams.hh b/examples/biomineralization/spatialparams.hh index 68ab59cfe0..ef9d00a886 100644 --- a/examples/biomineralization/spatialparams.hh +++ b/examples/biomineralization/spatialparams.hh @@ -32,12 +32,8 @@ // [[details]] includes // We include the basic spatial parameters for finite volumes file from which we will inherit #include -// We include the files for the two-phase laws: the linear material law -#include -// We include the files for the two-phase laws: the regularized Brooks-Corey pc-Sw and relative permeability laws -#include -// We include the files for the two-phase laws: the scaling from effective to absolute saturations -#include +// We include the files for the two-phase laws: the Brooks-Corey pc-Sw and relative permeability laws +#include // We include the laws for changing porosity due to precipitation #include // We include the laws for changing permeability based on porosity change according to Kozeny-Carman @@ -61,34 +57,25 @@ class ICPSpatialParams using ThisType = ICPSpatialParams; using ParentType = FVSpatialParams; using GridView = typename GridGeometry::GridView; - using EffectiveLaw = RegularizedBrooksCorey; using SubControlVolume = typename GridGeometry::SubControlVolume; using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using PcKrSwCurve = FluidMatrix::BrooksCoreyDefault; public: // type used for the permeability (i.e. tensor or scalar) using PermeabilityType = Scalar; - using MaterialLaw = EffToAbsLaw; - using MaterialLawParams = typename MaterialLaw::Params; // [[/codeblock]] // #### Using porosity and permeability laws to return the updated values // Due due calcium carbonate precipitation the porosity and the permeability change with time. At first, the initial values for the porosity and permeability are defined. Moreover, the functions that return the updated values, based on the chosen laws are defined. // [[codeblock]] ICPSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSw_("SpatialParams") // initialize from input file { // We read reference values for porosity and permeability from the input referencePorosity_ = getParam("SpatialParams.ReferencePorosity", 0.4); referencePermeability_ = getParam("SpatialParams.ReferencePermeability", 2.e-10); - - // Setting residual saturations - materialParams_.setSwr(0.2); - materialParams_.setSnr(0.05); - - // Setting parameters for the Brooks-Corey law - materialParams_.setPe(1e4); - materialParams_.setLambda(2.0); } // We return the reference or initial porosity. @@ -119,9 +106,9 @@ public: return permLaw_.evaluatePermeability(referencePermeability_, referencePorosity_, poro); } // [[/codeblock]] - // Return the brooks-corey context depending on the position - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { return materialParams_; } + // Return the fluid matrix interactions (here only Brooks-Corey curves) + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const + { return makeFluidMatrixInteraction(pcKrSw_); } // Define the wetting phase template @@ -133,7 +120,7 @@ public: // [[codeblock]] private: - MaterialLawParams materialParams_; + const PcKrSwCurve pcKrSw_; // Setting porosity precipitation as the porosity law PorosityPrecipitation poroLaw_; // Setting the Kozeny-Carman porosity-permeability relation as the permeability law -- GitLab From 33a29eacdad162f6d23a02e2ebfee17d59ae4cf4 Mon Sep 17 00:00:00 2001 From: Melanie Lipp Date: Fri, 30 Oct 2020 08:51:15 +0100 Subject: [PATCH 95/99] [doc][doxygen][material] Cleanup doxygen documentation --- .../3p/parkervangenuchten.hh | 37 +++++++++++++------ .../3pwateroil/volumevariables.hh | 2 + 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/dumux/material/fluidmatrixinteractions/3p/parkervangenuchten.hh b/dumux/material/fluidmatrixinteractions/3p/parkervangenuchten.hh index b42c0d6759..5e4a59e725 100644 --- a/dumux/material/fluidmatrixinteractions/3p/parkervangenuchten.hh +++ b/dumux/material/fluidmatrixinteractions/3p/parkervangenuchten.hh @@ -200,7 +200,7 @@ struct ParkerVanGenuchten3PEffToAbsPolicy /*! * \brief Convert an effective wetting saturation to an absolute one. * - * \param swe Effective saturation of the non-wetting phase \f$\mathrm{[\overline{S}_n]}\f$. + * \param ste Effective total liquid (wetting + non-wetting) saturation * \param params A container object that is populated with the appropriate coefficients for the respective law. * Therefore, in the (problem specific) spatialParameters first, the material law is chosen, * and then the params container is constructed accordingly. Afterwards the values are set there, too. @@ -405,7 +405,7 @@ public: * \brief Returns the partial derivative of the capillary * pressure to the effective saturation. * \param params Array of parameters - * \param seRegu Effective wetting phase saturation for regularization + * \param swe Effective wetting phase saturation for regularization */ template static Scalar dpcgw_dswe(const Scalar swe, const Params& params) @@ -420,7 +420,7 @@ public: * \brief Returns the partial derivative of the capillary * pressure to the effective saturation. * \param params Array of parameters - * \param seRegu Effective wetting phase saturation for regularization + * \param swe Effective wetting phase saturation for regularization */ template static Scalar dpcnw_dswe(const Scalar swe, const Params& params) @@ -435,7 +435,7 @@ public: * \brief Returns the partial derivative of the capillary * pressure to the effective saturation. * \param params Array of parameters - * \param seRegu Effective wetting phase saturation for regularization + * \param ste Effective total liquid (wetting + non-wetting) saturation for regularization */ template static Scalar dpcgn_dste(const Scalar ste, const Params& params) @@ -557,8 +557,7 @@ public: * \param params Array of parameters. * \param phaseIdx Indicator, The saturation of all phases. * \param swe Effective wetting phase saturation - * \param sn Absolute non-wetting liquid saturation - * \param ste Effective total liquid (wetting + non-wetting) saturation + * \param sne Effective non-wetting saturation */ template static Scalar kr(const int phaseIdx, const Scalar swe, const Scalar sne, const Params& params) @@ -582,7 +581,7 @@ private: * \brief The standard van Genuchten two-phase pc-S relation either with respect to * the effective wetting phase saturation Swe or the effective total liquid saturation Ste. * \param params Array of parameters. - * \param Se Effective wetting phase ortotal liquid saturation + * \param se Effective wetting phase ortotal liquid saturation */ template const static Scalar pc_(const Scalar se, const Params& params) @@ -754,6 +753,7 @@ private: * - low saturation: extend the \f$\mathrm{p_c(S_w)}\f$ curve with the slope at the regularization point (i.e. no kink). * - high saturation: connect the high regularization point with \f$\mathrm{\overline{S}_w =1}\f$ * with a spline and continue linearly for \f$\mathrm{\overline{S}_w > 1}\f$ + * \param swe Effective wetting phase saturation */ OptionalScalar pcgw(Scalar swe) const { @@ -839,6 +839,7 @@ private: /*! * \brief The regularized relative permeability for the wetting phase + * \param swe Effective wetting phase saturation */ OptionalScalar krw(const Scalar swe) const { @@ -853,6 +854,9 @@ private: /*! * \brief The regularized relative permeability for the non-wetting phase + * \param swe Effective wetting phase saturation + * \param sn Non-wetting saturation + * \param ste Effective total (wetting + non-wetting) saturation */ OptionalScalar krn(Scalar swe, const Scalar sn, Scalar ste) const { @@ -868,6 +872,7 @@ private: /*! * \brief The regularized relative permeability for the gas phase + * \param ste Effective total (wetting + non-wetting) saturation */ OptionalScalar krg(const Scalar ste) const { @@ -906,11 +911,9 @@ private: /*! * \brief The relative permeability for a phase. - * \param params Array of parameters. * \param phaseIdx Indicator, The saturation of all phases. * \param swe Effective wetting phase saturation - * \param sn Absolute non-wetting liquid saturation - * \param ste Effective total liquid (wetting + non-wetting) saturation + * \param sne Effective non-wetting saturation */ OptionalScalar kr(const int phaseIdx, const Scalar swe, const Scalar sne) const { @@ -1112,6 +1115,8 @@ public: /*! * \brief The capillary pressure-saturation curve for the gas and non-wetting phase + * \param sw Wetting saturation + * \param sn Non-wetting saturation */ template Scalar pcgn(const Scalar sw, const Scalar sn) const @@ -1129,8 +1134,6 @@ public: /*! * \brief This function ensures a continuous transition from 2 to 3 phases and vice versa - * \param params Array of parameters - * \param sn Non-wetting liquid saturation */ template Scalar pcAlpha(const Scalar /*dummySw*/, const Scalar sn) const @@ -1198,6 +1201,8 @@ public: /*! * \brief The relative permeability for the wetting phase + * \param sw Wetting saturation + * \param sn Non-wetting saturation */ template Scalar krw(const Scalar sw, const Scalar sn) const @@ -1215,6 +1220,8 @@ public: /*! * \brief The relative permeability for the non-wetting phase + * \param sw Wetting saturation + * \param sn Non-wetting saturation */ template Scalar krn(const Scalar sw, const Scalar sn) const @@ -1233,6 +1240,8 @@ public: /*! * \brief The relative permeability for the non-wetting phase + * \param sw Wetting saturation + * \param sn Non-wetting saturation */ template Scalar krg(const Scalar sw, const Scalar sn) const @@ -1250,6 +1259,9 @@ public: /*! * \brief The relative permeability for the non-wetting phase + * \param phaseIdx Indicator, The saturation of all phases. + * \param sw Wetting saturation + * \param sn Non-wetting saturation */ template Scalar kr(const int phaseIdx, const Scalar sw, const Scalar sn) const @@ -1269,6 +1281,7 @@ public: /*! * \brief The derivative of the relative permeability for the non-wetting phase w.r.t. saturation + * \param st Total (wetting + non-wetting) saturation */ template Scalar dkrg_dst(const Scalar st) const diff --git a/dumux/porousmediumflow/3pwateroil/volumevariables.hh b/dumux/porousmediumflow/3pwateroil/volumevariables.hh index bc46538779..93df10bd50 100644 --- a/dumux/porousmediumflow/3pwateroil/volumevariables.hh +++ b/dumux/porousmediumflow/3pwateroil/volumevariables.hh @@ -48,8 +48,10 @@ namespace Dumux { namespace Detail { // helper struct and function detecting if the fluid matrix interaction features a adsorptionModel() function +#ifndef DOXYGEN // hide from doxygen template using AdsorptionModelDetector = decltype(std::declval().adsorptionModel()); +#endif // DOXYGEN template static constexpr bool hasAdsorptionModel() -- GitLab From 6ae12b1093fc1acdab341b419e161c9ade469ffd Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Fri, 30 Oct 2020 13:22:29 +0100 Subject: [PATCH 96/99] [doc][material] Fix documentation of fluidMatrixInteraction function --- .../1p/sequential/test_diffusionspatialparams.hh | 2 +- .../1p/sequential/test_diffusionspatialparams3d.hh | 2 +- .../2p/sequential/test_3d2pspatialparams.hh | 2 +- .../2p/sequential/test_impesadaptivespatialparams.hh | 2 +- .../2p/sequential/test_impesspatialparams.hh | 2 +- .../2p/sequential/test_mpfa2pspatialparams.hh | 2 +- .../2p/sequential/test_transportspatialparams.hh | 2 +- .../implicit/chemicalnonequilibrium/spatialparams.hh | 2 +- .../2p2c/implicit/waterair/spatialparams.hh | 2 +- .../2p2c/sequential/test_dec2p2c_spatialparams.hh | 2 +- .../2pnc/implicit/diffusion/spatialparams.hh | 2 +- .../2pnc/implicit/fuelcell/spatialparams.hh | 2 +- .../2pncmin/implicit/isothermal/spatialparams.hh | 2 +- .../2pncmin/implicit/nonisothermal/spatialparams.hh | 2 +- .../3p/implicit/infiltration/spatialparams.hh | 2 +- test/porousmediumflow/co2/implicit/spatialparams.hh | 2 +- .../mpnc/implicit/kinetic/spatialparams.hh | 10 +++++----- .../mpnc/implicit/obstacle/spatialparams.hh | 2 +- .../implicit/thermalnonequilibrium/spatialparams.hh | 2 +- .../richards/implicit/analytical/spatialparams.hh | 2 +- .../richards/implicit/lens/spatialparams.hh | 4 ++-- .../richards/implicit/nonisothermal/spatialparams.hh | 2 +- .../richardsnc/implicit/spatialparams.hh | 2 +- 23 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test/porousmediumflow/1p/sequential/test_diffusionspatialparams.hh b/test/porousmediumflow/1p/sequential/test_diffusionspatialparams.hh index 0cb1c59956..87ad388043 100644 --- a/test/porousmediumflow/1p/sequential/test_diffusionspatialparams.hh +++ b/test/porousmediumflow/1p/sequential/test_diffusionspatialparams.hh @@ -88,7 +88,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/1p/sequential/test_diffusionspatialparams3d.hh b/test/porousmediumflow/1p/sequential/test_diffusionspatialparams3d.hh index 11694890da..4dc891770d 100644 --- a/test/porousmediumflow/1p/sequential/test_diffusionspatialparams3d.hh +++ b/test/porousmediumflow/1p/sequential/test_diffusionspatialparams3d.hh @@ -84,7 +84,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/2p/sequential/test_3d2pspatialparams.hh b/test/porousmediumflow/2p/sequential/test_3d2pspatialparams.hh index 9f243fb561..eefa797640 100644 --- a/test/porousmediumflow/2p/sequential/test_3d2pspatialparams.hh +++ b/test/porousmediumflow/2p/sequential/test_3d2pspatialparams.hh @@ -94,7 +94,7 @@ public: /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/2p/sequential/test_impesadaptivespatialparams.hh b/test/porousmediumflow/2p/sequential/test_impesadaptivespatialparams.hh index da2742e91c..4c67c969df 100644 --- a/test/porousmediumflow/2p/sequential/test_impesadaptivespatialparams.hh +++ b/test/porousmediumflow/2p/sequential/test_impesadaptivespatialparams.hh @@ -83,7 +83,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/2p/sequential/test_impesspatialparams.hh b/test/porousmediumflow/2p/sequential/test_impesspatialparams.hh index f2c62155a7..c2435326d7 100644 --- a/test/porousmediumflow/2p/sequential/test_impesspatialparams.hh +++ b/test/porousmediumflow/2p/sequential/test_impesspatialparams.hh @@ -83,7 +83,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/2p/sequential/test_mpfa2pspatialparams.hh b/test/porousmediumflow/2p/sequential/test_mpfa2pspatialparams.hh index 9b52441ba2..d758aef5ec 100644 --- a/test/porousmediumflow/2p/sequential/test_mpfa2pspatialparams.hh +++ b/test/porousmediumflow/2p/sequential/test_mpfa2pspatialparams.hh @@ -107,7 +107,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/2p/sequential/test_transportspatialparams.hh b/test/porousmediumflow/2p/sequential/test_transportspatialparams.hh index 77a915c561..b16a128274 100644 --- a/test/porousmediumflow/2p/sequential/test_transportspatialparams.hh +++ b/test/porousmediumflow/2p/sequential/test_transportspatialparams.hh @@ -83,7 +83,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos A global coordinate vector */ auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const diff --git a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh index 73efbc3e0a..4a917e81a8 100644 --- a/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/chemicalnonequilibrium/spatialparams.hh @@ -102,7 +102,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location */ auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { diff --git a/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh b/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh index 138079d15f..0ee720606f 100644 --- a/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/waterair/spatialparams.hh @@ -127,7 +127,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos The global coordinates for the given location */ auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const diff --git a/test/porousmediumflow/2p2c/sequential/test_dec2p2c_spatialparams.hh b/test/porousmediumflow/2p2c/sequential/test_dec2p2c_spatialparams.hh index 1843367baf..cbbc484c06 100644 --- a/test/porousmediumflow/2p2c/sequential/test_dec2p2c_spatialparams.hh +++ b/test/porousmediumflow/2p2c/sequential/test_dec2p2c_spatialparams.hh @@ -80,7 +80,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh b/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh index 71cf16416c..e291b2a8fb 100644 --- a/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh +++ b/test/porousmediumflow/2pnc/implicit/diffusion/spatialparams.hh @@ -85,7 +85,7 @@ public: { return 0.2; } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/2pnc/implicit/fuelcell/spatialparams.hh b/test/porousmediumflow/2pnc/implicit/fuelcell/spatialparams.hh index 6efbf239cb..6292e4659f 100644 --- a/test/porousmediumflow/2pnc/implicit/fuelcell/spatialparams.hh +++ b/test/porousmediumflow/2pnc/implicit/fuelcell/spatialparams.hh @@ -84,7 +84,7 @@ public: { return 0.2; } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos A global coordinate vector */ auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const diff --git a/test/porousmediumflow/2pncmin/implicit/isothermal/spatialparams.hh b/test/porousmediumflow/2pncmin/implicit/isothermal/spatialparams.hh index c0a59da7da..38ff739939 100644 --- a/test/porousmediumflow/2pncmin/implicit/isothermal/spatialparams.hh +++ b/test/porousmediumflow/2pncmin/implicit/isothermal/spatialparams.hh @@ -129,7 +129,7 @@ public: { return 10.0; } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos A global coordinate vector */ auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const diff --git a/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh b/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh index e3985f9e08..b0f95c1486 100644 --- a/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh +++ b/test/porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh @@ -130,7 +130,7 @@ public: { return 10.0; } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos A global coordinate vector */ auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const diff --git a/test/porousmediumflow/3p/implicit/infiltration/spatialparams.hh b/test/porousmediumflow/3p/implicit/infiltration/spatialparams.hh index 42c0ccf0da..bc0b79e05a 100644 --- a/test/porousmediumflow/3p/implicit/infiltration/spatialparams.hh +++ b/test/porousmediumflow/3p/implicit/infiltration/spatialparams.hh @@ -143,7 +143,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/co2/implicit/spatialparams.hh b/test/porousmediumflow/co2/implicit/spatialparams.hh index 43d2c5016a..8cfeada7b7 100644 --- a/test/porousmediumflow/co2/implicit/spatialparams.hh +++ b/test/porousmediumflow/co2/implicit/spatialparams.hh @@ -167,7 +167,7 @@ public: /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ diff --git a/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh b/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh index c1c2d0f1fc..ca8ba66062 100644 --- a/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/kinetic/spatialparams.hh @@ -196,7 +196,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos A global coordinate vector */ const NonwettingSolidInterfacialArea& nonwettingSolidInterfacialAreaAtPos(const GlobalPosition &globalPos) const @@ -209,7 +209,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos A global coordinate vector */ const WettingSolidInterfacialArea& wettingSolidInterfacialAreaAtPos(const GlobalPosition &globalPos) const @@ -218,7 +218,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos A global coordinate vector */ const WettingNonwettingInterfacialArea& wettingNonwettingInterfacialAreaAtPos(const GlobalPosition &globalPos) const @@ -232,7 +232,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location */ template auto fluidMatrixInteraction(const Element& element, @@ -243,7 +243,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location */ auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const { diff --git a/test/porousmediumflow/mpnc/implicit/obstacle/spatialparams.hh b/test/porousmediumflow/mpnc/implicit/obstacle/spatialparams.hh index a7843b2526..5b60e7488a 100644 --- a/test/porousmediumflow/mpnc/implicit/obstacle/spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/obstacle/spatialparams.hh @@ -89,7 +89,7 @@ public: { return porosity_; } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location */ auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const { diff --git a/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/spatialparams.hh b/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/spatialparams.hh index bcef6650c9..f273a4e84f 100644 --- a/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/thermalnonequilibrium/spatialparams.hh @@ -189,7 +189,7 @@ public: Scalar interfacialTension() const { return interfacialTension_ ; } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos A global coordinate vector */ auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const diff --git a/test/porousmediumflow/richards/implicit/analytical/spatialparams.hh b/test/porousmediumflow/richards/implicit/analytical/spatialparams.hh index 6a450aa0e8..62c184ac94 100644 --- a/test/porousmediumflow/richards/implicit/analytical/spatialparams.hh +++ b/test/porousmediumflow/richards/implicit/analytical/spatialparams.hh @@ -82,7 +82,7 @@ public: { return 0.4; } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos A global coordinate vector */ auto fluidMatrixInteractionAtPos(const GlobalPosition &globalPos) const diff --git a/test/porousmediumflow/richards/implicit/lens/spatialparams.hh b/test/porousmediumflow/richards/implicit/lens/spatialparams.hh index 100ecb90da..34468ca84d 100644 --- a/test/porousmediumflow/richards/implicit/lens/spatialparams.hh +++ b/test/porousmediumflow/richards/implicit/lens/spatialparams.hh @@ -102,7 +102,7 @@ public: { return 0.4; } /*! - * \brief Returns the parameters for the material law for the sub-control volume + * \brief Returns the fluid-matrix interaction law for the sub-control volume * * This method is not actually required by the Richards model, but provided * for the convenience of the RichardsLensProblem @@ -122,7 +122,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * This method is not actually required by the Richards model, but provided * for the convenience of the RichardsLensProblem diff --git a/test/porousmediumflow/richards/implicit/nonisothermal/spatialparams.hh b/test/porousmediumflow/richards/implicit/nonisothermal/spatialparams.hh index 7afce1ac6a..31ff4d0377 100644 --- a/test/porousmediumflow/richards/implicit/nonisothermal/spatialparams.hh +++ b/test/porousmediumflow/richards/implicit/nonisothermal/spatialparams.hh @@ -82,7 +82,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * \param globalPos The global coordinates for the given location */ auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const diff --git a/test/porousmediumflow/richardsnc/implicit/spatialparams.hh b/test/porousmediumflow/richardsnc/implicit/spatialparams.hh index 4e4434dd95..5d755c3201 100644 --- a/test/porousmediumflow/richardsnc/implicit/spatialparams.hh +++ b/test/porousmediumflow/richardsnc/implicit/spatialparams.hh @@ -93,7 +93,7 @@ public: } /*! - * \brief Returns the parameters for the material law at a given location + * \brief Returns the fluid-matrix interaction law at a given location * * \param globalPos The global coordinates for the given location */ -- GitLab From 644b3c92aa0475fcb8139644d53ac0a53f4c9ac1 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Fri, 30 Oct 2020 16:17:13 +0100 Subject: [PATCH 97/99] [test][2p][material] Output largest error of spline approximation --- .../2p/test_material_2p_spline.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/material/fluidmatrixinteractions/2p/test_material_2p_spline.cc b/test/material/fluidmatrixinteractions/2p/test_material_2p_spline.cc index 28f4fd6824..fe123a17ea 100644 --- a/test/material/fluidmatrixinteractions/2p/test_material_2p_spline.cc +++ b/test/material/fluidmatrixinteractions/2p/test_material_2p_spline.cc @@ -82,9 +82,9 @@ void runTest(const std::string& name, const Function& f, auto pcTest = swTest; Dune::Timer timer; - double res = 0.0; + auto resOrig = swTest; for (int i = 0; i < testSamples; ++i) - res += f(swTest[i], orig); + resOrig[i] = f(swTest[i], orig); timer.stop(); const auto vgTime = timer.elapsed(); @@ -92,15 +92,20 @@ void runTest(const std::string& name, const Function& f, timer.reset(); timer.start(); - res = 0.0; + auto resSpline = swTest; for (int i = 0; i < testSamples; ++i) - res += f(swTest[i], spline); + resSpline[i] = f(swTest[i], spline); timer.stop(); const auto vgSplineTime = timer.elapsed(); std::cout << "Spline law computed " << testSamples << " samples in " << vgSplineTime << " seconds." << std::endl; std::cout << "Speed-up factor ca. " << (vgTime/vgSplineTime) << "x (only in spline region)" << std::endl; + + auto error = resOrig; + for (int i = 0; i < error.size(); ++i) + error[i] = std::abs(error[i]-resSpline[i]); + std::cout << "Maximum error: " << *std::max_element(error.begin(), error.end()) << std::endl; } } -- GitLab From 6495860da50166f1c2951af576adae58fcd54203 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Fri, 30 Oct 2020 17:41:14 +0100 Subject: [PATCH 98/99] [changelog] Mention new material laws --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c6e2137e7..311f823640 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ Differences Between DuMux 3.3 and DuMux 3.2 In order to use this, include ``. `format`, `format_to`, `format_to_n`, `formatted_size` are available in the `Dumux::Fmt` namespace. The string formatting is documented [here](https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification) and follows the Python string formatting rules. The function are documented on [cppreference](https://en.cppreference.com/w/cpp/utility/format). + - The usage of laws for pc-Sw and kr-Sw has been completely revised. A caller does not have to pass a `parameters` object to the laws anymore. The `spatialParams` now provide a `fluidMatrixInteraction` function which bundles an arbitrary number of + different interaction laws such as a pc-Sw and kr-Sw curve and interfacial areas. + New pre-cached spline laws were added which can help to increase efficiency. The usage of the old interface is deprecated and warnings will be raised. The old interface will be removed after the release of 3.3. ### Immediate interface changes not allowing/requiring a deprecation period: - __Flash/Constraintsolver__: The flashes depending on material laws are immediately required to use new-style material laws (fluidMatrixInteraction interface in spatialparams) @@ -23,7 +26,7 @@ Differences Between DuMux 3.3 and DuMux 3.2 - __Quadmath__: Dumux::Quad has been removed without deprecation. Use Dune::Float128 instead. - Within the RANS group, two additional runtime parameters have been included 'IsFlatWallBounded' and 'WriteFlatWallBoundedFields'. For both the K-Epsilon and Zero-eq RANS models the 'IsFlatWallBounded' runtime parameter should be set as True, -as wall topology is not supported for these models with our geometric contraints. If not set as true, the geometry +as wall topology is not supported for these models with our geometric constraints. If not set as true, the geometry will be checked before the model is run. If either the runtime parameter or the geometry check indicate non-flat walls, the model will terminate. To add FlatWallBounded specific output to the vtk output, WriteFlatWallBoundedFields can be set as True. - __1d3d coupling__: The kernel coupling manager has been replaced with the one from Koch et al (2020) JCP https://doi.org/10.1016/j.jcp.2020.109370 -- GitLab From b3912847c36cb8959596b7dafd0ede7ee6b39ee4 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt Date: Fri, 30 Oct 2020 18:39:34 +0100 Subject: [PATCH 99/99] [test][richards] Adapt lens problem --- .../richards/implicit/lens/params.input | 12 +++++ .../richards/implicit/lens/problem.hh | 3 +- .../richards/implicit/lens/spatialparams.hh | 47 ++++++------------- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/test/porousmediumflow/richards/implicit/lens/params.input b/test/porousmediumflow/richards/implicit/lens/params.input index 72e9e5fedd..b39661fa2c 100644 --- a/test/porousmediumflow/richards/implicit/lens/params.input +++ b/test/porousmediumflow/richards/implicit/lens/params.input @@ -21,3 +21,15 @@ Type = bicgstabsolver Type = amg AmgMaxLevel = 2 AmgAccumulationMode = atOnce + +[SpatialParams.Lens] +Swr = 0.18 +Snr = 0.0 +VanGenuchtenAlpha = 0.00045 +VanGenuchtenN = 7.3 + +[SpatialParams.OuterDomain] +Swr = 0.05 +Snr = 0.0 +VanGenuchtenAlpha = 0.0037 +VanGenuchtenN = 4.7 diff --git a/test/porousmediumflow/richards/implicit/lens/problem.hh b/test/porousmediumflow/richards/implicit/lens/problem.hh index 69f408cfe3..d1a3e3d9ec 100644 --- a/test/porousmediumflow/richards/implicit/lens/problem.hh +++ b/test/porousmediumflow/richards/implicit/lens/problem.hh @@ -247,8 +247,7 @@ private: { PrimaryVariables values(0.0); const Scalar sw = 0.0; - using MaterialLaw = typename ParentType::SpatialParams::MaterialLaw; - const Scalar pc = MaterialLaw::pc(this->spatialParams().materialLawParamsAtPos(globalPos), sw); + const Scalar pc = this->spatialParams().fluidMatrixInteractionAtPos(globalPos).pc(sw); values[pressureIdx] = nonwettingReferencePressure() - pc; values.setState(bothPhases); return values; diff --git a/test/porousmediumflow/richards/implicit/lens/spatialparams.hh b/test/porousmediumflow/richards/implicit/lens/spatialparams.hh index 34468ca84d..015d8a31e7 100644 --- a/test/porousmediumflow/richards/implicit/lens/spatialparams.hh +++ b/test/porousmediumflow/richards/implicit/lens/spatialparams.hh @@ -26,8 +26,7 @@ #define DUMUX_RICHARDS_LENS_SPATIAL_PARAMETERS_HH #include -#include -#include +#include #include @@ -51,32 +50,19 @@ class RichardsLensSpatialParams enum { dimWorld = GridView::dimensionworld }; + using PcKrSwCurve = FluidMatrix::VanGenuchtenDefault; + public: - using MaterialLaw = EffToAbsLaw>; - using MaterialLawParams = typename MaterialLaw::Params; // export permeability type using PermeabilityType = Scalar; RichardsLensSpatialParams(std::shared_ptr gridGeometry) : ParentType(gridGeometry) + , pcKrSwCurveLens_("SpatialParams.Lens") + , pcKrSwCurveOuterDomain_("SpatialParams.OuterDomain") { - lensLowerLeft_ = {1.0, 2.0}; lensUpperRight_ = {4.0, 3.0}; - - // residual saturations - lensMaterialParams_.setSwr(0.18); - lensMaterialParams_.setSnr(0.0); - outerMaterialParams_.setSwr(0.05); - outerMaterialParams_.setSnr(0.0); - - // parameters for the Van Genuchten law - // alpha and n - lensMaterialParams_.setVgAlpha(0.00045); - lensMaterialParams_.setVgn(7.3); - outerMaterialParams_.setVgAlpha(0.0037); - outerMaterialParams_.setVgn(4.7); - lensK_ = 1e-12; outerK_ = 5e-12; } @@ -112,28 +98,23 @@ public: * \param elemSol The current element solution */ template - const MaterialLawParams& materialLawParams(const Element& element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + auto fluidMatrixInteraction(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { const auto& globalPos = scv.dofPosition(); - - return materialLawParamsAtPos(globalPos); + return fluidMatrixInteractionAtPos(globalPos); } /*! * \brief Returns the fluid-matrix interaction law at a given location - * - * This method is not actually required by the Richards model, but provided - * for the convenience of the RichardsLensProblem - * * \param globalPos The global coordinates for the given location */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + auto fluidMatrixInteractionAtPos(const GlobalPosition& globalPos) const { if (isInLens_(globalPos)) - return lensMaterialParams_; - return outerMaterialParams_; + return makeFluidMatrixInteraction(pcKrSwCurveLens_); + return makeFluidMatrixInteraction(pcKrSwCurveOuterDomain_); } private: @@ -153,8 +134,8 @@ private: Scalar lensK_; Scalar outerK_; - MaterialLawParams lensMaterialParams_; - MaterialLawParams outerMaterialParams_; + const PcKrSwCurve pcKrSwCurveLens_; + const PcKrSwCurve pcKrSwCurveOuterDomain_; }; } // end namespace Dumux -- GitLab