Bembel
SuperSpace.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_SUPERSPACE_HPP_
12 #define BEMBEL_SRC_ANSATZSPACE_SUPERSPACE_HPP_
13 namespace Bembel {
21 template <typename Derived>
22 struct SuperSpace {
23  typedef typename LinearOperatorTraits<Derived>::Scalar Scalar;
25  // constructors
27 
43  SuperSpace(Geometry& geom, int M, int P) { init_SuperSpace(geom, M, P); }
52  SuperSpace(const SuperSpace& other) {
53  mesh_ = other.mesh_;
54  phi = other.phi;
55  phiDx = other.phiDx;
56  phiPhi = other.phiPhi;
57  phiPhiDx = other.phiPhiDx;
58  phiPhiDy = other.phiPhiDy;
59  phiTimesPhi = other.phiTimesPhi;
60  // vPhiScalVPhi = other.vPhiScalVPhi;
61  divPhiTimesDivPhi = other.divPhiTimesDivPhi;
62  polynomial_degree = other.polynomial_degree;
63  polynomial_degree_plus_one_squared =
64  other.polynomial_degree_plus_one_squared;
65  }
75  mesh_ = other.mesh_;
76  phi = other.phi;
77  phiDx = other.phiDx;
78  phiPhi = other.phiPhi;
79  phiPhiDx = other.phiPhiDx;
80  phiPhiDy = other.phiPhiDy;
81  phiTimesPhi = other.phiTimesPhi;
82  // vPhiScalVPhi = other.vPhiScalVPhi;
83  divPhiTimesDivPhi = other.divPhiTimesDivPhi;
84  polynomial_degree = other.polynomial_degree;
85  polynomial_degree_plus_one_squared =
86  other.polynomial_degree_plus_one_squared;
87  }
98  mesh_ = other.mesh_;
99  phi = other.phi;
100  phiDx = other.phiDx;
101  phiPhi = other.phiPhi;
102  phiPhiDx = other.phiPhiDx;
103  phiPhiDy = other.phiPhiDy;
104  phiTimesPhi = other.phiTimesPhi;
105  // vPhiScalVPhi = other.vPhiScalVPhi;
106  divPhiTimesDivPhi = other.divPhiTimesDivPhi;
107  polynomial_degree = other.polynomial_degree;
108  polynomial_degree_plus_one_squared =
109  other.polynomial_degree_plus_one_squared;
110  return *this;
111  }
113  // getters
115  int get_polynomial_degree() const { return polynomial_degree; }
116  int get_polynomial_degree_plus_one_squared() const {
117  return polynomial_degree_plus_one_squared;
118  }
119  int get_refinement_level() const { return mesh_->get_max_level(); }
120  int get_number_of_elements() const { return mesh_->get_number_of_elements(); }
121  int get_number_of_patches() const { return mesh_->get_geometry().size(); }
122  const PatchVector& get_geometry() const { return mesh_->get_geometry(); }
123  const ClusterTree& get_mesh() const { return *mesh_; }
125  // init_SuperSpace
127  void init_SuperSpace(const Geometry& geom, int M, int P) {
128  polynomial_degree = P;
129  polynomial_degree_plus_one_squared =
130  (polynomial_degree + 1) * (polynomial_degree + 1);
131  phi = (Basis::BasisHandler<Scalar>::funPtrPhi(P));
132  phiDx = (Basis::BasisHandler<Scalar>::funPtrPhiDx(P));
133  phiPhi = (Basis::BasisHandler<Scalar>::funPtrPhiPhi(P));
134  phiPhiDx = (Basis::BasisHandler<Scalar>::funPtrPhiPhiDx(P));
135  phiPhiDy = (Basis::BasisHandler<Scalar>::funPtrPhiPhiDy(P));
136  phiTimesPhi = (Basis::BasisHandler<Scalar>::funPtrPhiTimesPhi(P));
137  // vPhiScalVPhi = (Basis::BasisHandler<typename
138  // LinearOperatorTraits<Derived>::Scalar>::funPtrVPhiScalVPhi(P));
139  divPhiTimesDivPhi =
140  (Basis::BasisHandler<Scalar>::funPtrDivPhiTimesDivPhi(P));
141  mesh_ = std::make_shared<ClusterTree>();
142  mesh_->init_ClusterTree(geom, M);
143  mesh_->checkOrientation();
144  return;
145  }
147  // map2surface
149 
160  void map2surface(const ElementTreeNode& e, const Eigen::Vector2d& xi,
161  double w, SurfacePoint* surf_pt) const {
162  Eigen::Vector2d st = e.llc_ + e.get_h() * xi;
163  mesh_->get_geometry()[e.patch_].updateSurfacePoint(surf_pt, st, w, xi);
164  return;
165  }
167  // Methods
169 
174  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>* intval,
176  const Eigen::Vector2d& s, const Eigen::Vector2d& t) const {
177  phiTimesPhi(intval, w, s, t);
178  }
183  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> basisInteraction(
184  const Eigen::Vector2d& s, const Eigen::Vector2d& t) const {
185  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> intval(
186  polynomial_degree_plus_one_squared, polynomial_degree_plus_one_squared);
187  intval.setZero();
188  phiTimesPhi(&intval, 1., s, t);
189  return intval;
190  }
191 
197  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>* intval, Scalar w,
198  const SurfacePoint& p1, const SurfacePoint& p2) const {
199  // surface measures
200  double kappa1 = p1.segment<3>(6).cross(p1.segment<3>(9)).norm();
201  double kappa2 = p2.segment<3>(6).cross(p2.segment<3>(9)).norm();
202  // compute basis functions's surface curl. Each column of s_curl is a basis
203  // function's surface curl at point s.
204  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> s_curl =
205  (1.0 / kappa1) *
206  (-p1.segment<3>(6) * basisDy(p1.segment<2>(0)).transpose() +
207  p1.segment<3>(9) * basisDx(p1.segment<2>(0)).transpose());
208  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> t_curl =
209  (1.0 / kappa2) *
210  (-p2.segment<3>(6) * basisDy(p2.segment<2>(0)).transpose() +
211  p2.segment<3>(9) * basisDx(p2.segment<2>(0)).transpose());
212  // inner product of surface curls of any two basis functions
213  for (int j = 0; j < polynomial_degree_plus_one_squared; ++j)
214  for (int i = 0; i < polynomial_degree_plus_one_squared; ++i)
215  (*intval)(j * polynomial_degree_plus_one_squared + i) +=
216  w * s_curl.col(i).dot(t_curl.col(j));
217  }
218 
224  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>* intval, Scalar w,
225  const SurfacePoint& p1, const SurfacePoint& p2) const {
226  // inner product of surface gradients of any two basis functions equals to
227  // inner product of surface curls of any two basis functions
228  addScaledSurfaceCurlInteraction(intval, w, p1, p2);
229  }
230 
237  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>* intval, Scalar w,
238  const Eigen::Vector2d& s, const Eigen::Vector2d& t,
239  const Eigen::Vector3d x_f_dx, const Eigen::Vector3d x_f_dy,
240  const Eigen::Vector3d y_f_dx, const Eigen::Vector3d y_f_dy) const {
241  auto basis_interaction = basisInteraction(s, t);
242  intval->block(0, 0, polynomial_degree_plus_one_squared,
243  polynomial_degree_plus_one_squared) +=
244  w * x_f_dx.dot(y_f_dx) * basis_interaction;
245  intval->block(0, polynomial_degree_plus_one_squared,
246  polynomial_degree_plus_one_squared,
247  polynomial_degree_plus_one_squared) +=
248  w * x_f_dx.dot(y_f_dy) * basis_interaction;
249  intval->block(polynomial_degree_plus_one_squared, 0,
250  polynomial_degree_plus_one_squared,
251  polynomial_degree_plus_one_squared) +=
252  w * x_f_dy.dot(y_f_dx) * basis_interaction;
253  intval->block(polynomial_degree_plus_one_squared,
254  polynomial_degree_plus_one_squared,
255  polynomial_degree_plus_one_squared,
256  polynomial_degree_plus_one_squared) +=
257  w * x_f_dy.dot(y_f_dy) * basis_interaction;
258  }
263  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> vectorBasisInteraction(
264  const Eigen::Vector2d& s, const Eigen::Vector2d& t,
265  const Eigen::Vector3d x_f_dx, const Eigen::Vector3d x_f_dy,
266  const Eigen::Vector3d y_f_dx, const Eigen::Vector3d y_f_dy) const {
267  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> intval(
268  2 * polynomial_degree_plus_one_squared,
269  2 * polynomial_degree_plus_one_squared);
270  intval.setZero();
271  addScaledVectorBasisInteraction(&intval, 1., s, t, x_f_dx, x_f_dy, y_f_dx,
272  y_f_dy);
273  return intval;
274  }
280  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>* intval, Scalar w,
281  const Eigen::Vector2d& s, const Eigen::Vector2d& t) const {
282  divPhiTimesDivPhi(intval, w, s, t);
283  }
288  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>
289  vectorBasisDivergenceInteraction(const Eigen::Vector2d& s,
290  const Eigen::Vector2d& t) const {
291  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> intval(
292  2 * polynomial_degree_plus_one_squared,
293  2 * polynomial_degree_plus_one_squared);
294  intval.setZero();
295  divPhiTimesDivPhi(&intval, 1., s, t);
296  return intval;
297  }
302  void addScaledBasis(Eigen::Matrix<Scalar, Eigen::Dynamic, 1>* intval,
303  Scalar w, const Eigen::Vector2d& s) const {
304  phiPhi(intval, w, s);
305  }
309  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> basis(
310  const Eigen::Vector2d& s) const {
311  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> intval(
312  polynomial_degree_plus_one_squared);
313  intval.setZero();
314  phiPhi(&intval, 1., s);
315  return intval;
316  }
321  void addScaledBasisDx(Eigen::Matrix<Scalar, Eigen::Dynamic, 1>* intval,
323  const Eigen::Vector2d& s) const {
324  phiPhiDx(intval, w, s);
325  }
330  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> basisDx(
331  const Eigen::Vector2d& s) const {
332  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> intval(
333  polynomial_degree_plus_one_squared);
334  intval.setZero();
335  phiPhiDx(&intval, 1., s);
336  return intval;
337  }
342  void addScaledBasisDy(Eigen::Matrix<Scalar, Eigen::Dynamic, 1>* intval,
344  const Eigen::Vector2d& s) const {
345  phiPhiDy(intval, w, s);
346  }
351  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> basisDy(
352  const Eigen::Vector2d& s) const {
353  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> intval(
354  polynomial_degree_plus_one_squared);
355  intval.setZero();
356  phiPhiDy(&intval, 1., s);
357  return intval;
358  }
363  void addScaledBasis1D(Eigen::Matrix<Scalar, Eigen::Dynamic, 1>* intval,
364  Scalar w, double s) const {
365  phi(intval, w, s);
366  }
370  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> basis1D(double s) const {
371  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> intval(polynomial_degree + 1);
372  intval.setZero();
373  phi(&intval, 1., s);
374  return intval;
375  }
380  void addScaledBasis1DDx(Eigen::Matrix<Scalar, Eigen::Dynamic, 1>* intval,
381  Scalar w, double s) const {
382  phiDx(intval, w, s);
383  }
388  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> basis1DDx(double s) const {
389  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> intval(polynomial_degree + 1);
390  intval.setZero();
391  phiDx(&intval, 1., s);
392  return intval;
393  }
395  // member variables
397  private:
398  std::shared_ptr<ClusterTree> mesh_;
399  Basis::funptr_phi<Scalar> phi;
400  Basis::funptr_phidx<Scalar> phiDx;
401  Basis::funptr_phiphi<Scalar> phiPhi;
402  Basis::funptr_phiphidx<Scalar> phiPhiDx;
403  Basis::funptr_phiphidy<Scalar> phiPhiDy;
404  Basis::funptr_phitimesphi<Scalar> phiTimesPhi;
405  // Basis::funptr_vphiscalvphi<typename LinearOperatorTraits<Derived>::Scalar>
406  // vPhiScalVPhi;
407  Basis::funptr_divphitimesdivphi<Scalar> divPhiTimesDivPhi;
408  int polynomial_degree;
409  int polynomial_degree_plus_one_squared;
410 }; // namespace Bembel
411 } // namespace Bembel
412 #endif // BEMBEL_SRC_ANSATZSPACE_SUPERSPACE_HPP_
The ElementTreeNode corresponds to an element in the element tree.
Eigen::Vector2d llc_
midpoint of the element
int patch_
level of the element
double get_h() const
getter
this class wraps a GeometryVector and provides some basic functionality, like reading Geometry files
Definition: Geometry.hpp:20
std::vector< Bembel::Patch > PatchVector
typedef for PatchVector
Definition: PatchVector.hpp:24
Eigen::Matrix< double, 12, 1 > SurfacePoint
typedef of SurfacePoint
Routines for the evalutation of pointwise errors.
Definition: AnsatzSpace.hpp:14
struct containing specifications on the linear operator has to be specialized or derived for any part...
The superspace manages local polynomial bases on each element of the mesh and provides an interface t...
Definition: SuperSpace.hpp:22
void addScaledBasisDy(Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > *intval, typename LinearOperatorTraits< Derived >::Scalar w, const Eigen::Vector2d &s) const
Evaluate derivatives in y direction of local shape functions on the unit square at coordinate s,...
Definition: SuperSpace.hpp:342
void addScaledSurfaceCurlInteraction(Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > *intval, Scalar w, const SurfacePoint &p1, const SurfacePoint &p2) const
Compute all products of surface curls of local shape functions on the unit square at coordinates s,...
Definition: SuperSpace.hpp:196
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > basisDx(const Eigen::Vector2d &s) const
Evaluate derivatives in x direction of local shape functions on the unit square at coordinate s.
Definition: SuperSpace.hpp:330
void addScaledBasisDx(Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > *intval, typename LinearOperatorTraits< Derived >::Scalar w, const Eigen::Vector2d &s) const
Evaluate derivatives in x direction of local shape functions on the unit square at coordinate s,...
Definition: SuperSpace.hpp:321
SuperSpace(const SuperSpace &other)
Copy constructor for the SuperSpace class.
Definition: SuperSpace.hpp:52
SuperSpace(Geometry &geom, int M, int P)
Parameterized constructor for the SuperSpace class.
Definition: SuperSpace.hpp:43
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > basis1D(double s) const
Evaluate local shape functions on the unit interval at coordinate s.
Definition: SuperSpace.hpp:370
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > basisInteraction(const Eigen::Vector2d &s, const Eigen::Vector2d &t) const
Compute all products of local shape functions on the unit square at coordinates s,...
Definition: SuperSpace.hpp:183
void addScaledVectorBasisDivergenceInteraction(Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > *intval, Scalar w, const Eigen::Vector2d &s, const Eigen::Vector2d &t) const
Compute all products of divergences of local shape functions on the unit square at coordinates s,...
Definition: SuperSpace.hpp:279
void addScaledBasis(Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > *intval, Scalar w, const Eigen::Vector2d &s) const
Evaluate local shape functions on the unit square at coordinate s, scale by w and add to intval.
Definition: SuperSpace.hpp:302
void addScaledBasis1DDx(Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > *intval, Scalar w, double s) const
Evaluate derivatives of local shape functions on the unit interval at coordinate s,...
Definition: SuperSpace.hpp:380
void addScaledBasisInteraction(Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > *intval, typename LinearOperatorTraits< Derived >::Scalar w, const Eigen::Vector2d &s, const Eigen::Vector2d &t) const
Compute all products of local shape functions on the unit square at coordinates s,...
Definition: SuperSpace.hpp:173
SuperSpace()
Default constructor for the SuperSpace class.
Definition: SuperSpace.hpp:32
SuperSpace(SuperSpace &&other)
Move constructor for the SuperSpace class.
Definition: SuperSpace.hpp:74
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > vectorBasisInteraction(const Eigen::Vector2d &s, const Eigen::Vector2d &t, const Eigen::Vector3d x_f_dx, const Eigen::Vector3d x_f_dy, const Eigen::Vector3d y_f_dx, const Eigen::Vector3d y_f_dy) const
Compute all scalar products of vector valued local shape functions on the surface points with referen...
Definition: SuperSpace.hpp:263
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > vectorBasisDivergenceInteraction(const Eigen::Vector2d &s, const Eigen::Vector2d &t) const
Compute all products of divergences of local shape functions on the unit square at coordinates s,...
Definition: SuperSpace.hpp:289
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > basis(const Eigen::Vector2d &s) const
Evaluate local shape functions on the unit square at coordinate s.
Definition: SuperSpace.hpp:309
void addScaledVectorBasisInteraction(Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > *intval, Scalar w, const Eigen::Vector2d &s, const Eigen::Vector2d &t, const Eigen::Vector3d x_f_dx, const Eigen::Vector3d x_f_dy, const Eigen::Vector3d y_f_dx, const Eigen::Vector3d y_f_dy) const
Compute all scalar products of vector valued local shape functions on the surface points with referen...
Definition: SuperSpace.hpp:236
void addScaledSurfaceGradientInteraction(Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > *intval, Scalar w, const SurfacePoint &p1, const SurfacePoint &p2) const
Compute all products of surface gradients of local shape functions on the unit square at coordinates ...
Definition: SuperSpace.hpp:223
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > basisDy(const Eigen::Vector2d &s) const
Evaluate derivatives in y direction of local shape functions on the unit square at coordinate s.
Definition: SuperSpace.hpp:351
SuperSpace & operator=(SuperSpace other)
Assignment operator for the SuperSpace class.
Definition: SuperSpace.hpp:97
void addScaledBasis1D(Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > *intval, Scalar w, double s) const
Evaluate local shape functions on the unit interval at coordinate s, scale by w and add to intval.
Definition: SuperSpace.hpp:363
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > basis1DDx(double s) const
Evaluate derivatives of local shape functions on the unit interval at coordinate s.
Definition: SuperSpace.hpp:388
void map2surface(const ElementTreeNode &e, const Eigen::Vector2d &xi, double w, SurfacePoint *surf_pt) const
Evaluation of a point in the element and its Jacobian matrix.
Definition: SuperSpace.hpp:160