FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
surface_integrator_basic_jobs.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#include "kernel/assembly/asm_traits.hpp"
8#include <kernel/assembly/surface_integrator.hpp>
10#include <kernel/trafo/inverse_mapping.hpp>
11#include <kernel/util/tiny_algebra.hpp>
12
13#include <unordered_map>
14
15
16
17namespace FEAT::Assembly
18{
19
20 template<typename AsmTraits_>
22 {
23 public:
24 typedef typename AsmTraits_::TrafoType TrafoType;
25 static constexpr int dim = TrafoType::ShapeType::dimension;
26 typedef Index IndexType;
27 typedef typename AsmTraits_::DataType DataType;
28 typedef AsmTraits_ AsmTraits;
29 typedef typename AsmTraits::TrafoEvaluator TrafoEval;
30 typedef typename TrafoEval::DomainPointType DomainPointType;
31 typedef typename TrafoEval::ImagePointType ImagePointType;
32
33 protected:
34 const TrafoType& _trafo;
36
37 std::vector<IndexType> _cell_helper;
38 std::vector<BoundingBoxType<DataType, dim>> _cell_bb;
39 std::vector<ImagePointType> _domain_points;
40 std::vector<DataType> _point_weights;
41 std::vector<std::vector<IndexType>> _cell_to_domain_point;
42
43 ImagePointType _cur_img_point;
44 ImagePointType _cur_dom_point;
45 ImagePointType _normal;
46 DataType _face_volume;
47 IndexType _cur_surface_index;
48
49 DataType _integration_weight;
50
51 public:
52 SurfaceIntegratorTaskBase(const TrafoType& trafo_)
53 : _trafo(trafo_),
54 _inv_mapping(_trafo, DataType(1E-2), DataType(1E-4), false),
55 _cell_helper(),
56 _cell_bb(),
57 _domain_points(),
58 _point_weights(),
59 _cell_to_domain_point(),
60 _cur_img_point(),
61 _cur_dom_point(),
62 _normal(),
63 _face_volume(),
64 _cur_surface_index(~IndexType(0)),
65 _integration_weight(DataType(0))
66 {}
67
68 template<typename DT_, typename ImgP_, typename IT_>
69 void prepare(const std::vector<IT_>& cells, const std::vector<IT_>& cell_offsets, const std::vector<ImgP_>& points,
70 const std::vector<DT_>& integration_weights, const ImgP_& normal, DT_ face_volume, IT_ surface_ind)
71 {
72 _normal = ImagePointType::convert_new(normal);
73 _face_volume = DataType(face_volume);
74 _cell_helper.resize(cell_offsets.at(surface_ind+1)-cell_offsets.at(surface_ind));
75 std::copy(cells.begin()+long(cell_offsets.at(surface_ind)), cells.begin()+long(cell_offsets.at(surface_ind+1)), _cell_helper.begin());
76 _cur_surface_index = surface_ind;
77 _cell_bb.resize(_cell_helper.size());
78
79 const auto& vtx_set = _trafo.get_mesh().get_vertex_set();
80 const auto& vtx_ind = _trafo.get_mesh().template get_index_set<dim, 0>();
81 for(IndexType k = 0; k < _cell_helper.size(); ++k)
82 {
83 _cell_bb[k] = Intern::get_boundingbox<DataType, dim>(vtx_set, vtx_ind[_cell_helper[k]], DataType(1E-4));
84 }
85
86 _cell_to_domain_point.resize(_cell_helper.size());
87 std::for_each(_cell_to_domain_point.begin(), _cell_to_domain_point.end(), [](auto& ele){ele.clear();});
88 _domain_points.clear();
89 _point_weights.clear();
90
91 std::unordered_map<IndexType, std::size_t> cell_to_index_map;
92 for(std::size_t k = 0; k < _cell_helper.size(); ++k)
93 {
94 cell_to_index_map.insert({_cell_helper[k], k});
95 }
96
97 std::vector<IndexType> pt_helper;
98 for(std::size_t pti = 0; pti < points.size(); ++pti)
99 {
100 pt_helper.clear();
101 for(IndexType k = 0; k < _cell_helper.size(); ++k)
102 {
103 if(Intern::check_point(ImagePointType(points[pti]), _cell_bb[k]))
104 {
105 pt_helper.push_back(_cell_helper[k]);
106 }
107 }
108 if(pt_helper.empty())
109 continue;
110
111 const auto& inv_mapping_data = _inv_mapping.unmap_point(ImagePointType(points[pti]), pt_helper, true);
112
113 // extract the cell -> point information from the inv mapping
114 const DataType point_weight = DataType(integration_weights[pti])/DataType(inv_mapping_data.size());
115 // std::cout << "Cur point " << points[pti] << " with " << inv_mapping_data.size() << " per cell found\n";
116 for(std::size_t l = 0; l < inv_mapping_data.size(); ++l)
117 {
118 _domain_points.push_back(inv_mapping_data.dom_points[l]);
119 _point_weights.push_back(point_weight);
120 _cell_to_domain_point.at(cell_to_index_map[inv_mapping_data.cells[l]]).push_back(_point_weights.size()-1);
121 }
122 }
123 }
124
125
126 void prepare_point(const DomainPointType& dom_point, DataType point_weight)
127 {
128 _cur_dom_point = dom_point;
129 _integration_weight = point_weight;
130 }
131
132
133 // to be implemented by child class
134 void assemble()
135 {
136 }
137
138 void scatter()
139 {
140 }
141
142 void combine()
143 {
144 }
145
146
147 };
148
149 namespace Intern
150 {
151 template<typename AsmTraits_, typename DataType_, int domain_dim_, int image_dim_>
153 {
154 static constexpr int domain_dim = domain_dim_;
155 static constexpr int image_dim = image_dim_;
159
160 struct Empty {};
161 std::conditional_t<*(AsmTraits_::space_config & SpaceTags::value), ValueType, Empty> value;
162 std::conditional_t<*(AsmTraits_::space_config & SpaceTags::grad), GradType, Empty> grad;
163 std::conditional_t<*(AsmTraits_::space_config & SpaceTags::hess), HessType, Empty> hess;
164
165 static constexpr bool has_value = *(AsmTraits_::space_config & SpaceTags::value);
166 static constexpr bool has_grad = *(AsmTraits_::space_config & SpaceTags::grad);
167 static constexpr bool has_hess = *(AsmTraits_::space_config & SpaceTags::hess);
168 };
169
170 template<typename AsmTraits_, typename DataType_, int domain_dim_>
171 struct LocalFEValueHolder<AsmTraits_, DataType_, domain_dim_, 1>
172 {
173 static constexpr int domain_dim = domain_dim_;
174 static constexpr int image_dim = 1;
175 typedef DataType_ ValueType;
178
179 struct Empty {};
180 std::conditional_t<*(AsmTraits_::space_config & SpaceTags::value), ValueType, Empty> value;
181 std::conditional_t<*(AsmTraits_::space_config & SpaceTags::grad), GradType, Empty> grad;
182 std::conditional_t<*(AsmTraits_::space_config & SpaceTags::hess), HessType, Empty> hess;
183
184 static constexpr bool has_value = *(AsmTraits_::space_config & SpaceTags::value);
185 static constexpr bool has_grad = *(AsmTraits_::space_config & SpaceTags::grad);
186 static constexpr bool has_hess = *(AsmTraits_::space_config & SpaceTags::hess);
187 };
188
189 template<typename ValueType_>
191 {
192 static constexpr int dim = 1;
193 };
194
195 template<typename DT_, int n_, int sn_>
196 struct ValueTypeHelper<Tiny::Vector<DT_, n_, sn_>>
197 {
198 static constexpr int dim = n_;
199 };
200 }
201
202 template<typename Derived_, typename AsmTraits_, typename Space_, typename FEVector_>
204 public SurfaceIntegratorTaskBase<AsmTraits_>
205 {
206 public:
208 typedef AsmTraits_ AsmTraits;
209 typedef typename BaseClass::IndexType IndexType;
210 typedef typename BaseClass::DomainPointType DomainPointType;
211 static constexpr int dim = BaseClass::dim;
212 typedef typename AsmTraits_::DataType DataType;
213 typedef typename FEVector_::ValueType ValueType;
214 static constexpr int image_dim = Intern::ValueTypeHelper<ValueType>::dim;
216
217 protected:
218 Derived_& cast()
219 {
220 return static_cast<Derived_&>(*this);
221 }
222
223 const Derived_& cast() const
224 {
225 return static_cast<const Derived_&>(*this);
226 }
227
228 public:
230 const FEVector_& primal_vector;
232 const Space_& space;
234 typename AsmTraits::TrafoEvaluator trafo_eval;
236 typename AsmTraits::SpaceEvaluator space_eval;
238 typename AsmTraits::DofMapping dof_mapping;
240 typename AsmTraits::TrafoEvalData trafo_data;
242 typename AsmTraits::SpaceEvalData space_data;
244 typename AsmTraits::template TLocalVector<ValueType> local_vector;
246 typename FEVector_::GatherAxpy gather_axpy;
249
250 public:
254 explicit FEVectorIntegratorTaskCRTP(const Space_& space_, const FEVector_& primal_vec_) :
255 BaseClass(space_.get_trafo()),
256 primal_vector(primal_vec_),
257 space(space_),
258 trafo_eval(this->_trafo),
262 {
263 }
264
265 protected:
266 void _prepare_cell(IndexType cell)
267 {
268 dof_mapping.prepare(cell);
269 trafo_eval.prepare(cell);
270 space_eval.prepare(trafo_eval);
271 // gather our local vector
272 local_vector.format();
274 }
275
276 void _prepare_point(const DomainPointType& point)
277 {
278 trafo_eval(trafo_data, point);
280 const int num_loc_dofs = this->space_eval.get_num_local_dofs();
281 if constexpr(LocalValueHolder::has_value)
282 {
283 loc_value_holder.value = ValueType(0);
284 for(int i = 0; i < num_loc_dofs; ++i)
285 {
286 Tiny::axpy(loc_value_holder.value, local_vector[i], space_data.phi[i].value);
287 }
288 }
289 if constexpr(LocalValueHolder::has_grad)
290 {
291 loc_value_holder.grad.format();
292 for(int i = 0; i < num_loc_dofs; ++i)
293 {
294 if constexpr(image_dim == 1)
295 Tiny::axpy(loc_value_holder.grad, space_data.phi[i].grad, local_vector[i]);
296 else
297 loc_value_holder.grad.add_outer_product(local_vector[i], space_data.phi[i].grad);
298 }
299 }
300 if constexpr(LocalValueHolder::has_hess)
301 {
302 XABORTM("Hessian not implemented yet");
303 }
304 }
305
306 void _integrate(DataType DOXY(weight), IndexType DOXY(point_idx))
307 {
308 XABORTM("Has to be implmented by derived class");
309 }
310
311 void _assemble_cell(const std::vector<IndexType>& domain_point_idx)
312 {
313 for(auto pti : domain_point_idx)
314 {
315 const auto dom_point = this->_domain_points[pti];
316 this->cast()._prepare_point(dom_point);
317
318 this->cast()._integrate(this->_point_weights[pti], pti);
319 }
320 }
321
322 void _assemble()
323 {
324 for(IndexType k = 0; k < this->_cell_helper.size(); ++k)
325 {
326 const auto& domain_point_idx = this->_cell_to_domain_point.at(k);
327 if(domain_point_idx.empty())
328 continue;
329 // prepare our cell
330 this->cast()._prepare_cell(this->_cell_helper[k]);
331
332 this->cast()._assemble_cell(domain_point_idx);
333 }
334 }
335
336
337 public:
338 void prepare_cell(IndexType cell)
339 {
340 this->cast()._prepare_cell(cell);
341 }
342
343 void prepare_point(const DomainPointType& point)
344 {
345 this->cast()._prepare_point(point);
346 }
347
348 void assemble()
349 {
350 this->cast()._assemble();
351 }
352
353 };
354
355 template<typename FaceVector_, typename Space_, typename FEVector_>
357 {
358 public:
359 typedef Space_ SpaceType;
360 typedef FEVector_ FEVector;
361 typedef FaceVector_ FaceVector;
363 typedef typename FEVector_::DataType DataType;
365 typedef typename FEVector_::ValueType ValueType;
366
367 static constexpr TrafoTags trafo_config_ = TrafoTags::img_point | TrafoTags::dom_point;
368 static constexpr SpaceTags space_config_ = SpaceTags::value;
369
371 typedef Assembly::AsmTraits1<
372 DataType,
373 Space_,
374 trafo_config_,
375 space_config_
377
378
379
380
381 class Task :
382 public FEVectorIntegratorTaskCRTP<Task, AsmTraits, Space_, FEVector_>
383 {
384 public:
386 typedef typename BaseClass::IndexType IndexType;
387 typedef typename BaseClass::DomainPointType DomainPointType;
388 static constexpr int dim = BaseClass::dim;
390 FaceVector_& vector;
391 DataType face_val;
394
395 public:
400 BaseClass(job.space, job.primal_vec),
401 vector(job.face_vec),
402 face_val(DataType(0)),
404 {
405 }
406
407 void _assemble()
408 {
409 face_val = DataType(0);
410
411 BaseClass::_assemble();
412
413 this->vector(this->_cur_surface_index, face_val*scatter_alpha);
414 }
415
416 void _integrate(DataType weight, [[maybe_unused]] IndexType point_idx)
417 {
418 auto normal_val = Tiny::dot(this->loc_value_holder.value, this->_normal);
419 face_val += normal_val * weight;
420 }
421
422 }; // class Task
423
424 FaceVector_& face_vec;
425 const FEVector_& primal_vec;
426 const Space_& space;
427 DataType scatter_alpha;
428
429 explicit NormalValueSurfaceIntegratorJob(FaceVector_& face_vec_, const FEVector_& primal_vec_, const Space_& space_, DataType scatter_alpha_ = DataType(1)) :
430 face_vec(face_vec_),
431 primal_vec(primal_vec_),
432 space(space_),
433 scatter_alpha(scatter_alpha_)
434 {
435 }
436
437 }; // class NormalValueSurfaceIntegrator
438
439 template<typename FaceVector_, typename Space_, typename FEVector_>
441 {
442 public:
443 typedef Space_ SpaceType;
444 typedef FEVector_ FEVector;
445 typedef FaceVector_ FaceVector;
447 typedef typename FEVector_::DataType DataType;
449 typedef typename FEVector_::ValueType ValueType;
450
451 static constexpr TrafoTags trafo_config_ = TrafoTags::img_point | TrafoTags::dom_point;
452 static constexpr SpaceTags space_config_ = SpaceTags::grad;
453
455 typedef Assembly::AsmTraits1<
456 DataType,
457 Space_,
458 trafo_config_,
459 space_config_
461
462
463
464
465 class Task :
466 public FEVectorIntegratorTaskCRTP<Task, AsmTraits, Space_, FEVector_>
467 {
468 public:
470 typedef typename BaseClass::IndexType IndexType;
471 typedef typename BaseClass::DomainPointType DomainPointType;
472 static constexpr int dim = BaseClass::dim;
474 FaceVector_& vector;
475 DataType face_val;
478
479 public:
484 BaseClass(job.space, job.primal_vec),
485 vector(job.face_vec),
486 face_val(DataType(0)),
488 {
489 }
490
491 void _assemble()
492 {
493 face_val = DataType(0);
494
495 BaseClass::_assemble();
496
497 this->vector(this->_cur_surface_index, face_val*scatter_alpha);
498 }
499
500 void _integrate(DataType weight, [[maybe_unused]] IndexType point_idx)
501 {
502 auto normal_grad = this->loc_value_holder.grad * this->_normal;
503 face_val += Math::sqrt(Tiny::dot(normal_grad, normal_grad)) * weight;
504 }
505
506 }; // class Task
507
508 FaceVector_& face_vec;
509 const FEVector_& primal_vec;
510 const Space_& space;
511 DataType scatter_alpha;
512
513 explicit NormalGradientSurfaceIntegratorJob(FaceVector_& face_vec_, const FEVector_& primal_vec_, const Space_& space_, DataType scatter_alpha_ = DataType(1)) :
514 face_vec(face_vec_),
515 primal_vec(primal_vec_),
516 space(space_),
517 scatter_alpha(scatter_alpha_)
518 {
519 }
520
521 }; // class NormalGradientSurfaceIntegrator
522}
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
FEAT Kernel base header.
Common single-space assembly traits class template.
Definition: asm_traits.hpp:83
AsmTraits::DofMapping dof_mapping
the space dof-mapping
FEVectorIntegratorTaskCRTP(const Space_ &space_, const FEVector_ &primal_vec_)
Constructor.
LocalValueHolder loc_value_holder
local fe point/grad/hess values
AsmTraits::template TLocalVector< ValueType > local_vector
the local vector to be gathered
const FEVector_ & primal_vector
the vector from which to gather the values
FEVector_::GatherAxpy gather_axpy
the gather object
AsmTraits::SpaceEvaluator space_eval
the space evaluator
AsmTraits::SpaceEvalData space_data
the space evaluation data
AsmTraits::TrafoEvaluator trafo_eval
the trafo evaluator
const Space_ & space
the test-/trial-space to be used
AsmTraits::TrafoEvalData trafo_data
the trafo evaluation data
Task(NormalGradientSurfaceIntegratorJob &job)
Constructor.
Assembly::AsmTraits1< DataType, Space_, trafo_config_, space_config_ > AsmTraits
our assembly traits
FEVector_::DataType DataType
the data-type of the vector
FEVector_::ValueType ValueType
the value-type of the vector
FaceVector_ & vector
the vector that is to be assembled
Task(NormalValueSurfaceIntegratorJob &job)
Constructor.
FEVector_::DataType DataType
the data-type of the vector
Assembly::AsmTraits1< DataType, Space_, trafo_config_, space_config_ > AsmTraits
our assembly traits
FEVector_::ValueType ValueType
the value-type of the vector
Tiny Matrix class template.
Tiny Tensor3 class template.
Tiny Vector class template.
Inverse Trafo mapping class template.
InvMapDataType unmap_point(const ImagePointType &img_point, bool ignore_failures=false) const
Unmaps a given image point.
Assembly namespace.
T_ sqrt(T_ x)
Returns the square-root of a value.
Definition: math.hpp:300
CUDA_HOST_DEVICE T_ dot(const T_ &a, const T_ &b)
Computes the dot-product of two scalars.
CUDA_HOST_DEVICE void axpy(T_ &y, const T_ &x, const T_ &alpha)
Performs an AXPY of two scalars.
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
std::uint64_t Index
Index data type.
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