116 std::vector<moonolith::Integer> &pairs)
124 std::vector<::moonolith::AABB<1, double>> src_boxes, dest_boxes;
128 ::moonolith::SerialHashGrid<1, double> grid;
129 return grid.detect(src_boxes, dest_boxes, pairs);
133 std::vector<::moonolith::AABB<2, double>> src_boxes, dest_boxes;
137 ::moonolith::SerialHashGrid<2, double> grid;
138 return grid.detect(src_boxes, dest_boxes, pairs);
142 std::vector<::moonolith::AABB<3, double>> src_boxes, dest_boxes;
146 ::moonolith::SerialHashGrid<3, double> grid;
147 return grid.detect(src_boxes, dest_boxes, pairs);
176 const bool verbose = impl_->verbose;
178 const auto &source_mesh = *impl_->source->GetMesh();
179 const auto &destination_mesh = *impl_->destination->GetMesh();
181 int dim = source_mesh.Dimension();
183 std::vector<::moonolith::Integer> pairs;
192 assert(
false &&
"NOT Supported!");
201 B = make_shared<SparseMatrix>(impl_->destination->GetNDofs(),
202 impl_->source->GetNDofs());
205 std::unique_ptr<BilinearFormIntegrator> mass_integr(
206 impl_->new_mass_integrator());
208 if (impl_->assemble_mass_and_coupling_together)
210 impl_->mass_matrix = make_shared<SparseMatrix>(impl_->destination->GetNDofs(),
211 impl_->destination->GetNDofs());
219 double local_element_matrices_sum = 0.0;
221 long n_intersections = 0;
222 long n_candidates = 0;
226 for (
auto i_ptr : impl_->integrators)
228 max_q_order = std::max(i_ptr->GetQuadratureOrder(), max_q_order);
231 bool intersected =
false;
232 for (
auto it = begin(pairs); it != end(pairs); )
234 const int source_index = *it++;
235 const int destination_index = *it++;
237 auto &source_fe = *impl_->source->GetFE(source_index);
238 auto &destination_fe = *impl_->destination->GetFE(destination_index);
241 *impl_->destination->GetElementTransformation(destination_index);
247 const int src_order = src_order_mult * source_fe.GetOrder();
248 const int dest_order = dest_order_mult * destination_fe.GetOrder();
250 int contraction_order = src_order + dest_order;
252 if (impl_->assemble_mass_and_coupling_together)
254 contraction_order = std::max(contraction_order, 2 * dest_order);
257 const int order = contraction_order + dest_order_mult *
258 destination_Trans.
OrderW() + max_q_order;
261 cut->SetIntegrationOrder(order);
265 if (cut->BuildQuadrature(*impl_->source, source_index, *impl_->destination,
266 destination_index, source_ir, destination_ir))
268 impl_->source->GetElementVDofs(source_index, source_vdofs);
269 impl_->destination->GetElementVDofs(destination_index, destination_vdofs);
272 *impl_->source->GetElementTransformation(source_index);
275 for (
auto i_ptr : impl_->integrators)
279 i_ptr->AssembleElementMatrix(source_fe, source_ir, source_Trans,
280 destination_fe, destination_ir,
281 destination_Trans, cumulative_elemmat);
286 i_ptr->AssembleElementMatrix(source_fe, source_ir, source_Trans,
287 destination_fe, destination_ir,
288 destination_Trans, elemmat);
289 cumulative_elemmat += elemmat;
293 local_element_matrices_sum += Sum(cumulative_elemmat);
295 B->AddSubMatrix(destination_vdofs, source_vdofs, cumulative_elemmat,
298 if (impl_->assemble_mass_and_coupling_together)
300 mass_integr->SetIntRule(&destination_ir);
301 mass_integr->AssembleElementMatrix(destination_fe, destination_Trans, elemmat);
302 impl_->mass_matrix->AddSubMatrix(destination_vdofs, destination_vdofs, elemmat,
318 if (impl_->assemble_mass_and_coupling_together)
320 impl_->mass_matrix->Finalize();
325 mfem::out <<
"local_element_matrices_sum: " << local_element_matrices_sum
327 mfem::out <<
"B in R^(" << B->Height() <<
" x " << B->Width() <<
")"
330 mfem::out <<
"n_intersections: " << n_intersections
331 <<
", n_candidates: " << n_candidates <<
'\n';