<br>
(Martin Kronbichler, 2011/08/02)
-
-<li> Fixed: The function VectorTools::create_right_hand_side now also works
-for objects of type hp::DoFHandler with different finite elements.
-<br>
-(Daniel Gerecht, 2011/07/20)
-
-
<li> Fixed: deal.II can link with Trilinos but previously it required a
very specific set of Trilinos sub-libraries; if Trilinos had been compiled
with a larger set of sub-libraries, linking would sometimes fail. This
<h3>Specific improvements</h3>
<ol>
+<li> Improved: The PETScWrapper::VectorBase class was rather generous in
+calling the PETSc <code>VecAssembleBegin/End</code> functions that incur
+communication in the %parallel case and are therefore causes of potential
+slowdowns. This has been improved.
+<br>
+(Wolfgang Bangerth, 2011/08/03)
+
+<li> Fixed: The function VectorTools::create_right_hand_side now also works
+for objects of type hp::DoFHandler with different finite elements.
+<br>
+(Daniel Gerecht, 2011/07/20)
+
<li> Improved: Evaluation of Lagrangian basis functions has been made stable
by exchanging polynomial evaluation from the standard form
$a_n x^n+\ldots+a_1 x + a_0$ to a product of linear factors,
const VectorReference &
VectorReference::operator = (const PetscScalar &value) const
{
- if (vector.last_action != VectorBase::LastAction::insert)
+ // if the last action was an addition, we need to flush buffers
+ if (vector.last_action == VectorBase::LastAction::add)
{
int ierr;
ierr = VecAssemblyBegin (vector);
const VectorReference &
VectorReference::operator += (const PetscScalar &value) const
{
- if (vector.last_action != VectorBase::LastAction::add)
+ // 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);
ierr = VecAssemblyEnd (vector);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- vector.last_action = VectorBase::LastAction::add;
}
+ vector.last_action = VectorBase::LastAction::add;
+
// we have to do above actions in any
// case to be consistent with the MPI
// communication model (see the
const VectorReference &
VectorReference::operator -= (const PetscScalar &value) const
{
- if (vector.last_action != VectorBase::LastAction::add)
+ // 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);
ierr = VecAssemblyEnd (vector);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- vector.last_action = VectorBase::LastAction::add;
}
- // we have to do above actions in any
+ vector.last_action = VectorBase::LastAction::add;
+
+ // we have to do above actions in any
// case to be consistent with the MPI
// communication model (see the
// comments in the documentation of
const VectorReference &
VectorReference::operator *= (const PetscScalar &value) const
{
- if (vector.last_action != VectorBase::LastAction::insert)
+ // if the last action was an addition, we need to flush buffers
+ if (vector.last_action == VectorBase::LastAction::add)
{
int ierr;
ierr = VecAssemblyBegin (vector);
ierr = VecAssemblyEnd (vector);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- vector.last_action = VectorBase::LastAction::insert;
}
+ vector.last_action = VectorBase::LastAction::insert;
+
// we have to do above actions in any
// case to be consistent with the MPI
// communication model (see the
const VectorReference &
VectorReference::operator /= (const PetscScalar &value) const
{
- if (vector.last_action != VectorBase::LastAction::insert)
+ // 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);
ierr = VecAssemblyEnd (vector);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- vector.last_action = VectorBase::LastAction::insert;
}
+ vector.last_action = VectorBase::LastAction::insert;
+
// we have to do above actions in any
// case to be consistent with the MPI
// communication model (see the
void
VectorBase::compress ()
{
+ // note that one may think that we only need to do something
+ // if in fact the state is anything but LastAction::none. but
+ // that's not true: one frequently gets into situations where
+ // only one processor (or a subset of processors) actually writes
+ // something into a vector, but we still need to call
+ // VecAssemblyBegin/End on all processors, even those that are
+ // still in LastAction::none state
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;
}
const PetscScalar *values,
const bool add_values)
{
- if (last_action != VectorBase::LastAction::insert)
+ // if the last action was a set operation, we need to flush buffers
+ if (last_action == VectorBase::LastAction::insert)
{
int ierr;
ierr = VecAssemblyBegin (vector);
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;
}
// VecSetValues complains if we
AssertThrow (ierr == 0, ExcPETScError(ierr));
}
+ // set the mode here, independent of whether we have actually
+ // written elements or whether the list was empty
last_action = LastAction::insert;
}