17 #include <deal.II/base/logstream.h> 18 #include <deal.II/base/function.h> 20 #include <deal.II/lac/vector.h> 21 #include <deal.II/lac/block_vector.h> 22 #include <deal.II/lac/block_indices.h> 23 #include <deal.II/lac/sparse_matrix.h> 24 #include <deal.II/lac/block_sparse_matrix.h> 25 #include <deal.II/grid/tria.h> 26 #include <deal.II/grid/tria_iterator.h> 27 #include <deal.II/dofs/dof_tools.h> 28 #include <deal.II/fe/fe.h> 29 #include <deal.II/dofs/dof_accessor.h> 30 #include <deal.II/multigrid/mg_transfer_component.h> 31 #include <deal.II/multigrid/mg_transfer_component.templates.h> 32 #include <deal.II/multigrid/mg_tools.h> 38 DEAL_II_NAMESPACE_OPEN
77 template <
int dim,
typename number,
int spacedim>
79 reinit_vector_by_components (
80 const ::DoFHandler<dim,spacedim> &mg_dof,
82 const std::vector<bool> &sel,
83 const std::vector<unsigned int> &target_comp,
84 std::vector<std::vector<types::global_dof_index> > &ndofs)
86 std::vector<bool> selected=sel;
87 std::vector<unsigned int> target_component=target_comp;
88 const unsigned int ncomp = mg_dof.get_fe().n_components();
99 if (target_component.size() == 0)
101 target_component.resize(ncomp);
102 for (
unsigned int i=0; i<ncomp; ++i)
103 target_component[i] = i;
108 if (selected.size() == 0)
110 selected.resize(target_component.size());
111 std::fill_n (selected.begin(), ncomp,
false);
112 for (
unsigned int i=0; i<target_component.size(); ++i)
113 selected[target_component[i]] =
true;
116 Assert (selected.size() == target_component.size(),
117 ExcDimensionMismatch(selected.size(), target_component.size()));
120 const unsigned int n_selected
121 = std::accumulate(selected.begin(),
125 if (ndofs.size() == 0)
127 std::vector<std::vector<types::global_dof_index> >
128 new_dofs(mg_dof.get_triangulation().n_levels(),
129 std::vector<types::global_dof_index>(target_component.size()));
130 std::swap(ndofs, new_dofs);
134 for (
unsigned int level=v.min_level();
135 level<=v.max_level(); ++level)
137 v[level].reinit(n_selected, 0);
139 for (
unsigned int i=0; i<selected.size() && (k<v[level].n_blocks()); ++i)
143 v[level].block(k++).reinit(ndofs[level][i]);
145 v[level].collect_sizes();
177 template <
int dim,
typename number,
int spacedim>
179 reinit_vector_by_components (
180 const ::DoFHandler<dim,spacedim> &mg_dof,
183 const std::vector<unsigned int> &target_component,
184 std::vector<std::vector<types::global_dof_index> > &ndofs)
187 ExcMessage (
"The component mask does not have the correct size."));
189 unsigned int selected_block = 0;
190 for (
unsigned int i=0; i<target_component.size(); ++i)
191 if (component_mask[i])
192 selected_block = target_component[i];
194 if (ndofs.size() == 0)
196 std::vector<std::vector<types::global_dof_index> >
197 new_dofs(mg_dof.get_triangulation().n_levels(),
198 std::vector<types::global_dof_index>(target_component.size()));
199 std::swap(ndofs, new_dofs);
204 for (
unsigned int level=v.min_level();
205 level<=v.max_level(); ++level)
207 v[level].reinit(ndofs[level][selected_block]);
213 template <
typename number>
214 template <
int dim,
class InVector,
int spacedim>
219 const InVector &src)
const 224 ExcMatricesNotBuilt());
226 reinit_vector_by_components(mg_dof_handler, dst,
228 mg_target_component, sizes);
242 for (
unsigned int level=mg_dof_handler.
get_triangulation().n_levels(); level!=0;)
246 typedef std::vector<std::pair<types::global_dof_index, unsigned int> >::const_iterator IT;
247 for (IT i=copy_to_and_from_indices[level].begin();
248 i != copy_to_and_from_indices[level].end(); ++i)
249 dst[level](i->second) = src(i->first);
256 restrict_and_add (level+1, dst[level], dst[level+1]);
262 template <
int dim,
int spacedim>
270 if (target_component.size() == 0)
272 target_component.resize(mg_dof.
get_fe().n_components());
273 for (
unsigned int i=0; i<target_component.size(); ++i)
274 target_component[i] = i;
279 Assert (target_component.size() == mg_dof.
get_fe().n_components(),
280 ExcDimensionMismatch(target_component.size(),
281 mg_dof.
get_fe().n_components()));
283 for (
unsigned int i=0; i<target_component.size(); ++i)
285 Assert(i<target_component.size(),
286 ExcIndexRange(i,0,target_component.size()));
302 mg_dof.
get_fe().n_components()));
318 const unsigned int n_components =
324 ExcMessage (
"Component mask has wrong size."));
327 sizes.resize(n_levels);
328 for (
unsigned int l=0; l<n_levels; ++l)
329 sizes[l].resize(n_components);
349 target_component.end()) + 1);
383 prolongation_sparsities.resize (0);
385 for (
unsigned int i=0; i<n_levels-1; ++i)
387 prolongation_sparsities
396 std::vector<types::global_dof_index> dof_indices_parent (dofs_per_cell);
397 std::vector<types::global_dof_index> dof_indices_child (dofs_per_cell);
406 for (
unsigned int level=0; level<n_levels-1; ++level)
416 prolongation_sparsities[level]->reinit (n_components, n_components);
417 for (
unsigned int i=0; i<n_components; ++i)
418 for (
unsigned int j=0; j<n_components; ++j)
420 prolongation_sparsities[level]->block(i,j)
421 .reinit(
sizes[level+1][i],
425 prolongation_sparsities[level]->block(i,j)
426 .reinit(
sizes[level+1][i],
430 prolongation_sparsities[level]->collect_sizes();
433 cell != mg_dof.
end(level); ++cell)
434 if (cell->has_children())
436 cell->get_mg_dof_indices (dof_indices_parent);
438 for (
unsigned int child=0; child<cell->n_children(); ++child)
444 = mg_dof.
get_fe().get_prolongation_matrix (child, cell->refinement_case());
446 cell->child(child)->get_mg_dof_indices (dof_indices_child);
451 for (
unsigned int i=0; i<dofs_per_cell; ++i)
452 for (
unsigned int j=0; j<dofs_per_cell; ++j)
453 if (prolongation(i,j) != 0)
455 const unsigned int icomp
457 const unsigned int jcomp
460 prolongation_sparsities[level]->add(dof_indices_child[i],
461 dof_indices_parent[j]);
465 prolongation_sparsities[level]->compress ();
470 cell != mg_dof.
end(level); ++cell)
471 if (cell->has_children())
473 cell->get_mg_dof_indices (dof_indices_parent);
475 for (
unsigned int child=0; child<cell->n_children(); ++child)
481 = mg_dof.
get_fe().get_prolongation_matrix (child, cell->refinement_case());
483 cell->child(child)->get_mg_dof_indices (dof_indices_child);
487 for (
unsigned int i=0; i<dofs_per_cell; ++i)
488 for (
unsigned int j=0; j<dofs_per_cell; ++j)
489 if (prolongation(i,j) != 0)
495 dof_indices_parent[j],
508 std::vector<std::vector<types::global_dof_index> >
510 std::vector<types::global_dof_index>(n_components));
513 for (
unsigned int level=0; level<n_levels-1; ++level)
518 for (
unsigned int iblock=0; iblock<n_components; ++iblock)
519 for (
unsigned int jblock=0; jblock<n_components; ++jblock)
527 for (; anfang != ende; ++anfang)
532 const BlockIndices block_indices_coarse (dofs_per_component[level]);
535 std::set<types::global_dof_index>::const_iterator found_dof =
538 const bool is_boundary_index =
541 if (is_boundary_index)
544 .set(i,column_number,0);
554 template <
typename number>
555 template <
int dim,
int spacedim>
560 unsigned int mg_select,
561 const std::vector<unsigned int> &t_component,
562 const std::vector<unsigned int> &mg_t_component,
563 const std::vector<std::set<types::global_dof_index> > &bdry_indices)
566 unsigned int ncomp = mg_dof.
get_fe().n_components();
568 target_component = t_component;
572 selected_component = select;
573 mg_selected_component = mg_select;
576 std::vector<bool> tmp(ncomp,
false);
577 for (
unsigned int c=0; c<ncomp; ++c)
578 if (t_component[c] == selected_component)
584 std::vector<bool> tmp(ncomp,
false);
585 for (
unsigned int c=0; c<ncomp; ++c)
586 if (mg_t_component[c] == mg_selected_component)
595 for (
unsigned int i=0; i<target_component.size(); ++i)
597 if (target_component[i] == select)
599 selected_component = i;
608 mg_selected_component = i;
618 interface_dofs[l].clear();
619 interface_dofs[l].set_size(mg_dof.
n_dofs(l));
625 std::vector<types::global_dof_index> temp_copy_indices;
626 std::vector<types::global_dof_index> global_dof_indices (fe.
dofs_per_cell);
627 std::vector<types::global_dof_index> level_dof_indices (fe.
dofs_per_cell);
636 temp_copy_indices.resize (0);
641 for (; level_cell!=level_end; ++level_cell)
647 level_cell->get_dof_indices(global_dof_indices);
648 level_cell->get_mg_dof_indices (level_dof_indices);
652 const unsigned int component
654 if (component_mask[component] &&
655 !interface_dofs[level].is_element(level_dof_indices[i]))
661 temp_copy_indices[level_dof_indices[i]-level_start] =
662 global_dof_indices[i] - global_start;
670 std::count_if (temp_copy_indices.begin(), temp_copy_indices.end(),
671 std::bind2nd(std::not_equal_to<types::global_dof_index>(),
678 std::pair<types::global_dof_index, unsigned int> (temp_copy_indices[i], i);
679 Assert (counter == n_active_dofs, ExcInternalError());
686 #include "mg_transfer_component.inst" 689 DEAL_II_NAMESPACE_CLOSE
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 > >())
cell_iterator begin(const unsigned int level=0) const
std::vector< std::set< types::global_dof_index > > boundary_indices
::ExceptionBase & ExcMessage(std::string arg1)
cell_iterator end() const
Auxiliary class aiding in the handling of block structures like in BlockVector or FESystem...
bool represents_n_components(const unsigned int n) const
ActiveSelector::active_cell_iterator active_cell_iterator
std::vector< std_cxx11::shared_ptr< BlockSparseMatrix< double > > > prolongation_matrices
const FiniteElement< dim, spacedim > & get_fe() const
active_cell_iterator begin_active(const unsigned int level=0) const
ActiveSelector::cell_iterator cell_iterator
ComponentMask mg_component_mask
unsigned int global_dof_index
#define Assert(cond, exc)
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
std::vector< unsigned int > mg_target_component
void do_copy_to_mg(const DoFHandler< dim, spacedim > &mg_dof, MGLevelObject< Vector< number > > &dst, const InVector &src) const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
unsigned int n_components() const
const Triangulation< dim, spacedim > & get_triangulation() const
std::vector< std::vector< types::global_dof_index > > mg_component_start
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