31#include <deal.II/multigrid/mg_transfer_block.templates.h>
49 template <
int dim,
typename number,
int spacedim>
51 reinit_vector_by_blocks(
54 const std::vector<bool> &sel,
55 std::vector<std::vector<types::global_dof_index>> &ndofs)
57 std::vector<bool> selected = sel;
59 const unsigned int n_selected =
60 std::accumulate(selected.begin(), selected.end(), 0u);
64 std::vector<std::vector<types::global_dof_index>> new_dofs(
66 std::vector<types::global_dof_index>(selected.size()));
67 std::swap(ndofs, new_dofs);
71 for (
unsigned int level = v.min_level();
level <= v.max_level(); ++
level)
73 v[
level].reinit(n_selected, 0);
75 for (
unsigned int i = 0;
76 i < selected.size() && (k < v[
level].n_blocks());
83 v[
level].collect_sizes();
95 template <
int dim,
typename number,
int spacedim>
97 reinit_vector_by_blocks(
100 const unsigned int selected_block,
101 std::vector<std::vector<types::global_dof_index>> &ndofs)
106 std::vector<bool> selected(n_blocks,
false);
107 selected[selected_block] =
true;
111 std::vector<std::vector<types::global_dof_index>> new_dofs(
113 std::vector<types::global_dof_index>(selected.size()));
114 std::swap(ndofs, new_dofs);
118 for (
unsigned int level = v.min_level();
level <= v.max_level(); ++
level)
120 v[
level].reinit(ndofs[
level][selected_block]);
126template <
typename number>
127template <
int dim,
typename number2,
int spacedim>
134 reinit_vector_by_blocks(dof_handler, dst, selected_block, sizes);
143 for (IT i = copy_indices[selected_block][
level].
begin();
144 i != copy_indices[selected_block][
level].end();
146 dst[
level](i->second) = src.
block(selected_block)(i->first);
152template <
typename number>
153template <
int dim,
typename number2,
int spacedim>
160 reinit_vector_by_blocks(dof_handler, dst, selected_block, sizes);
168 for (IT i = copy_indices[selected_block][
level].
begin();
169 i != copy_indices[selected_block][
level].end();
171 dst[
level](i->second) = src(i->first);
177template <
typename number>
178template <
int dim,
typename number2,
int spacedim>
185 reinit_vector_by_blocks(dof_handler, dst, selected, sizes);
190 for (
unsigned int block = 0; block < selected.size(); ++block)
192 for (IT i = copy_indices[block][
level].
begin();
193 i != copy_indices[block][
level].end();
195 dst[
level].block(mg_block[block])(i->second) =
196 src.
block(block)(i->first);
202template <
int dim,
int spacedim>
207 const unsigned int n_blocks = fe.
n_blocks();
219 for (
unsigned int i = 0; i < n_blocks; ++i)
227 sizes.resize(n_levels, std::vector<types::global_dof_index>(fe.
n_blocks()));
240 level_block_start = k;
262 for (
unsigned int block = 0; block < n_blocks; ++block)
283 for (
unsigned int i = 0; i < n_levels - 1; ++i)
292 std::vector<types::global_dof_index> dof_indices_parent(dofs_per_cell);
293 std::vector<types::global_dof_index> dof_indices_child(dofs_per_cell);
314 for (
unsigned int i = 0; i < n_blocks; ++i)
315 for (
unsigned int j = 0; j < n_blocks; ++j)
329 if (cell->has_children())
331 cell->get_mg_dof_indices(dof_indices_parent);
333 Assert(cell->n_children() ==
336 for (
unsigned int child = 0; child < cell->n_children(); ++child)
343 child, cell->refinement_case());
345 cell->child(child)->get_mg_dof_indices(dof_indices_child);
350 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
351 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
352 if (prolongation(i, j) != 0)
354 const unsigned int icomp =
356 const unsigned int jcomp =
358 if ((icomp == jcomp) &&
selected[icomp])
360 dof_indices_child[i], dof_indices_parent[j]);
372 if (cell->has_children())
374 cell->get_mg_dof_indices(dof_indices_parent);
376 Assert(cell->n_children() ==
379 for (
unsigned int child = 0; child < cell->n_children(); ++child)
386 child, cell->refinement_case());
388 cell->child(child)->get_mg_dof_indices(dof_indices_child);
392 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
393 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
394 if (prolongation(i, j) != 0)
396 const unsigned int icomp =
398 const unsigned int jcomp =
400 if ((icomp == jcomp) &&
selected[icomp])
402 dof_indices_child[i],
403 dof_indices_parent[j],
415 std::vector<types::global_dof_index> constrain_indices;
416 std::vector<std::vector<bool>> constraints_per_block(n_blocks);
428 constrain_indices.resize(0);
433 for (; dof != endd; ++dof)
434 constrain_indices[*dof] = 1;
436 unsigned int index = 0;
437 for (
unsigned int block = 0; block < n_blocks; ++block)
441 constraints_per_block[block].resize(0);
442 constraints_per_block[block].resize(n_dofs,
false);
444 constraints_per_block[block][i] =
445 (constrain_indices[index] == 1);
451 ->block(block, block)
455 for (; start_row != end_row; ++start_row)
457 if (constraints_per_block[block][start_row->column()])
458 start_row->value() = 0.;
466template <
typename number>
467template <
int dim,
int spacedim>
476 selected_block = select;
477 selected.resize(n_blocks,
false);
478 selected[select] =
true;
482 std::vector<types::global_dof_index> temp_copy_indices;
483 std::vector<types::global_dof_index> global_dof_indices(fe.
n_dofs_per_cell());
484 std::vector<types::global_dof_index> level_dof_indices(fe.
n_dofs_per_cell());
494 temp_copy_indices.resize(0);
495 temp_copy_indices.resize(sizes[
level][selected_block],
500 for (; level_cell != level_end; ++level_cell)
506 level_cell->get_dof_indices(global_dof_indices);
507 level_cell->get_mg_dof_indices(level_dof_indices);
514 if (mg_constrained_dofs !=
nullptr)
516 if (!mg_constrained_dofs->at_refinement_edge(
517 level, level_dof_indices[i]))
518 temp_copy_indices[level_dof_indices[i] -
519 mg_block_start[
level][block]] =
520 global_dof_indices[i] - block_start[block];
523 temp_copy_indices[level_dof_indices[i] -
524 mg_block_start[
level][block]] =
525 global_dof_indices[i] - block_start[block];
537 std::count_if(temp_copy_indices.begin(),
538 temp_copy_indices.end(),
540 return index != numbers::invalid_dof_index;
542 copy_indices[selected_block][
level].resize(n_active_dofs);
546 copy_indices[selected_block][
level][counter++] =
547 std::pair<types::global_dof_index, unsigned int>(
548 temp_copy_indices[i], i);
554template <
typename number>
555template <
int dim,
int spacedim>
558 const std::vector<bool> &sel)
565 Assert(sel.size() == n_blocks,
569 if (selected.empty())
570 selected = std::vector<bool>(n_blocks,
true);
574 std::vector<std::vector<types::global_dof_index>> temp_copy_indices(n_blocks);
575 std::vector<types::global_dof_index> global_dof_indices(fe.
n_dofs_per_cell());
576 std::vector<types::global_dof_index> level_dof_indices(fe.
n_dofs_per_cell());
585 for (
unsigned int block = 0; block < n_blocks; ++block)
588 temp_copy_indices[block].resize(0);
589 temp_copy_indices[block].resize(sizes[
level][block],
595 for (; level_cell != level_end; ++level_cell)
601 level_cell->get_dof_indices(global_dof_indices);
602 level_cell->get_mg_dof_indices(level_dof_indices);
608 temp_copy_indices[block][level_dof_indices[i] -
609 mg_block_start[
level][block]] =
610 global_dof_indices[i] - block_start[block];
614 for (
unsigned int block = 0; block < n_blocks; ++block)
618 std::count_if(temp_copy_indices[block].
begin(),
619 temp_copy_indices[block].
end(),
623 copy_indices[block][
level].resize(n_active_dofs);
626 i < temp_copy_indices[block].size();
629 copy_indices[block][
level][counter++] =
630 std::pair<types::global_dof_index, unsigned int>(
631 temp_copy_indices[block][i], i);
640#include "multigrid/mg_transfer_block.inst"
BlockType & block(const unsigned int i)
cell_iterator end() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const Triangulation< dim, spacedim > & get_triangulation() const
active_cell_iterator begin_active(const unsigned int level=0) const
active_cell_iterator end_active(const unsigned int level) const
cell_iterator begin(const unsigned int level=0) const
unsigned int n_dofs_per_cell() const
unsigned int n_blocks() const
std::pair< unsigned int, types::global_dof_index > system_to_block_index(const unsigned int component) const
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
size_type n_elements() const
ElementIterator begin() const
ElementIterator end() const
bool have_boundary_indices() const
const IndexSet & get_boundary_indices(const unsigned int level) const
std::vector< unsigned int > mg_block
std::vector< std::vector< types::global_dof_index > > sizes
void build(const DoFHandler< dim, spacedim > &dof_handler)
std::vector< bool > selected
std::vector< types::global_dof_index > block_start
std::vector< std::shared_ptr< BlockSparseMatrix< double > > > prolongation_matrices
std::vector< std::shared_ptr< BlockSparsityPattern > > prolongation_sparsities
ObserverPointer< const MGConstrainedDoFs, MGTransferBlockBase > mg_constrained_dofs
std::vector< std::vector< types::global_dof_index > > mg_block_start
std::vector< std::vector< std::vector< std::pair< unsigned int, unsigned int > > > > copy_indices
void copy_to_mg(const DoFHandler< dim, spacedim > &dof_handler, MGLevelObject< Vector< number > > &dst, const Vector< number2 > &src) const
void build(const DoFHandler< dim, spacedim > &dof_handler, unsigned int selected)
void build(const DoFHandler< dim, spacedim > &dof_handler, const std::vector< bool > &selected)
void copy_to_mg(const DoFHandler< dim, spacedim > &dof_handler, MGLevelObject< BlockVector< number > > &dst, const BlockVector< number2 > &src) const
unsigned int n_levels() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
typename ActiveSelector::cell_iterator cell_iterator
typename ActiveSelector::active_cell_iterator active_cell_iterator
std::enable_if_t< IsBlockVector< VectorType >::value, unsigned int > n_blocks(const VectorType &vector)
constexpr types::global_dof_index invalid_dof_index
constexpr unsigned int invalid_unsigned_int