From 590d2abad77dc1d615a07a5cfa467722dccca724 Mon Sep 17 00:00:00 2001 From: kronbichler Date: Mon, 16 Mar 2009 15:01:24 +0000 Subject: [PATCH] Final update of local_to_global functions in ConstraintMatrix, making the sparsity pattern creation even faster. One possibly could improve things further by pre-ordering the indices to be added, if our other functions were smart enough to handle that. Right now, that doesn't really help, and all I get from ordering is some additional overhead. git-svn-id: https://svn.dealii.org/trunk@18488 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/doc/news/changes.h | 10 ++++ .../include/lac/constraint_matrix.templates.h | 52 ++++++++++++++++--- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index edd544096b..4d1a9ad516 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -573,6 +573,16 @@ inconvenience this causes.

lac

    +
  1. +

    + Updated: The local_to_global functions in ConstraintMatrix got smarter, + which imcreases the speed of sparsity pattern generation with + ConstraintMatrix argument, and makes writing into sparse matrices using + distribute_local_to_global faster, in case there are many constraints. +
    + (Martin Kronbichler 2009/03/16) +

    +
  2. Fixed: The FullMatrix::swap_row and FullMatrix::swap_col functions diff --git a/deal.II/lac/include/lac/constraint_matrix.templates.h b/deal.II/lac/include/lac/constraint_matrix.templates.h index 7b6c033183..f00825a3bd 100644 --- a/deal.II/lac/include/lac/constraint_matrix.templates.h +++ b/deal.II/lac/include/lac/constraint_matrix.templates.h @@ -1113,7 +1113,7 @@ add_entries_local_to_global (const std::vector &local_dof_indices, const Table<2,bool> &dof_mask) const { // similar to the function for distributing - // matrix entries; see there for comments. + // matrix entries. const unsigned int n_local_dofs = local_dof_indices.size(); bool dof_mask_is_active = false; if (dof_mask.n_rows() == n_local_dofs) @@ -1187,11 +1187,19 @@ add_entries_local_to_global (const std::vector &local_dof_indices, if (column_indices.size() < n_max_entries_per_row) column_indices.resize(n_max_entries_per_row); - // TODO (M.K.): Some rows are added - // several times in this function. Can - // do that more efficiently by keeping a - // list of which rows have already been - // added. + // we might add the same row with some + // column entries several times when + // using constraints. To avoid doing so, + // we keep a list of (global) rows that + // have already been inserted, which is + // then used to break the loop. This is + // only useful for the case when we leave + // out constrained dofs. Otherwise, there + // are some more entries that we can't + // keep track of that easily. + std::vector already_inserted; + already_inserted.reserve(n_local_dofs); + for (unsigned int i=0; i &local_dof_indices, if (is_constrained_i == false) { + // in case we are at a row that has + // already been added, do not need to go + // on. the way how we do it is to first + // find an insertion point and then check + // whether the element is already present + std::vector::iterator inserted_it = + std::lower_bound(already_inserted.begin(), already_inserted.end(), + local_dof_indices[i]); + if (inserted_it != already_inserted.end()) + if (*inserted_it == local_dof_indices[i]) + continue; + unsigned int col_counter = 0; for (unsigned int j=0; j &local_dof_indices, sparsity_pattern.add_entries (local_dof_indices[i], column_indices.begin(), column_indices.begin()+col_counter); + + // now this row has been visited, so se + if (keep_constrained_entries == false) + already_inserted.insert(inserted_it, local_dof_indices[i]); } else { @@ -1302,8 +1326,19 @@ add_entries_local_to_global (const std::vector &local_dof_indices, // way as in the unconstrained rows. for (unsigned int p=0; pentries.size(); ++p) { - unsigned int col_counter = 0; const unsigned int row = position_i->entries[p].first; + + // in case we are at a row that has + // already been added, do not need to go + // on + std::vector::iterator inserted_it = + std::lower_bound(already_inserted.begin(), already_inserted.end(), + row); + if (inserted_it != already_inserted.end()) + if (*inserted_it == row) + continue; + + unsigned int col_counter = 0; for (unsigned int j=0; j &local_dof_indices, sparsity_pattern.add_entries (row, column_indices.begin(), column_indices.begin()+col_counter); + + if (keep_constrained_entries == false) + already_inserted.insert(inserted_it, row); } } } -- 2.39.5