OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
TriangleQuadrature.hpp
1// Note that this code is mostly from the Drake project: https://drake.mit.edu/
2// and is governed by their BSD 3-Clause license:
3// https://github.com/RobotLocomotion/drake/blob/master/LICENSE.TXT
4// Only minor modifications have been made to make it work in OpenMD.
5
6#ifndef MATH_INTEGRATION_TRIANGLEQUADRATURE_HPP
7#define MATH_INTEGRATION_TRIANGLEQUADRATURE_HPP
8
9#include <functional>
10#include <vector>
11
13#include "math/Vector2.hpp"
14#include "math/Vector3.hpp"
15#include "math/integration/TriangleQuadratureRule.hpp"
16
17namespace OpenMD {
18
19 /// A class for integrating a function using numerical quadrature
20 /// over triangular domains.
21 ///
22 /// @tparam NumericReturnType the output type of the function being
23 /// integrated. Commonly will be a IEEE floating point
24 /// scalar (e.g., `double`), but could be a
25 /// VectorXd, or any other
26 /// numeric type that supports both scalar multiplication
27 /// (i.e., operator*(const NumericReturnType&, double) and
28 /// addition with another of the same type (i.e.,
29 /// operator+(const NumericReturnType&, const
30 /// NumericReturnType&)).
31 /// @tparam T the scalar type of the function being integrated
32 /// over. Supported types are currently only IEEE floating
33 /// point scalars.
34 template<typename NumericReturnType, typename T>
36 public:
37 /// Numerically integrates the function f over a triangle using the given
38 /// quadrature rule and the initial value.
39 /// @param f(p) a function that returns a numerical value for point p in the
40 /// domain of the triangle, specified in barycentric coordinates.
41 /// The barycentric coordinates are given by
42 /// (p[0], p[1], 1 - p[0] - p[1]).
43 /// @param area the area of the triangle.
44 static NumericReturnType Integrate(
45 const std::function<NumericReturnType(const Vector<T, 2>&)>& f,
46 const TriangleQuadratureRule& rule, const T& area);
47
48 /// Alternative signature for Integrate() that uses three-dimensional
49 /// barycentric coordinates.
50 /// @param f(p) a function that returns a numerical value for point p in the
51 /// domain of the triangle, specified in barycentric coordinates.
52 /// The barycentric coordinates are given by
53 /// (p[0], p[1], p[2]).
54 /// @param area the area of the triangle.
55 static NumericReturnType Integrate(
56 const std::function<NumericReturnType(const Vector<T, 3>&)>& f,
57 const TriangleQuadratureRule& rule, const T& area);
58 };
59
60 template<typename NumericReturnType, typename T>
62 const std::function<NumericReturnType(const Vector<T, 2>&)>& f,
63 const TriangleQuadratureRule& rule, const T& area) {
64 // Get the quadrature points and weights.
65 const std::vector<Vector2<T>>& barycentric_coordinates =
66 rule.quadrature_points();
67 const std::vector<T>& weights = rule.weights();
68 assert(barycentric_coordinates.size() == weights.size());
69 assert(weights.size() >= 1);
70
71 // Sum the weighted function evaluated at the transformed
72 // quadrature points. The looping is done in this particular way
73 // so that the return type can be either a traditional scalar
74 // (e.g., `double`), a Vector, or some other numeric type,
75 // without having to worry about the numerous possible ways to
76 // initialize to zero (e.g., `double integral = 0.0` vs.
77 // VectorXd = VectorXd:zZero())` or having to know
78 // the dimension of the NumericReturnType (i.e., scalar or vector
79 // dimension).
80 NumericReturnType integral = f(barycentric_coordinates[0]) * weights[0];
81 for (int i = 1; i < static_cast<int>(weights.size()); ++i)
82 integral += f(barycentric_coordinates[i]) * weights[i];
83
84 return integral * area;
85 }
86
87 template<typename NumericReturnType, typename T>
89 const std::function<NumericReturnType(const Vector<T, 3>&)>& f,
90 const TriangleQuadratureRule& rule, const T& area) {
91 // Create a function fprime accepting a 2D barycentric representation but
92 // using it to call the given 3D function f.
93 std::function<NumericReturnType(const Vector<T, 2>&)> fprime =
94 [&f](const Vector<T, 2>& barycentric_2D) {
95 return f(Vector3<T>(barycentric_2D[0], barycentric_2D[1],
96 T(1.0) - barycentric_2D[0] - barycentric_2D[1]));
97 };
98
99 return Integrate(fprime, rule, area);
100 }
101} // namespace OpenMD
102#endif
A class for integrating a function using numerical quadrature over triangular domains.
static NumericReturnType Integrate(const std::function< NumericReturnType(const Vector< T, 2 > &)> &f, const TriangleQuadratureRule &rule, const T &area)
Numerically integrates the function f over a triangle using the given quadrature rule and the initial...
A "rule" (weights and quadrature points) for computing quadrature over triangular domains.
const std::vector< RealType > & weights() const
Returns the vector of weights. These sum to 1 and there is one weight for each point returned by quad...
const std::vector< Vector2d > & quadrature_points() const
Returns the vector of quadrature points. These are returned as the first two barycentric coordinates ...
Fix length vector class.
Definition Vector.hpp:78
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.