FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
discrete_projector.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/assembly/asm_traits.hpp>
10
11#include <vector>
12
13namespace FEAT
14{
15 namespace Assembly
16 {
26 {
27 public:
40 template<
41 typename VectorOut_,
42 typename VectorIn_,
43 typename Space_>
44 static void project(
45 VectorOut_& vector,
46 const VectorIn_& coeff,
47 const Space_& space)
48 {
49 typedef Space_ SpaceType;
50 typedef typename SpaceType::TrafoType TrafoType;
51 typedef typename TrafoType::MeshType MeshType;
52 typedef typename MeshType::ShapeType ShapeType;
53
54 static constexpr int shape_dim = ShapeType::dimension;
55 static constexpr int nverts = Shape::FaceTraits<ShapeType, 0>::count;
56
57 // define assembly traits
59 typedef typename AsmTraits::DataType DataType;
60
61 // get our value type
62 typedef typename VectorOut_::ValueType ValueType;
63
64 // fetch the trafo and the mesh
65 const TrafoType& trafo(space.get_trafo());
66 const MeshType& mesh(space.get_mesh());
67
68 // fetch the index set
69 typedef typename MeshType::template IndexSet<shape_dim, 0>::Type IndexSetType;
70 const IndexSetType& vert_idx(mesh.template get_index_set<shape_dim, 0>());
71
72 // fetch the cell count
73 const Index num_verts(mesh.get_num_entities(0));
74
75 // create a clear output vector
76 vector = VectorOut_(num_verts, DataType(0));
77
78 // allocate an auxiliary count array
79 std::vector<int> aux(num_verts, 0);
80
81 // create a trafo evaluator
82 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
83
84 // create a space evaluator and evaluation data
85 typename AsmTraits::SpaceEvaluator space_eval(space);
86
87 // create a dof-mapping
88 typename AsmTraits::DofMapping dof_mapping(space);
89
90 // create trafo evaluation data
91 typename AsmTraits::TrafoEvalData trafo_data;
92
93 // create space evaluation data
94 typename AsmTraits::SpaceEvalData space_data;
95
96 // create local vector data
97 typename AsmTraits::template TLocalVector<ValueType> loc_vec;
98
99 // create a vector gather-axpy
100 typename VectorIn_::GatherAxpy gather_axpy(coeff);
101
102 // loop over all cells of the mesh
103 for(Index cell(0); cell < trafo_eval.get_num_cells(); ++cell)
104 {
105 // format local matrix
106 loc_vec.format();
107
108 // initialize dof-mapping
109 dof_mapping.prepare(cell);
110
111 // fetch local vector
112 gather_axpy(loc_vec, dof_mapping);
113
114 // finish dof-mapping
115 dof_mapping.finish();
116
117 // prepare trafo evaluator
118 trafo_eval.prepare(cell);
119
120 // prepare space evaluator
121 space_eval.prepare(trafo_eval);
122
123 // fetch number of local dofs
124 int num_loc_dofs = space_eval.get_num_local_dofs();
125
126 // loop over all vertices of the cell
127 for(int k(0); k < nverts; ++k)
128 {
129 typename AsmTraits::DomainPointType dom_point;
130
131 // initialize domain point
132 for(int i(0); i < shape_dim; ++i)
133 {
134 dom_point[i] = Shape::ReferenceCell<ShapeType>::template vertex<DataType>(k, i);
135 }
136
137 // compute trafo data
138 trafo_eval(trafo_data, dom_point);
139
140 // compute basis function data
141 space_eval(space_data, trafo_data);
142
143 // compute function value
144 ValueType value(DataType(0));
145
146 // basis function loop
147 for(int i(0); i < num_loc_dofs; ++i)
148 {
149 // evaluate fe function
150 Tiny::axpy(value, loc_vec[i], space_data.phi[i].value);
151
152 // continue with next basis function
153 }
154
155 // fetch the vertex index
156 Index vi = vert_idx(cell, k);
157
158 // add vertex contribution
159 vector(vi, vector(vi) + value);
160
161 // update contribution counter
162 ++aux[vi];
163
164 // continue with next vertex
165 }
166
167 // finish evaluators
168 space_eval.finish();
169 trafo_eval.finish();
170
171 // continue with next cell
172 }
173
174 // finally, scale the output vector
175 for(Index i(0); i < num_verts; ++i)
176 {
177 if(aux[i] > 1)
178 {
179 vector(i, (DataType(1) / DataType(aux[i])) * vector(i));
180 }
181 }
182 }
183
198 template<
199 typename VectorOut_,
200 typename VectorIn_,
201 typename Space_>
202 static void project_gradient(
203 VectorOut_& vector,
204 const VectorIn_& coeff,
205 const Space_& space)
206 {
207 typedef Space_ SpaceType;
208 typedef typename SpaceType::TrafoType TrafoType;
209 typedef typename TrafoType::MeshType MeshType;
210 typedef typename MeshType::ShapeType ShapeType;
211
212 static constexpr int shape_dim = ShapeType::dimension;
213 static constexpr int nverts = Shape::FaceTraits<ShapeType, 0>::count;
214
215 // define assembly traits
217 typedef typename AsmTraits::DataType DataType;
218
219 // get our value type
220 typedef typename VectorOut_::ValueType ValueOutType;
221 typedef typename VectorIn_::ValueType ValueInType;
222
223 // fetch the trafo and the mesh
224 const TrafoType& trafo(space.get_trafo());
225 const MeshType& mesh(space.get_mesh());
226
227 // fetch the index set
228 typedef typename MeshType::template IndexSet<shape_dim, 0>::Type IndexSetType;
229 const IndexSetType& vert_idx(mesh.template get_index_set<shape_dim, 0>());
230
231 // fetch the cell count
232 const Index num_verts(mesh.get_num_entities(0));
233
234 // create a clear output vector
235 vector = VectorOut_(num_verts, DataType(0));
236
237 // allocate an auxiliary count array
238 std::vector<int> aux(num_verts, 0);
239
240 // create a trafo evaluator
241 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
242
243 // create a space evaluator and evaluation data
244 typename AsmTraits::SpaceEvaluator space_eval(space);
245
246 // create a dof-mapping
247 typename AsmTraits::DofMapping dof_mapping(space);
248
249 // create trafo evaluation data
250 typename AsmTraits::TrafoEvalData trafo_data;
251
252 // create space evaluation data
253 typename AsmTraits::SpaceEvalData space_data;
254
255 // create local vector data
256 typename AsmTraits::template TLocalVector<ValueInType> loc_vec;
257
258 // create a vector gather-axpy
259 typename VectorIn_::GatherAxpy gather_axpy(coeff);
260
261 // loop over all cells of the mesh
262 for(Index cell(0); cell < trafo_eval.get_num_cells(); ++cell)
263 {
264 // format local matrix
265 loc_vec.format();
266
267 // initialize dof-mapping
268 dof_mapping.prepare(cell);
269
270 // fetch local vector
271 gather_axpy(loc_vec, dof_mapping);
272
273 // finish dof-mapping
274 dof_mapping.finish();
275
276 // prepare trafo evaluator
277 trafo_eval.prepare(cell);
278
279 // prepare space evaluator
280 space_eval.prepare(trafo_eval);
281
282 // fetch number of local dofs
283 int num_loc_dofs = space_eval.get_num_local_dofs();
284
285 // loop over all vertices of the cell
286 for(int k(0); k < nverts; ++k)
287 {
288 typename AsmTraits::DomainPointType dom_point;
289
290 // initialize domain point
291 for(int i(0); i < shape_dim; ++i)
292 {
293 dom_point[i] = Shape::ReferenceCell<ShapeType>::template vertex<DataType>(k, i);
294 }
295
296 // compute trafo data
297 trafo_eval(trafo_data, dom_point);
298
299 // compute basis function data
300 space_eval(space_data, trafo_data);
301
302 // compute function value
303 ValueOutType value(DataType(0));
304
305 // basis function loop
306 for(int i(0); i < num_loc_dofs; ++i)
307 {
308 // evaluate fe function
309 Tiny::axpy(value, space_data.phi[i].grad, loc_vec[i]);
310
311 // continue with next basis function
312 }
313
314 // fetch the vertex index
315 Index vi = vert_idx(cell, k);
316
317 // add vertex contribution
318 vector(vi, vector(vi) + value);
319
320 // update contribution counter
321 ++aux[vi];
322
323 // continue with next vertex
324 }
325
326 // finish evaluators
327 space_eval.finish();
328 trafo_eval.finish();
329
330 // continue with next cell
331 }
332
333 ValueOutType* vv = vector.elements();
334
335 // finally, scale the output vector
336 for(Index i(0); i < num_verts; ++i)
337 {
338 if(aux[i] > 1)
339 {
340 vv[i] *= (DataType(1) / DataType(aux[i]));
341 }
342 }
343 }
344 }; // class DiscreteVertexProjector<...>
345
355 {
356 public:
369 template<
370 typename VectorOut_,
371 typename VectorIn_,
372 typename Space_>
373 static void project(
374 VectorOut_& vector,
375 const VectorIn_& coeff,
376 const Space_& space)
377 {
378 Cubature::DynamicFactory cubature_factory("barycentre");
379 project(vector, coeff, space, cubature_factory);
380 }
381
397 template<
398 typename VectorOut_,
399 typename VectorIn_,
400 typename Space_>
401 static void project(
402 VectorOut_& vector,
403 const VectorIn_& coeff,
404 const Space_& space,
405 const String& cubature_name)
406 {
407 Cubature::DynamicFactory cubature_factory(cubature_name);
408 project(vector, coeff, space, cubature_factory);
409 }
410
426 template<typename VectorOut_, typename VectorIn_, typename Space_>
427 static void project(
428 VectorOut_& vector,
429 const VectorIn_& coeff,
430 const Space_& space,
431 const Cubature::DynamicFactory& cubature_factory)
432 {
433 typedef Space_ SpaceType;
434 typedef typename SpaceType::TrafoType TrafoType;
435 typedef typename TrafoType::MeshType MeshType;
436 typedef typename MeshType::ShapeType ShapeType;
437
438 // define assembly traits
440 typedef typename AsmTraits::DataType DataType;
441
442 // get our value type
443 typedef typename VectorOut_::ValueType ValueType;
444
445 // define the cubature rule
446 typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
447
448 // fetch the trafo and the mesh
449 const TrafoType& trafo(space.get_trafo());
450 const MeshType& mesh(space.get_mesh());
451
452 // fetch the cell count
453 const Index num_cells(mesh.get_num_entities(ShapeType::dimension));
454
455 // create a clear output vector
456 vector = VectorOut_(num_cells, DataType(0));
457
458 // create a trafo evaluator
459 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
460
461 // create a space evaluator and evaluation data
462 typename AsmTraits::SpaceEvaluator space_eval(space);
463
464 // create a dof-mapping
465 typename AsmTraits::DofMapping dof_mapping(space);
466
467 // create trafo evaluation data
468 typename AsmTraits::TrafoEvalData trafo_data;
469
470 // create space evaluation data
471 typename AsmTraits::SpaceEvalData space_data;
472
473 // create local vector data
474 typename AsmTraits::template TLocalVector<ValueType> loc_vec;
475
476 // create a vector gather-axpy
477 typename VectorIn_::GatherAxpy gather_axpy(coeff);
478
479 // loop over all cells of the mesh
480 for(Index cell(0); cell < trafo_eval.get_num_cells(); ++cell)
481 {
482 // format local matrix
483 loc_vec.format();
484
485 // initialize dof-mapping
486 dof_mapping.prepare(cell);
487
488 // fetch local vector
489 gather_axpy(loc_vec, dof_mapping);
490
491 // finish dof-mapping
492 dof_mapping.finish();
493
494 // prepare trafo evaluator
495 trafo_eval.prepare(cell);
496
497 // prepare space evaluator
498 space_eval.prepare(trafo_eval);
499
500 // fetch number of local dofs
501 int num_loc_dofs = space_eval.get_num_local_dofs();
502
503 // compute function value
504 DataType value(DataType(0));
505 DataType area(DataType(0));
506
507 // loop over all quadrature points and integrate
508 for(int k(0); k < cubature_rule.get_num_points(); ++k)
509 {
510 // compute trafo data
511 trafo_eval(trafo_data, cubature_rule.get_point(k));
512
513 // compute basis function data
514 space_eval(space_data, trafo_data);
515
516 ValueType val(DataType(0));
517
518 // basis function loop
519 for(int i(0); i < num_loc_dofs; ++i)
520 {
521 // evaluate functor and integrate
522 Tiny::axpy(val, loc_vec[i], space_data.phi[i].value);
523 // continue with next basis function
524 }
525
526 // compute weight
527 DataType weight(trafo_data.jac_det * cubature_rule.get_weight(k));
528
529 // update cell area
530 area += weight;
531
532 // update cell value
533 value += weight * val;
534
535 // continue with next vertex
536 }
537
538 // set contribution
539 vector(cell, (DataType(1) / area) * value);
540
541 // finish evaluators
542 space_eval.finish();
543 trafo_eval.finish();
544
545 // continue with next cell
546 }
547 }
548
565 template<
566 typename VectorOut_,
567 typename VectorIn_,
568 typename Space_>
569 static void project_gradient(
570 VectorOut_& vector,
571 const VectorIn_& coeff,
572 const Space_& space,
573 const String& cubature_name)
574 {
575 Cubature::DynamicFactory cubature_factory(cubature_name);
576 project_gradient(vector, coeff, space, cubature_factory);
577 }
578
594 template<typename VectorOut_, typename VectorIn_, typename Space_>
595 static void project_gradient(
596 VectorOut_& vector,
597 const VectorIn_& coeff,
598 const Space_& space,
599 const Cubature::DynamicFactory& cubature_factory)
600 {
601 typedef Space_ SpaceType;
602 typedef typename SpaceType::TrafoType TrafoType;
603 typedef typename TrafoType::MeshType MeshType;
604 typedef typename MeshType::ShapeType ShapeType;
605
606 // define assembly traits
608 typedef typename AsmTraits::DataType DataType;
609
610 // get our value type
611 typedef typename VectorIn_::ValueType ValueInType;
612 typedef typename VectorOut_::ValueType ValueOutType;
613
614 // define the cubature rule
615 typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
616
617 // fetch the trafo and the mesh
618 const TrafoType& trafo(space.get_trafo());
619 const MeshType& mesh(space.get_mesh());
620
621 // fetch the cell count
622 const Index num_cells(mesh.get_num_entities(ShapeType::dimension));
623
624 // create a clear output vector
625 vector = VectorOut_(num_cells, DataType(0));
626
627 // create a trafo evaluator
628 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
629
630 // create a space evaluator and evaluation data
631 typename AsmTraits::SpaceEvaluator space_eval(space);
632
633 // create a dof-mapping
634 typename AsmTraits::DofMapping dof_mapping(space);
635
636 // create trafo evaluation data
637 typename AsmTraits::TrafoEvalData trafo_data;
638
639 // create space evaluation data
640 typename AsmTraits::SpaceEvalData space_data;
641
642 // create local vector data
643 typename AsmTraits::template TLocalVector<ValueInType> loc_vec;
644
645 // create a vector gather-axpy
646 typename VectorIn_::GatherAxpy gather_axpy(coeff);
647
648 // loop over all cells of the mesh
649 for(Index cell(0); cell < trafo_eval.get_num_cells(); ++cell)
650 {
651 // format local matrix
652 loc_vec.format();
653
654 // initialize dof-mapping
655 dof_mapping.prepare(cell);
656
657 // fetch local vector
658 gather_axpy(loc_vec, dof_mapping);
659
660 // finish dof-mapping
661 dof_mapping.finish();
662
663 // prepare trafo evaluator
664 trafo_eval.prepare(cell);
665
666 // prepare space evaluator
667 space_eval.prepare(trafo_eval);
668
669 // fetch number of local dofs
670 int num_loc_dofs = space_eval.get_num_local_dofs();
671
672 // compute function value
673 ValueOutType value(DataType(0));
674 DataType area(DataType(0));
675
676 // loop over all quadrature points and integrate
677 for(int k(0); k < cubature_rule.get_num_points(); ++k)
678 {
679 // compute trafo data
680 trafo_eval(trafo_data, cubature_rule.get_point(k));
681
682 // compute basis function data
683 space_eval(space_data, trafo_data);
684
685 ValueOutType val(DataType(0));
686
687 // basis function loop
688 for(int i(0); i < num_loc_dofs; ++i)
689 {
690 // evaluate functor and integrate
691 Tiny::axpy(val, space_data.phi[i].grad, loc_vec[i]);
692 // continue with next basis function
693 }
694
695 // compute weight
696 DataType weight(trafo_data.jac_det * cubature_rule.get_weight(k));
697
698 // update cell area
699 area += weight;
700
701 // update cell value
702 Tiny::axpy(value, val, weight);
703
704 // continue with next vertex
705 }
706
707 // set contribution
708 vector(cell, (DataType(1) / area) * value);
709
710 // finish evaluators
711 space_eval.finish();
712 trafo_eval.finish();
713
714 // continue with next cell
715 }
716 }
717
730 template<typename VectorOut_, typename VectorIn_, typename Space_>
731 static void project_refined(VectorOut_& vector, const VectorIn_& coeff, const Space_& space)
732 {
733 typedef Space_ SpaceType;
734 typedef typename SpaceType::TrafoType TrafoType;
735 typedef typename TrafoType::MeshType MeshType;
736 typedef typename MeshType::ShapeType ShapeType;
737
738 // define assembly traits
740 typedef typename AsmTraits::DataType DataType;
741
742 // get our value type
743 typedef typename VectorOut_::ValueType ValueType;
744
745 // define the cubature rule
746 Cubature::DynamicFactory cubature_factory("refine:midpoint");
747 typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
748
749 // fetch the trafo and the mesh
750 const TrafoType& trafo(space.get_trafo());
751 const MeshType& mesh(space.get_mesh());
752
753 // fetch the cell count
754 const Index num_cells(mesh.get_num_entities(ShapeType::dimension));
755 const int num_points = cubature_rule.get_num_points();
756
757 // create a clear output vector
758 vector = VectorOut_(num_cells * Index(num_points), DataType(0));
759
760 // create a trafo evaluator
761 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
762
763 // create a space evaluator and evaluation data
764 typename AsmTraits::SpaceEvaluator space_eval(space);
765
766 // create a dof-mapping
767 typename AsmTraits::DofMapping dof_mapping(space);
768
769 // create trafo evaluation data
770 typename AsmTraits::TrafoEvalData trafo_data;
771
772 // create space evaluation data
773 typename AsmTraits::SpaceEvalData space_data;
774
775 // create local vector data
776 typename AsmTraits::template TLocalVector<ValueType> loc_vec;
777
778 // create a vector gather-axpy
779 typename VectorIn_::GatherAxpy gather_axpy(coeff);
780
781 // loop over all cells of the mesh
782 for(Index cell(0); cell < trafo_eval.get_num_cells(); ++cell)
783 {
784 // format local matrix
785 loc_vec.format();
786
787 // initialize dof-mapping
788 dof_mapping.prepare(cell);
789
790 // fetch local vector
791 gather_axpy(loc_vec, dof_mapping);
792
793 // finish dof-mapping
794 dof_mapping.finish();
795
796 // prepare trafo evaluator
797 trafo_eval.prepare(cell);
798
799 // prepare space evaluator
800 space_eval.prepare(trafo_eval);
801
802 // fetch number of local dofs
803 int num_loc_dofs = space_eval.get_num_local_dofs();
804
805 // loop over all quadrature points and integrate
806 for(int k(0); k < cubature_rule.get_num_points(); ++k)
807 {
808 // compute trafo data
809 trafo_eval(trafo_data, cubature_rule.get_point(k));
810
811 // compute basis function data
812 space_eval(space_data, trafo_data);
813
814 ValueType value(DataType(0));
815
816 // basis function loop
817 for(int i(0); i < num_loc_dofs; ++i)
818 {
819 // evaluate functor and integrate
820 Tiny::axpy(value, loc_vec[i], space_data.phi[i].value);
821 // continue with next basis function
822 }
823
824 // save value
825 vector(cell*Index(num_points) + Index(k), value);
826
827 // continue with next vertex
828 }
829
830 // finish evaluators
831 space_eval.finish();
832 trafo_eval.finish();
833
834 // continue with next cell
835 }
836 }
837 }; // class DiscreteCellProjector<...>
838 } // namespace Assembly
839} // namespace FEAT
Common single-space assembly traits class template.
Definition: asm_traits.hpp:83
Discrete cell projector class.
static void project(VectorOut_ &vector, const VectorIn_ &coeff, const Space_ &space, const String &cubature_name)
Projects a discrete function into the cells.
static void project(VectorOut_ &vector, const VectorIn_ &coeff, const Space_ &space)
Projects a discrete function into the cells using the barycentre cubature rule.
static void project(VectorOut_ &vector, const VectorIn_ &coeff, const Space_ &space, const Cubature::DynamicFactory &cubature_factory)
Projects a discrete function into the cells.
static void project_refined(VectorOut_ &vector, const VectorIn_ &coeff, const Space_ &space)
Projects a discrete function into the cells of a once refined mesh.
static void project_gradient(VectorOut_ &vector, const VectorIn_ &coeff, const Space_ &space, const Cubature::DynamicFactory &cubature_factory)
Projects the gradient of a scalar discrete function into the cells.
static void project_gradient(VectorOut_ &vector, const VectorIn_ &coeff, const Space_ &space, const String &cubature_name)
Projects the gradient of a scalar discrete function into the cells.
Discrete vertex projector class.
static void project_gradient(VectorOut_ &vector, const VectorIn_ &coeff, const Space_ &space)
Projects the gradient of a scalar discrete function into the vertices.
static void project(VectorOut_ &vector, const VectorIn_ &coeff, const Space_ &space)
Projects a discrete function into the vertices.
String class implementation.
Definition: string.hpp:46
CUDA_HOST_DEVICE void axpy(T_ &y, const T_ &x, const T_ &alpha)
Performs an AXPY of two scalars.
FEAT namespace.
Definition: adjactor.hpp:12
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
@ dom_point
specifies whether the trafo should supply domain point coordinates
Face traits tag struct template.
Definition: shape.hpp:106
Reference cell traits structure.
Definition: shape.hpp:230