</p>
<ol>
+<li> Changed: The PETScWrapper::VectorBase class tried to keep track of
+whether the last operation done on a vector was to add to an element or to
+write into one. If the previous such operation was of a different kind
+than the current one, we would flush buffers (see the description in
+@ref GlossCompress). However, trying to do this automatically turned
+out to be an endless source of hard-to-find bugs in %parallel programs.
+The scheme has therefore now been changed to the following: the class
+keeps track of the previous operation and if it differs from the
+current one, reports an error stating that the user needs to call
+PETScWrapper::VectorBase::compress() instead.
+<br>
+(Wolfgang Bangerth, 2011/08/03)
+
<li> Changed: The classes Tensor, SymmetricTensor and Point now have an
additional template argument for the number type. While a default template
value of double ensures that all old code is still valid, this
<< " of a distributed vector, but only elements "
<< arg2 << " through " << arg3
<< " are stored locally and can be accessed.");
+ /**
+ * Exception.
+ */
+ DeclException2 (ExcWrongMode,
+ int, int,
+ << "You tried to do a "
+ << (arg1 == 1 ?
+ "'set'" :
+ (arg1 == 2 ?
+ "'add'" : "???"))
+ << " operation but the vector is currently in "
+ << (arg2 == 1 ?
+ "'set'" :
+ (arg2 == 2 ?
+ "'add'" : "???"))
+ << " mode. You first have to call 'compress()'.");
private:
/**
const VectorReference &
VectorReference::operator = (const PetscScalar &value) const
{
- // if the last action was an addition, we need to flush buffers
- if (vector.last_action == VectorBase::LastAction::add)
- {
- int ierr;
- ierr = VecAssemblyBegin (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- ierr = VecAssemblyEnd (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
- }
+ Assert ((vector.last_action == VectorBase::LastAction::insert)
+ ||
+ (vector.last_action == VectorBase::LastAction::none),
+ ExcWrongMode (VectorBase::LastAction::insert,
+ vector.last_action));
#ifdef PETSC_USE_64BIT_INDICES
const PetscInt petsc_i = index;
const VectorReference &
VectorReference::operator += (const PetscScalar &value) const
{
- // if the last action was a set operation, we need to flush buffers
- if (vector.last_action == VectorBase::LastAction::insert)
- {
- int ierr;
- ierr = VecAssemblyBegin (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- ierr = VecAssemblyEnd (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
- }
+ Assert ((vector.last_action == VectorBase::LastAction::add)
+ ||
+ (vector.last_action == VectorBase::LastAction::none),
+ ExcWrongMode (VectorBase::LastAction::add,
+ vector.last_action));
vector.last_action = VectorBase::LastAction::add;
const VectorReference &
VectorReference::operator -= (const PetscScalar &value) const
{
- // if the last action was a set operation, we need to flush buffers
- if (vector.last_action == VectorBase::LastAction::insert)
- {
- int ierr;
- ierr = VecAssemblyBegin (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- ierr = VecAssemblyEnd (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
- }
+ Assert ((vector.last_action == VectorBase::LastAction::add)
+ ||
+ (vector.last_action == VectorBase::LastAction::none),
+ ExcWrongMode (VectorBase::LastAction::add,
+ vector.last_action));
vector.last_action = VectorBase::LastAction::add;
const VectorReference &
VectorReference::operator *= (const PetscScalar &value) const
{
- // if the last action was an addition, we need to flush buffers
- if (vector.last_action == VectorBase::LastAction::add)
- {
- int ierr;
- ierr = VecAssemblyBegin (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- ierr = VecAssemblyEnd (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
- }
+ Assert ((vector.last_action == VectorBase::LastAction::insert)
+ ||
+ (vector.last_action == VectorBase::LastAction::none),
+ ExcWrongMode (VectorBase::LastAction::insert,
+ vector.last_action));
vector.last_action = VectorBase::LastAction::insert;
const VectorReference &
VectorReference::operator /= (const PetscScalar &value) const
{
- // if the last action was a set operation, we need to flush buffers
- if (vector.last_action == VectorBase::LastAction::insert)
- {
- int ierr;
- ierr = VecAssemblyBegin (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- ierr = VecAssemblyEnd (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
- }
+ Assert ((vector.last_action == VectorBase::LastAction::insert)
+ ||
+ (vector.last_action == VectorBase::LastAction::none),
+ ExcWrongMode (VectorBase::LastAction::insert,
+ vector.last_action));
vector.last_action = VectorBase::LastAction::insert;
const PetscScalar *values,
const bool add_values)
{
- // if the last action was a set operation, we need to flush buffers
- if (last_action == VectorBase::LastAction::insert)
- {
- int ierr;
- ierr = VecAssemblyBegin (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- ierr = VecAssemblyEnd (vector);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- // reset the last action field to indicate that we're back to
- // a pristine state
- last_action = VectorBase::LastAction::none;
- }
+ Assert ((last_action == (add_values ?
+ LastAction::add :
+ LastAction::insert))
+ ||
+ (last_action == LastAction::none),
+ internal::VectorReference::ExcWrongMode ((add_values ?
+ LastAction::add :
+ LastAction::insert),
+ last_action));
// VecSetValues complains if we
// come with an empty
const int * petsc_indices = (const int*)indices;
#endif
- InsertMode mode = ADD_VALUES;
- if (!add_values)
- mode = INSERT_VALUES;
+ const InsertMode mode = (add_values ? ADD_VALUES : INSERT_VALUES);
const int ierr
= VecSetValues (vector, n_elements, petsc_indices, values,
mode);
// set the mode here, independent of whether we have actually
// written elements or whether the list was empty
- last_action = LastAction::insert;
+ last_action = (add_values ?
+ VectorBase::LastAction::add :
+ VectorBase::LastAction::insert);
}