Bembel
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 
14 namespace Bembel {
20 template <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<
81  getFunctionSpaceOutputDimension<LinearOperatorTraits<Derived>::Form>(), 1>
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 =
86  elements_per_direction * elements_per_direction;
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 =
93  x_idx + elements_per_direction * y_idx + patch * elements_per_patch;
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 
101  SurfacePoint sp;
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<
108  getFunctionSpaceOutputDimension<LinearOperatorTraits<Derived>::Form>(), 1>
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 =
136  getFunctionSpaceVectorDimension<LinearOperatorTraits<Derived>::Form>();
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,
151  getFunctionSpaceVectorDimension<LinearOperatorTraits<Derived>::Form>()>
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.
Definition: AnsatzSpace.hpp:25
This class organizes an element structure on a Geometry object and handles refinement.
Definition: ElementTree.hpp:32
ElementTreeNode::const_iterator cpbegin() const
Returns an iterator to the beginning of the sequence represented by the leafs as ElementTreeNodes of ...
The ElementTreeNode corresponds to an element in the element tree.
int id_
radius of the element
Eigen::Vector2d mapToReferenceElement(const Eigen::Vector2d &in) const
Maps a point in the reference domain of a patch to the reference element of this element.
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.
Definition: AnsatzSpace.hpp:14
constexpr int getFunctionSpaceVectorDimension()
struct containing specifications on the linear operator has to be specialized or derived for any part...