#ifdef DEAL_II_USE_TRILINOS
# ifdef DEAL_II_COMPILER_SUPPORTS_MPI
# include <Epetra_MpiComm.h>
+# include <lac/vector_memory.h>
+# include <lac/trilinos_vector.h>
+# include <lac/trilinos_block_vector.h>
# endif
# include "Epetra_SerialComm.h"
#endif
MPI_InitFinalize::~MPI_InitFinalize()
{
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
+
+# ifdef DEAL_II_USE_TRILINOS
+ // make memory pool release all
+ // vectors that are no longer
+ // used at this point. this is
+ // relevant because the static
+ // object destructors run for
+ // these vectors at the end of
+ // the program would run after
+ // MPI_Finalize is called,
+ // leading to errors
+ GrowingVectorMemory<TrilinosWrappers::MPI::Vector>
+ ::release_unused_memory ();
+ GrowingVectorMemory<TrilinosWrappers::MPI::BlockVector>
+ ::release_unused_memory ();
+# endif
+
int mpi_err = 0;
- if (program_uses_mpi() == true && owns_mpi == true)
+ int MPI_has_been_started = 0;
+ MPI_Initialized(&MPI_has_been_started);
+ if (program_uses_mpi() == true && owns_mpi == true &&
+ MPI_has_been_started != 0)
mpi_err = MPI_Finalize();
AssertThrow (mpi_err == 0,
*/
virtual void free (const VECTOR * const);
+ /**
+ * Release all vectors that are
+ * not currently in use.
+ */
+ static void release_unused_memory ();
+
/**
* Memory consumed by this class
* and all currently allocated
+template<typename VECTOR>
+void
+GrowingVectorMemory<VECTOR>::release_unused_memory ()
+{
+ Threads::ThreadMutex::ScopedLock lock(mutex);
+
+ std::vector<entry_type> new_data;
+
+ if (pool.data != 0)
+ {
+ const typename std::vector<entry_type>::const_iterator
+ end = pool.data->end();
+ for (typename std::vector<entry_type>::const_iterator
+ i = pool.data->begin(); i != end ; ++i)
+ if (i->first == false)
+ delete i->second;
+ else
+ new_data.push_back (*i);
+
+ *pool.data = new_data;
+ }
+}
+
+
+
template<typename VECTOR>
inline
unsigned int