114 std::vector<moonolith::Integer> &pairs)
122 std::vector<::moonolith::AABB<1, double>> src_boxes, dest_boxes;
126 ::moonolith::SerialHashGrid<1, double> grid;
127 return grid.detect(src_boxes, dest_boxes, pairs);
131 std::vector<::moonolith::AABB<2, double>> src_boxes, dest_boxes;
135 ::moonolith::SerialHashGrid<2, double> grid;
136 return grid.detect(src_boxes, dest_boxes, pairs);
140 std::vector<::moonolith::AABB<3, double>> src_boxes, dest_boxes;
144 ::moonolith::SerialHashGrid<3, double> grid;
145 return grid.detect(src_boxes, dest_boxes, pairs);
174 const bool verbose = impl_->verbose;
176 const auto &source_mesh = *impl_->source->GetMesh();
177 const auto &destination_mesh = *impl_->destination->GetMesh();
179 int dim = source_mesh.Dimension();
181 std::vector<::moonolith::Integer> pairs;
190 assert(
false &&
"NOT Supported!");
199 B = make_shared<SparseMatrix>(impl_->destination->GetNDofs(),
200 impl_->source->GetNDofs());
203 std::unique_ptr<BilinearFormIntegrator> mass_integr(impl_->new_mass_integrator());
205 if(impl_->assemble_mass_and_coupling_together) {
206 impl_->mass_matrix = make_shared<SparseMatrix>(impl_->destination->GetNDofs(), impl_->destination->GetNDofs());
214 double local_element_matrices_sum = 0.0;
216 long n_intersections = 0;
217 long n_candidates = 0;
221 for (
auto i_ptr : impl_->integrators)
223 max_q_order = std::max(i_ptr->GetQuadratureOrder(), max_q_order);
226 bool intersected =
false;
227 for (
auto it = begin(pairs); it != end(pairs); )
229 const int source_index = *it++;
230 const int destination_index = *it++;
232 auto &source_fe = *impl_->source->GetFE(source_index);
233 auto &destination_fe = *impl_->destination->GetFE(destination_index);
236 *impl_->destination->GetElementTransformation(destination_index);
242 const int src_order = src_order_mult * source_fe.GetOrder();
243 const int dest_order = dest_order_mult * destination_fe.GetOrder();
245 int contraction_order = src_order + dest_order;
247 if(impl_->assemble_mass_and_coupling_together) {
248 contraction_order = std::max(contraction_order, 2 * dest_order);
251 const int order = contraction_order + dest_order_mult * destination_Trans.
OrderW() + max_q_order;
254 cut->SetIntegrationOrder(order);
258 if (cut->BuildQuadrature(*impl_->source, source_index, *impl_->destination,
259 destination_index, source_ir, destination_ir))
261 impl_->source->GetElementVDofs(source_index, source_vdofs);
262 impl_->destination->GetElementVDofs(destination_index, destination_vdofs);
265 *impl_->source->GetElementTransformation(source_index);
268 for (
auto i_ptr : impl_->integrators)
272 i_ptr->AssembleElementMatrix(source_fe, source_ir, source_Trans,
273 destination_fe, destination_ir,
274 destination_Trans, cumulative_elemmat);
279 i_ptr->AssembleElementMatrix(source_fe, source_ir, source_Trans,
280 destination_fe, destination_ir,
281 destination_Trans, elemmat);
282 cumulative_elemmat += elemmat;
286 local_element_matrices_sum += Sum(cumulative_elemmat);
288 B->AddSubMatrix(destination_vdofs, source_vdofs, cumulative_elemmat,
291 if(impl_->assemble_mass_and_coupling_together) {
292 mass_integr->SetIntRule(&destination_ir);
293 mass_integr->AssembleElementMatrix(destination_fe, destination_Trans, elemmat);
294 impl_->mass_matrix->AddSubMatrix(destination_vdofs, destination_vdofs, elemmat, skip_zeros);
309 if(impl_->assemble_mass_and_coupling_together) {
310 impl_->mass_matrix->Finalize();
315 mfem::out <<
"local_element_matrices_sum: " << local_element_matrices_sum
317 mfem::out <<
"B in R^(" << B->Height() <<
" x " << B->Width() <<
")"
320 mfem::out <<
"n_intersections: " << n_intersections
321 <<
", n_candidates: " << n_candidates <<
'\n';