version 3.11-dev
Loading...
Searching...
No Matches
numericdifferentiation.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
13#ifndef DUMUX_NUMERIC_DIFFERENTIATION_HH
14#define DUMUX_NUMERIC_DIFFERENTIATION_HH
15
16#include <cmath>
17#include <cassert>
18#include <limits>
19
20#include <dune/common/ftraits.hh>
21
22namespace Dumux {
23
29{
30public:
31
41 template<class Scalar, class Magnitude = typename Dune::FieldTraits<Scalar>::real_type>
42 static Magnitude epsilon(const Scalar value, const Magnitude baseEps = 1e-10)
43 {
44 assert(std::numeric_limits<Magnitude>::epsilon()*1e4 < baseEps);
45 // the epsilon value used for the numeric differentiation is
46 // now scaled by the absolute value of the primary variable...
47 using std::abs;
48 return baseEps*(abs(value) + 1.0);
49 }
50
55 template<class Function, class Scalar, class FunctionEvalType>
56 static void partialDerivative(const Function& function, Scalar x0,
57 FunctionEvalType& derivative,
58 const FunctionEvalType& fx0,
59 const int numericDifferenceMethod = 1)
60 { partialDerivative(function, x0, derivative, fx0, epsilon(x0), numericDifferenceMethod); }
61
72 template<class Function, class Scalar, class EpsType, class FunctionEvalType>
73 static void partialDerivative(const Function& function, Scalar x0,
74 FunctionEvalType& derivative,
75 const FunctionEvalType& fx0,
76 const EpsType eps,
77 const int numericDifferenceMethod = 1)
78 requires(
79 std::is_same_v<Scalar, decltype(std::declval<Scalar>() + std::declval<EpsType>())>
80 && std::is_same_v<Scalar, decltype(std::declval<Scalar>() - std::declval<EpsType>())>
81 ){
82 // Five-point stencil numeric difference,
83 // Abramowitz & Stegun, Table 25.2.
84 // The error is proportional to eps^4.
85 if (numericDifferenceMethod == 5)
86 {
87 derivative = function(x0 + eps);
88 derivative -= function(x0 - eps);
89 derivative *= 8.0;
90 derivative += function(x0 - 2.0*eps);
91 derivative -= function(x0 + 2.0*eps);
92 derivative /= 12.0*eps;
93 return;
94 }
95
96 // Forward, central, or backward differences
97 EpsType delta = 0.0;
98
99 // we are using forward or central differences, i.e. we need to calculate f(x + \epsilon)
100 if (numericDifferenceMethod >= 0)
101 {
102 delta += eps;
103 // calculate the function evaluated with the deflected variable
104 derivative = function(x0 + eps);
105 }
106
107 // we are using backward differences,
108 // i.e. we don't need to calculate f(x + \epsilon)
109 // we can recycle the (possibly cached) f(x)
110 else derivative = fx0;
111
112 // we are using backward or central differences,
113 // i.e. we need to calculate f(x - \epsilon)
114 if (numericDifferenceMethod <= 0)
115 {
116 delta += eps;
117 // subtract the function evaluated with the deflected variable
118 derivative -= function(x0 - eps);
119 }
120
121 // we are using forward differences,
122 // i.e. we don't need to calculate f(x - \epsilon)
123 // we can recycle the (possibly cached) f(x)
124 else derivative -= fx0;
125
126 // divide difference in residuals by the magnitude of the
127 // deflections between the two function evaluation
128 derivative /= delta;
129 }
130};
131
132} // end namespace Dumux
133
134#endif
A class for numeric differentiation with respect to a scalar parameter.
Definition numericdifferentiation.hh:29
static void partialDerivative(const Function &function, Scalar x0, FunctionEvalType &derivative, const FunctionEvalType &fx0, const EpsType eps, const int numericDifferenceMethod=1)
Computes the derivative of a function with respect to a function parameter.
Definition numericdifferentiation.hh:73
static void partialDerivative(const Function &function, Scalar x0, FunctionEvalType &derivative, const FunctionEvalType &fx0, const int numericDifferenceMethod=1)
Computes the derivative of a function with respect to a function parameter.
Definition numericdifferentiation.hh:56
static Magnitude epsilon(const Scalar value, const Magnitude baseEps=1e-10)
Computes the epsilon used for numeric differentiation.
Definition numericdifferentiation.hh:42
Definition adapt.hh:17