62 template <
int dim0,
int dim1,
int spacedim>
63 std::pair<std::vector<Point<spacedim>>, std::vector<unsigned int>>
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 =
118 points_over_local_cells.insert(points_over_local_cells.end(),
125 return {std::move(points_over_local_cells), std::move(used_cells_ids)};
135 template <
int dim0,
int dim1,
int spacedim>
136 std::pair<std::vector<unsigned int>, std::vector<unsigned int>>
158 for (
unsigned int i = 0, j = 0; i < gtl0.size(); ++i)
162 for (
unsigned int i = 0, j = 0; i < gtl1.size(); ++i)
221 ExcMessage(
"This function can only work if dim1 <= dim0"));
227 const bool tria_is_parallel =
230 const auto &space_fe = space_dh.
get_fe();
231 const auto &immersed_fe = immersed_dh.
get_fe();
234 std::vector<types::global_dof_index> dofs(immersed_fe.n_dofs_per_cell());
235 std::vector<types::global_dof_index> odofs(space_fe.n_dofs_per_cell());
243 (immersed_comps.
size() == 0 ?
251 std::vector<unsigned int> space_gtl(space_fe.n_components(),
253 std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(),
256 for (
unsigned int i = 0, j = 0; i < space_gtl.size(); ++i)
260 for (
unsigned int i = 0, j = 0; i < immersed_gtl.size(); ++i)
262 immersed_gtl[i] = j++;
264 const unsigned int n_q_points = quad.
size();
265 const unsigned int n_active_c =
269 cache, immersed_dh, quad, immersed_mapping, tria_is_parallel);
271 const auto &points_over_local_cells = std::get<0>(qpoints_cells_data);
272 const auto &used_cells_ids = std::get<1>(qpoints_cells_data);
298 const auto &all_cells = std::get<0>(cpm);
299 const auto &maps = std::get<2>(cpm);
302 std::set<typename Triangulation<dim0, spacedim>::active_cell_iterator>>
303 cell_sets(n_active_c);
305 for (
unsigned int i = 0; i < maps.size(); ++i)
311 unsigned int cell_id;
312 for (
const unsigned int idx : maps[i])
315 if (tria_is_parallel)
316 cell_id = used_cells_ids[idx / n_q_points];
318 cell_id = idx / n_q_points;
320 if (last_id != cell_id)
322 cell_sets[cell_id].insert(all_cells[i]);
334 cell->get_dof_indices(dofs);
337 const auto &cells = cell_sets[i];
339 for (
const auto &cell_c : cells)
345 if (ocell->is_locally_owned())
347 ocell->get_dof_indices(odofs);
352 odofs, dofs, sparsity);
361 template <
int dim0,
int dim1,
int spacedim,
typename Matrix>
389 template <
int dim0,
int dim1,
int spacedim,
typename Matrix>
405 ExcMessage(
"This function can only work if dim1 <= dim0"));
411 const bool tria_is_parallel =
415 const auto &space_fe = space_dh.
get_fe();
416 const auto &immersed_fe = immersed_dh.
get_fe();
419 std::vector<types::global_dof_index> dofs(immersed_fe.n_dofs_per_cell());
420 std::vector<types::global_dof_index> odofs(space_fe.n_dofs_per_cell());
428 (immersed_comps.
size() == 0 ?
435 std::vector<unsigned int> space_gtl(space_fe.n_components(),
437 std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(),
440 for (
unsigned int i = 0, j = 0; i < space_gtl.size(); ++i)
444 for (
unsigned int i = 0, j = 0; i < immersed_gtl.size(); ++i)
446 immersed_gtl[i] = j++;
458 const unsigned int n_q_points = quad.
size();
459 const unsigned int n_active_c =
463 cache, immersed_dh, quad, immersed_mapping, tria_is_parallel);
465 const auto &points_over_local_cells = std::get<0>(used_cells_data);
466 const auto &used_cells_ids = std::get<1>(used_cells_data);
471 const auto &all_cells = std::get<0>(cpm);
472 const auto &all_qpoints = std::get<1>(cpm);
473 const auto &all_maps = std::get<2>(cpm);
476 std::vector<typename Triangulation<dim0, spacedim>::active_cell_iterator>>
477 cell_container(n_active_c);
478 std::vector<std::vector<std::vector<Point<dim0>>>> qpoints_container(
480 std::vector<std::vector<std::vector<unsigned int>>> maps_container(
485 for (
unsigned int o = 0; o < all_cells.size(); ++o)
487 for (
unsigned int j = 0; j < all_maps[o].size(); ++j)
492 unsigned int cell_id;
493 if (tria_is_parallel)
494 cell_id = used_cells_ids[all_maps[o][j] / n_q_points];
496 cell_id = all_maps[o][j] / n_q_points;
498 const unsigned int n_pt = all_maps[o][j] % n_q_points;
501 if (cell_container[cell_id].empty())
503 cell_container[cell_id].emplace_back(all_cells[o]);
504 qpoints_container[cell_id].emplace_back(
506 maps_container[cell_id].emplace_back(
507 std::vector<unsigned int>{n_pt});
511 else if (cell_container[cell_id].back() == all_cells[o])
513 qpoints_container[cell_id].back().emplace_back(
515 maps_container[cell_id].back().emplace_back(n_pt);
520 const auto cell_p = std::find(cell_container[cell_id].
begin(),
521 cell_container[cell_id].
end() - 1,
524 if (cell_p == cell_container[cell_id].
end() - 1)
526 cell_container[cell_id].emplace_back(all_cells[o]);
527 qpoints_container[cell_id].emplace_back(
529 maps_container[cell_id].emplace_back(
530 std::vector<unsigned int>{n_pt});
534 const unsigned int pos =
535 cell_p - cell_container[cell_id].begin();
536 qpoints_container[cell_id][pos].emplace_back(
538 maps_container[cell_id][pos].emplace_back(n_pt);
546 endc = immersed_dh.
end();
548 for (
unsigned int j = 0; cell != endc; ++cell, ++j)
552 cell->get_dof_indices(dofs);
555 const auto &cells = cell_container[j];
556 const auto &qpoints = qpoints_container[j];
557 const auto &maps = maps_container[j];
559 for (
unsigned int c = 0; c < cells.size(); ++c)
563 *cells[c], &space_dh);
565 if (ocell->is_locally_owned())
567 const std::vector<Point<dim0>> & qps = qpoints[c];
568 const std::vector<unsigned int> &ids = maps[c];
575 ocell->get_dof_indices(odofs);
580 for (
unsigned int i = 0;
581 i < space_dh.
get_fe().n_dofs_per_cell();
587 for (
unsigned int j = 0;
588 j < immersed_dh.
get_fe().n_dofs_per_cell();
591 const auto comp_j = immersed_dh.
get_fe()
594 if (space_gtl[comp_i] == immersed_gtl[comp_j])
595 for (
unsigned int oq = 0;
600 const unsigned int q = ids[oq];
640 ExcMessage(
"When epsilon is zero, you can only "
641 "call this function with dim1 <= dim0."));
656 const bool zero_is_distributed =
659 const bool one_is_distributed =
672 const bool outer_loop_on_zero =
673 (zero_is_distributed && !one_is_distributed) ||
677 const auto &fe0 = dh0.
get_fe();
678 const auto &fe1 = dh1.
get_fe();
681 std::vector<types::global_dof_index> dofs0(fe0.n_dofs_per_cell());
682 std::vector<types::global_dof_index> dofs1(fe1.n_dofs_per_cell());
684 if (outer_loop_on_zero)
690 std::vector<std::pair<
696 if (cell0->is_locally_owned())
698 intersection.resize(0);
702 boost::geometry::index::query(tree1,
703 boost::geometry::index::intersects(
705 std::back_inserter(intersection));
706 if (!intersection.empty())
708 cell0->get_dof_indices(dofs0);
709 for (
const auto &entry : intersection)
712 *entry.second, &dh1);
713 cell1->get_dof_indices(dofs1);
726 std::vector<std::pair<
732 if (cell1->is_locally_owned())
734 intersection.resize(0);
738 boost::geometry::index::query(tree0,
739 boost::geometry::index::intersects(
741 std::back_inserter(intersection));
742 if (!intersection.empty())
744 cell1->get_dof_indices(dofs1);
745 for (
const auto &entry : intersection)
748 *entry.second, &dh0);
749 cell0->get_dof_indices(dofs0);
761 template <
int dim0,
int dim1,
int spacedim,
typename Matrix>
780 ExcMessage(
"When epsilon is zero, you can only "
781 "call this function with dim1 <= dim0."));
797 const bool zero_is_distributed =
800 const bool one_is_distributed =
813 const bool outer_loop_on_zero =
814 (zero_is_distributed && !one_is_distributed) ||
818 const auto &fe0 = dh0.
get_fe();
819 const auto &fe1 = dh1.
get_fe();
834 std::vector<types::global_dof_index> dofs0(fe0.n_dofs_per_cell());
835 std::vector<types::global_dof_index> dofs1(fe1.n_dofs_per_cell());
839 fe1.n_dofs_per_cell());
844 const auto >l0 = p.first;
845 const auto >l1 = p.second;
848 std::vector<double> kernel_values(quadrature1.
size());
850 auto assemble_one_pair = [&]() {
852 for (
unsigned int q0 = 0; q0 < quadrature0.
size(); ++q0)
856 for (
unsigned int j = 0; j < fe1.n_dofs_per_cell(); ++j)
858 const auto comp_j = fe1.system_to_component_index(j).first;
862 typename Matrix::value_type sum_q1 = {};
863 for (
unsigned int q1 = 0; q1 < quadrature1.
size(); ++q1)
866 sum_q1 *= fev0.
JxW(q0);
871 for (
unsigned int i = 0; i < fe0.n_dofs_per_cell(); ++i)
873 const auto comp_i = fe0.system_to_component_index(i).first;
875 gtl1[comp_j] == gtl0[comp_i])
887 if (outer_loop_on_zero)
893 std::vector<std::pair<
899 if (cell0->is_locally_owned())
901 intersection.resize(0);
905 boost::geometry::index::query(tree1,
906 boost::geometry::index::intersects(
908 std::back_inserter(intersection));
909 if (!intersection.empty())
911 cell0->get_dof_indices(dofs0);
913 for (
const auto &entry : intersection)
916 *entry.second, &dh1);
917 cell1->get_dof_indices(dofs1);
929 std::vector<std::pair<
935 if (cell1->is_locally_owned())
937 intersection.resize(0);
941 boost::geometry::index::query(tree0,
942 boost::geometry::index::intersects(
944 std::back_inserter(intersection));
945 if (!intersection.empty())
947 cell1->get_dof_indices(dofs1);
949 for (
const auto &entry : intersection)
952 *entry.second, &dh0);
953 cell0->get_dof_indices(dofs0);
962#include "coupling.inst"
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) 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 extend(const Number &amount)
unsigned int size() const
cell_iterator end() const
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
const Triangulation< dim, spacedim > & get_triangulation() const
active_cell_iterator begin_active(const unsigned int level=0) const
types::global_dof_index n_dofs() const
const std::vector< Point< spacedim > > & get_quadrature_points() const
const unsigned int n_quadrature_points
double JxW(const unsigned int quadrature_point) const
const Point< spacedim > & quadrature_point(const unsigned int q) const
const double & shape_value(const unsigned int function_no, const unsigned int point_no) const
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access > > &cell)
unsigned int n_dofs_per_cell() const
unsigned int n_components() const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
virtual void value_list(const std::vector< Point< dim > > &points, std::vector< RangeNumberType > &values, const unsigned int component=0) const
virtual void set_radius(const double r)
virtual void set_center(const Point< dim > &p)
Abstract base class for mapping classes.
virtual BoundingBox< spacedim > get_bounding_box(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
unsigned int size() const
unsigned int n_active_cells() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
@ update_values
Shape function values.
@ update_JxW_values
Transformed quadrature weights.
@ update_quadrature_points
Transformed quadrature points.
IteratorRange< active_cell_iterator > active_cell_iterators() const
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
typename ActiveSelector::cell_iterator cell_iterator
typename ActiveSelector::active_cell_iterator active_cell_iterator
@ matrix
Contents is actually a matrix.
void cell_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const FEValuesBase< dim > &fetest, const ArrayView< const std::vector< double > > &velocity, const double factor=1.)
std::pair< std::vector< unsigned int >, std::vector< unsigned int > > compute_components_coupling(const ComponentMask &comps0, const ComponentMask &comps1, const FiniteElement< dim0, spacedim > &fe0, const FiniteElement< dim1, spacedim > &fe1)
std::pair< std::vector< Point< spacedim > >, std::vector< unsigned int > > qpoints_over_locally_owned_cells(const GridTools::Cache< dim0, spacedim > &cache, const DoFHandler< dim1, spacedim > &immersed_dh, const Quadrature< dim1 > &quad, const Mapping< dim1, spacedim > &immersed_mapping, const bool tria_is_parallel)
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)
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)
SymmetricTensor< 2, dim, Number > epsilon(const Tensor< 2, dim, Number > &Grad_u)
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
static const unsigned int invalid_unsigned_int