From 1694cfde8b578155e41234934605547c1f92b971 Mon Sep 17 00:00:00 2001 From: Elias Pipping <elias.pipping@fu-berlin.de> Date: Wed, 23 Nov 2011 13:02:09 +0100 Subject: [PATCH] Implement addHessian() --- dune/tectonic/globallaursennonlinearity.hh | 7 +++-- dune/tectonic/globalnonlinearity.hh | 12 +++++++- dune/tectonic/globalruinanonlinearity.hh | 6 ++-- dune/tectonic/localnonlinearity.hh | 33 ++++++++++++++++++++++ dune/tectonic/nicefunction.hh | 6 ++++ 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/dune/tectonic/globallaursennonlinearity.hh b/dune/tectonic/globallaursennonlinearity.hh index c4701b9f..0b69101c 100644 --- a/dune/tectonic/globallaursennonlinearity.hh +++ b/dune/tectonic/globallaursennonlinearity.hh @@ -13,8 +13,11 @@ #include "nicefunction.hh" namespace Dune { -template <int dim, class OuterFunctionType> -class GlobalLaursenNonlinearity : public GlobalNonlinearity<dim> { +template <int dim, class OuterFunctionType, + class VectorType = BlockVector<FieldVector<double, dim>>, + class MatrixType = BCRSMatrix<FieldMatrix<double, dim, dim>>> +class GlobalLaursenNonlinearity + : public GlobalNonlinearity<dim, VectorType, MatrixType> { public: GlobalLaursenNonlinearity( shared_ptr<BlockVector<FieldVector<double, 1>> const> mu, diff --git a/dune/tectonic/globalnonlinearity.hh b/dune/tectonic/globalnonlinearity.hh index 3a1bc373..73042d74 100644 --- a/dune/tectonic/globalnonlinearity.hh +++ b/dune/tectonic/globalnonlinearity.hh @@ -10,12 +10,22 @@ #include "localnonlinearity.hh" namespace Dune { -template <int dim> class GlobalNonlinearity { +template <int dim, class VectorType = BlockVector<FieldVector<double, dim>>, + class MatrixType = BCRSMatrix<FieldMatrix<double, dim, dim>>> +class GlobalNonlinearity { public: /* Return a restriction of the outer function to the i'th node. */ virtual shared_ptr<LocalNonlinearity<dim> const> restriction(int i) const = 0; + + virtual void addHessian(const VectorType& v, MatrixType& hessian) const { + // TODO: is this correct? + for (size_t i = 0; i < v.size(); ++i) { + auto res = restriction(i); + res->addHessian(v[i], hessian[i][i]); + } + } }; } #endif diff --git a/dune/tectonic/globalruinanonlinearity.hh b/dune/tectonic/globalruinanonlinearity.hh index 90e8af36..2ff49ef0 100644 --- a/dune/tectonic/globalruinanonlinearity.hh +++ b/dune/tectonic/globalruinanonlinearity.hh @@ -13,8 +13,10 @@ #include "nicefunction.hh" namespace Dune { -template <int dim> -class GlobalRuinaNonlinearity : public GlobalNonlinearity<dim> { +template <int dim, class VectorType = BlockVector<FieldVector<double, dim>>, + class MatrixType = BCRSMatrix<FieldMatrix<double, dim, dim>>> +class GlobalRuinaNonlinearity + : public GlobalNonlinearity<dim, VectorType, MatrixType> { public: GlobalRuinaNonlinearity( shared_ptr<BlockVector<FieldVector<double, 1>> const> nodalIntegrals, diff --git a/dune/tectonic/localnonlinearity.hh b/dune/tectonic/localnonlinearity.hh index 34e595f0..3dc5e53b 100644 --- a/dune/tectonic/localnonlinearity.hh +++ b/dune/tectonic/localnonlinearity.hh @@ -1,6 +1,7 @@ #ifndef DUNE_TECTONIC_LOCAL_NONLINEARITY_HH #define DUNE_TECTONIC_LOCAL_NONLINEARITY_HH +#include <cmath> #include <limits> #include <dune/common/fvector.hh> @@ -45,6 +46,38 @@ template <int dimension> class LocalNonlinearity { } } + /* + H''(|x|) x \otimes x / |x|^2 + + H'(|x|) [|x|^2 id - x \otimes x] / |x|^3 + + For i == j, this is (writing k and using the notation from below) + + h2 * x[k] * x[k] / normX2 + h1 [normX2 - x[k]^2]/normX^3 + = h2 * x[k] * x[k] / normX2 + h1ox - h1 x[k]^2/normX^3 + = (h2-h1ox) * x[k] * x[k] / normX2 + h1ox + + For i != j, this is (again, using the notation from below) + + h2 * x[i] * x[j] / normX2 - h1 * x[i] * x[j]/normX^3 + = (h2 - h1ox) * x[i] * x[j] / normX2 + */ + void addHessian(VectorType const &x, MatrixType &A) const { + double const normX2 = x.two_norm2(); + double const normX = sqrt(normX2); + double const h1ox = func_->rightDifferential(normX) / normX; + double const h2 = func_->second_deriv(normX); + + for (int i = 0; i < dimension; ++i) + for (int j = 0; j < i; ++j) { + double const entry = (h2 - h1ox) * x[i] * x[j] / normX2; + A[i][j] += entry; + A[j][i] += entry; + } + + for (int k = 0; k < dimension; ++k) + A[k][k] += (h2 - h1ox) * x[k] * x[k] / normX2 + h1ox; + } + void upperGradient(VectorType const &x, VectorType &ret) const { ret = x; ret *= func_->rightDifferential(x.two_norm()) / x.two_norm(); diff --git a/dune/tectonic/nicefunction.hh b/dune/tectonic/nicefunction.hh index 4b926f9c..ed6dc388 100644 --- a/dune/tectonic/nicefunction.hh +++ b/dune/tectonic/nicefunction.hh @@ -14,6 +14,8 @@ class NiceFunction : public VirtualFunction<double, double> { virtual double leftDifferential(double s) const = 0; virtual double rightDifferential(double s) const = 0; + + double virtual second_deriv(double s) const = 0; }; class RuinaFunction : public NiceFunction { @@ -110,6 +112,8 @@ class LinearFunction : public NiceFunction { double virtual rightDifferential(double s) const { return coefficient; } + double virtual second_deriv(double) const { return 0; } + private: double coefficient; }; @@ -145,6 +149,8 @@ class TrivialFunction : public NiceFunction { double virtual leftDifferential(double) const { return 0; } double virtual rightDifferential(double) const { return 0; } + + double virtual second_deriv(double) const { return 0; } }; // slope in [n-1,n] is n -- GitLab