From 530f9f701475dc250cec35d48fab74e821979d72 Mon Sep 17 00:00:00 2001
From: heister <heister@0785d39b-7218-0410-832d-ea1e28bc413d>
Date: Wed, 22 Aug 2012 21:37:41 +0000
Subject: [PATCH] fix has_ghost_elements() in trilinos 10.12.x

git-svn-id: https://svn.dealii.org/trunk@26093 0785d39b-7218-0410-832d-ea1e28bc413d
---
 deal.II/doc/news/changes.h                         |  7 +++++++
 deal.II/include/deal.II/lac/trilinos_vector.h      |  2 ++
 deal.II/include/deal.II/lac/trilinos_vector_base.h | 13 +++++++++++--
 deal.II/source/lac/trilinos_vector.cc              |  4 ++++
 deal.II/source/lac/trilinos_vector_base.cc         |  4 ++++
 5 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h
index c75381a056..ee0efc5bf7 100644
--- a/deal.II/doc/news/changes.h
+++ b/deal.II/doc/news/changes.h
@@ -293,6 +293,13 @@ enabled due to a missing include file in file
 <h3>Specific improvements</h3>
 
 <ol>
+<li> Changed: To support Trilinos version 10.12.x we need to cache the
+result of has_ghost_elements() in parallel vectors at construction time
+of the vector. Starting from 10.12 Trilinos will communicate in this
+call, which therefore only works if called from all CPUs.
+<br>
+(Timo Heister, 2012/08/22)
+
 <li> New: The copy constructor of FullMatrix from IdentityMatrix
 used to be explicit, but that didn't appear to be necessary in hindsight.
 Consequently, it is now a regular copy constructor.
diff --git a/deal.II/include/deal.II/lac/trilinos_vector.h b/deal.II/include/deal.II/lac/trilinos_vector.h
index f70303b23b..a2891c18fd 100644
--- a/deal.II/include/deal.II/lac/trilinos_vector.h
+++ b/deal.II/include/deal.II/lac/trilinos_vector.h
@@ -508,6 +508,8 @@ namespace TrilinosWrappers
       if (vector.get() != 0 && vector->Map().SameAs(parallel_partitioner))
         vector.reset (new Epetra_FEVector(parallel_partitioner));
 
+      has_ghosts = vector->Map().UniqueGIDs()==false;
+
       const int size = parallel_partitioner.NumMyElements();
 
                                    // Need to copy out values, since the
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 48d3b13c81..f7e1450221 100644
--- a/deal.II/include/deal.II/lac/trilinos_vector_base.h
+++ b/deal.II/include/deal.II/lac/trilinos_vector_base.h
@@ -494,7 +494,9 @@ namespace TrilinosWrappers
 
                                        /**
                                         * Return if the vector contains ghost
-                                        * elements.
+                                        * elements. This answer is true if there
+                                        * are ghost elements on at least one
+                                        * process.
                                         */
       bool has_ghost_elements() const;
 
@@ -1011,6 +1013,13 @@ namespace TrilinosWrappers
                                         */
       bool compressed;
 
+      /**
+       * Whether this vector has ghost elements. This is true
+       * on all processors even if only one of them has any
+       * ghost elements.
+       */
+      bool has_ghosts;
+
                                        /**
                                         * An Epetra distibuted vector
                                         * type. Requires an existing
@@ -1165,7 +1174,7 @@ namespace TrilinosWrappers
   bool
   VectorBase::has_ghost_elements() const
   {
-    return vector->Map().UniqueGIDs()==false;
+    return has_ghosts;
   }
 
 
diff --git a/deal.II/source/lac/trilinos_vector.cc b/deal.II/source/lac/trilinos_vector.cc
index ddda7908ac..3d8f1a05ad 100644
--- a/deal.II/source/lac/trilinos_vector.cc
+++ b/deal.II/source/lac/trilinos_vector.cc
@@ -61,6 +61,7 @@ namespace TrilinosWrappers
     {
       last_action = Zero;
       vector.reset (new Epetra_FEVector(*v.vector));
+      has_ghosts = v.has_ghosts;
     }
 
 
@@ -124,6 +125,7 @@ namespace TrilinosWrappers
           Assert (ierr == 0, ExcTrilinosError(ierr));
         }
 
+      has_ghosts = vector->Map().UniqueGIDs()==false;
       last_action = Zero;
     }
 
@@ -158,6 +160,7 @@ namespace TrilinosWrappers
           if (vector->Map().SameAs(v.vector->Map()) == false)
             {
               vector.reset (new Epetra_FEVector(v.vector->Map()));
+              has_ghosts = v.has_ghosts;
               last_action = Zero;
             }
           else if (fast == false)
@@ -306,6 +309,7 @@ namespace TrilinosWrappers
         {
           vector.reset (new Epetra_FEVector(*v.vector));
           last_action = Zero;
+          has_ghosts = v.has_ghosts;
         }
 
       return *this;
diff --git a/deal.II/source/lac/trilinos_vector_base.cc b/deal.II/source/lac/trilinos_vector_base.cc
index afb660aa72..a90bb9e0ae 100644
--- a/deal.II/source/lac/trilinos_vector_base.cc
+++ b/deal.II/source/lac/trilinos_vector_base.cc
@@ -57,6 +57,7 @@ namespace TrilinosWrappers
                         :
                         last_action (Zero),
                         compressed  (true),
+                        has_ghosts  (false),
 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
                         vector(new Epetra_FEVector(
                                  Epetra_Map(0,0,Epetra_MpiComm(MPI_COMM_SELF))))
@@ -73,6 +74,7 @@ namespace TrilinosWrappers
                         Subscriptor(),
                         last_action (Zero),
                         compressed (true),
+                        has_ghosts  (v.has_ghosts),
                         vector(new Epetra_FEVector(*v.vector))
   {}
 
@@ -95,6 +97,7 @@ namespace TrilinosWrappers
     Epetra_Map map (0, 0, Epetra_SerialComm());
 #endif
 
+    has_ghosts = false;
     vector.reset (new Epetra_FEVector(map));
     last_action = Zero;
   }
@@ -111,6 +114,7 @@ namespace TrilinosWrappers
       {
         last_action = Zero;
         vector.reset (new Epetra_FEVector(*v.vector));
+        has_ghosts = v.has_ghosts;
       }
     else
       {
-- 
2.39.5