Bembel
IncidenceMatrix.hpp
1 // This file is part of Bembel, the higher order C++ boundary element library.
2 //
3 // Copyright (C) 2024 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_AUGMENTEDEFIE_INCIDENCEMATRIX_HPP_
12 #define BEMBEL_SRC_AUGMENTEDEFIE_INCIDENCEMATRIX_HPP_
13 
14 namespace Bembel {
18 template <typename Derived_vec, typename Derived>
20  typedef Eigen::SparseMatrix<typename LinearOperatorTraits<Derived>::Scalar>
21  MatrixType;
22  typedef Eigen::Matrix<typename LinearOperatorTraits<Derived>::Scalar,
23  Eigen::Dynamic, 1>
24  VectorType;
25 
26  public:
28  // constructors
30  IncidenceMatrix() {}
31  IncidenceMatrix(const AnsatzSpace<Derived_vec> &ansatz_space_vec,
32  const AnsatzSpace<Derived> &ansatz_space) {
33  static_assert(
34  std::is_same<
37  "Scalar Types need to be equal");
38  init_IncidenceMatrix(ansatz_space_vec, ansatz_space);
39  }
41  // init_IncidenceMatrix
43  void init_IncidenceMatrix(const AnsatzSpace<Derived_vec> &ansatz_space_vec,
44  const AnsatzSpace<Derived> &ansatz_space) {
45  ansatz_space_vec_ = ansatz_space_vec;
46  ansatz_space_ = ansatz_space;
47  return;
48  }
50  // compute
52  void compute() {
53  const SuperSpace<Derived_vec> &super_space_vec =
54  ansatz_space_vec_.get_superspace();
55  const SuperSpace<Derived> &super_space = ansatz_space_.get_superspace();
56  const auto &element_tree = super_space.get_mesh().get_element_tree();
57 
58  // Quadrature
59  GaussSquare<20> GS;
60  Cubature Q = GS[19];
61  const auto &number_of_elements = element_tree.get_number_of_elements();
62  const auto polynomial_degree_plus_one_squared_vec =
63  super_space_vec.get_polynomial_degree_plus_one_squared();
64  const auto polynomial_degree_plus_one_squared =
65  super_space.get_polynomial_degree_plus_one_squared();
66 
67  // Triplets
68  typedef Eigen::Triplet<typename LinearOperatorTraits<Derived>::Scalar> T;
69  std::vector<T> tripletList;
70  tripletList.reserve(2 * polynomial_degree_plus_one_squared_vec *
71  polynomial_degree_plus_one_squared *
72  number_of_elements);
73 
74  // Iterate over elements
75  for (auto element = element_tree.cpbegin(); element != element_tree.cpend();
76  ++element) {
77  Eigen::Matrix<typename LinearOperatorTraits<Derived>::Scalar,
78  Eigen::Dynamic, Eigen::Dynamic>
79  intval(2 * polynomial_degree_plus_one_squared_vec,
80  polynomial_degree_plus_one_squared);
81  intval.setZero();
82  // Iterate over quadrature points
83  for (auto i = 0; i < Q.w_.size(); ++i) {
84  SurfacePoint qp;
85  super_space.map2surface(*element, Q.xi_.col(i), Q.w_(i), &qp);
86  evaluateIntegrand(super_space_vec, super_space, qp, &intval);
87  }
88  // Transform local element matrices to triplets
89  for (auto jj = 0; jj < polynomial_degree_plus_one_squared; ++jj)
90  for (auto i = 0; i < 2; ++i)
91  for (auto ii = 0; ii < polynomial_degree_plus_one_squared_vec; ++ii)
92  tripletList.push_back(
93  T(polynomial_degree_plus_one_squared_vec *
94  (i * number_of_elements + element->id_) +
95  ii,
96  polynomial_degree_plus_one_squared * element->id_ + jj,
97  intval(i * polynomial_degree_plus_one_squared_vec + ii, jj)));
98  }
99  incidence_matrix_.resize(
100  2 * polynomial_degree_plus_one_squared_vec * number_of_elements,
101  polynomial_degree_plus_one_squared * number_of_elements);
102  incidence_matrix_.setFromTriplets(tripletList.begin(), tripletList.end());
103  auto projector_vec = ansatz_space_vec_.get_transformation_matrix();
104  auto projector = ansatz_space_.get_transformation_matrix();
105  incidence_matrix_ =
106  projector_vec.transpose() * (incidence_matrix_ * projector);
107  return;
108  }
110  // getter
112  const MatrixType &get_incidence_matrix() const { return incidence_matrix_; }
114  // private member variables
116  private:
117  template <class T_vec, class T>
118  void evaluateIntegrand(
119  const T_vec &super_space_vec, const T &super_space, const SurfacePoint &p,
120  Eigen::Matrix<typename LinearOperatorTraits<Derived>::Scalar,
121  Eigen::Dynamic, Eigen::Dynamic> *intval) {
122  const auto polynomial_degree_plus_one_squared_vec =
123  super_space_vec.get_polynomial_degree_plus_one_squared();
124 
125  // const auto polynomial_degree_plus_one_squared =
126  // super_space.get_polynomial_degree_plus_one_squared();
127  VectorType intval_scal =
128  super_space.basis(p.segment<2>(0)).array().real();
129  VectorType intval_dx = super_space_vec.basisDx(p.segment<2>(0));
130  VectorType intval_dy = super_space_vec.basisDy(p.segment<2>(0));
131  VectorType intval_div(2 * polynomial_degree_plus_one_squared_vec);
132  intval_div << intval_dx, intval_dy;
133 
134  // get basic information
135  const unsigned int elements_per_direction =
136  (1 << super_space.get_refinement_level());
137  const double h = 1. / ((double)(elements_per_direction));
138 
139  // compute surface measures from tangential derivatives
140  double x_kappa = p.segment<3>(6).cross(p.segment<3>(9)).norm();
141  double w = p(2) / h;
142  intval[0] += w * intval_div * intval_scal.transpose();
143  }
144  MatrixType incidence_matrix_;
145  AnsatzSpace<Derived_vec> ansatz_space_vec_;
146  AnsatzSpace<Derived> ansatz_space_;
147 };
148 
149 } // namespace Bembel
150 #endif // BEMBEL_SRC_AUGMENTEDEFIE_INCIDENCEMATRIX_HPP_
const Eigen::SparseMatrix< double > & get_transformation_matrix() const
Retrieves the transformation matrix associated with this AnsatzSpace.
const SuperSpace< Derived > & get_superspace() const
Retrieves the reference to the SuperSpace associated with this AnsatzSpace.
ElementTree & get_element_tree()
getter
Definition: ClusterTree.hpp:95
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 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