#include <base/config.h>
#include <lac/vector_memory.h>
#include <base/smartpointer.h>
+#include <base/template_constraints.h>
DEAL_II_NAMESPACE_OPEN
{
this->PreconditionRelaxation<MATRIX>::initialize (rA, parameters);
+ // in case we have a SparseMatrix class,
+ // we can extract information about the
+ // diagonal.
+ const SparseMatrix<typename MATRIX::value_type> * mat =
+ dynamic_cast<const SparseMatrix<typename MATRIX::value_type> *>(&*this->A);
+
// calculate the positions first after
// the diagonal.
- const std::size_t * rowstart_ptr =
- this->A->get_sparsity_pattern().get_rowstart_indices();
- const unsigned int * const colnums =
- this->A->get_sparsity_pattern().get_column_numbers();
- const unsigned int n = this->A->n();
- pos_right_of_diagonal.resize(n);
- for (unsigned int row=0; row<n; ++row, ++rowstart_ptr)
+ if (mat != 0)
{
+ const std::size_t * rowstart_ptr =
+ mat->get_sparsity_pattern().get_rowstart_indices();
+ const unsigned int * const colnums =
+ mat->get_sparsity_pattern().get_column_numbers();
+ const unsigned int n = this->A->n();
+ pos_right_of_diagonal.resize(n);
+ for (unsigned int row=0; row<n; ++row, ++rowstart_ptr)
+ {
// find the first element in this line
// which is on the right of the diagonal.
// we need to precondition with the
// note: the first entry in each
// line denotes the diagonal element,
// which we need not check.
- pos_right_of_diagonal[row] =
- std::lower_bound (&colnums[*rowstart_ptr+1],
- &colnums[*(rowstart_ptr+1)],
- row)
- - colnums;
+ pos_right_of_diagonal[row] =
+ std::lower_bound (&colnums[*rowstart_ptr+1],
+ &colnums[*(rowstart_ptr+1)],
+ row)
+ - colnums;
+ }
}
}
PreconditionSSOR<MATRIX>::Tvmult (VECTOR &dst, const VECTOR &src) const
{
Assert (this->A!=0, ExcNotInitialized());
- this->A->precondition_SSOR (dst, src, this->relaxation);
+ this->A->precondition_SSOR (dst, src, this->relaxation, pos_right_of_diagonal);
}
pos_right_of_diagonal[row];
Assert (first_right_of_diagonal_index <= *(rowstart_ptr+1),
ExcInternalError());
- double s = *dst_ptr;
+ number s = *dst_ptr;
for (unsigned int j=(*rowstart_ptr)+1; j<first_right_of_diagonal_index; ++j)
s -= val[j] * dst(cols->colnums[j]);
const unsigned int end_row = *(rowstart_ptr+1);
const unsigned int first_right_of_diagonal_index
= pos_right_of_diagonal[row];
- double s = *dst_ptr;
+ number s = *dst_ptr;
for (unsigned int j=first_right_of_diagonal_index; j<end_row; ++j)
s -= val[j] * dst(cols->colnums[j]);
-
&cols->colnums[0]);
- double s = *dst_ptr;
+ number s = *dst_ptr;
for (unsigned int j=(*rowstart_ptr)+1; j<first_right_of_diagonal_index; ++j)
s -= val[j] * dst(cols->colnums[j]);
&cols->colnums[end_row],
static_cast<unsigned int>(row)) -
&cols->colnums[0]);
- double s = *dst_ptr;
+ number s = *dst_ptr;
for (unsigned int j=first_right_of_diagonal_index; j<end_row; ++j)
s -= val[j] * dst(cols->colnums[j]);
-
*dst_ptr = s * om / val[*rowstart_ptr];
};
}
void
SparseMatrixEZ<number>::precondition_SSOR (Vector<somenumber> &dst,
const Vector<somenumber> &src,
- const number om) const
+ const number om,
+ const std::vector<unsigned int> &) const
{
Assert (m() == n(), ExcNotQuadratic());
Assert (dst.size() == n(), ExcDimensionMismatch (dst.size(), n()));
number s = *src_ptr;
const unsigned int end_row = ri->start + ri->diagonal;
for (unsigned int i=ri->start;i<end_row;++i)
- s -= om * data[i].value * dst(data[i].column);
+ s -= data[i].value * dst(data[i].column);
- *dst_ptr = s / data[ri->start + ri->diagonal].value;
+ *dst_ptr = s * om / data[ri->start + ri->diagonal].value;
}
// Diagonal
dst_ptr = dst.begin();
for (rri = row_info.rbegin(); rri != rend; --dst_ptr, ++rri)
{
const unsigned int end_row = rri->start + rri->length;
+ number s = *dst_ptr;
for (unsigned int i=rri->start+rri->diagonal+1;i<end_row;++i)
- *dst_ptr -= om * data[i].value * dst(data[i].column);
- *dst_ptr /= data[rri->start + rri->diagonal].value;
+ s -= om * data[i].value * dst(data[i].column);
+
+ *dst_ptr = s * om / data[rri->start + rri->diagonal].value;
}
}