FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
discrete_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#include <kernel/assembly/asm_traits.hpp>
9#include <kernel/trafo/inverse_mapping.hpp>
10#include <kernel/lafem/dense_vector.hpp>
11#include <kernel/lafem/dense_vector_blocked.hpp>
12#include <kernel/util/dist.hpp>
13
14#include <vector>
15
16namespace FEAT
17{
18 namespace Assembly
19 {
31 template<typename DT_, int dim_>
33 {
34 public:
36 static constexpr int dim = dim_;
38 typedef DT_ DataType;
41
43 std::vector<ValueType> values;
44
48 bool empty() const
49 {
50 return values.empty();
51 }
52
64 {
65 if(values.empty())
66 return DT_(0);
67
68 // compute and return mean value
69 DT_ r = DT_(0);
70 for(const auto& v : values)
71 r += v;
72 return r / DT_(values.size());
73 }
74
85 {
86 // In a distributed domain, we need to compute the mean value
87 // over all patches, as the evaluation point may intersect
88 // with several patches. Therefore, we also need to sum up
89 // the number of values in addition to the values themselves,
90 // so that we can compute the mean value over all patches.
91 DT_ val[2] =
92 {
93 DT_(values.size()),
94 DT_(0)
95 };
96
97 // add all values from this patch
98 for(const auto& v : values)
99 val[1] += v;
100
101 // sum up over all patches
102 comm.allreduce(val, val, std::size_t(2), Dist::op_sum);
103
104 // compute global mean value
105 return (val[0] > DT_(0)) ? (val[1] / val[0]) : DT_(0);
106 }
107 }; // class ScalarDiscreteEvalData
108
120 template<typename DT_, int dim_>
122 {
123 public:
125 static constexpr int dim = dim_;
127 typedef DT_ DataType;
130
132 std::vector<ValueType> values;
133
137 bool empty() const
138 {
139 return values.empty();
140 }
141
153 {
154 ValueType r;
155 r.format();
156 if(values.empty())
157 return r;
158
159 for(const auto& v : values)
160 r += v;
161 r *= (DT_(1) / DT_(values.size()));
162
163 return r;
164 }
165
176 {
177 ValueType r;
178 r.format();
179
180 DT_ val[1+dim_] =
181 {
182 DT_(values.size()),
183 };
184
185 for(int i(0); i < dim_; ++i)
186 val[i+1] = DT_(0);
187
188 for(const auto& v : values)
189 {
190 for(int i(0); i < dim_; ++i)
191 val[i+1] += v[i];
192 }
193
194 comm.allreduce(val, val, std::size_t(dim_+1), Dist::op_sum);
195
196 for(int i(0); i < dim_; ++i)
197 r[i] = val[i+1];
198
199 if(val[0] > DT_(0))
200 r *= (DT_(1) / val[0]);
201
202 return r;
203 }
204 }; // class VectorDiscreteEvalData
205
217 template<typename DT_, int dim_i_, int dim_j_>
219 {
220 public:
222 static constexpr int dim_i = dim_i_;
223 static constexpr int dim_j = dim_j_;
225 typedef DT_ DataType;
228
230 std::vector<ValueType> values;
231
235 bool empty() const
236 {
237 return values.empty();
238 }
239
251 {
252 ValueType r;
253 r.format();
254 if(values.empty())
255 return r;
256
257 for(const auto& v : values)
258 r += v;
259 r *= (DT_(1) / DT_(values.size()));
260
261 return r;
262 }
263
274 {
275 ValueType r;
276 r.format();
277
278 DT_ val[1+dim_i_*dim_j_] =
279 {
280 DT_(values.size()),
281 };
282
283 for(int i(0); i < dim_i_; ++i)
284 {
285 for(int j(0); j < dim_j_; ++j)
286 {
287 val[i*dim_j_ + j + 1] = DT_(0);
288 }
289 }
290
291 for(const auto& v : values)
292 {
293 for(int i(0); i < dim_i_; ++i)
294 {
295 for(int j(0); j < dim_j_; ++j)
296 {
297 val[i*dim_j_ + j + 1] += v[i][j];
298 }
299 }
300 }
301
302 comm.allreduce(val, val, std::size_t(dim_i_*dim_j_+1), Dist::op_sum);
303
304 for(int i(0); i < dim_i_; ++i)
305 {
306 for(int j(0); j < dim_j_; ++j)
307 {
308 r[i][j] = val[i*dim_j_ + j + 1];
309 }
310 }
311
312 if(val[0] > DT_(0))
313 r *= (DT_(1) / val[0]);
314
315 return r;
316 }
317 }; // class MatrixDiscreteEvalData
318
355 {
356 public:
378 template<typename DT_, typename DTP_, typename IT_, int dim_, int s_, typename Space_>
380 const Tiny::Vector<DTP_, dim_, s_>& point,
381 const LAFEM::DenseVector<DT_, IT_>& vector,
382 const Space_& space)
383 {
384 // create inverse trafo mapping
385 Trafo::InverseMapping<typename Space_::TrafoType, DT_> inv_mapping(space.get_trafo());
386
387 // unmap point
388 auto inv_map_data = inv_mapping.unmap_point(point);
389
390 // evaluate FE function
391 return eval_fe_function(inv_map_data, vector, space);
392 }
393
410 template<typename DT_, typename DTP_, typename IT_, int dim_, typename Space_>
413 const LAFEM::DenseVector<DT_, IT_>& vector,
414 const Space_& space)
415 {
416 // vector type
417 typedef LAFEM::DenseVector<DT_, IT_> VectorType;
418 // space type
419 typedef Space_ SpaceType;
420 // assembly traits
422 // data type
423 typedef typename AsmTraits::DataType DataType;
424
425 // fetch the trafo
426 const typename AsmTraits::TrafoType& trafo = space.get_trafo();
427
428 // create a trafo evaluator
429 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
430
431 // create a space evaluator and evaluation data
432 typename AsmTraits::SpaceEvaluator space_eval(space);
433
434 // create a dof-mapping
435 typename AsmTraits::DofMapping dof_mapping(space);
436
437 // create trafo evaluation data
438 typename AsmTraits::TrafoEvalData trafo_data;
439
440 // create space evaluation data
441 typename AsmTraits::SpaceEvalData space_data;
442
443 // create local vector data
444 typename AsmTraits::template TLocalVector<DT_> local_vector;
445
446 // create matrix scatter-axpy
447 typename VectorType::GatherAxpy gather_axpy(vector);
448
449 // create evaluation data
451
452 // loop over all cells of the mesh
453 for(std::size_t i(0); i < inv_map_data.size(); ++i)
454 {
455 const Index& cell = inv_map_data.cells.at(i);
456 const auto& dom_point = inv_map_data.dom_points.at(i);
457
458 // format local vector
459 local_vector.format();
460
461 // initialize dof-mapping
462 dof_mapping.prepare(cell);
463
464 // gather local vector data
465 gather_axpy(local_vector, dof_mapping);
466
467 // finish dof-mapping
468 dof_mapping.finish();
469
470 // prepare trafo evaluator
471 trafo_eval.prepare(cell);
472
473 // prepare space evaluator
474 space_eval.prepare(trafo_eval);
475
476 // compute trafo data
477 trafo_eval(trafo_data, dom_point);
478
479 // compute basis function data
480 space_eval(space_data, trafo_data);
481
482 // fetch number of local dofs
483 const int num_loc_dofs = space_eval.get_num_local_dofs();
484
485 // compute function value
486 DataType value = DataType(0);
487 for(int j(0); j < num_loc_dofs; ++j)
488 value += local_vector[j] * space_data.phi[j].value;
489
490 // finally, add this result to the eval data
491 eval_data.values.push_back(value);
492
493 // finish evaluators
494 space_eval.finish();
495 trafo_eval.finish();
496
497 // continue with next cell
498 }
499
500 // return evaluation data
501 return eval_data;
502 }
503
525 template<typename DT_, typename DTP_, typename IT_, int dim_, int s_, typename Space_>
527 const Tiny::Vector<DTP_, dim_, s_>& point,
529 const Space_& space)
530 {
531 // create inverse trafo mapping
532 Trafo::InverseMapping<typename Space_::TrafoType, DT_> inv_mapping(space.get_trafo());
533
534 // unmap point
535 auto inv_map_data = inv_mapping.unmap_point(point);
536
537 // evaluate FE function
538 return eval_fe_function(inv_map_data, vector, space);
539 }
540
557 template<typename DT_, typename DTP_, typename IT_, int dim_, typename Space_>
561 const Space_& space)
562 {
563 // vector type
565 // space type
566 typedef Space_ SpaceType;
567 // assembly traits
569 // data type
570 typedef typename AsmTraits::DataType DataType;
571
572 // fetch the trafo
573 const typename AsmTraits::TrafoType& trafo = space.get_trafo();
574
575 // create a trafo evaluator
576 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
577
578 // create a space evaluator and evaluation data
579 typename AsmTraits::SpaceEvaluator space_eval(space);
580
581 // create a dof-mapping
582 typename AsmTraits::DofMapping dof_mapping(space);
583
584 // create trafo evaluation data
585 typename AsmTraits::TrafoEvalData trafo_data;
586
587 // create space evaluation data
588 typename AsmTraits::SpaceEvalData space_data;
589
590 // get maximum number of local dofs
591 static constexpr int max_local_dofs = AsmTraits::max_local_test_dofs;
592
593 // create local vector data
594 typedef Tiny::Vector<DataType, dim_> ValueType;
595 typedef Tiny::Vector<ValueType, max_local_dofs> LocalVectorType;
596 LocalVectorType local_vector;
597
598 // create matrix scatter-axpy
599 typename VectorType::GatherAxpy gather_axpy(vector);
600
601 // create evaluation data
603
604 ValueType value;
605
606 // loop over all cells of the mesh
607 for(std::size_t i(0); i < inv_map_data.size(); ++i)
608 {
609 const Index& cell = inv_map_data.cells.at(i);
610 const auto& dom_point = inv_map_data.dom_points.at(i);
611
612 // format local vector
613 local_vector.format();
614
615 // initialize dof-mapping
616 dof_mapping.prepare(cell);
617
618 // gather local vector data
619 gather_axpy(local_vector, dof_mapping);
620
621 // finish dof-mapping
622 dof_mapping.finish();
623
624 // prepare trafo evaluator
625 trafo_eval.prepare(cell);
626
627 // prepare space evaluator
628 space_eval.prepare(trafo_eval);
629
630 // compute trafo data
631 trafo_eval(trafo_data, dom_point);
632
633 // compute basis function data
634 space_eval(space_data, trafo_data);
635
636 // fetch number of local dofs
637 const int num_loc_dofs = space_eval.get_num_local_dofs();
638
639 // compute function value
640 value.format();
641 for(int j(0); j < num_loc_dofs; ++j)
642 value.axpy(space_data.phi[j].value, local_vector[j]);
643
644 // finally, add this result to the eval data
645 eval_data.values.push_back(value);
646
647 // finish evaluators
648 space_eval.finish();
649 trafo_eval.finish();
650
651 // continue with next cell
652 }
653
654 // return evaluation data
655 return eval_data;
656 }
657
679 template<typename DT_, typename DTP_, typename IT_, int dim_, int s_, typename Space_>
681 const Tiny::Vector<DTP_, dim_, s_>& point,
682 const LAFEM::DenseVector<DT_, IT_>& vector,
683 const Space_& space)
684 {
685 // create inverse trafo mapping
686 Trafo::InverseMapping<typename Space_::TrafoType, DT_> inv_mapping(space.get_trafo());
687
688 // unmap point
689 auto inv_map_data = inv_mapping.unmap_point(point);
690
691 // evaluate FE function
692 return eval_fe_gradient(inv_map_data, vector, space);
693 }
694
711 template<typename DT_, typename DTP_, typename IT_, int dim_, typename Space_>
714 const LAFEM::DenseVector<DT_, IT_>& vector,
715 const Space_& space)
716 {
717 // vector type
718 typedef LAFEM::DenseVector<DT_, IT_> VectorType;
719 // space type
720 typedef Space_ SpaceType;
721 // assembly traits
723 // data type
724 typedef typename AsmTraits::DataType DataType;
725
726 // fetch the trafo
727 const typename AsmTraits::TrafoType& trafo = space.get_trafo();
728
729 // create a trafo evaluator
730 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
731
732 // create a space evaluator and evaluation data
733 typename AsmTraits::SpaceEvaluator space_eval(space);
734
735 // create a dof-mapping
736 typename AsmTraits::DofMapping dof_mapping(space);
737
738 // create trafo evaluation data
739 typename AsmTraits::TrafoEvalData trafo_data;
740
741 // create space evaluation data
742 typename AsmTraits::SpaceEvalData space_data;
743
744 // get maximum number of local dofs
745 static constexpr int max_local_dofs = AsmTraits::max_local_test_dofs;
746
747 // create local vector data
748 typedef Tiny::Vector<DataType, max_local_dofs> LocalVectorType;
749 LocalVectorType local_vector;
750
751 // create matrix scatter-axpy
752 typename VectorType::GatherAxpy gather_axpy(vector);
753
754 // our local gradient
756 loc_grad.format();
757
758 // create evaluation data
760
761 // loop over all cells of the mesh
762 for(std::size_t i(0); i < inv_map_data.size(); ++i)
763 {
764 const Index& cell = inv_map_data.cells.at(i);
765 const auto& dom_point = inv_map_data.dom_points.at(i);
766
767 // format local vector
768 local_vector.format();
769
770 // initialize dof-mapping
771 dof_mapping.prepare(cell);
772
773 // gather local vector data
774 gather_axpy(local_vector, dof_mapping);
775
776 // finish dof-mapping
777 dof_mapping.finish();
778
779 // prepare trafo evaluator
780 trafo_eval.prepare(cell);
781
782 // prepare space evaluator
783 space_eval.prepare(trafo_eval);
784
785 // compute trafo data
786 trafo_eval(trafo_data, dom_point);
787
788 // compute basis function data
789 space_eval(space_data, trafo_data);
790
791 // fetch number of local dofs
792 const int num_loc_dofs = space_eval.get_num_local_dofs();
793
794 // compute function value
795 loc_grad.format();
796 for(int j(0); j < num_loc_dofs; ++j)
797 {
798 // update gradient
799 Tiny::axpy(loc_grad, space_data.phi[j].grad, local_vector[j]);
800 }
801
802 // finally, add this result to the eval data
803 eval_data.values.push_back(loc_grad);
804
805 // finish evaluators
806 space_eval.finish();
807 trafo_eval.finish();
808
809 // continue with next cell
810 }
811
812 // return evaluation data
813 return eval_data;
814 }
815
837 template<typename DT_, typename DTP_, typename IT_, int dim_, int s_, typename Space_>
839 const Tiny::Vector<DTP_, dim_, s_>& point,
841 const Space_& space)
842 {
843 // create inverse trafo mapping
844 Trafo::InverseMapping<typename Space_::TrafoType, DT_> inv_mapping(space.get_trafo());
845
846 // unmap point
847 auto inv_map_data = inv_mapping.unmap_point(point);
848
849 // evaluate FE function
850 return eval_fe_gradient(inv_map_data, vector, space);
851 }
852
869 template<typename DT_, typename DTP_, typename IT_, int dim_, typename Space_>
873 const Space_& space)
874 {
875 // vector type
877 // space type
878 typedef Space_ SpaceType;
879 // assembly traits
881 // data type
882 typedef typename AsmTraits::DataType DataType;
883
884 // fetch the trafo
885 const typename AsmTraits::TrafoType& trafo = space.get_trafo();
886
887 // create a trafo evaluator
888 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
889
890 // create a space evaluator and evaluation data
891 typename AsmTraits::SpaceEvaluator space_eval(space);
892
893 // create a dof-mapping
894 typename AsmTraits::DofMapping dof_mapping(space);
895
896 // create trafo evaluation data
897 typename AsmTraits::TrafoEvalData trafo_data;
898
899 // create space evaluation data
900 typename AsmTraits::SpaceEvalData space_data;
901
902 // get maximum number of local dofs
903 static constexpr int max_local_dofs = AsmTraits::max_local_test_dofs;
904
905 // create local vector data
906 typedef Tiny::Vector<DataType, dim_> ValueType;
907 typedef Tiny::Vector<ValueType, max_local_dofs> LocalVectorType;
908 LocalVectorType local_vector;
909
910 // create matrix scatter-axpy
911 typename VectorType::GatherAxpy gather_axpy(vector);
912
913 // our local gradient
915 loc_grad.format();
916
917 // create evaluation data
919
920 // loop over all cells of the mesh
921 for(std::size_t i(0); i < inv_map_data.size(); ++i)
922 {
923 const Index& cell = inv_map_data.cells.at(i);
924 const auto& dom_point = inv_map_data.dom_points.at(i);
925
926 // format local vector
927 local_vector.format();
928
929 // initialize dof-mapping
930 dof_mapping.prepare(cell);
931
932 // gather local vector data
933 gather_axpy(local_vector, dof_mapping);
934
935 // finish dof-mapping
936 dof_mapping.finish();
937
938 // prepare trafo evaluator
939 trafo_eval.prepare(cell);
940
941 // prepare space evaluator
942 space_eval.prepare(trafo_eval);
943
944 // compute trafo data
945 trafo_eval(trafo_data, dom_point);
946
947 // compute basis function data
948 space_eval(space_data, trafo_data);
949
950 // fetch number of local dofs
951 const int num_loc_dofs = space_eval.get_num_local_dofs();
952
953 // compute function value
954 loc_grad.format();
955 for(int j(0); j < num_loc_dofs; ++j)
956 {
957 // update gradient
958 loc_grad.add_outer_product(local_vector[j], space_data.phi[j].grad);
959 }
960
961 // finally, add this result to the eval data
962 eval_data.values.push_back(loc_grad);
963
964 // finish evaluators
965 space_eval.finish();
966 trafo_eval.finish();
967
968 // continue with next cell
969 }
970
971 // return evaluation data
972 return eval_data;
973 }
974 }; // class DiscreteEvaluator<...>
975 } // namespace Assembly
976} // namespace FEAT
Common single-space assembly traits class template.
Definition: asm_traits.hpp:83
Discrete function evaluator.
static VectorDiscreteEvalData< DT_, dim_ > eval_fe_gradient(const Tiny::Vector< DTP_, dim_, s_ > &point, const LAFEM::DenseVector< DT_, IT_ > &vector, const Space_ &space)
Evaluates the gradient of a scalar finite-element function in a given point.
static VectorDiscreteEvalData< DT_, dim_ > eval_fe_function(const Tiny::Vector< DTP_, dim_, s_ > &point, const LAFEM::DenseVectorBlocked< DT_, IT_, dim_ > &vector, const Space_ &space)
Evaluates a vector-valued finite-element function in a given point.
static MatrixDiscreteEvalData< DT_, dim_, dim_ > eval_fe_gradient(const Trafo::InverseMappingData< DTP_, dim_, dim_ > &inv_map_data, const LAFEM::DenseVectorBlocked< DT_, IT_, dim_ > &vector, const Space_ &space)
Evaluates the gradient of a vector-valued finite-element function in a given unmapped point.
static ScalarDiscreteEvalData< DT_, dim_ > eval_fe_function(const Trafo::InverseMappingData< DTP_, dim_, dim_ > &inv_map_data, const LAFEM::DenseVector< DT_, IT_ > &vector, const Space_ &space)
Evaluates a scalar finite-element function in a given unmapped point.
static ScalarDiscreteEvalData< DT_, dim_ > eval_fe_function(const Tiny::Vector< DTP_, dim_, s_ > &point, const LAFEM::DenseVector< DT_, IT_ > &vector, const Space_ &space)
Evaluates a scalar finite-element function in a given point.
static MatrixDiscreteEvalData< DT_, dim_, dim_ > eval_fe_gradient(const Tiny::Vector< DTP_, dim_, s_ > &point, const LAFEM::DenseVectorBlocked< DT_, IT_, dim_ > &vector, const Space_ &space)
Evaluates the gradient of a vector-valued finite-element function in a given point.
static VectorDiscreteEvalData< DT_, dim_ > eval_fe_gradient(const Trafo::InverseMappingData< DTP_, dim_, dim_ > &inv_map_data, const LAFEM::DenseVector< DT_, IT_ > &vector, const Space_ &space)
Evaluates the gradient of a scalar finite-element function in a given unmapped point.
static VectorDiscreteEvalData< DT_, dim_ > eval_fe_function(const Trafo::InverseMappingData< DTP_, dim_, dim_ > &inv_map_data, const LAFEM::DenseVectorBlocked< DT_, IT_, dim_ > &vector, const Space_ &space)
Evaluates a vector-valued finite-element function in a given unmapped point.
Discrete evaluation data for matrix-valued functions.
ValueType mean_value_dist(const Dist::Comm &comm) const
Computes the mean function value on a distributed domain.
std::vector< ValueType > values
the vector of values
Tiny::Matrix< DT_, dim_i_, dim_j_ > ValueType
the value type
static constexpr int dim_i
the image dimension
ValueType mean_value() const
Computes the mean function value.
bool empty() const
Checks whether the evaluation data is empty.
Discrete evaluation data for scalar functions.
bool empty() const
Checks whether the evaluation data is empty.
ValueType mean_value_dist(const Dist::Comm &comm) const
Computes the mean function value on a distributed domain.
ValueType mean_value() const
Computes the mean function value.
std::vector< ValueType > values
the vector of values
static constexpr int dim
the image dimension
Discrete evaluation data for vector-valued functions.
static constexpr int dim
the image dimension
Tiny::Vector< DT_, dim_ > ValueType
the value type
std::vector< ValueType > values
the vector of values
bool empty() const
Checks whether the evaluation data is empty.
ValueType mean_value() const
Computes the mean function value.
ValueType mean_value_dist(const Dist::Comm &comm) const
Computes the mean function value on a distributed domain.
Communicator class.
Definition: dist.hpp:1349
void allreduce(const void *sendbuf, void *recvbuf, std::size_t count, const Datatype &datatype, const Operation &op) const
Blocking All-Reduce.
Definition: dist.cpp:655
Blocked Dense data vector class template.
Dense data vector class template.
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & add_outer_product(const Vector< T_, m_, snx_ > &x, const Vector< T_, n_, sny_ > &y, const DataType alpha=DataType(1))
Adds the outer product of two vectors onto the matrix.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the matrix.
Tiny Vector class template.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the vector.
Data structure for InverseMapping evaluations.
std::vector< Index > cells
the indices of the cells that intersect with the image point
std::vector< DomainPointType > dom_points
the domain points on each cell that map onto the image point
Inverse Trafo mapping class template.
InvMapDataType unmap_point(const ImagePointType &img_point, bool ignore_failures=false) const
Unmaps a given image point.
const Operation op_sum(MPI_SUM)
Operation wrapper for MPI_SUM.
Definition: dist.hpp:271
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