Skip to content
Snippets Groups Projects
Commit 2e900b92 authored by Timo Koch's avatar Timo Koch
Browse files

[math] Add smoothMin/Max to common/math.hh

parent 1f786c16
No related branches found
No related tags found
1 merge request!3793Feature/smoothmin
...@@ -111,6 +111,35 @@ void harmonicMeanMatrix(Dune::FieldMatrix<Scalar, m, n> &K, ...@@ -111,6 +111,35 @@ void harmonicMeanMatrix(Dune::FieldMatrix<Scalar, m, n> &K,
} }
} }
/*!
* \ingroup Core
* \brief A smoothed minimum function (using cubic interpolation)
* \note The returned value is guaranteed to be smaller or equal to the minimum of the two input values.
* \note The smoothing kicks in if the difference between the two input values is smaller than the smoothing parameter.
* \param a The first input value
* \param b The second input value
* \param k The smoothing parameter (k > 0)
*/
template<class Scalar>
Scalar smoothMin(const Scalar a, const Scalar b, const Scalar k)
{
using std::max; using std::min; using std::abs;
const auto h = max(k-abs(a-b), 0.0 )/k;
return min(a, b) - h*h*h*k*(1.0/6.0);
}
/*!
* \ingroup Core
* \brief A smoothed maximum function (using cubic interpolation)
*
* \param a The first input value
* \param b The second input value
* \param k The smoothing parameter (k > 0)
*/
template<class Scalar>
Scalar smoothMax(const Scalar a, const Scalar b, const Scalar k)
{ return -smoothMin(-a, -b, k); }
/*! /*!
* \ingroup Core * \ingroup Core
* \brief Invert a linear polynomial analytically * \brief Invert a linear polynomial analytically
......
...@@ -377,5 +377,25 @@ int main() ...@@ -377,5 +377,25 @@ int main()
if (!Dune::FloatCmp::eq(roots[0], -3.863448718244389e-02, 1e-14)) if (!Dune::FloatCmp::eq(roots[0], -3.863448718244389e-02, 1e-14))
DUNE_THROW(Dune::Exception, "Root of cubic equation does not match reference"); DUNE_THROW(Dune::Exception, "Root of cubic equation does not match reference");
// Test smoothMin and smoothMax
{
const double a = 1.0;
const double b = 2.0;
const double k = 0.5;
if (!Dune::FloatCmp::eq(Dumux::smoothMin(a, b, k), a))
DUNE_THROW(Dune::Exception, "smoothMin does not work as expected");
if (!Dune::FloatCmp::eq(Dumux::smoothMax(a, b, k), b))
DUNE_THROW(Dune::Exception, "smoothMax does not work as expected");
}
{
const double a = 1.0;
const double b = 2.0;
const double k = 2.0;
if (Dumux::smoothMin(a, b, k) >= a)
DUNE_THROW(Dune::Exception, "smoothMin does not work as expected");
if (Dumux::smoothMax(a, b, k) <= b)
DUNE_THROW(Dune::Exception, "smoothMax does not work as expected");
}
return 0; return 0;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment