https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MathUtils.h
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#pragma once
11
12#include "Moose.h"
13#include "MooseError.h"
14#include "MooseTypes.h"
15#include "libmesh/libmesh.h"
16#include "libmesh/utility.h"
17#include "libmesh/numeric_vector.h"
18#include "libmesh/compare_types.h"
19#include "libmesh/point.h"
20
21namespace MathUtils
22{
23
25static constexpr Real sqrt2 = 1.4142135623730951;
26
27Real poly1Log(Real x, Real tol, unsigned int derivative_order);
28Real poly2Log(Real x, Real tol, unsigned int derivative_order);
29Real poly3Log(Real x, Real tol, unsigned int derivative_order);
30Real poly4Log(Real x, Real tol, unsigned int derivative_order);
31Real taylorLog(Real x);
40Point barycentricToCartesian2D(const Point & p0,
41 const Point & p1,
42 const Point & p2,
43 const Real b0,
44 const Real b1,
45 const Real b2);
54Point barycentricToCartesian3D(const Point & p0,
55 const Point & p1,
56 const Point & p2,
57 const Point & p3,
58 const Real b0,
59 const Real b1,
60 const Real b2,
61 const Real b3);
67Point circumcenter2D(const Point & p0, const Point & p1, const Point & p2);
73Point circumcenter3D(const Point & p0, const Point & p1, const Point & p2, const Point & p3);
74
75template <typename T>
76T
78{
79 return ::round(x); // use round from math.h
80}
81
82template <typename T>
83T
84sign(T x)
85{
86 return x >= 0.0 ? 1.0 : -1.0;
87}
88
89template <typename T>
90T
91pow(T x, int e)
92{
93 bool neg = false;
94 T result = 1.0;
95
96 if (e < 0)
97 {
98 neg = true;
99 e = -e;
100 }
101
102 while (e)
103 {
104 // if bit 0 is set multiply the current power of two factor of the exponent
105 if (e & 1)
106 result *= x;
107
108 // x is incrementally set to consecutive powers of powers of two
109 x *= x;
110
111 // bit shift the exponent down
112 e >>= 1;
113 }
114
115 return neg ? 1.0 / result : result;
116}
117
118template <typename T>
119T
121{
122 return x < 0.0 ? 0.0 : 1.0;
123}
124
125template <typename T>
126T
127regularizedHeavyside(const T & x, Real smoothing_length)
128{
129 if (x <= -smoothing_length)
130 return 0.0;
131 else if (x < smoothing_length)
132 {
133 using std::sin;
134 return 0.5 * (1 + sin(libMesh::pi * x / 2 / smoothing_length));
135 }
136 else
137 return 1.0;
138}
139
140template <typename T>
141T
142regularizedHeavysideDerivative(const T & x, Real smoothing_length)
143{
144 if (x < smoothing_length && x > -smoothing_length)
145 {
146 using std::cos;
147 return 0.25 * libMesh::pi / smoothing_length * (cos(libMesh::pi * x / 2 / smoothing_length));
148 }
149 else
150 return 0.0;
151}
152
153template <typename T>
154T
156{
157 return x > 0.0 ? x : 0.0;
158}
159
160template <typename T>
161T
163{
164 return x < 0.0 ? x : 0.0;
165}
166
167template <
168 typename T,
169 typename T2,
170 typename T3,
171 typename std::enable_if<libMesh::ScalarTraits<T>::value && libMesh::ScalarTraits<T2>::value &&
173 int>::type = 0>
174void
175addScaled(const T & a, const T2 & b, T3 & result)
176{
177 result += a * b;
178}
179
180template <typename T,
181 typename T2,
182 typename T3,
183 typename std::enable_if<libMesh::ScalarTraits<T>::value, int>::type = 0>
184void
185addScaled(const T & scalar,
186 const libMesh::NumericVector<T2> & numeric_vector,
188{
189 result.add(scalar, numeric_vector);
190}
191
192template <
193 typename T,
194 typename T2,
195 template <typename> class W,
196 template <typename> class W2,
197 typename std::enable_if<std::is_same<typename W<T>::index_type, unsigned int>::value &&
198 std::is_same<typename W2<T2>::index_type, unsigned int>::value,
199 int>::type = 0>
201dotProduct(const W<T> & a, const W2<T2> & b)
202{
203 return a * b;
204}
205
206template <typename T,
207 typename T2,
208 template <typename> class W,
209 template <typename> class W2,
210 typename std::enable_if<std::is_same<typename W<T>::index_type,
211 std::tuple<unsigned int, unsigned int>>::value &&
212 std::is_same<typename W2<T2>::index_type,
213 std::tuple<unsigned int, unsigned int>>::value,
214 int>::type = 0>
216dotProduct(const W<T> & a, const W2<T2> & b)
217{
218 return a.contract(b);
219}
220
234template <typename C,
235 typename T,
237R
238poly(const C & c, const T x, const bool derivative = false)
239{
240 const auto size = c.size();
241 if (size == 0)
242 return 0.0;
243
244 R value = c[0];
245 if (derivative)
246 {
247 value *= size - 1;
248 for (std::size_t i = 1; i < size - 1; ++i)
249 value = value * x + c[i] * (size - i - 1);
250 }
251 else
252 {
253 for (std::size_t i = 1; i < size; ++i)
254 value = value * x + c[i];
255 }
256
257 return value;
258}
259
269template <typename C,
270 typename T,
272R
273polynomial(const C & c, const T x)
274{
275 auto size = c.size();
276 if (size == 0)
277 return 0.0;
278
279 size--;
280 R value = c[size];
281 for (std::size_t i = 1; i <= size; ++i)
282 value = value * x + c[size - i];
283
284 return value;
285}
286
290template <typename C,
291 typename T,
293R
294polynomialDerivative(const C & c, const T x)
295{
296 auto size = c.size();
297 if (size <= 1)
298 return 0.0;
299
300 size--;
301 R value = c[size] * size;
302 for (std::size_t i = 1; i < size; ++i)
303 value = value * x + c[size - i] * (size - i);
304
305 return value;
306}
307
308template <typename T, typename T2>
309T
310clamp(const T & x, T2 lowerlimit, T2 upperlimit)
311{
312 if (x < lowerlimit)
313 return lowerlimit;
314 if (x > upperlimit)
315 return upperlimit;
316 return x;
317}
318
319template <typename T, typename T2>
320T
321smootherStep(T x, T2 start, T2 end, bool derivative = false)
322{
323 mooseAssert("start < end", "Start value must be lower than end value for smootherStep");
324 if (x <= start)
325 return 0.0;
326 else if (x >= end)
327 {
328 if (derivative)
329 return 0.0;
330 else
331 return 1.0;
332 }
333 x = (x - start) / (end - start);
334 if (derivative)
335 return 30.0 * libMesh::Utility::pow<2>(x) * (x * (x - 2.0) + 1.0) / (end - start);
336 return libMesh::Utility::pow<3>(x) * (x * (x * 6.0 - 15.0) + 10.0);
337}
338
339enum class ComputeType
340{
341 value,
343};
344
345template <ComputeType compute_type, typename X, typename S, typename E>
346auto
347smootherStep(const X & x, const S & start, const E & end)
348{
349 mooseAssert("start < end", "Start value must be lower than end value for smootherStep");
350 if (x <= start)
351 return 0.0;
352 else if (x >= end)
353 {
354 if constexpr (compute_type == ComputeType::derivative)
355 return 0.0;
356 if constexpr (compute_type == ComputeType::value)
357 return 1.0;
358 }
359 const auto u = (x - start) / (end - start);
360 if constexpr (compute_type == ComputeType::derivative)
361 return 30.0 * libMesh::Utility::pow<2>(u) * (u * (u - 2.0) + 1.0) / (end - start);
362 if constexpr (compute_type == ComputeType::value)
363 return libMesh::Utility::pow<3>(u) * (u * (u * 6.0 - 15.0) + 10.0);
364}
365
371template <typename T>
372inline void
374{
380 v = 0;
381}
382template <typename T>
383inline void
385{
386 mooseError("mooseSetToZero does not accept pointers");
387}
388
389template <>
390inline void
391mooseSetToZero(std::vector<Real> & vec)
392{
393 for (auto & v : vec)
394 v = 0.;
395}
396
414std::vector<std::vector<unsigned int>> multiIndex(unsigned int dim, unsigned int order);
415
416template <ComputeType compute_type, typename X, typename X1, typename X2, typename Y1, typename Y2>
417auto
418linearInterpolation(const X & x, const X1 & x1, const X2 & x2, const Y1 & y1, const Y2 & y2)
419{
420 const auto m = (y2 - y1) / (x2 - x1);
421 if constexpr (compute_type == ComputeType::derivative)
422 return m;
423 if constexpr (compute_type == ComputeType::value)
424 return m * (x - x1) + y1;
425}
426
433template <typename T1, typename T2>
434std::size_t
435euclideanMod(T1 dividend, T2 divisor)
436{
437 return (dividend % divisor + divisor) % divisor;
438}
439
444template <typename T>
445T
446gradName(const T & base_prop_name)
447{
448 return "grad_" + base_prop_name;
449}
450
455template <typename T>
456T
457timeDerivName(const T & base_prop_name)
458{
459 return "d" + base_prop_name + "_dt";
460}
461
468void kron(RealEigenMatrix & product, const RealEigenMatrix & mat_A, const RealEigenMatrix & mat_B);
469
470} // namespace MathUtils
471
473std::vector<std::vector<unsigned int>> multiIndexHelper(unsigned int N, unsigned int K);
std::vector< std::vector< unsigned int > > multiIndexHelper(unsigned int N, unsigned int K)
A helper function for MathUtils::multiIndex.
Definition MathUtils.C:333
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
virtual void add(const numeric_index_type i, const T value)=0
void mooseSetToZero(T &v)
Helper function templates to set a variable to zero.
Definition MathUtils.h:373
Real poly1Log(Real x, Real tol, unsigned int derivative_order)
Definition MathUtils.C:49
void kron(RealEigenMatrix &product, const RealEigenMatrix &mat_A, const RealEigenMatrix &mat_B)
Computes the Kronecker product of two matrices.
Definition MathUtils.C:17
T pow(T x, int e)
Definition MathUtils.h:91
T regularizedHeavyside(const T &x, Real smoothing_length)
Definition MathUtils.h:127
std::vector< std::vector< unsigned int > > multiIndex(unsigned int dim, unsigned int order)
generate a complete multi index table for given dimension and order i.e.
Definition MathUtils.C:186
Real taylorLog(Real x)
Definition MathUtils.C:172
T positivePart(T x)
Definition MathUtils.h:155
T negativePart(T x)
Definition MathUtils.h:162
auto linearInterpolation(const X &x, const X1 &x1, const X2 &x2, const Y1 &y1, const Y2 &y2)
Definition MathUtils.h:418
T sign(T x)
Definition MathUtils.h:84
T gradName(const T &base_prop_name)
automatic prefixing for naming material properties based on gradients of coupled variables/functors
Definition MathUtils.h:446
void addScaled(const T &a, const T2 &b, T3 &result)
Definition MathUtils.h:175
T clamp(const T &x, T2 lowerlimit, T2 upperlimit)
Definition MathUtils.h:310
T timeDerivName(const T &base_prop_name)
automatic prefixing for naming material properties based on time derivatives of coupled variables/fun...
Definition MathUtils.h:457
T smootherStep(T x, T2 start, T2 end, bool derivative=false)
Definition MathUtils.h:321
Real poly2Log(Real x, Real tol, unsigned int derivative_order)
Definition MathUtils.C:76
R polynomial(const C &c, const T x)
Evaluate a polynomial with the coefficients c at x.
Definition MathUtils.h:273
Real poly4Log(Real x, Real tol, unsigned int derivative_order)
Definition MathUtils.C:133
R poly(const C &c, const T x, const bool derivative=false)
Evaluate a polynomial with the coefficients c at x.
Definition MathUtils.h:238
Point circumcenter2D(const Point &p0, const Point &p1, const Point &p2)
Evaluate circumcenter of a triangle given three arbitrary points.
Definition MathUtils.C:260
libMesh::CompareTypes< T, T2 >::supertype dotProduct(const W< T > &a, const W2< T2 > &b)
Definition MathUtils.h:201
Real poly3Log(Real x, Real tol, unsigned int derivative_order)
Definition MathUtils.C:104
T regularizedHeavysideDerivative(const T &x, Real smoothing_length)
Definition MathUtils.h:142
Point barycentricToCartesian3D(const Point &p0, const Point &p1, const Point &p2, const Point &p3, const Real b0, const Real b1, const Real b2, const Real b3)
Evaluate Cartesian coordinates of any center point of a tetrahedron given Barycentric coordinates of ...
Definition MathUtils.C:237
std::size_t euclideanMod(T1 dividend, T2 divisor)
perform modulo operator for Euclidean division that ensures a non-negative result
Definition MathUtils.h:435
static constexpr Real sqrt2
std::sqrt is not constexpr, so we add sqrt(2) as a constant (used in Mandel notation)
Definition MathUtils.h:25
R polynomialDerivative(const C &c, const T x)
Returns the derivative of polynomial(c, x) with respect to x.
Definition MathUtils.h:294
Point barycentricToCartesian2D(const Point &p0, const Point &p1, const Point &p2, const Real b0, const Real b1, const Real b2)
Evaluate Cartesian coordinates of any center point of a triangle given Barycentric coordinates of cen...
Definition MathUtils.C:217
T round(T x)
Definition MathUtils.h:77
Point circumcenter3D(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Evaluate circumcenter of a tetrahedrom given four arbitrary points.
Definition MathUtils.C:289
T heavyside(T x)
Definition MathUtils.h:120
const Real pi