OpenMD 3.2
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
12 public TriangleQuadratureRule {
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.
int order() const
Returns the order of this rule.
virtual int do_order() const =0
Derived classes shall return the order (>= 1) of this rule.
virtual const std::vector< Vector2d > & do_quadrature_points() const =0
Derived classes shall return the vector of quadrature points. Each of these Vector2d objects represen...
virtual const std::vector< RealType > & do_weights() const =0
Derived classes shall return the vector of weights. The sum of all weights must equal 1....
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.