17 #include <deal.II/base/function.h> 18 #include <deal.II/base/logstream.h> 20 #include <deal.II/dofs/dof_accessor.h> 21 #include <deal.II/dofs/dof_tools.h> 23 #include <deal.II/fe/fe.h> 25 #include <deal.II/grid/tria.h> 26 #include <deal.II/grid/tria_iterator.h> 28 #include <deal.II/lac/block_indices.h> 29 #include <deal.II/lac/block_sparse_matrix.h> 30 #include <deal.II/lac/block_vector.h> 31 #include <deal.II/lac/sparse_matrix.h> 32 #include <deal.II/lac/vector.h> 34 #include <deal.II/multigrid/mg_tools.h> 35 #include <deal.II/multigrid/mg_transfer_component.h> 36 #include <deal.II/multigrid/mg_transfer_component.templates.h> 42 DEAL_II_NAMESPACE_OPEN
81 template <
int dim,
typename number,
int spacedim>
83 reinit_vector_by_components(
84 const ::DoFHandler<dim, spacedim> & mg_dof,
86 const std::vector<bool> & sel,
87 const std::vector<unsigned int> & target_comp,
88 std::vector<std::vector<types::global_dof_index>> &ndofs)
90 std::vector<bool> selected = sel;
91 std::vector<unsigned int> target_component = target_comp;
92 const unsigned int ncomp = mg_dof.get_fe(0).n_components();
103 if (target_component.size() == 0)
105 target_component.resize(ncomp);
106 for (
unsigned int i = 0; i < ncomp; ++i)
107 target_component[i] = i;
112 if (selected.size() == 0)
114 selected.resize(target_component.size());
115 std::fill_n(selected.begin(), ncomp,
false);
116 for (
const unsigned int component : target_component)
117 selected[component] =
true;
120 Assert(selected.size() == target_component.size(),
124 const unsigned int n_selected =
125 std::accumulate(selected.begin(), selected.end(), 0u);
127 if (ndofs.size() == 0)
129 std::vector<std::vector<types::global_dof_index>> new_dofs(
130 mg_dof.get_triangulation().n_levels(),
131 std::vector<types::global_dof_index>(target_component.size()));
136 for (
unsigned int level = v.min_level(); level <= v.max_level(); ++level)
138 v[level].reinit(n_selected, 0);
140 for (
unsigned int i = 0;
141 i < selected.size() && (k < v[level].n_blocks());
146 v[level].block(k++).reinit(ndofs[level][i]);
148 v[level].collect_sizes();
180 template <
int dim,
typename number,
int spacedim>
182 reinit_vector_by_components(
183 const ::DoFHandler<dim, spacedim> & mg_dof,
186 const std::vector<unsigned int> & target_component,
187 std::vector<std::vector<types::global_dof_index>> &ndofs)
190 ExcMessage(
"The component mask does not have the correct size."));
192 unsigned int selected_block = 0;
193 for (
unsigned int i = 0; i < target_component.size(); ++i)
194 if (component_mask[i])
195 selected_block = target_component[i];
197 if (ndofs.size() == 0)
199 std::vector<std::vector<types::global_dof_index>> new_dofs(
200 mg_dof.get_triangulation().n_levels(),
201 std::vector<types::global_dof_index>(target_component.size()));
206 for (
unsigned int level = v.min_level(); level <= v.max_level(); ++level)
208 v[level].reinit(ndofs[level][selected_block]);
214 template <
typename number>
215 template <
int dim,
class InVector,
int spacedim>
220 const InVector & src)
const 225 ExcMatricesNotBuilt());
227 reinit_vector_by_components(
228 mg_dof_handler, dst, mg_component_mask, mg_target_component, sizes);
246 using IT = std::vector<
247 std::pair<types::global_dof_index, unsigned int>>::const_iterator;
248 for (IT i = copy_to_and_from_indices[level].begin();
249 i != copy_to_and_from_indices[level].end();
251 dst[level](i->second) = src(i->first);
256 template <
int dim,
int spacedim>
275 mg_dof.
get_fe(0).n_components()));
296 mg_dof.
get_fe(0).n_components()));
312 const unsigned int n_components =
319 ExcMessage(
"Component mask has wrong size."));
322 sizes.resize(n_levels);
323 for (
unsigned int l = 0; l < n_levels; ++l)
324 sizes[l].resize(n_components);
338 level_component_start = k;
377 prolongation_sparsities.resize(0);
379 prolongation_sparsities.reserve(n_levels - 1);
381 for (
unsigned int i = 0; i < n_levels - 1; ++i)
390 std::vector<types::global_dof_index> dof_indices_parent(dofs_per_cell);
391 std::vector<types::global_dof_index> dof_indices_child(dofs_per_cell);
400 for (
unsigned int level = 0; level < n_levels - 1; ++level)
410 prolongation_sparsities[level]->reinit(n_components, n_components);
411 for (
unsigned int i = 0; i < n_components; ++i)
412 for (
unsigned int j = 0; j < n_components; ++j)
414 prolongation_sparsities[level]->block(i, j).reinit(
415 sizes[level + 1][i],
sizes[level][j], dofs_per_cell + 1);
417 prolongation_sparsities[level]->block(i, j).reinit(
420 prolongation_sparsities[level]->collect_sizes();
424 cell != mg_dof.
end(level);
426 if (cell->has_children())
428 cell->get_mg_dof_indices(dof_indices_parent);
430 for (
unsigned int child = 0; child < cell->n_children(); ++child)
436 mg_dof.
get_fe().get_prolongation_matrix(
437 child, cell->refinement_case());
439 cell->child(child)->get_mg_dof_indices(dof_indices_child);
444 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
445 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
446 if (prolongation(i, j) != 0)
448 const unsigned int icomp =
450 const unsigned int jcomp =
453 prolongation_sparsities[level]->add(
454 dof_indices_child[i], dof_indices_parent[j]);
458 prolongation_sparsities[level]->compress();
464 cell != mg_dof.
end(level);
466 if (cell->has_children())
468 cell->get_mg_dof_indices(dof_indices_parent);
470 for (
unsigned int child = 0; child < cell->n_children(); ++child)
476 mg_dof.
get_fe().get_prolongation_matrix(
477 child, cell->refinement_case());
479 cell->child(child)->get_mg_dof_indices(dof_indices_child);
483 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
484 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
485 if (prolongation(i, j) != 0)
487 const unsigned int icomp =
489 const unsigned int jcomp =
493 dof_indices_child[i],
494 dof_indices_parent[j],
507 std::vector<std::vector<types::global_dof_index>> dofs_per_component(
509 std::vector<types::global_dof_index>(n_components));
514 for (
unsigned int level = 0; level < n_levels - 1; ++level)
519 for (
unsigned int iblock = 0; iblock < n_components; ++iblock)
520 for (
unsigned int jblock = 0; jblock < n_components; ++jblock)
521 if (iblock == jblock)
529 ->block(iblock, jblock)
532 ->block(iblock, jblock)
534 for (; anfang != ende; ++anfang)
541 dofs_per_component[level]);
546 std::set<types::global_dof_index>::const_iterator
549 const bool is_boundary_index =
552 if (is_boundary_index)
555 ->block(iblock, jblock)
556 .set(i, column_number, 0);
566 template <
typename number>
567 template <
int dim,
int spacedim>
573 unsigned int mg_select,
574 const std::vector<unsigned int> & t_component,
575 const std::vector<unsigned int> & mg_t_component,
576 const std::vector<std::set<types::global_dof_index>> &bdry_indices)
579 unsigned int ncomp = mg_dof.
get_fe(0).n_components();
581 target_component = t_component;
582 mg_target_component = mg_t_component;
583 boundary_indices = bdry_indices;
585 selected_component = select;
586 mg_selected_component = mg_select;
589 std::vector<bool> tmp(ncomp,
false);
590 for (
unsigned int c = 0; c < ncomp; ++c)
591 if (t_component[c] == selected_component)
597 std::vector<bool> tmp(ncomp,
false);
598 for (
unsigned int c = 0; c < ncomp; ++c)
599 if (mg_t_component[c] == mg_selected_component)
608 for (
unsigned int i = 0; i < target_component.size(); ++i)
610 if (target_component[i] == select)
612 selected_component = i;
617 for (
unsigned int i = 0; i < mg_target_component.size(); ++i)
619 if (mg_target_component[i] == mg_select)
621 mg_selected_component = i;
631 interface_dofs[l].clear();
632 interface_dofs[l].set_size(mg_dof.
n_dofs(l));
638 std::vector<types::global_dof_index> temp_copy_indices;
639 std::vector<types::global_dof_index> global_dof_indices(fe.
dofs_per_cell);
640 std::vector<types::global_dof_index> level_dof_indices(fe.
dofs_per_cell);
643 copy_to_and_from_indices[level].clear();
649 temp_copy_indices.resize(0);
650 temp_copy_indices.resize(mg_dof.
n_dofs(level),
655 for (; level_cell != level_end; ++level_cell)
661 level_cell->get_dof_indices(global_dof_indices);
662 level_cell->get_mg_dof_indices(level_dof_indices);
666 const unsigned int component =
668 if (component_mask[component] &&
669 !interface_dofs[level].is_element(level_dof_indices[i]))
672 mg_component_start[level][mg_target_component[component]];
674 component_start[target_component[component]];
675 temp_copy_indices[level_dof_indices[i] - level_start] =
676 global_dof_indices[i] - global_start;
684 std::count_if(temp_copy_indices.begin(),
685 temp_copy_indices.end(),
686 std::bind(std::not_equal_to<types::global_dof_index>(),
687 std::placeholders::_1,
689 copy_to_and_from_indices[level].resize(n_active_dofs);
693 copy_to_and_from_indices[level][counter++] =
694 std::pair<types::global_dof_index, unsigned int>(
695 temp_copy_indices[i], i);
703 #include "mg_transfer_component.inst" 706 DEAL_II_NAMESPACE_CLOSE
const Triangulation< dim, spacedim > & get_triangulation() const
std::vector< std::shared_ptr< BlockSparseMatrix< double > > > prolongation_matrices
cell_iterator begin(const unsigned int level=0) const
std::vector< std::set< types::global_dof_index > > boundary_indices
cell_iterator end() const
std::vector< unsigned int > target_component
bool represents_n_components(const unsigned int n) const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
active_cell_iterator begin_active(const unsigned int level=0) const
static ::ExceptionBase & ExcMessage(std::string arg1)
ComponentMask mg_component_mask
void build_matrices(const DoFHandler< dim, spacedim > &dof, const DoFHandler< dim, spacedim > &mg_dof, unsigned int selected, unsigned int mg_selected, const std::vector< unsigned int > &target_component=std::vector< unsigned int >(), const std::vector< unsigned int > &mg_target_component=std::vector< unsigned int >(), const std::vector< std::set< types::global_dof_index >> &boundary_indices=std::vector< std::set< types::global_dof_index >>())
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::vector< types::global_dof_index > component_start
active_cell_iterator end_active(const unsigned int level) const
std::vector< std::vector< std::pair< types::global_dof_index, unsigned int > > > copy_to_and_from_indices
types::global_dof_index n_dofs() const
size_type local_to_global(const unsigned int block, const size_type index) const
const unsigned int dofs_per_cell
void swap(Vector< Number > &u, Vector< Number > &v)
unsigned int global_dof_index
void do_copy_to_mg(const DoFHandler< dim, spacedim > &mg_dof, MGLevelObject< Vector< number >> &dst, const InVector &src) const
std::vector< unsigned int > mg_target_component
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
unsigned int n_components() const
typename ActiveSelector::cell_iterator cell_iterator
std::vector< std::vector< types::global_dof_index > > mg_component_start
typename ActiveSelector::active_cell_iterator active_cell_iterator
const types::global_dof_index invalid_dof_index
void build_matrices(const DoFHandler< dim, spacedim > &dof, const DoFHandler< dim, spacedim > &mg_dof)
std::vector< std::vector< types::global_dof_index > > sizes
static ::ExceptionBase & ExcInternalError()