11 #ifndef BEMBEL_SRC_H2MATRIX_H2MATRIX_HPP_
12 #define BEMBEL_SRC_H2MATRIX_H2MATRIX_HPP_
28 template <
typename ScalarT>
32 template <
typename ScalarT>
34 typedef ScalarT Scalar;
35 typedef int StorageIndex;
37 typedef MatrixXpr XprKind;
39 RowsAtCompileTime = Dynamic,
40 ColsAtCompileTime = Dynamic,
41 MaxRowsAtCompileTime = Dynamic,
42 MaxColsAtCompileTime = Dynamic,
48 template <
typename ScalarT>
50 enum { value =
false };
52 template <
typename ScalarT>
53 struct is_ref_compatible<const
H2Matrix<ScalarT>>
54 : is_ref_compatible<H2Matrix<ScalarT>> {};
59 template <
typename ScalarT>
67 typedef typename NumTraits<ScalarT>::Real RealScalar;
68 typedef Index StorageIndex;
70 ColsAtCompileTime = Dynamic,
71 MaxColsAtCompileTime = Dynamic,
76 Index rows()
const {
return transformation_matrix_.cols(); }
77 Index cols()
const {
return transformation_matrix_.cols(); }
79 template <
typename Rhs>
80 Product<H2Matrix, Rhs, AliasFreeProduct> operator*(
81 const MatrixBase<Rhs>& x)
const {
82 return Product<H2Matrix, Rhs, AliasFreeProduct>(*
this, x.derived());
93 template <
typename Derived>
96 int number_of_points = 9) {
107 block_cluster_tree_.resize(vector_dimension, vector_dimension);
110 for (
int i = 0; i < vector_dimension; ++i)
111 for (
int j = 0; j < vector_dimension; ++j)
112 block_cluster_tree_(i, j) =
115 auto parameters = block_cluster_tree_(0, 0).get_parameters();
117 int cluster_level = parameters.max_level_ - parameters.min_cluster_level_;
118 if (cluster_level < 0) cluster_level = 0;
119 int cluster_refinement = parameters.min_cluster_level_;
120 if (cluster_refinement > parameters.max_level_)
121 cluster_refinement = parameters.max_level_;
124 fmm_moment_matrix_ = Bembel::H2Multipole::
125 Moment2D<Bembel::H2Multipole::ChebychevRoots, Derived>::compute2DMoment(
129 Eigen::VectorXd interpolation_points1D =
131 Eigen::MatrixXd interpolation_points2D =
135 int polynomial_degree_plus_one_squared =
136 (polynomial_degree + 1) * (polynomial_degree + 1);
139 auto ffield_deg = linOp.get_FarfieldQuadratureDegree(polynomial_degree);
140 std::vector<ElementSurfacePoints> ffield_qnodes =
142 const int NumberOfFMMComponents =
150 typename std::vector<Bembel::BlockClusterTree<Scalar>*>::iterator>
152 leafs.resize(vector_dimension * vector_dimension);
153 for (
int i = 0; i < vector_dimension; ++i)
154 for (
int j = 0; j < vector_dimension; ++j)
155 leafs[i * vector_dimension + j] =
156 block_cluster_tree_(j, i).lbegin();
158 for (; leafs[0] != block_cluster_tree_(0, 0).lend();) {
159 #pragma omp task firstprivate(leafs)
161 switch ((*(leafs[0]))->get_cc()) {
163 case Bembel::BlockClusterAdmissibility::Dense: {
165 (*(leafs[0]))->get_cluster1();
167 (*(leafs[0]))->get_cluster2();
169 std::distance(cluster2->
begin(), cluster2->
end()) *
170 polynomial_degree_plus_one_squared;
172 Eigen::Matrix<ScalarT, Eigen::Dynamic, Eigen::Dynamic>>
174 for (
int i = 0; i < vector_dimension * vector_dimension; ++i)
176 Eigen::Matrix<ScalarT, Eigen::Dynamic, Eigen::Dynamic>(
177 block_size, block_size));
179 unsigned int cl1index = 0;
180 unsigned int cl2index = 0;
181 for (
const auto& element1 : *cluster1) {
183 for (
const auto& element2 : *cluster2) {
184 Eigen::Matrix<ScalarT, Eigen::Dynamic, Eigen::Dynamic>
185 intval(vector_dimension *
186 polynomial_degree_plus_one_squared,
188 polynomial_degree_plus_one_squared);
191 linOp, super_space, element1, element2, GS,
192 ffield_qnodes[element1.id_],
193 ffield_qnodes[element2.id_], &intval);
195 for (
int i = 0; i < vector_dimension; ++i)
196 for (
int j = 0; j < vector_dimension; ++j)
197 F[i * vector_dimension + j].block(
198 polynomial_degree_plus_one_squared * cl1index,
199 polynomial_degree_plus_one_squared * cl2index,
200 polynomial_degree_plus_one_squared,
201 polynomial_degree_plus_one_squared) =
202 intval.block(j * polynomial_degree_plus_one_squared,
203 i * polynomial_degree_plus_one_squared,
204 polynomial_degree_plus_one_squared,
205 polynomial_degree_plus_one_squared);
210 for (
int i = 0; i < vector_dimension * vector_dimension; ++i)
211 (*(leafs[i]))->get_leaf().set_F(F[i]);
214 case Bembel::BlockClusterAdmissibility::LowRank: {
215 auto F = Bembel::H2Multipole::interpolateKernel<Derived>(
216 linOp, super_space, interpolation_points2D,
217 *((*(leafs[0]))->get_cluster1()),
218 *((*(leafs[0]))->get_cluster2()));
219 for (
int i = 0; i < vector_dimension; ++i) {
220 for (
int j = 0; j < vector_dimension; ++j) {
221 (*(leafs[i * vector_dimension + j]))
223 .set_F(F.block(j * interpolation_points2D.rows() *
224 NumberOfFMMComponents,
225 i * interpolation_points2D.rows() *
226 NumberOfFMMComponents,
227 interpolation_points2D.rows() *
228 NumberOfFMMComponents,
229 interpolation_points2D.rows() *
230 NumberOfFMMComponents));
231 (*(leafs[i * vector_dimension + j]))
233 .set_low_rank_flag(
true);
240 assert(0 &&
"This should never happen");
245 for (
auto leafsit = leafs.begin(); leafsit != leafs.end(); ++leafsit)
254 Eigen::Matrix<ScalarT, Eigen::Dynamic, Eigen::Dynamic>
get_dense()
const {
255 Eigen::Matrix<ScalarT, Eigen::Dynamic, Eigen::Dynamic> dense(rows(),
257 for (
int i = 0; i < cols(); ++i) {
258 Eigen::VectorXd unit(cols());
261 dense.col(i) = (*this) * unit;
269 return transformation_matrix_;
271 const Eigen::MatrixXd get_fmm_transfer_matrices()
const {
272 return fmm_transfer_matrices_;
274 const std::vector<Eigen::MatrixXd> get_fmm_moment_matrix()
const {
275 return fmm_moment_matrix_;
278 get_block_cluster_tree()
const {
279 return block_cluster_tree_;
292 Eigen::SparseMatrix<double> transformation_matrix_;
294 Eigen::MatrixXd fmm_transfer_matrices_;
295 std::vector<Eigen::MatrixXd> fmm_moment_matrix_;
301 template <
typename Scalar>
302 struct evaluator<
H2Matrix<Scalar>> : evaluator<H2MatrixBase<H2Matrix<Scalar>>> {
303 typedef evaluator<H2MatrixBase<H2Matrix<Scalar>>> Base;
305 evaluator() : Base() {}
306 explicit evaluator(
const H2MatrixType& mat) : Base(mat) {}
The AnsatzSpace is the class that handles the assembly of the discrete basis.
int get_polynomial_degree() const
Retrieves the polynomial degree of this AnsatzSpace.
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.
The ElementTreeNode corresponds to an element in the element tree.
const_iterator begin() const
Returns an iterator pointing to the element in the sequence before this ElementTreeNodes.
const_iterator end() const
Returns an iterator pointing to the element in the sequence after this ElementTreeNode.
forward definition of the H2Matrix Class in order to define traits
Eigen::Matrix< ScalarT, Eigen::Dynamic, Eigen::Dynamic > get_dense() const
methods
ScalarT Scalar
Eigen related things.
const Eigen::SparseMatrix< double > get_transformation_matrix() const
getter
void init_H2Matrix(const Derived &linOp, const Bembel::AnsatzSpace< Derived > &ansatz_space, int number_of_points=9)
Assemble H2-Matrix for linear operator linOp and AnsatzSpace ansatz_space with number_of_points inter...
Hierarchical Matrix class, which extends the EigenBase class.
void evaluateBilinearForm(const LinearOperatorBase< Derived > &linOp, const T &super_space, const ElementTreeNode &e1, const ElementTreeNode &e2, const CubatureVector &GS, const ElementSurfacePoints &ffield_qnodes1, const ElementSurfacePoints &ffield_qnodes2, Eigen::Matrix< typename LinearOperatorTraits< Derived >::Scalar, Eigen::Dynamic, Eigen::Dynamic > *intval)
This function wraps the quadrature routines for the DuffyTrick and returns all integrals for the give...
std::vector< ElementSurfacePoints > computeFfieldQnodes(const T &super_space, const Cubature &Q)
evaluates a given quadrature on all surface panels storage format is qNodes.col(k) = [xi,...
Eigen::MatrixXd interpolationPoints2D(const Eigen::VectorXd &x)
Compute tensor interpolation points on unit square from 1D interpolation points.
Eigen::MatrixXd computeTransferMatrices(int number_of_points)
Computes transfer matrices in required order to apply them all-at-once in a matrix-vector-product,...
constexpr int getFunctionSpaceVectorDimension()
Computes the number_of_points Chebychev points.
struct containing specifications on the linear operator has to be specialized or derived for any part...