From 5e6a01271a2447c2efbed0a6d200a4f4198de2a8 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 31 Jan 2000 18:26:46 +0000 Subject: [PATCH] First step towards parallelization. git-svn-id: https://svn.dealii.org/trunk@2299 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/lac/include/lac/sparse_vanka.h | 41 +++++++++++++++++++ .../lac/include/lac/sparse_vanka.templates.h | 40 +++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/deal.II/lac/include/lac/sparse_vanka.h b/deal.II/lac/include/lac/sparse_vanka.h index 9facd46b5d..0bbda58ab5 100644 --- a/deal.II/lac/include/lac/sparse_vanka.h +++ b/deal.II/lac/include/lac/sparse_vanka.h @@ -252,6 +252,47 @@ class SparseVanka */ void compute_inverse (const unsigned int row, map &local_index); + + /** + * Apply the inverses in the + * range #[begin,end)# to the + * #src# vector and move the + * result into #dst#. Actually, + * only values of #src# from + * within the range are taken + * (all others are set to zero), + * and only values inside the + * range are written to #dst#, so + * the application of this + * function only does what is + * announced in the general + * documentation if the given + * range is the whole interval. + * + * The reason for providing the + * interval anyway is that in + * derived classes we may want to + * apply the preconditioner to + * blocks of the matrix only, in + * order to parallelize the + * application. Then, it is + * important to only write to + * some slices of #dst# and only + * takes values from similar + * slices of #src#, in order to + * eliminate the dependencies of + * threads of each other. + * + * The #operator()# of this class + * of course calls this function + * with the whole interval + * #[begin,end)=[0,matrix.m())#. + */ + template + void apply_preconditioner (Vector &dst, + const Vector &src, + const unsigned int begin, + const unsigned int end) const; }; diff --git a/deal.II/lac/include/lac/sparse_vanka.templates.h b/deal.II/lac/include/lac/sparse_vanka.templates.h index de90498615..149b4bad17 100644 --- a/deal.II/lac/include/lac/sparse_vanka.templates.h +++ b/deal.II/lac/include/lac/sparse_vanka.templates.h @@ -215,11 +215,37 @@ SparseVanka::operator ()(Vector &dst, { // first set output vector to zero dst.clear (); + // then pass on to the function + // that actually does the work + apply_preconditioner (dst, src, 0, matrix->m()); +}; + + + +template +template +void +SparseVanka::apply_preconditioner (Vector &dst, + const Vector &src, + const unsigned int begin, + const unsigned int end) const +{ + Assert (begin < end, ExcInternalError()); + // first define an alias to the sparsity // pattern of the matrix, since this // will be used quite often const SparsityPattern &structure = matrix->get_sparsity_pattern(); + + + // store whether we shall work on + // the whole matrix, or only on + // blocks. this variable is used to + // optimize access to vectors a + // little bit. + const bool range_is_restricted = (begin != 0) && (end != matrix->m()); + // space to be used for local // systems. allocate as much memory @@ -289,7 +315,11 @@ SparseVanka::operator ()(Vector &dst, const unsigned int irow_length = structure.row_length(irow); // copy rhs - b(i) = src(irow); + if (!range_is_restricted || + ((begin <= irow) && (irow < end))) + b(i) = src(irow); + else + b(i) = 0; // for all the DoFs that irow // couples with @@ -310,6 +340,7 @@ SparseVanka::operator ()(Vector &dst, // // note that if so, we already // have copied the entry above +//TODO: why is dst accessed here??? if (js == local_index.end()) b(i) -= matrix->raw_entry(irow,j) * dst(col); else @@ -333,7 +364,12 @@ SparseVanka::operator ()(Vector &dst, { const unsigned int irow = is->first; const unsigned int i = is->second; - dst(irow) = x(i); + + if (!range_is_restricted || + ((begin <= irow) && (irow < end))) + dst(irow) = x(i); + // do nothing if not in + // the range }; // if we don't store the -- 2.39.5