OpenMD 3.1
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
StrangFixCowperTriangleQuadrature.hpp
1#ifndef MATH_INTEGRATION_STRANGFIXCOWPERTRIANGLEQUADRATURE_HPP
2#define MATH_INTEGRATION_STRANGFIXCOWPERTRIANGLEQUADRATURE_HPP
3
4#include <stdexcept>
5#include <vector>
6
7#include "math/integration/TriangleQuadratureRule.hpp"
8
9namespace OpenMD {
10
13 public:
14 /// Constructs the StrangFixCowper quadrature rule of the specified order,
15 /// which must be between 1 and 5.
17 assert(order >= 1);
18 if (order > 7) {
19 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
20 "StrangFixCowperTriangleQuadrature does not implement a %d "
21 "point algorithm\n",
22 order);
23 painCave.isFatal = 1;
24 ;
25 simError();
26 }
27 SetWeightsAndQuadraturePoints();
28 }
29
30 private:
31 // A partial implementation of the Triangular quadrature schemes
32 // in: Gilbert Strang & George Fix, An Analysis of the Finite
33 // Element Method, (Wellesley-Cambridge Press, 1973),
34 // https://bookstore.siam.org/wc08/
35 //
36 // and G.R. Cowper, "Gaussian quadrature formulas for triangles",
37 // Numerical Methods in Engineering, 7(3), pp. 405-408 (1973).
38 // https://doi.org/10.1002/nme.1620070316
39 void SetWeightsAndQuadraturePoints() {
40 switch (order_) {
41 case 2:
42 // Strang-Fix-Cowper scheme 2
43 weights_.resize(3);
44 quadrature_points_.resize(3);
45 weights_[0] = weights_[1] = weights_[2] = 1.0 / 3.0;
46 quadrature_points_[0] = Vector2d(1.0 / 2.0, 1.0 / 2.0);
47 quadrature_points_[1] = Vector2d(0.0, 1.0 / 2.0);
48 quadrature_points_[2] = Vector2d(1.0 / 2.0, 0.0);
49 break;
50 case 3:
51 // Strang-Fix-Cowper Scheme 3
52 weights_.resize(4);
53 quadrature_points_.resize(4);
54 weights_[0] = -27.0 / 48.0;
55 weights_[1] = weights_[2] = weights_[3] = 25.0 / 48.0;
56 quadrature_points_[0] = Vector2d(1.0 / 3.0, 1.0 / 3.0);
57 quadrature_points_[1] = Vector2d(1.0 / 5.0, 1.0 / 5.0);
58 quadrature_points_[2] = Vector2d(1.0 / 5.0, 3.0 / 5.0);
59 quadrature_points_[3] = Vector2d(3.0 / 5.0, 1.0 / 5.0);
60 break;
61 case 4:
62 weights_.resize(6);
63 quadrature_points_.resize(6);
64 weights_[0] = weights_[1] = weights_[2] = 0.223381589678011;
65 weights_[3] = weights_[4] = weights_[5] = 0.109951743655322;
66 quadrature_points_[0] = Vector2d(0.445948490915965, 0.445948490915965);
67 quadrature_points_[1] = Vector2d(0.445948490915965, 0.108103018168070);
68 quadrature_points_[2] = Vector2d(0.108103018168070, 0.445948490915965);
69 quadrature_points_[3] = Vector2d(0.091576213509771, 0.091576213509771);
70 quadrature_points_[4] = Vector2d(0.091576213509771, 0.816847572980459);
71 quadrature_points_[5] = Vector2d(0.816847572980459, 0.091576213509771);
72 break;
73 case 6:
74 // Strang-Fix-Cowper scheme 4
75 weights_.resize(6);
76 quadrature_points_.resize(6);
77 weights_[0] = weights_[1] = weights_[2] = 1.0 / 6.0;
78 weights_[3] = weights_[4] = weights_[5] = 1.0 / 6.0;
79 quadrature_points_[0] = Vector2d(0.659027622374092, 0.231933368553031);
80 quadrature_points_[1] = Vector2d(0.109039009072877, 0.659027622374092);
81 quadrature_points_[2] = Vector2d(0.231933368553031, 0.109039009072877);
82 quadrature_points_[3] = Vector2d(0.231933368553031, 0.659027622374092);
83 quadrature_points_[4] = Vector2d(0.109039009072877, 0.231933368553031);
84 quadrature_points_[5] = Vector2d(0.659027622374092, 0.109039009072877);
85 break;
86 case 7:
87 // Strang-Fix-Cowper scheme 7
88 weights_.resize(7);
89 quadrature_points_.resize(7);
90 weights_[0] = 0.225;
91 weights_[1] = weights_[2] = weights_[3] = 0.125939180544827;
92 weights_[4] = weights_[5] = weights_[6] = 0.132394152788506;
93 quadrature_points_[0] = Vector2d(1.0 / 3.0, 1.0 / 3.0);
94 quadrature_points_[1] = Vector2d(0.797426985353087, 0.101286507323456);
95 quadrature_points_[2] = Vector2d(0.101286507323456, 0.797426985353087);
96 quadrature_points_[3] = Vector2d(0.101286507323456, 0.101286507323456);
97 quadrature_points_[4] = Vector2d(0.059715871789770, 0.470142064105115);
98 quadrature_points_[5] = Vector2d(0.470142064105115, 0.059715871789770);
99 quadrature_points_[6] = Vector2d(0.470142064105115, 0.470142064105115);
100 break;
101
102 default:
103 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
104 "StrangFixCowperTriangleQuadrature does not implement a %d "
105 "point algorithm\n",
106 order_);
107 painCave.isFatal = 1;
108 ;
109 simError();
110 }
111 }
112
113 int do_order() const final { return order_; }
114
115 const std::vector<RealType>& do_weights() const final { return weights_; }
116
117 const std::vector<Vector2d>& do_quadrature_points() const final {
118 return quadrature_points_;
119 }
120
121 const int order_ {-1};
122 std::vector<RealType> weights_;
123 std::vector<Vector2d> quadrature_points_;
124 };
125
126} // namespace OpenMD
127#endif
StrangFixCowperTriangleQuadratureRule(int order)
Constructs the StrangFixCowper quadrature rule of the specified order, which must be between 1 and 5.
A "rule" (weights and quadrature points) for computing quadrature over triangular domains.
int order() const
Returns the order of this rule.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.