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)