FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
auto_alias.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
9#include <kernel/shape.hpp>
10#include <kernel/cubature/scalar/gauss_legendre_driver.hpp>
11#include <kernel/cubature/lauffer_driver.hpp>
12#include <kernel/cubature/hammer_stroud_driver.hpp>
13#include <kernel/cubature/dunavant_driver.hpp>
14#include <kernel/cubature/shunn_ham_driver.hpp>
15
16// includes, STL
17#include <deque>
18#include <algorithm>
19
20namespace FEAT
21{
22 namespace Cubature
23 {
25 namespace Intern
26 {
27 template<typename Shape_>
28 class AutoDegree;
29 }
31
32 template<typename Shape_>
34 {
35 public:
37 static constexpr int max_auto_degree = Intern::AutoDegree<Shape_>::max_degree;
38
39 static String map(const String& name)
40 {
41 // split the name into its parts
42 std::deque<String> parts = name.split_by_string(":");
43
44 // ensure that we have at least two parts
45 if(parts.size() < std::size_t(2))
46 return name;
47
48 // fetch the last two parts
49 String param(parts.back());
50 parts.pop_back();
51 String auto_part(parts.back());
52 parts.pop_back();
53
54 // try to split the auto-part
55 std::deque<String> args = auto_part.split_by_string("-");
56
57 // does this identify an auto-alias rule?
58 if(args.front().compare_no_case("auto") != 0)
59 return name;
60
61 // auto-degree?
62 if((args.size() == std::size_t(2)) && (args.back().compare_no_case("degree") == 0))
63 {
64 // try to parse the degree
65 Index degree = 0;
66 if(!param.parse(degree))
67 return name; // failed to parse degree
68
69 // map auto-degree rule alias
70 String alias(Intern::AutoDegree<Shape_>::choose(degree));
71
72 // join up with remaining prefix parts (if any)
73 if(!parts.empty())
74 return stringify_join(parts, ":").append(":").append(alias);
75 else
76 return alias;
77 }
78
79 // unknown auto-alias
80 return name;
81 }
82 };
83
84 // \cond internal
85 namespace Intern
86 {
87 template<>
88 class AutoDegree< Shape::Simplex<1> >
89 {
90 public:
91 // We choose the Gauss-Legendre cubature rule, so our maximum degree is 2*n-1.
92 static constexpr int max_degree = 2*Scalar::GaussLegendreDriver::max_points - 1;
93
94 static String choose(Index degree)
95 {
96 // k-point Gauss-Legendre cubature is exact up to a degree of 2*k-1,
97 // so for a degree of n we need k := (n+2)/2 = n/2 + 1
98 Index k = degree/2 + 1;
99
100 // Also, ensure that we respect the currently implemented borders...
101 k = std::max(k, Index(Scalar::GaussLegendreDriver::min_points));
102 k = std::min(k, Index(Scalar::GaussLegendreDriver::max_points));
103
104 // and build the name
105 return
106#ifdef FEAT_CUBATURE_SCALAR_PREFIX
107 "scalar:" +
108#endif
109 Scalar::GaussLegendreDriver::name() + ":" + stringify(k);
110 }
111 };
112
113 template<>
114 class AutoDegree< Shape::Simplex<2> >
115 {
116 public:
117 static constexpr int max_degree = 19;
118
119 static String choose(Index degree)
120 {
121 switch(int(degree))
122 {
123 case 0:
124 case 1:
125 return BarycentreDriver<Shape::Simplex<2> >::name();
126 case 2:
127 return DunavantDriver<Shape::Simplex<2> >::name() + ":2";
128 case 3: // dunavant:3 has negative weights
129 case 4:
130 return DunavantDriver<Shape::Simplex<2> >::name() + ":4";
131 case 5:
132 return DunavantDriver<Shape::Simplex<2> >::name() + ":5";
133 case 6:
134 return DunavantDriver<Shape::Simplex<2> >::name() + ":6";
135 case 7: // dunavant:7 has negative weights
136 case 8:
137 return DunavantDriver<Shape::Simplex<2> >::name() + ":8";
138 case 9:
139 return DunavantDriver<Shape::Simplex<2> >::name() + ":9";
140 case 10:
141 return DunavantDriver<Shape::Simplex<2> >::name() + ":10";
142 case 11: // dunavant:11 has points outside the element
143 case 12:
144 return DunavantDriver<Shape::Simplex<2> >::name() + ":12";
145 case 13:
146 return DunavantDriver<Shape::Simplex<2> >::name() + ":13";
147 case 14:
148 return DunavantDriver<Shape::Simplex<2> >::name() + ":14";
149 case 15: // dunavant:15 has points outside the element
150 case 16: // dunavant:16 has points outside the element
151 case 17:
152 return DunavantDriver<Shape::Simplex<2> >::name() + ":17";
153 //case 18: // dunavant:18 has points outside the element and negative weights
154 //case 19:
155 default:
156 return DunavantDriver<Shape::Simplex<2> >::name() + ":19";
157 }
158 }
159 };
160
161 template<>
162 class AutoDegree< Shape::Simplex<3> >
163 {
164 public:
165 static constexpr int max_degree = 5;
166
167 static String choose(Index degree)
168 {
169 if(degree <= 1) // barycentre
170 return BarycentreDriver<Shape::Simplex<3> >::name();
171 else if(degree <= 2)
172 return ShunnHamDriver<Shape::Simplex<3>>::name() + ":2";
173 else if(degree <= 3)
174 return ShunnHamDriver<Shape::Simplex<3>>::name() + ":3";
175 else if(degree <= 5)
176 return ShunnHamDriver<Shape::Simplex<3>>::name() + ":4";
177 else if(degree <= 7)
178 return ShunnHamDriver<Shape::Simplex<3>>::name() + ":5";
179 else //if(degree <= 9)
180 return ShunnHamDriver<Shape::Simplex<3>>::name() + ":6";
181 }
182 };
183
184 template<int dim_>
185 class AutoDegree< Shape::Hypercube<dim_> >
186 {
187 public:
188 // We choose the Gauss-Legendre cubature rule, so our maximum degree is 2*n-1.
189 static constexpr int max_degree = 2*Scalar::GaussLegendreDriver::max_points - 1;
190
191 static String choose(Index degree)
192 {
193 // k-point Gauss-Legendre cubature is exact up to a degree of 2*k-1,
194 // so for a degree of n we need k := (n+2)/2 = n/2 + 1
195 Index k = degree/2 + 1;
196
197 // Also, ensure that we respect the currently implemented borders...
198 k = std::max(k, Index(Scalar::GaussLegendreDriver::min_points));
199 k = std::min(k, Index(Scalar::GaussLegendreDriver::max_points));
200
201 // and build the name
202 return
203#ifdef FEAT_CUBATURE_TENSOR_PREFIX
204 "tensor:" +
205#endif
206 Scalar::GaussLegendreDriver::name() + ":" + stringify(k);
207 }
208 };
209 } // namespace Intern
211 } // namespace Cubature
212} // namespace FEAT
static constexpr int max_auto_degree
Maximum specialized auto-degree parameter.
Definition: auto_alias.hpp:37
String class implementation.
Definition: string.hpp:46
bool parse(T_ &t) const
Parses the string and stores its value in the provided variable.
Definition: string.hpp:837
std::deque< String > split_by_string(const String &delimiter) const
Splits the string by a delimiter substring.
Definition: string.hpp:539
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
String stringify_join(Iterator_ first, Iterator_ last, const String &delimiter="")
Joins a sequence of strings.
Definition: string.hpp:1017
std::uint64_t Index
Index data type.