From 0e91f0c9f7abf0560ee849ab80fd636bcef0eb38 Mon Sep 17 00:00:00 2001
From: bangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Date: Mon, 6 Aug 2012 09:47:20 +0000
Subject: [PATCH] Disallow modifying operations on vectors with ghost elements.

git-svn-id: https://svn.dealii.org/trunk@25751 0785d39b-7218-0410-832d-ea1e28bc413d
---
 deal.II/doc/news/changes.h                    | 12 ++++++
 .../deal.II/lac/trilinos_vector_base.h        | 41 +++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h
index 0cbea7afb4..36057055e3 100644
--- a/deal.II/doc/news/changes.h
+++ b/deal.II/doc/news/changes.h
@@ -24,6 +24,18 @@ inconvenience this causes.
 </p>
 
 <ol>
+<li> Changed/fixed: Several operations on Trilinos vectors that change the
+elements of these vectors were allowed accidentally for vectors that have
+ghost elements. This is a source of errors because a change on one
+MPI process will not show up on a different processor. Consequently, we
+intended to disallow all functions that modify vectors with ghost elements
+but this was not enforced for all of these functions. This is now fixed
+but it may lead to errors if your code relied on the existing behavior. The
+way to work around this is to only ever modify fully distributed vectors,
+and then copy it into a vector with ghost elements.
+<br>
+(Wolfgang Bangerth, 2012/08/06)
+
 <li> Changed: The argument material_id of the estimate-functions of
 the KellyErrorEstimator class is now of type types::material_id_type
 with default value types::invalid_material_id, instead of type
diff --git a/deal.II/include/deal.II/lac/trilinos_vector_base.h b/deal.II/include/deal.II/lac/trilinos_vector_base.h
index c3d422bcfc..549bc76afb 100644
--- a/deal.II/include/deal.II/lac/trilinos_vector_base.h
+++ b/deal.II/include/deal.II/lac/trilinos_vector_base.h
@@ -1243,6 +1243,9 @@ namespace TrilinosWrappers
   VectorBase &
   VectorBase::operator = (const TrilinosScalar s)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
 
     Assert (numbers::is_finite(s), ExcNumberNotFinite());
 
@@ -1260,6 +1263,10 @@ namespace TrilinosWrappers
   VectorBase::set (const std::vector<unsigned int>    &indices,
                    const std::vector<TrilinosScalar>  &values)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
+
     Assert (indices.size() == values.size(),
             ExcDimensionMismatch(indices.size(),values.size()));
 
@@ -1273,6 +1280,10 @@ namespace TrilinosWrappers
   VectorBase::set (const std::vector<unsigned int>        &indices,
                    const ::dealii::Vector<TrilinosScalar> &values)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
+
     Assert (indices.size() == values.size(),
             ExcDimensionMismatch(indices.size(),values.size()));
 
@@ -1616,6 +1627,9 @@ namespace TrilinosWrappers
   void
   VectorBase::add (const TrilinosScalar s)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (numbers::is_finite(s), ExcNumberNotFinite());
 
     unsigned int n_local = local_size();
@@ -1630,6 +1644,9 @@ namespace TrilinosWrappers
   VectorBase::add (const TrilinosScalar  a,
                    const VectorBase     &v)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (local_size() == v.local_size(),
             ExcDimensionMismatch(local_size(), v.local_size()));
 
@@ -1648,6 +1665,9 @@ namespace TrilinosWrappers
                    const TrilinosScalar  b,
                    const VectorBase     &w)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (local_size() == v.local_size(),
             ExcDimensionMismatch(local_size(), v.local_size()));
     Assert (local_size() == w.local_size(),
@@ -1668,6 +1688,9 @@ namespace TrilinosWrappers
   VectorBase::sadd (const TrilinosScalar  s,
                     const VectorBase     &v)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (local_size() == v.local_size(),
             ExcDimensionMismatch(local_size(), v.local_size()));
 
@@ -1686,6 +1709,9 @@ namespace TrilinosWrappers
                     const TrilinosScalar  a,
                     const VectorBase     &v)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (local_size() == v.local_size(),
             ExcDimensionMismatch(local_size(), v.local_size()));
 
@@ -1707,6 +1733,9 @@ namespace TrilinosWrappers
                     const TrilinosScalar  b,
                     const VectorBase     &w)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (local_size() == v.local_size(),
             ExcDimensionMismatch(local_size(), v.local_size()));
     Assert (local_size() == w.local_size(),
@@ -1733,6 +1762,9 @@ namespace TrilinosWrappers
                     const TrilinosScalar  c,
                     const VectorBase     &x)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (local_size() == v.local_size(),
             ExcDimensionMismatch(local_size(), v.local_size()));
     Assert (local_size() == w.local_size(),
@@ -1762,6 +1794,9 @@ namespace TrilinosWrappers
   void
   VectorBase::scale (const VectorBase &factors)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (local_size() == factors.local_size(),
             ExcDimensionMismatch(local_size(), factors.local_size()));
 
@@ -1776,6 +1811,9 @@ namespace TrilinosWrappers
   VectorBase::equ (const TrilinosScalar  a,
                    const VectorBase     &v)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (numbers::is_finite(a), ExcNumberNotFinite());
 
                                    // If we don't have the same map, copy.
@@ -1804,6 +1842,9 @@ namespace TrilinosWrappers
                    const TrilinosScalar  b,
                    const VectorBase     &w)
   {
+                                     // if we have ghost values, do not allow
+                                     // writing to this vector at all.
+    Assert (!has_ghost_elements(), ExcGhostsPresent());
     Assert (v.local_size() == w.local_size(),
             ExcDimensionMismatch (v.local_size(), w.local_size()));
 
-- 
2.39.5