From 9767ac4cb3fc62e05ab6a8d65650d7a9fa62ded4 Mon Sep 17 00:00:00 2001 From: guido Date: Fri, 27 Aug 2004 12:38:27 +0000 Subject: [PATCH] avoid expensive computation in MGTools::reinit_vector git-svn-id: https://svn.dealii.org/trunk@9592 0785d39b-7218-0410-832d-ea1e28bc413d --- .../deal.II/include/multigrid/mg_dof_tools.h | 12 ++--- .../deal.II/include/multigrid/mg_transfer.h | 9 +++- .../include/multigrid/mg_transfer.templates.h | 6 ++- .../deal.II/source/multigrid/mg_dof_tools.cc | 25 +++++++---- .../source/multigrid/mg_transfer_block.cc | 44 ++++++++++++++++++- 5 files changed, 77 insertions(+), 19 deletions(-) diff --git a/deal.II/deal.II/include/multigrid/mg_dof_tools.h b/deal.II/deal.II/include/multigrid/mg_dof_tools.h index fd12cf46e4..5b1271df7c 100644 --- a/deal.II/deal.II/include/multigrid/mg_dof_tools.h +++ b/deal.II/deal.II/include/multigrid/mg_dof_tools.h @@ -180,10 +180,10 @@ class MGTools */ template static void - reinit_vector (const MGDoFHandler &mg_dof, - MGLevelObject > &v, - const std::vector &selected = std::vector(), - const std::vector &target_component + reinit_vector (const MGDoFHandler& mg_dof, + MGLevelObject >& v, + const std::vector& selected = std::vector(), + const std::vector& target_component = std::vector()); /** * Adjust vectors on all levels @@ -216,7 +216,9 @@ class MGTools reinit_vector (const MGDoFHandler &mg_dof, MGLevelObject > &v, const std::vector &selected, - const std::vector &target_component); + const std::vector &target_component, + std::vector >& cached_sizes + = std::vector >()); }; diff --git a/deal.II/deal.II/include/multigrid/mg_transfer.h b/deal.II/deal.II/include/multigrid/mg_transfer.h index ff4f49e383..1e34181d94 100644 --- a/deal.II/deal.II/include/multigrid/mg_transfer.h +++ b/deal.II/deal.II/include/multigrid/mg_transfer.h @@ -299,7 +299,7 @@ class MGTransferBlockBase /** * Sizes of the multi-level vectors. */ - std::vector > sizes; + mutable std::vector > sizes; /** * Start index of each component. @@ -347,7 +347,12 @@ class MGTransferBlockBase std::vector > > prolongation_matrices; #endif - std::vector > > + /** + * Unused now, but intended to + * hold the mapping for the + * copy_to/from_mg-functions. + */ + std::vector > copy_to_and_from_indices; }; 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 309f822c6c..db3e7a5b3c 100644 --- a/deal.II/deal.II/include/multigrid/mg_transfer.templates.h +++ b/deal.II/deal.II/include/multigrid/mg_transfer.templates.h @@ -356,7 +356,7 @@ MGTransferSelect::do_copy_to_mg ( ExcMatricesNotBuilt()); MGTools::reinit_vector(mg_dof_handler, dst, - mg_selected, mg_target_component); + mg_selected, mg_target_component, sizes); std::vector global_dof_indices (dofs_per_cell); std::vector level_dof_indices (dofs_per_cell); @@ -386,7 +386,8 @@ MGTransferSelect::do_copy_to_mg ( // already have built. for (int level=maxlevel; level>=static_cast(minlevel); --level) { - typename MGDoFHandler::active_cell_iterator + + typename MGDoFHandler::active_cell_iterator level_cell = mg_dof_handler.begin_active(level); const typename MGDoFHandler::active_cell_iterator level_end = mg_dof_handler.end_active(level); @@ -423,6 +424,7 @@ MGTransferSelect::do_copy_to_mg ( = src(global_dof_indices[*i] - offset); } } + // for that part of the level // which is further refined: // get the defect by diff --git a/deal.II/deal.II/source/multigrid/mg_dof_tools.cc b/deal.II/deal.II/source/multigrid/mg_dof_tools.cc index efffe1984c..268613979e 100644 --- a/deal.II/deal.II/source/multigrid/mg_dof_tools.cc +++ b/deal.II/deal.II/source/multigrid/mg_dof_tools.cc @@ -13,6 +13,7 @@ #include +#include #include #include #include @@ -353,7 +354,7 @@ MGTools::count_dofs_per_component ( dofs_in_component[i]); }; threads.join_all(); - + // next count what we got for (unsigned int i=0; i &mg_dof, MGLevelObject > &v, const std::vector &selected, - const std::vector &target_component) + const std::vector &target_component, + std::vector >& ndofs) { Assert (selected.size() == target_component.size(), ExcDimensionMismatch(selected.size(), target_component.size())); @@ -479,12 +481,15 @@ MGTools::reinit_vector (const MGDoFHandler &mg_dof, unsigned int selected_block = 0; while (!selected[selected_block]) ++selected_block; - - std::vector > - ndofs(mg_dof.get_tria().n_levels(), - std::vector(target_component.size())); - count_dofs_per_component (mg_dof, ndofs, target_component); + if (ndofs.size() == 0) + { + std::vector > + new_dofs(mg_dof.get_tria().n_levels(), + std::vector(target_component.size())); + std::swap(ndofs, new_dofs); + count_dofs_per_component (mg_dof, ndofs, target_component); + } for (unsigned int level=v.get_minlevel(); level<=v.get_maxlevel();++level) @@ -610,12 +615,14 @@ template void MGTools::reinit_vector ( const MGDoFHandler&, MGLevelObject >&, const std::vector&, - const std::vector&); + const std::vector&, + std::vector >&); template void MGTools::reinit_vector ( const MGDoFHandler&, MGLevelObject >&, const std::vector&, - const std::vector&); + const std::vector&, + std::vector >&); template void MGTools::count_dofs_per_component ( diff --git a/deal.II/deal.II/source/multigrid/mg_transfer_block.cc b/deal.II/deal.II/source/multigrid/mg_transfer_block.cc index defa69125b..04cea80a77 100644 --- a/deal.II/deal.II/source/multigrid/mg_transfer_block.cc +++ b/deal.II/deal.II/source/multigrid/mg_transfer_block.cc @@ -31,7 +31,7 @@ template void MGTransferBlockBase::build_matrices ( - const DoFHandler& dof, + const DoFHandler&, const MGDoFHandler& mg_dof) { // Fill target component with @@ -127,6 +127,8 @@ void MGTransferBlockBase::build_matrices ( // be prebuilt, since the // get_dof_indices functions are // too slow + + copy_to_and_from_indices.resize(n_levels); // Building the prolongation matrices starts here! @@ -356,6 +358,7 @@ void MGTransferSelect::build_matrices ( const std::vector& t_component, const std::vector& mg_t_component) { + const FiniteElement& fe = mg_dof.get_fe(); unsigned int ncomp = mg_dof.get_fe().n_components(); target_component = t_component; @@ -389,6 +392,45 @@ void MGTransferSelect::build_matrices ( } } MGTransferBlockBase::build_matrices (dof, mg_dof); +//TODO:[GK] Rewrite this to suit MGTransferBlock and move to base class + + std::vector global_dof_indices (fe.dofs_per_cell); + std::vector level_dof_indices (fe.dofs_per_cell); + for (int level=dof.get_tria().n_levels()-1; level>=0; --level) + { + typename MGDoFHandler::active_cell_iterator + level_cell = mg_dof.begin_active(level); + const typename MGDoFHandler::active_cell_iterator + level_end = mg_dof.end_active(level); + + // Compute coarse level right hand side + // by restricting from fine level. + for (; level_cell!=level_end; ++level_cell) + { + DoFObjectAccessor& global_cell = *level_cell; + // get the dof numbers of + // this cell for the global + // and the level-wise + // numbering + global_cell.get_dof_indices(global_dof_indices); + level_cell->get_mg_dof_indices (level_dof_indices); + + for (unsigned int i=0; i