Bembel
 
Loading...
Searching...
No Matches
FunctionEvaluator.hpp
1// This file is part of Bembel, the higher order C++ boundary element library.
2//
3// Copyright (C) 2022 see <http://www.bembel.eu>
4//
5// It was written as part of a cooperation of J. Doelz, H. Harbrecht, S. Kurz,
6// M. Multerer, S. Schoeps, and F. Wolf at Technische Universitaet Darmstadt,
7// Universitaet Basel, and Universita della Svizzera italiana, Lugano. This
8// source code is subject to the GNU General Public License version 3 and
9// provided WITHOUT ANY WARRANTY, see <http://www.bembel.eu> for further
10// information.
11#ifndef BEMBEL_SRC_ANSATZSPACE_FUNCTIONEVALUATOR_HPP_
12#define BEMBEL_SRC_ANSATZSPACE_FUNCTIONEVALUATOR_HPP_
13
14namespace Bembel {
20template <typename Derived>
22 public:
24 // constructors
27 FunctionEvaluator(const FunctionEvaluator &other) = default;
28 FunctionEvaluator(FunctionEvaluator &&other) = default;
29 FunctionEvaluator &operator=(FunctionEvaluator other) {
30 ansatz_space_ = other.ansatz_space_;
31 fun_ = other.fun_;
32 polynomial_degree_plus_one_squared_ =
33 other.polynomial_degree_plus_one_squared_;
34 return *this;
35 }
36 explicit FunctionEvaluator(const AnsatzSpace<Derived> &ansatz_space) {
37 init_FunctionEvaluator(ansatz_space);
38 return;
39 }
41 const AnsatzSpace<Derived> &ansatz_space,
42 const Eigen::Matrix<typename LinearOperatorTraits<Derived>::Scalar,
43 Eigen::Dynamic, 1> &fun) {
44 init_FunctionEvaluator(ansatz_space, fun);
45 return;
46 }
48 // init_Ansatzspace
50 void init_FunctionEvaluator(const AnsatzSpace<Derived> &ansatz_space) {
51 ansatz_space_ = ansatz_space;
52 auto polynomial_degree = ansatz_space_.get_polynomial_degree();
53 polynomial_degree_plus_one_squared_ =
54 (polynomial_degree + 1) * (polynomial_degree + 1);
55 reordering_vector_ = ansatz_space_.get_superspace()
56 .get_mesh()
57 .get_element_tree()
58 .computeReorderingVector();
59 return;
60 }
61 void init_FunctionEvaluator(
62 const AnsatzSpace<Derived> &ansatz_space,
63 const Eigen::Matrix<typename LinearOperatorTraits<Derived>::Scalar,
64 Eigen::Dynamic, 1> &fun) {
65 ansatz_space_ = ansatz_space;
66 set_function(fun);
67 auto polynomial_degree = ansatz_space_.get_polynomial_degree();
68 polynomial_degree_plus_one_squared_ =
69 (polynomial_degree + 1) * (polynomial_degree + 1);
70 reordering_vector_ = ansatz_space_.get_superspace()
71 .get_mesh()
72 .get_element_tree()
73 .computeReorderingVector();
74 return;
75 }
77 // evaluators
79 Eigen::Matrix<
82 evaluateOnPatch(int patch, const Eigen::Vector2d &ref_point) const {
83 const int elements_per_direction =
84 (1 << ansatz_space_.get_refinement_level());
85 const int elements_per_patch =
87 const double h = 1. / ((double)(elements_per_direction));
88 const int x_idx_ = std::floor(ref_point(0) / h);
89 const int y_idx_ = std::floor(ref_point(1) / h);
90 const int x_idx = std::min(std::max(x_idx_, 0), elements_per_direction - 1);
91 const int y_idx = std::min(std::max(y_idx_, 0), elements_per_direction - 1);
92 const int tp_idx =
94 const int et_idx = reordering_vector_[tp_idx];
95 const ElementTree &et =
96 ansatz_space_.get_superspace().get_mesh().get_element_tree();
97 auto it = et.cpbegin();
98 std::advance(it, et_idx);
99 const ElementTreeNode &element = *it;
100
102 ansatz_space_.get_superspace().get_geometry()[patch].updateSurfacePoint(
103 &sp, ref_point, 1, element.mapToReferenceElement(ref_point));
104 return evaluate(element, sp);
105 }
106 Eigen::Matrix<
109 evaluate(const ElementTreeNode &element, const SurfacePoint &p) const {
110 return eval_.eval(
111 ansatz_space_.get_superspace(), polynomial_degree_plus_one_squared_,
112 element, p,
113 fun_.block(polynomial_degree_plus_one_squared_ * element.id_, 0,
114 polynomial_degree_plus_one_squared_,
117 }
118 typename LinearOperatorTraits<Derived>::Scalar evaluateDiv(
119 const ElementTreeNode &element, const SurfacePoint &p) const {
120 return eval_.evalDiv(
121 ansatz_space_.get_superspace(), polynomial_degree_plus_one_squared_,
122 element, p,
123 fun_.block(polynomial_degree_plus_one_squared_ * element.id_, 0,
124 polynomial_degree_plus_one_squared_,
127 }
129 // setters
131 void set_function(
132 Eigen::Matrix<typename LinearOperatorTraits<Derived>::Scalar,
133 Eigen::Dynamic, 1>
134 fun) {
135 const auto vec_dim =
137 auto longfun = (ansatz_space_.get_transformation_matrix() * fun).eval();
138 fun_ =
139 Eigen::Map<Eigen::Matrix<typename LinearOperatorTraits<Derived>::Scalar,
140 Eigen::Dynamic, vec_dim>>(
141 longfun.data(), longfun.rows() / vec_dim, vec_dim);
142 }
144 // private member variables
146 private:
147 std::vector<int> reordering_vector_;
148 AnsatzSpace<Derived> ansatz_space_;
149 Eigen::Matrix<
150 typename LinearOperatorTraits<Derived>::Scalar, Eigen::Dynamic,
152 fun_;
153 int polynomial_degree_plus_one_squared_;
156 eval_;
157};
158
159} // namespace Bembel
160#endif // BEMBEL_SRC_ANSATZSPACE_FUNCTIONEVALUATOR_HPP_
The AnsatzSpace is the class that handles the assembly of the discrete basis.
This class organizes an element structure on a Geometry object and handles refinement.
The ElementTreeNode corresponds to an element in the element tree.
The FunctionEvaluator provides means to evaluate coefficient vectors as functions on the geometry.
Eigen::Matrix< double, 12, 1 > SurfacePoint
typedef of SurfacePoint
Routines for the evalutation of pointwise errors.
constexpr int getFunctionSpaceOutputDimension()
constexpr int getFunctionSpaceVectorDimension()
struct containing specifications on the linear operator has to be specialized or derived for any part...