FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
evaluator.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/space/evaluator_base.hpp>
10#include <kernel/geometry/intern/sub_index_mapping.hpp>
11
12namespace FEAT
13{
14 namespace Space
15 {
16 namespace Argyris
17 {
23 template<
24 typename Space_,
25 typename TrafoEvaluator_,
26 typename SpaceEvalTraits_,
27 typename Shape_ = typename Space_::ShapeType>
28 class Evaluator DOXY({});
29
35 template<
36 typename Space_,
37 typename TrafoEvaluator_,
38 typename SpaceEvalTraits_>
39 class Evaluator<Space_, TrafoEvaluator_, SpaceEvalTraits_, Shape::Simplex<2> > :
40 public EvaluatorBase<
41 Evaluator<
42 Space_,
43 TrafoEvaluator_,
44 SpaceEvalTraits_,
45 Shape::Simplex<2> >,
46 TrafoEvaluator_,
47 SpaceEvalTraits_>
48 {
49 public:
52
54 typedef Space_ SpaceType;
55
57 typedef SpaceEvalTraits_ SpaceEvalTraits;
58
60 typedef TrafoEvaluator_ TrafoEvaluator;
61
63 typedef typename TrafoEvaluator::EvalTraits TrafoEvalTraits;
64
66 typedef typename SpaceEvalTraits::EvalPolicy EvalPolicy;
67
69 typedef typename EvalPolicy::DomainPointType DomainPointType;
70
72 typedef typename EvalPolicy::ImagePointType ImagePointType;
73
75 typedef typename SpaceEvalTraits::DataType DataType;
76
77 static constexpr SpaceTags eval_caps = (SpaceTags::value | SpaceTags::grad | SpaceTags::hess);
78
79 template<SpaceTags cfg_>
80 struct ConfigTraits
81 {
83 static constexpr SpaceTags config = cfg_;
84
86 static constexpr TrafoTags trafo_config = TrafoTags::img_point;
87
90 };
91
92 protected:
93 // coefficient matrix
95 // triangle barycentre
96 ImagePointType _barycentre;
97
98 public:
105 explicit Evaluator(const SpaceType& DOXY(space))
106 {
107 }
108
116 {
117 return 21;
118 }
119
126 void prepare(const TrafoEvaluator& trafo_eval)
127 {
128 // domain point
131
132 // create sub-index mapping
133 typedef Geometry::Intern::SubIndexMapping<Shape::Simplex<2>, 1, 0> SimType;
134
135 // compute edge orientations
136 SimType sim(
137 trafo_eval.get_trafo().get_mesh().template get_index_set<2,0>()[trafo_eval.get_cell_index()],
138 trafo_eval.get_trafo().get_mesh().template get_index_set<2,1>()[trafo_eval.get_cell_index()],
139 trafo_eval.get_trafo().get_mesh().template get_index_set<1,0>());
140 DataType edge_ori[3] =
141 {
142 DataType(1) - DataType(2*sim.map(0, 0)),
143 DataType(1) - DataType(2*sim.map(1, 0)),
144 DataType(1) - DataType(2*sim.map(2, 0))
145 };
146
147 // initialize edge vectors
148 ImagePointType edge_vec[3];
149 edge_vec[0].format();
150 edge_vec[1].format();
151 edge_vec[2].format();
152
153 // compute barycentre
154 dom_point[0] = dom_point[1] = DataType(1) / DataType(3);
155 trafo_eval.map_point(_barycentre, dom_point);
156
157 // nodal matrix
159 node_mat.format();
160
161 // loop over all vertices
162 for(int vi(0); vi < 3; ++vi)
163 {
164 // compute vertex coordinate
165 dom_point[0] = (vi == 1) ? DataType(1) : DataType(0);
166 dom_point[1] = (vi == 2) ? DataType(1) : DataType(0);
167 trafo_eval.map_point(img_point, dom_point);
168 img_point -= _barycentre;
169
170 // update edge vectors
171 edge_vec[(vi+1) % 3] += img_point;
172 edge_vec[(vi+2) % 3] -= img_point;
173
174 // initialize monomial powers
176 vx(0) = vy(0) = DataType(1);
177 for(int l(0); l < 5; ++l)
178 {
179 vx(l+1) = vx(l) * img_point[0];
180 vy(l+1) = vy(l) * img_point[1];
181 }
182
183 // set monomial values
184 int k(0);
185 for(int i(0); i < 6; ++i)
186 {
187 for(int j(0); i+j < 6; ++j, ++k)
188 {
189 // monomial value
190 node_mat(k, 6*vi+0) = vx(i) * vy(j);
191 // dx-derivative
192 if(i > 0)
193 node_mat(k, 6*vi+1) = DataType(i) * vx(i-1) * vy(j);
194 // dy-derivative
195 if(j > 0)
196 node_mat(k, 6*vi+2) = DataType(j) * vy(j-1) * vx(i);
197 // dxx-derivative
198 if(i > 1)
199 node_mat(k, 6*vi+3) = DataType(i) * DataType(i-1) * vx(i-2) * vy(j);
200 // dyy-derivative
201 if(j > 1)
202 node_mat(k, 6*vi+4) = DataType(j) * DataType(j-1) * vy(j-2) * vx(i);
203 // dxy-derivative
204 if(i*j > 0)
205 node_mat(k, 6*vi+5) = DataType(i) * vx(i-1) * DataType(j) * vy(j-1);
206 }
207 }
208 }
209
210 for(int ei(0); ei < 3; ++ei)
211 {
212 // compute edge midpoint
213 dom_point[0] = (ei != int(1) ? DataType(0.5) : DataType(0));
214 dom_point[1] = (ei != int(2) ? DataType(0.5) : DataType(0));
215 trafo_eval.map_point(img_point, dom_point);
216 img_point -= _barycentre;
217
218 // compute edge normal and apply orientation
219 DataType dnorm = edge_vec[ei].norm_euclid();
220 DataType dnx = +(edge_vec[ei](1) * edge_ori[ei]) / dnorm;
221 DataType dny = -(edge_vec[ei](0) * edge_ori[ei]) / dnorm;
222
223 // initialize monomial powers
225 vx(0) = vy(0) = DataType(1);
226 for(int l(0); l < 5; ++l)
227 {
228 vx(l+1) = vx(l) * img_point[0];
229 vy(l+1) = vy(l) * img_point[1];
230 }
231
232 // set monomial values
233 int k(0);
234 for(int i(0); i < 6; ++i)
235 {
236 for(int j(0); i+j < 6; ++j, ++k)
237 {
238 // edge normal derivative
239 if(i > 0)
240 node_mat(k, 18+ei) += DataType(i) * dnx * vx(i-1) * vy(j);
241 if(j > 0)
242 node_mat(k, 18+ei) += DataType(j) * dny * vy(j-1) * vx(i);
243 }
244 }
245 }
246
247 // invert nodal matrix to get the coefficient matrix
248 _coeff.set_inverse(node_mat);
249 }
250
251 template<SpaceTags space_cfg_, TrafoTags trafo_cfg_>
252 void eval_values(
255 {
256 // initialize monomial powers
258 vx(0) = vy(0) = DataType(1);
259 for(int l(0); l < 5; ++l)
260 {
261 vx(l+1) = vx(l) * (tau.img_point[0] - _barycentre[0]);
262 vy(l+1) = vy(l) * (tau.img_point[1] - _barycentre[1]);
263 }
264
265 // compute basis function values
266 for(int l(0); l < 21; ++l)
267 {
268 int k(0);
269 DataType v(DataType(0));
270 for(int i(0); i < 6; ++i)
271 for(int j(0); i+j < 6; ++j, ++k)
272 v += _coeff(l,k) * vx(i) * vy(j);
273 phi.phi[l].value = v;
274 }
275 }
276
277 template<SpaceTags space_cfg_, TrafoTags trafo_cfg_>
278 void eval_gradients(
279 EvalData<SpaceEvalTraits, space_cfg_>& phi,
280 const Trafo::EvalData<TrafoEvalTraits, trafo_cfg_>& tau) const
281 {
282 // initialize monomial powers
283 Tiny::Vector<DataType, 6> vx, vy;
284 vx(0) = vy(0) = DataType(1);
285 for(int l(0); l < 5; ++l)
286 {
287 vx(l+1) = vx(l) * (tau.img_point[0] - _barycentre[0]);
288 vy(l+1) = vy(l) * (tau.img_point[1] - _barycentre[1]);
289 }
290
291 // compute basis function gradients
292 for(int l(0); l < 21; ++l)
293 {
294 int k(0);
295 DataType dx(DataType(0)), dy(DataType(0));
296 for(int i(0); i < 6; ++i)
297 {
298 for(int j(0); i+j < 6; ++j, ++k)
299 {
300 if(i > 0)
301 dx += _coeff(l,k) * DataType(i) * vx(i-1) * vy(j);
302 if(j > 0)
303 dy += _coeff(l,k) * DataType(j) * vy(j-1) * vx(i);
304 }
305 }
306 phi.phi[l].grad[0] = dx;
307 phi.phi[l].grad[1] = dy;
308 }
309 }
310
311 template<SpaceTags space_cfg_, TrafoTags trafo_cfg_>
312 void eval_hessians(
313 EvalData<SpaceEvalTraits, space_cfg_>& phi,
314 const Trafo::EvalData<TrafoEvalTraits, trafo_cfg_>& tau) const
315 {
316 // initialize monomial powers
317 Tiny::Vector<DataType, 6> vx, vy;
318 vx(0) = vy(0) = DataType(1);
319 for(int l(0); l < 5; ++l)
320 {
321 vx(l+1) = vx(l) * (tau.img_point[0] - _barycentre[0]);
322 vy(l+1) = vy(l) * (tau.img_point[1] - _barycentre[1]);
323 }
324
325 // compute basis function hessians
326 for(int l(0); l < 21; ++l)
327 {
328 int k(0);
329 DataType dxx(DataType(0)), dyy(DataType(0)), dxy(DataType(0));
330 for(int i(0); i < 6; ++i)
331 {
332 for(int j(0); i+j < 6; ++j, ++k)
333 {
334 if(i > 1)
335 dxx += _coeff(l,k) * DataType(i) * DataType(i-1) * vx(i-2) * vy(j);
336 if(j > 1)
337 dyy += _coeff(l,k) * DataType(j) * DataType(j-1) * vy(j-2) * vx(i);
338 if(i*j > 0)
339 dxy += _coeff(l,k) * DataType(i) * vx(i-1) * DataType(j) * vy(j-1);
340 }
341 }
342 phi.phi[l].hess(0,0) = dxx;
343 phi.phi[l].hess(1,1) = dyy;
344 phi.phi[l].hess(0,1) = phi.phi[l].hess(1,0) = dxy;
345 }
346 }
347 }; // class Evaluator<...,Simplex<2>>
348 } // namespace Argyris
349 } // namespace Space
350} // namespace FEAT
EvaluatorBase< Evaluator, TrafoEvaluator_, SpaceEvalTraits_ > BaseClass
base-class typedef
Definition: evaluator.hpp:51
void prepare(const TrafoEvaluator &trafo_eval)
Prepares the evaluator for a given cell.
Definition: evaluator.hpp:126
Argyris Element Evaluator class template declaration.
Definition: evaluator.hpp:28
EvalTraits_::BasisValueType value
basis function value object
Definition: eval_data.hpp:47
Space evaluation data structure.
Definition: eval_data.hpp:141
BasisDataType phi[max_local_dofs]
the basis function data vector
Definition: eval_data.hpp:150
Basic Space Evaluator CRTP base-class template.
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & set_inverse(const Matrix< T_, m_, n_, sma_, sna_ > &a)
Sets this matrix to the inverse of another matrix.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the matrix.
Tiny Vector class template.
Trafo evaluation data structure.
Definition: eval_data.hpp:33
EvalTraits::ImagePointType img_point
image point
Definition: eval_data.hpp:53
FEAT namespace.
Definition: adjactor.hpp:12
SpaceTags
Space configuration tags enum.
Definition: eval_tags.hpp:97
@ value
specifies whether the space should supply basis function values
@ hess
specifies whether the space should supply basis function hessians
@ grad
specifies whether the space should supply basis function gradients
TrafoTags
Trafo configuration tags enum.
Definition: eval_tags.hpp:22
@ img_point
specifies whether the trafo should supply image point coordinates
@ dom_point
specifies whether the trafo should supply domain point coordinates