From 3f7ef489d157bca4eeaea9fa9412e849a77d7e1e Mon Sep 17 00:00:00 2001 From: janssen Date: Fri, 5 Feb 2010 13:50:34 +0000 Subject: [PATCH] prepared the MGTransferSelect for adaptive refinement, cleaned up in mg_tools.h git-svn-id: https://svn.dealii.org/trunk@20505 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/deal.II/include/multigrid/mg_tools.h | 11 ++ .../deal.II/include/multigrid/mg_transfer.h | 32 +---- .../include/multigrid/mg_transfer.templates.h | 69 +---------- .../include/multigrid/mg_transfer_component.h | 68 ++++++++-- .../mg_transfer_component.templates.h | 116 ++++++++---------- .../include/multigrid/multigrid.templates.h | 27 +++- 6 files changed, 151 insertions(+), 172 deletions(-) diff --git a/deal.II/deal.II/include/multigrid/mg_tools.h b/deal.II/deal.II/include/multigrid/mg_tools.h index d421dffcdf..6967a36a6d 100644 --- a/deal.II/deal.II/include/multigrid/mg_tools.h +++ b/deal.II/deal.II/include/multigrid/mg_tools.h @@ -243,6 +243,7 @@ class MGTools std::vector >& boundary_indices, const std::vector& component_mask = std::vector()); /** + * Maybe no longer needed. */ template @@ -282,6 +283,16 @@ class MGTools extract_inner_interface_dofs (const MGDoFHandler &mg_dof_handler, std::vector > &interface_dofs, std::vector > &boundary_interface_dofs); + + /** + * Does the same as the function above, + * but fills only the interface_dofs. + */ + template + static + void + extract_inner_interface_dofs (const MGDoFHandler &mg_dof_handler, + std::vector > &interface_dofs); }; /*@}*/ diff --git a/deal.II/deal.II/include/multigrid/mg_transfer.h b/deal.II/deal.II/include/multigrid/mg_transfer.h index 670ed5f0b3..0a7e9b618c 100644 --- a/deal.II/deal.II/include/multigrid/mg_transfer.h +++ b/deal.II/deal.II/include/multigrid/mg_transfer.h @@ -86,7 +86,9 @@ class MGTransferPrebuilt : public MGTransferBase * matrices for each level. */ template - void build_matrices (const MGDoFHandler &mg_dof); + void build_matrices (const MGDoFHandler &mg_dof, + const std::vector >&boundary_indices + ); virtual void prolongate (const unsigned int to_level, VECTOR &dst, @@ -220,7 +222,7 @@ class MGTransferPrebuilt : public MGTransferBase * The data is first the global * index, then the level index. */ - std::vector > > + std::vector > copy_indices; /** @@ -231,36 +233,12 @@ class MGTransferPrebuilt : public MGTransferBase */ std::vector component_to_block_map; - /** - * Fill the two boolean vectors - * #dofs_on_refinement_edge and - * #dofs_on_refinement_boundary. - */ - template - void find_dofs_on_refinement_edges ( - const MGDoFHandler& mg_dof); - /** * Degrees of freedom on the * refinement edge excluding * those on the boundary. - * - * @todo Clean up names - */ - std::vector > dofs_on_refinement_edge; - /** - * The degrees of freedom on the - * the refinement edges. For each - * level (outer vector) and each - * dof index (inner vector), this - * bool is true if the level - * degree of freedom is on the - * refinement edge towards the - * lower level. - * - * @todo Clean up names */ - std::vector > dofs_on_refinement_boundary; + std::vector > interface_dofs; /** * The constraints of the global * system. diff --git a/deal.II/deal.II/include/multigrid/mg_transfer.templates.h b/deal.II/deal.II/include/multigrid/mg_transfer.templates.h index 96cdc1c4f7..ac3e9308d8 100644 --- a/deal.II/deal.II/include/multigrid/mg_transfer.templates.h +++ b/deal.II/deal.II/include/multigrid/mg_transfer.templates.h @@ -28,7 +28,6 @@ DEAL_II_NAMESPACE_OPEN /* --------------------- MGTransferPrebuilt -------------- */ -typedef std::vector >::const_iterator IT; @@ -50,6 +49,7 @@ MGTransferPrebuilt::copy_from_mg( dst = 0; for (unsigned int level=0;level::const_iterator IT; for (IT i= copy_indices[level].begin(); i != copy_indices[level].end();++i) dst(i->first) = src[level](i->second); @@ -76,9 +76,12 @@ MGTransferPrebuilt::copy_from_mg_add ( // have fine level basis // functions for (unsigned int level=0;level::const_iterator IT; for (IT i= copy_indices[level].begin(); i != copy_indices[level].end();++i) dst(i->first) += src[level](i->second); + } } @@ -91,70 +94,6 @@ set_component_to_block_map (const std::vector &map) component_to_block_map = map; } - - -template -template -void MGTransferPrebuilt::find_dofs_on_refinement_edges ( - const MGDoFHandler& mg_dof) -{ - for (unsigned int level = 0; level tmp (mg_dof.n_dofs(level)); - dofs_on_refinement_edge.push_back (tmp); - dofs_on_refinement_boundary.push_back (tmp); - } - - const unsigned int dofs_per_cell = mg_dof.get_fe().dofs_per_cell; - const unsigned int dofs_per_face = mg_dof.get_fe().dofs_per_face; - - std::vector local_dof_indices (dofs_per_cell); - std::vector face_dof_indices (dofs_per_face); - - typename MGDoFHandler::cell_iterator cell = mg_dof.begin(), - endc = mg_dof.end(); - - for (; cell!=endc; ++cell) - { - std::vector cell_dofs(dofs_per_cell); - std::vector boundary_cell_dofs(dofs_per_cell); - const unsigned int level = cell->level(); - cell->get_mg_dof_indices (local_dof_indices); - for (unsigned int face_nr=0; - face_nr::faces_per_cell; ++face_nr) - { - typename DoFHandler::face_iterator face = cell->face(face_nr); - if(!cell->at_boundary(face_nr)) - { - //interior face - typename MGDoFHandler::cell_iterator neighbor - = cell->neighbor(face_nr); - // Do refinement face - // from the coarse side - if (neighbor->level() < cell->level()) - { - for(unsigned int j=0; j unsigned int MGTransferPrebuilt::memory_consumption () const diff --git a/deal.II/deal.II/include/multigrid/mg_transfer_component.h b/deal.II/deal.II/include/multigrid/mg_transfer_component.h index f1d24840d1..ea98f0b957 100644 --- a/deal.II/deal.II/include/multigrid/mg_transfer_component.h +++ b/deal.II/deal.II/include/multigrid/mg_transfer_component.h @@ -16,6 +16,7 @@ #include #include +#include #ifdef DEAL_PREFER_MATRIX_EZ # include # include @@ -135,13 +136,13 @@ class MGTransferComponentBase * Start index of each component. */ std::vector component_start; - + /** * Start index of each component on * all levels. */ std::vector > mg_component_start; - + /** * Call build_matrices() * function first. @@ -164,12 +165,21 @@ class MGTransferComponentBase std::vector > > prolongation_matrices; /** - * Unused now, but intended to - * hold the mapping for the + * Holds the mapping for the * copy_to/from_mg-functions. + * The data is first the global + * index, then the level index. */ std::vector > copy_to_and_from_indices; + + /** + * Store the boundary_indices. + * These are needed for the + * boundary values in the + * restriction matrix. + */ + std::vector > boundary_indices; }; //TODO:[GK] Update documentation for copy_* functions @@ -191,6 +201,20 @@ class MGTransferSelect : public MGTransferBase >, private MGTransferComponentBase { public: + /** + * Constructor without constraint + * matrices. Use this constructor + * only with discontinuous finite + * elements or with no local + * refinement. + */ + MGTransferSelect (); + + /** + * Constructor with constraint matrices. + */ + MGTransferSelect (const ConstraintMatrix& constraints); + /** * Destructor. */ @@ -233,6 +257,9 @@ class MGTransferSelect : public MGTransferBase >, * DoFRenumbering::component_wise). It * also affects the behavior of * the selected argument + * + * @arg boundary_indices: holds the + * boundary indices on each level. */ template void build_matrices (const DoFHandler &dof, @@ -242,7 +269,10 @@ class MGTransferSelect : public MGTransferBase >, const std::vector& target_component = std::vector(), const std::vector& mg_target_component - = std::vector()); + = std::vector(), + const std::vector >& boundary_indices + = std::vector >() + ); /** * Change selected @@ -352,8 +382,7 @@ class MGTransferSelect : public MGTransferBase >, void do_copy_from_mg (const MGDoFHandler &mg_dof, OutVector &dst, - const MGLevelObject > &src, - const unsigned int offset) const; + const MGLevelObject > &src) const; /** * Implementation of the public @@ -363,8 +392,7 @@ class MGTransferSelect : public MGTransferBase >, void do_copy_from_mg_add (const MGDoFHandler &mg_dof, OutVector &dst, - const MGLevelObject > &src, - const unsigned int offset) const; + const MGLevelObject > &src) const; /** * Actual implementation of @@ -374,8 +402,7 @@ class MGTransferSelect : public MGTransferBase >, void do_copy_to_mg (const MGDoFHandler &mg_dof, MGLevelObject > &dst, - const InVector &src, - const unsigned int offset) const; + const InVector &src) const; /** * Selected component of global vector. */ @@ -384,6 +411,25 @@ class MGTransferSelect : public MGTransferBase >, * Selected component inside multigrid. */ unsigned int mg_selected_component; + + /** + * The degrees of freedom on the + * the refinement edges. For each + * level (outer vector) and each + * dof index (inner vector), this + * bool is true if the level + * degree of freedom is on the + * refinement edge towards the + * lower level excluding boundary dofs. + */ + std::vector > interface_dofs; + + /** + * The constraints of the global + * system. + */ + public: + SmartPointer constraints; }; /*@}*/ diff --git a/deal.II/deal.II/include/multigrid/mg_transfer_component.templates.h b/deal.II/deal.II/include/multigrid/mg_transfer_component.templates.h index 4765f323c9..301c987de5 100644 --- a/deal.II/deal.II/include/multigrid/mg_transfer_component.templates.h +++ b/deal.II/deal.II/include/multigrid/mg_transfer_component.templates.h @@ -22,8 +22,11 @@ #include #include #include +#include #include +#include +#include DEAL_II_NAMESPACE_OPEN @@ -39,7 +42,7 @@ MGTransferSelect::copy_to_mg ( MGLevelObject > &dst, const BlockVector &src) const { - do_copy_to_mg (mg_dof_handler, dst, src, 0); + do_copy_to_mg (mg_dof_handler, dst, src); } @@ -52,7 +55,7 @@ MGTransferSelect::copy_to_mg ( MGLevelObject > &dst, const Vector &src) const { - do_copy_to_mg (mg_dof_handler, dst, src, component_start[selected_component]); + do_copy_to_mg (mg_dof_handler, dst, src); } @@ -65,7 +68,9 @@ MGTransferSelect::copy_from_mg ( BlockVector& dst, const MGLevelObject >& src) const { - do_copy_from_mg (mg_dof_handler, dst, src, 0); + do_copy_from_mg (mg_dof_handler, dst, src); + if (constraints != 0) + constraints->condense(dst); } @@ -78,8 +83,30 @@ MGTransferSelect::copy_from_mg ( Vector& dst, const MGLevelObject >& src) const { - do_copy_from_mg (mg_dof_handler, dst, src, - component_start[selected_component]); + do_copy_from_mg (mg_dof_handler, dst, src); + if (constraints != 0) + { + //If we were given constraints + //apply them to the dst that goes + //back now to the linear solver. + //Since constraints are globally + //defined create a global vector here + //and copy dst to the right component, + //apply the constraints then and copy + //the block back to dst. + const unsigned int n_blocks = + *std::max_element(target_component.begin(), target_component.end()) + 1; + std::vector dofs_per_block (n_blocks); + DoFTools::count_dofs_per_block (mg_dof_handler, dofs_per_block, target_component); + BlockVector tmp; + tmp.reinit(n_blocks); + for(unsigned int b=0; bcondense(tmp); + dst = tmp.block(target_component[selected_component]); + } } @@ -92,7 +119,7 @@ MGTransferSelect::copy_from_mg_add ( BlockVector& dst, const MGLevelObject >& src) const { - do_copy_from_mg_add (mg_dof_handler, dst, src, 0); + do_copy_from_mg_add (mg_dof_handler, dst, src); } @@ -105,8 +132,7 @@ MGTransferSelect::copy_from_mg_add ( Vector& dst, const MGLevelObject >& src) const { - do_copy_from_mg_add (mg_dof_handler, dst, src, - component_start[selected_component]); + do_copy_from_mg_add (mg_dof_handler, dst, src); } @@ -117,14 +143,13 @@ void MGTransferSelect::do_copy_from_mg ( const MGDoFHandler &mg_dof_handler, OutVector &dst, - const MGLevelObject > &src, - const unsigned int offset) const + const MGLevelObject > &src) const { - const FiniteElement& fe = mg_dof_handler.get_fe(); +// const FiniteElement& fe = mg_dof_handler.get_fe(); - const unsigned int dofs_per_cell = fe.dofs_per_cell; - std::vector global_dof_indices (dofs_per_cell); - std::vector level_dof_indices (dofs_per_cell); +// const unsigned int dofs_per_cell = fe.dofs_per_cell; +// std::vector global_dof_indices (dofs_per_cell); +// std::vector level_dof_indices (dofs_per_cell); typename MGDoFHandler::active_cell_iterator level_cell = mg_dof_handler.begin_active(); @@ -137,44 +162,25 @@ MGTransferSelect::do_copy_from_mg ( // Note that the level is // monotonuosly increasing + dst = 0; for (; level_cell != endc; ++level_cell) - { - const unsigned int level = level_cell->level(); - - // get the dof numbers of - // this cell for the global - // and the level-wise - // numbering - level_cell->get_dof_indices (global_dof_indices); - level_cell->get_mg_dof_indices(level_dof_indices); - - // copy level-wise data to - // global vector - for (unsigned int i=0; ilevel(); + typedef std::map::const_iterator IT; + for (IT i=copy_to_and_from_indices[level].begin(); + i != copy_to_and_from_indices[level].end(); ++i) + dst(i->first) = src[level](i->second); + } } - template template void MGTransferSelect::do_copy_from_mg_add ( const MGDoFHandler &mg_dof_handler, OutVector &dst, - const MGLevelObject > &src, - const unsigned int offset) const + const MGLevelObject > &src) const { const FiniteElement& fe = mg_dof_handler.get_fe(); const unsigned int dofs_per_cell = fe.dofs_per_cell; @@ -193,30 +199,14 @@ MGTransferSelect::do_copy_from_mg_add ( // Note that the level is // monotonuosly increasing + dst = 0; for (; level_cell != endc; ++level_cell) { const unsigned int level = level_cell->level(); - - // get the dof numbers of - // this cell for the global - // and the level-wise - // numbering - level_cell->get_dof_indices (global_dof_indices); - level_cell->get_mg_dof_indices(level_dof_indices); - // copy level-wise data to - // global vector - for (unsigned int i=0; i::const_iterator IT; + for (IT i=copy_to_and_from_indices[level].begin(); + i != copy_to_and_from_indices[level].end(); ++i) + dst(i->first) += src[level](i->second); } } diff --git a/deal.II/deal.II/include/multigrid/multigrid.templates.h b/deal.II/deal.II/include/multigrid/multigrid.templates.h index e0710af388..34562a2e90 100644 --- a/deal.II/deal.II/include/multigrid/multigrid.templates.h +++ b/deal.II/deal.II/include/multigrid/multigrid.templates.h @@ -16,7 +16,7 @@ #include -#include "iostream" +#include DEAL_II_NAMESPACE_OPEN @@ -141,8 +141,11 @@ Multigrid::level_v_step(const unsigned int level) deallog << "Smoothing on level " << level << std::endl; // smoothing of the residual by // modifying s +// defect[level].print(std::cout, 2,false); +// std::cout<smooth(level, solution[level], defect[level]); - +// solution[level].print(std::cout, 2,false); + if (debug>2) deallog << "Solution norm " << solution[level].l2_norm() << std::endl; @@ -151,6 +154,8 @@ Multigrid::level_v_step(const unsigned int level) deallog << "Residual on level " << level << std::endl; // t = A*solution[level] matrix->vmult(level, t[level], solution[level]); +// std::cout<::level_v_step(const unsigned int level) { t[l-1] = 0.; if (l==level && edge_out != 0) - edge_out->vmult_add(level, t[level], solution[level]); - + { + edge_out->vmult_add(level, t[level], solution[level]); + deallog << "Norm t[" << level << "] " << t[level].l2_norm() << std::endl; + } + if (l==level && edge_down != 0) edge_down->vmult(level, t[level-1], solution[level]); transfer->restrict_and_add (l, t[l-1], t[l]); + deallog << "restrict t[" << l-1 << "] " << t[l-1].l2_norm() << std::endl; defect[l-1] -= t[l-1]; + deallog << "defect d[" << l-1 << "] " << defect[l-1].l2_norm() << std::endl; } // do recursion @@ -198,14 +208,19 @@ Multigrid::level_v_step(const unsigned int level) } if (debug>2) - deallog << "V-cycle Defect norm " << defect[level].l2_norm() + deallog << "V-cycle Defect norm hier " << defect[level].l2_norm() << std::endl; if (debug>1) deallog << "Smoothing on level " << level << std::endl; // post-smoothing + +// std::cout<smooth(level, solution[level], defect[level]); - +// solution[level].print(std::cout, 2,false); +// std::cout<2) deallog << "Solution norm " << solution[level].l2_norm() << std::endl; -- 2.39.5