From: kronbichler Date: Thu, 4 Feb 2010 11:24:09 +0000 (+0000) Subject: Simplify generation of copy_indices: do this from a std::vector that stores the mappi... X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f3c4e25cc3565a984f4e1b6bcd6b85109d6ae08;p=dealii-svn.git Simplify generation of copy_indices: do this from a std::vector that stores the mapping level_indices <> global_indices, which avoids sorting indices and compressing out duplicates. git-svn-id: https://svn.dealii.org/trunk@20493 0785d39b-7218-0410-832d-ea1e28bc413d --- 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 119432c140..613749c1e2 100644 --- a/deal.II/deal.II/source/multigrid/mg_transfer_block.cc +++ b/deal.II/deal.II/source/multigrid/mg_transfer_block.cc @@ -247,7 +247,8 @@ void MGTransferBlockBase::build_matrices ( } block_start.resize(n_blocks); - DoFTools::count_dofs_per_block (static_cast&>(mg_dof), block_start); + DoFTools::count_dofs_per_block (static_cast&>(mg_dof), + block_start); unsigned int k=0; for (unsigned int i=0;i::build_matrices ( MGTransferBlockBase::build_matrices (dof, mg_dof); + std::vector temp_copy_indices; 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) @@ -431,6 +433,10 @@ void MGTransferBlockSelect::build_matrices ( const typename MGDoFHandler::active_cell_iterator level_end = mg_dof.end_active(level); + temp_copy_indices.resize (0); + temp_copy_indices.resize (sizes[level][selected_block], + numbers::invalid_unsigned_int); + // Compute coarse level right hand side // by restricting from fine level. for (; level_cell!=level_end; ++level_cell) @@ -447,30 +453,28 @@ void MGTransferBlockSelect::build_matrices ( { const unsigned int block = fe.system_to_block_index(i).first; if (selected[block]) - copy_indices[block][level].push_back( - std::make_pair(global_dof_indices[i] - block_start[block], - level_dof_indices[i] - mg_block_start[level][block])); - } - } - // sort the list of dof numbers and compress - // out duplicates - for (unsigned int block=0; block 0) - { - std::sort (copy_indices[block][level].begin(), - copy_indices[block][level].end()); - - std::vector >::iterator - it1 = copy_indices[block][level].begin(), it2 = it1, it3 = it1; - it2++, it1++; - for ( ; it2!=copy_indices[block][level].end(); ++it2, ++it3) - if (*it2 > *it3) - *it1++ = *it2; - copy_indices[block][level].erase(it1,copy_indices[block][level].end()); + temp_copy_indices[level_dof_indices[i] - mg_block_start[level][block]] + = global_dof_indices[i] - block_start[block]; } } + + // now all the active dofs got a valid entry, + // the other ones have an invalid entry. Count + // the invalid entries and then resize the + // copy_indices object. Then, insert the pairs + // of global index and level index into + // copy_indices. + const unsigned int n_active_dofs = + std::count_if (temp_copy_indices.begin(), temp_copy_indices.end(), + std::bind2nd(std::not_equal_to(), + numbers::invalid_unsigned_int)); + copy_indices[selected_block][level].resize (n_active_dofs); + unsigned int counter = 0; + for (unsigned int i=0; i (temp_copy_indices[i], i); + Assert (counter == n_active_dofs, ExcInternalError()); } } @@ -498,6 +502,7 @@ void MGTransferBlock::build_matrices ( MGTransferBlockBase::build_matrices (dof, mg_dof); + std::vector > temp_copy_indices (n_blocks); 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) @@ -507,6 +512,14 @@ void MGTransferBlock::build_matrices ( const typename MGDoFHandler::active_cell_iterator level_end = mg_dof.end_active(level); + for (unsigned int block=0; block::build_matrices ( { const unsigned int block = fe.system_to_block_index(i).first; if (selected[block]) - copy_indices[block][level].push_back( - std::make_pair(global_dof_indices[i] - block_start[block], - level_dof_indices[i] - mg_block_start[level][block])); + temp_copy_indices[block][level_dof_indices[i] - mg_block_start[level][block]] + = global_dof_indices[i] - block_start[block]; } } for (unsigned int block=0; block 0) - { - std::sort (copy_indices[block][level].begin(), - copy_indices[block][level].end()); - - std::vector >::iterator - it1 = copy_indices[block][level].begin(), it2 = it1, it3 = it1; - it2++, it1++; - for ( ; it2!=copy_indices[block][level].end(); ++it2, ++it3) - if (*it2 > *it3) - *it1++ = *it2; - copy_indices[block][level].erase(it1,copy_indices[block][level].end()); - } - } + if (selected[block]) + { + const unsigned int n_active_dofs = + std::count_if (temp_copy_indices[block].begin(), + temp_copy_indices[block].end(), + std::bind2nd(std::not_equal_to(), + numbers::invalid_unsigned_int)); + copy_indices[block][level].resize (n_active_dofs); + unsigned int counter = 0; + for (unsigned int i=0; i + (temp_copy_indices[block][i], i); + Assert (counter == n_active_dofs, ExcInternalError()); + } } } diff --git a/deal.II/deal.II/source/multigrid/mg_transfer_prebuilt.cc b/deal.II/deal.II/source/multigrid/mg_transfer_prebuilt.cc index 8e3972bf72..e4f958f789 100644 --- a/deal.II/deal.II/source/multigrid/mg_transfer_prebuilt.cc +++ b/deal.II/deal.II/source/multigrid/mg_transfer_prebuilt.cc @@ -181,9 +181,6 @@ void MGTransferPrebuilt::build_matrices ( std::vector dof_indices_parent (dofs_per_cell); std::vector dof_indices_child (dofs_per_cell); - copy_indices.resize(mg_dof.get_tria().n_levels()); - find_dofs_on_refinement_edges (mg_dof); - // for each level: first build the sparsity // pattern of the matrices and then build the // matrices themselves. note that we only @@ -191,6 +188,7 @@ void MGTransferPrebuilt::build_matrices ( // level which have children for (unsigned int level=0; level::build_matrices ( prolongation_matrices[level]->reinit (*prolongation_sparsities[level]); - copy_indices[level+1].clear(); - if (level == 0) - copy_indices[0].clear(); - std::vector global_dof_indices (dofs_per_cell); - // now actually build the matrices for (typename MGDoFHandler::cell_iterator cell=mg_dof.begin(level); cell != mg_dof.end(level); ++cell) @@ -273,66 +266,8 @@ void MGTransferPrebuilt::build_matrices ( &dof_indices_parent[0], &prolongation(i,0), true); - - if (cell->child(child)->has_children()==false) - { - DoFCellAccessor >& global_cell - = *cell->child(child); - global_cell.get_dof_indices(global_dof_indices); - for (unsigned int i=0; i >& global_cell = *cell; - - // get the dof numbers of - // this cell for the global - // and the level-wise - // numbering - global_cell.get_dof_indices(global_dof_indices); - cell->get_mg_dof_indices (dof_indices_parent); - - for (unsigned int i=0; i=0; --level) - { - if (copy_indices[level].size() > 0) - { - std::sort (copy_indices[level].begin(), copy_indices[level].end()); - - std::vector >::iterator - it1 = copy_indices[level].begin(), it2 = it1, it3 = it1; - it2++, it1++; - for ( ; it2!=copy_indices[level].end(); ++it2, ++it3) - if (*it2 > *it3) - *it1++ = *it2; - copy_indices[level].erase(it1,copy_indices[level].end()); - } - } - // if we have only one single level, we did - // not enter the above code. Need to create - // the respective vector manually - if (n_levels == 1) - { - copy_indices[0].resize (sizes[0]); - for (unsigned int i=0; i(i,i); } // impose boundary conditions @@ -373,6 +308,66 @@ void MGTransferPrebuilt::build_matrices ( start_row->value() = 0; } } + } + + // to find the indices that describe the + // relation between global dofs and local + // numbering on the individual level, first + // create a temp vector where the ith level + // entry contains the respective global + // entry. this gives a neat way to find those + // indices. in a second step, actually build + // the std::vector > that + // only contains the active dofs on the + // levels. + copy_indices.resize(n_levels); + std::vector temp_copy_indices; + std::vector global_dof_indices (dofs_per_cell); + std::vector level_dof_indices (dofs_per_cell); + for (int level=mg_dof.get_tria().n_levels()-1; level>=0; --level) + { + copy_indices[level].clear(); + 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); + + temp_copy_indices.resize (0); + temp_copy_indices.resize (mg_dof.n_dofs(level), numbers::invalid_unsigned_int); + + // Compute coarse level right hand side + // by restricting from fine level. + for (; level_cell!=level_end; ++level_cell) + { + DoFAccessor >& 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(), + numbers::invalid_unsigned_int)); + copy_indices[level].resize (n_active_dofs); + unsigned int counter = 0; + for (unsigned int i=0; i (temp_copy_indices[i], i); + Assert (counter == n_active_dofs, ExcInternalError()); } }