*/
void compute_inverse (const unsigned int row,
map<unsigned int, unsigned int> &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<typename number2>
+ void apply_preconditioner (Vector<number2> &dst,
+ const Vector<number2> &src,
+ const unsigned int begin,
+ const unsigned int end) const;
};
{
// 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<typename number>
+template<typename number2>
+void
+SparseVanka<number>::apply_preconditioner (Vector<number2> &dst,
+ const Vector<number2> &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
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
//
// 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
{
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