diff --git a/src/Makefile.am b/src/Makefile.am index 4cca1056223006b91a0d55c175242bca7d0a0bb5..b648151d932a2f0dff6b7b3d15e6bd29030ebb45 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,8 +5,6 @@ SOURCES = \ assemblers.cc \ boundary_writer.cc \ friction_writer.cc \ - state/compute_state_dieterich_euler.cc \ - state/compute_state_ruina.cc \ solverfactory.cc \ one-body-sample.cc \ timestepping.cc \ diff --git a/src/state/compute_state_dieterich_euler.cc b/src/state/compute_state_dieterich_euler.cc deleted file mode 100644 index 103c56f2c3d514c086ad91cfdf58bf71a4191220..0000000000000000000000000000000000000000 --- a/src/state/compute_state_dieterich_euler.cc +++ /dev/null @@ -1,73 +0,0 @@ -#include <cassert> - -#include <dune/tnnmg/problem-classes/bisection.hh> - -#include <dune/tnnmg/problem-classes/directionalconvexfunction.hh> - -#include "compute_state_dieterich_euler.hh" - -#include <dune/common/fvector.hh> -#include <dune/common/fmatrix.hh> -#include <dune/solvers/common/interval.hh> - -/* Dieterich's law: - - \f$ \dot \theta = 1 - V \theta/L \f$ - - Transformed using \alpha = \log \theta: - - \f$ \dot \alpha = \exp(-\alpha) - V/L \f$ - - discretised in time (using backward euler): - - \f$\delta \alpha_1 = \exp(-\alpha_1) - V/L\f$ - - or - - \f$ 0 = ( \alpha_1 - \alpha_0 )/\tau - ( \exp(-\alpha_1) - V/L ) \f$ - - this is obviously monotone in \f$\alpha_1\f$; we can thus see if as - a convex minimisation problem. - - find the antiderivative: - - \f$ J(\alpha_1) - = 0.5/\tau * \alpha_1^2 - ( \alpha_0/\tau - V/L ) \alpha_1 + - \exp(-\alpha_1)\f$ - - Consequence: linear part is \f$ \alpha_0/\tau - V/L \f$; nonlinear - part is \f$\exp(-\alpha_1)\f$ which has derivative \f$ - -\exp(-\alpha_1) \f$. -*/ - -//! The nonlinearity \f$f(x) = exp(-x)\f$ -class DieterichNonlinearity { -public: - using VectorType = Dune::FieldVector<double, 1>; - using MatrixType = Dune::FieldMatrix<double, 1, 1>; - - DieterichNonlinearity() {} - - void directionalSubDiff(VectorType const &u, VectorType const &v, - Dune::Solvers::Interval<double> &D) const { - D[0] = D[1] = v[0] * (-std::exp(-u[0])); - } - - void directionalDomain(VectorType const &, VectorType const &, - Dune::Solvers::Interval<double> &dom) const { - dom[0] = -std::numeric_limits<double>::max(); - dom[1] = std::numeric_limits<double>::max(); - } -}; - -double state_update_dieterich_euler(double tau, double VoL, double logState_o) { - DieterichNonlinearity::VectorType const start(0); - DieterichNonlinearity::VectorType const direction(1); - DieterichNonlinearity phi; - DirectionalConvexFunction<DieterichNonlinearity> const J( - 1.0 / tau, logState_o / tau - VoL, phi, start, direction); - - int bisectionsteps = 0; - Bisection const bisection; - return bisection.minimize(J, 0.0, 0.0, bisectionsteps); -} diff --git a/src/state/compute_state_dieterich_euler.hh b/src/state/compute_state_dieterich_euler.hh deleted file mode 100644 index 95690601f2d6caaa602afcb2cba4c2ae22cbd279..0000000000000000000000000000000000000000 --- a/src/state/compute_state_dieterich_euler.hh +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef COMPUTE_STATE_DIETERICH_EULER_HH -#define COMPUTE_STATE_DIETERICH_EULER_HH - -double state_update_dieterich_euler(double h, double VoL, double logState_o); -#endif diff --git a/src/state/compute_state_ruina.cc b/src/state/compute_state_ruina.cc deleted file mode 100644 index 4ad016936a1ec4c46d228a5d07b7c47c85145f04..0000000000000000000000000000000000000000 --- a/src/state/compute_state_ruina.cc +++ /dev/null @@ -1,13 +0,0 @@ -#include <cassert> - -#include <cmath> - -#include "compute_state_ruina.hh" - -double state_update_ruina(double tau, double uol, double logState_o) { - if (uol == 0) - return logState_o; - - double const ret = logState_o - uol * std::log(uol / tau); - return ret / (1 + uol); -} diff --git a/src/state/compute_state_ruina.hh b/src/state/compute_state_ruina.hh deleted file mode 100644 index 07dc4d7549fe91a0e8e5294c7bec037ace6b1df9..0000000000000000000000000000000000000000 --- a/src/state/compute_state_ruina.hh +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef COMPUTE_STATE_RUINA_HH -#define COMPUTE_STATE_RUINA_HH - -double state_update_ruina(double h, double uol, double logState_o); -#endif diff --git a/src/state/dieterichstateupdater.hh b/src/state/dieterichstateupdater.hh index cd28d97810b046077904047281df23ee5a788083..ffb417a08d39a3e3b5ebe1d040869664dbfbd75e 100644 --- a/src/state/dieterichstateupdater.hh +++ b/src/state/dieterichstateupdater.hh @@ -1,7 +1,6 @@ #ifndef DIETERICH_STATE_UPDATER_HH #define DIETERICH_STATE_UPDATER_HH -#include "compute_state_dieterich_euler.hh" #include "stateupdater.hh" template <class ScalarVector, class Vector> @@ -39,14 +38,33 @@ void DieterichStateUpdater<ScalarVector, Vector>::setup(double _tau) { tau = _tau; } +/* + Approximate (1-exp(-tV))/V, i.e. t*(exp(x) - 1)/x + for x = -t*v close to 0 + + with t, V >= 0, so that x should be non-positive +*/ +double approximateMyPowerSeries(double V, double t) { + double mVt = -V * t; + if (mVt >= 0) + return t; + + return -std::expm1(mVt) / V; +} + template <class ScalarVector, class Vector> void DieterichStateUpdater<ScalarVector, Vector>::solve( Vector const &velocity_field) { - for (size_t i = 0; i < nodes.size(); ++i) - if (nodes[i][0]) { - double const V = velocity_field[i].two_norm(); - logState[i] = state_update_dieterich_euler(tau, V / L, logState_o[i]); - } + for (size_t i = 0; i < nodes.size(); ++i) { + if (not nodes[i][0]) + continue; + + double const VoL = velocity_field[i].two_norm() / L; + // log( (1-exp(-tV))/V + exp(alpha_old - tV) ) with a + // liftable singularity at V=0 + logState[i] = std::log(approximateMyPowerSeries(VoL, tau) + + std::exp(logState_o[i] - tau * VoL)); + } } template <class ScalarVector, class Vector> diff --git a/src/state/ruinastateupdater.hh b/src/state/ruinastateupdater.hh index 18604f991a105f8e5f871fc02a7f5c056e4f9be9..d87870bb0716508d32176a46e08265562770e333 100644 --- a/src/state/ruinastateupdater.hh +++ b/src/state/ruinastateupdater.hh @@ -1,7 +1,6 @@ #ifndef RUINA_STATE_UPDATER_HH #define RUINA_STATE_UPDATER_HH -#include "compute_state_ruina.hh" #include "stateupdater.hh" template <class ScalarVector, class Vector> @@ -42,11 +41,16 @@ void RuinaStateUpdater<ScalarVector, Vector>::setup(double _tau) { template <class ScalarVector, class Vector> void RuinaStateUpdater<ScalarVector, Vector>::solve( Vector const &velocity_field) { - for (size_t i = 0; i < nodes.size(); ++i) - if (nodes[i][0]) { - double const V = velocity_field[i].two_norm(); - logState[i] = state_update_ruina(tau, V * tau / L, logState_o[i]); - } + for (size_t i = 0; i < nodes.size(); ++i) { + if (not nodes[i][0]) + continue; + + double const VoL = velocity_field[i].two_norm() / L; + // (exp(-tV) - 1)*log(V) + alpha_old*exp(-tV) + logState[i] = + (VoL <= 0) ? logState_o[i] : std::expm1(-tau * VoL) * std::log(VoL) + + logState_o[i] * std::exp(-tau * VoL); + } } template <class ScalarVector, class Vector>