16 #include <deal.II/base/exceptions.h> 17 #include <deal.II/base/point.h> 18 #include <deal.II/base/tensor.h> 20 #include <deal.II/distributed/shared_tria.h> 21 #include <deal.II/distributed/tria.h> 23 #include <deal.II/fe/fe_values.h> 25 #include <deal.II/grid/grid_tools.h> 26 #include <deal.II/grid/grid_tools_cache.h> 28 #include <deal.II/lac/block_sparse_matrix.h> 29 #include <deal.II/lac/block_sparsity_pattern.h> 30 #include <deal.II/lac/petsc_block_sparse_matrix.h> 31 #include <deal.II/lac/petsc_sparse_matrix.h> 32 #include <deal.II/lac/sparse_matrix.h> 33 #include <deal.II/lac/sparsity_pattern.h> 34 #include <deal.II/lac/trilinos_block_sparse_matrix.h> 35 #include <deal.II/lac/trilinos_sparse_matrix.h> 36 #include <deal.II/lac/trilinos_sparsity_pattern.h> 38 #include <deal.II/non_matching/coupling.h> 40 DEAL_II_NAMESPACE_OPEN
62 template <
int dim0,
int dim1,
int spacedim>
63 std::pair<std::vector<Point<spacedim>>, std::vector<unsigned int>>
64 qpoints_over_locally_owned_cells(
69 const bool tria_is_parallel)
71 const auto & immersed_fe = immersed_dh.
get_fe();
72 std::vector<Point<spacedim>> points_over_local_cells;
74 std::vector<unsigned int> used_cells_ids;
80 unsigned int cell_id = 0;
83 bool use_cell =
false;
86 const auto bbox = cell->bounding_box();
87 std::vector<std::pair<
92 boost::geometry::index::intersects(bbox),
93 std::back_inserter(out_vals));
98 for (
const auto &bbox_it : out_vals)
99 if (bbox_it.second->is_locally_owned())
102 used_cells_ids.emplace_back(cell_id);
114 const std::vector<Point<spacedim>> &x_points =
115 fe_v.get_quadrature_points();
118 points_over_local_cells.insert(points_over_local_cells.end(),
125 return {std::move(points_over_local_cells), std::move(used_cells_ids)};
180 static_assert(dim1 <= dim0,
"This function can only work if dim1 <= dim0");
186 const bool tria_is_parallel =
189 const auto &space_fe = space_dh.
get_fe();
190 const auto &immersed_fe = immersed_dh.
get_fe();
193 std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
194 std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
202 (immersed_comps.
size() == 0 ?
210 std::vector<unsigned int> space_gtl(space_fe.n_components(),
212 std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(),
215 for (
unsigned int i = 0, j = 0; i < space_gtl.size(); ++i)
219 for (
unsigned int i = 0, j = 0; i < immersed_gtl.size(); ++i)
221 immersed_gtl[i] = j++;
223 const unsigned int n_q_points = quad.
size();
224 const unsigned int n_active_c =
227 const auto qpoints_cells_data = internal::qpoints_over_locally_owned_cells(
228 cache, immersed_dh, quad, immersed_mapping, tria_is_parallel);
230 const auto &points_over_local_cells = std::get<0>(qpoints_cells_data);
231 const auto &used_cells_ids = std::get<1>(qpoints_cells_data);
257 const auto &all_cells = std::get<0>(cpm);
258 const auto &maps = std::get<2>(cpm);
261 std::set<typename Triangulation<dim0, spacedim>::active_cell_iterator>>
262 cell_sets(n_active_c);
264 for (
unsigned int i = 0; i < maps.size(); ++i)
269 unsigned int last_id = std::numeric_limits<unsigned int>::max();
270 unsigned int cell_id;
271 for (
const unsigned int idx : maps[i])
274 if (tria_is_parallel)
275 cell_id = used_cells_ids[idx / n_q_points];
277 cell_id = idx / n_q_points;
279 if (last_id != cell_id)
281 cell_sets[cell_id].insert(all_cells[i]);
293 cell->get_dof_indices(dofs);
296 const auto &cells = cell_sets[i];
298 for (
const auto &cell_c : cells)
304 if (ocell->is_locally_owned())
306 ocell->get_dof_indices(odofs);
311 odofs, dofs, sparsity);
320 template <
int dim0,
int dim1,
int spacedim,
typename Matrix>
348 template <
int dim0,
int dim1,
int spacedim,
typename Matrix>
363 static_assert(dim1 <= dim0,
"This function can only work if dim1 <= dim0");
369 const bool tria_is_parallel =
373 const auto &space_fe = space_dh.
get_fe();
374 const auto &immersed_fe = immersed_dh.
get_fe();
377 std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
378 std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
386 (immersed_comps.
size() == 0 ?
393 std::vector<unsigned int> space_gtl(space_fe.n_components(),
395 std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(),
398 for (
unsigned int i = 0, j = 0; i < space_gtl.size(); ++i)
402 for (
unsigned int i = 0, j = 0; i < immersed_gtl.size(); ++i)
404 immersed_gtl[i] = j++;
407 space_dh.
get_fe().dofs_per_cell, immersed_dh.
get_fe().dofs_per_cell);
415 const unsigned int n_q_points = quad.
size();
416 const unsigned int n_active_c =
419 const auto used_cells_data = internal::qpoints_over_locally_owned_cells(
420 cache, immersed_dh, quad, immersed_mapping, tria_is_parallel);
422 const auto &points_over_local_cells = std::get<0>(used_cells_data);
423 const auto &used_cells_ids = std::get<1>(used_cells_data);
428 const auto &all_cells = std::get<0>(cpm);
429 const auto &all_qpoints = std::get<1>(cpm);
430 const auto &all_maps = std::get<2>(cpm);
433 std::vector<typename Triangulation<dim0, spacedim>::active_cell_iterator>>
434 cell_container(n_active_c);
435 std::vector<std::vector<std::vector<Point<dim0>>>> qpoints_container(
437 std::vector<std::vector<std::vector<unsigned int>>> maps_container(
442 for (
unsigned int o = 0; o < all_cells.size(); ++o)
444 for (
unsigned int j = 0; j < all_maps[o].size(); ++j)
449 unsigned int cell_id;
450 if (tria_is_parallel)
451 cell_id = used_cells_ids[all_maps[o][j] / n_q_points];
453 cell_id = all_maps[o][j] / n_q_points;
455 const unsigned int n_pt = all_maps[o][j] % n_q_points;
458 if (cell_container[cell_id].empty())
460 cell_container[cell_id].emplace_back(all_cells[o]);
461 qpoints_container[cell_id].emplace_back(
463 maps_container[cell_id].emplace_back(
464 std::vector<unsigned int>{n_pt});
468 else if (cell_container[cell_id].back() == all_cells[o])
470 qpoints_container[cell_id].back().emplace_back(
472 maps_container[cell_id].back().emplace_back(n_pt);
477 const auto cell_p = std::find(cell_container[cell_id].begin(),
478 cell_container[cell_id].end() - 1,
481 if (cell_p == cell_container[cell_id].end() - 1)
483 cell_container[cell_id].emplace_back(all_cells[o]);
484 qpoints_container[cell_id].emplace_back(
486 maps_container[cell_id].emplace_back(
487 std::vector<unsigned int>{n_pt});
491 const unsigned int pos =
492 cell_p - cell_container[cell_id].begin();
493 qpoints_container[cell_id][pos].emplace_back(
495 maps_container[cell_id][pos].emplace_back(n_pt);
503 endc = immersed_dh.
end();
505 for (
unsigned int j = 0; cell != endc; ++cell, ++j)
509 cell->get_dof_indices(dofs);
512 const auto &cells = cell_container[j];
513 const auto &qpoints = qpoints_container[j];
514 const auto &maps = maps_container[j];
516 for (
unsigned int c = 0; c < cells.size(); ++c)
520 *cells[c], &space_dh);
522 if (ocell->is_locally_owned())
524 const std::vector<Point<dim0>> & qps = qpoints[c];
525 const std::vector<unsigned int> &ids = maps[c];
532 ocell->get_dof_indices(odofs);
535 cell_matrix =
typename Matrix::value_type();
537 for (
unsigned int i = 0; i < space_dh.
get_fe().dofs_per_cell;
541 space_dh.
get_fe().system_to_component_index(i).first;
543 for (
unsigned int j = 0;
544 j < immersed_dh.
get_fe().dofs_per_cell;
547 const auto comp_j = immersed_dh.
get_fe()
548 .system_to_component_index(j)
550 if (space_gtl[comp_i] == immersed_gtl[comp_j])
551 for (
unsigned int oq = 0;
552 oq < o_fe_v.n_quadrature_points;
556 const unsigned int q = ids[oq];
559 (fe_v.shape_value(j, q) *
560 o_fe_v.shape_value(i, oq) * fe_v.JxW(q));
575 #include "coupling.inst" 579 DEAL_II_NAMESPACE_CLOSE
Transformed quadrature weights.
const Triangulation< dim, spacedim > & get_triangulation() const
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
cell_iterator end() const
Transformed quadrature points.
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
void create_coupling_sparsity_pattern(const DoFHandler< dim0, spacedim > &space_dh, const DoFHandler< dim1, spacedim > &immersed_dh, const Quadrature< dim1 > &quad, Sparsity &sparsity, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const ComponentMask &space_comps=ComponentMask(), const ComponentMask &immersed_comps=ComponentMask(), const Mapping< dim0, spacedim > &space_mapping=StaticMappingQ1< dim0, spacedim >::mapping, const Mapping< dim1, spacedim > &immersed_mapping=StaticMappingQ1< dim1, spacedim >::mapping)
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
active_cell_iterator begin_active(const unsigned int level=0) const
#define Assert(cond, exc)
IteratorRange< active_cell_iterator > active_cell_iterators() const
Abstract base class for mapping classes.
types::global_dof_index n_dofs() const
unsigned int size() const
void add_entries_local_to_global(const std::vector< size_type > &local_dof_indices, SparsityPatternType &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) const
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access >> &cell)
unsigned int size() const
void create_coupling_mass_matrix(const DoFHandler< dim0, spacedim > &space_dh, const DoFHandler< dim1, spacedim > &immersed_dh, const Quadrature< dim1 > &quad, Matrix &matrix, const AffineConstraints< typename Matrix::value_type > &constraints=AffineConstraints< typename Matrix::value_type >(), const ComponentMask &space_comps=ComponentMask(), const ComponentMask &immersed_comps=ComponentMask(), const Mapping< dim0, spacedim > &space_mapping=StaticMappingQ1< dim0, spacedim >::mapping, const Mapping< dim1, spacedim > &immersed_mapping=StaticMappingQ1< dim1, spacedim >::mapping)
static ::ExceptionBase & ExcNotImplemented()
typename ActiveSelector::cell_iterator cell_iterator
typename ActiveSelector::active_cell_iterator active_cell_iterator