From: heister Date: Thu, 9 Aug 2012 11:38:01 +0000 (+0000) Subject: move mpi namespace from trilinos_block_vector.h into new trilinos_parallel_block_vector.h X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=536c0740f5559da5c85e1569c909ba13afa6d95f;p=dealii-svn.git move mpi namespace from trilinos_block_vector.h into new trilinos_parallel_block_vector.h git-svn-id: https://svn.dealii.org/trunk@25802 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/include/deal.II/lac/trilinos_block_vector.h b/deal.II/include/deal.II/lac/trilinos_block_vector.h index 9ad16d347a..61017fd564 100644 --- a/deal.II/include/deal.II/lac/trilinos_block_vector.h +++ b/deal.II/include/deal.II/lac/trilinos_block_vector.h @@ -18,6 +18,7 @@ #ifdef DEAL_II_USE_TRILINOS # include +# include # include # include # include @@ -42,489 +43,6 @@ namespace TrilinosWrappers class BlockSparseMatrix; - namespace MPI - { -/** - * An implementation of block vectors based on the vector class - * implemented in TrilinosWrappers. While the base class provides for - * most of the interface, this class handles the actual allocation of - * vectors and provides functions that are specific to the underlying - * vector type. - * - * The model of distribution of data is such that each of the blocks - * is distributed across all MPI processes named in the MPI - * communicator. I.e. we don't just distribute the whole vector, but - * each component. In the constructors and reinit() functions, one - * therefore not only has to specify the sizes of the individual - * blocks, but also the number of elements of each of these blocks to - * be stored on the local process. - * - * @ingroup Vectors - * @ingroup TrilinosWrappers - * @see @ref GlossBlockLA "Block (linear algebra)" - * @author Martin Kronbichler, Wolfgang Bangerth, 2008, 2009 - */ - class BlockVector : public BlockVectorBase - { - public: - /** - * Typedef the base class for simpler - * access to its own typedefs. - */ - typedef BlockVectorBase BaseClass; - - /** - * Typedef the type of the underlying - * vector. - */ - typedef BaseClass::BlockType BlockType; - - /** - * Import the typedefs from the base - * class. - */ - typedef BaseClass::value_type value_type; - typedef BaseClass::pointer pointer; - typedef BaseClass::const_pointer const_pointer; - typedef BaseClass::reference reference; - typedef BaseClass::const_reference const_reference; - typedef BaseClass::size_type size_type; - typedef BaseClass::iterator iterator; - typedef BaseClass::const_iterator const_iterator; - - /** - * Default constructor. Generate an - * empty vector without any blocks. - */ - BlockVector (); - - /** - * Constructor. Generate a block - * vector with as many blocks as - * there are entries in @p - * partitioning. Each Epetra_Map - * contains the layout of the - * distribution of data among the MPI - * processes. - */ - BlockVector (const std::vector ¶llel_partitioning); - - /** - * Constructor. Generate a block - * vector with as many blocks as - * there are entries in - * @p partitioning. Each IndexSet - * together with the MPI communicator - * contains the layout of the - * distribution of data among the MPI - * processes. - */ - BlockVector (const std::vector ¶llel_partitioning, - const MPI_Comm &communicator = MPI_COMM_WORLD); - - /** - * Copy-Constructor. Set all the - * properties of the parallel vector - * to those of the given argument and - * copy the elements. - */ - BlockVector (const BlockVector &V); - - /** - * Creates a block vector - * consisting of - * num_blocks - * components, but there is no - * content in the individual - * components and the user has to - * fill appropriate data using a - * reinit of the blocks. - */ - BlockVector (const unsigned int num_blocks); - - /** - * Destructor. Clears memory - */ - ~BlockVector (); - - /** - * Copy operator: fill all - * components of the vector that - * are locally stored with the - * given scalar value. - */ - BlockVector & - operator = (const value_type s); - - /** - * Copy operator for arguments of - * the same type. - */ - BlockVector & - operator = (const BlockVector &V); - - /** - * Copy operator for arguments of - * the localized Trilinos vector - * type. - */ - BlockVector & - operator = (const ::dealii::TrilinosWrappers::BlockVector &V); - - /** - * Another copy function. This - * one takes a deal.II block - * vector and copies it into a - * TrilinosWrappers block - * vector. Note that the number - * of blocks has to be the same - * in the vector as in the input - * vector. Use the reinit() - * command for resizing the - * BlockVector or for changing - * the internal structure of the - * block components. - * - * Since Trilinos only works on - * doubles, this function is - * limited to accept only one - * possible number type in the - * deal.II vector. - */ - template - BlockVector & - operator = (const ::dealii::BlockVector &V); - - /** - * Reinitialize the BlockVector to - * contain as many blocks as there - * are Epetra_Maps given in the input - * argument, according to the - * parallel distribution of the - * individual components described - * in the maps. - * - * If fast==false, the vector - * is filled with zeros. - */ - void reinit (const std::vector ¶llel_partitioning, - const bool fast = false); - - /** - * Reinitialize the BlockVector to - * contain as many blocks as there - * are index sets given in the input - * argument, according to the - * parallel distribution of the - * individual components described - * in the maps. - * - * If fast==false, the vector - * is filled with zeros. - */ - void reinit (const std::vector ¶llel_partitioning, - const MPI_Comm &communicator = MPI_COMM_WORLD, - const bool fast = false); - - /** - * Change the dimension to that - * of the vector V. The same - * applies as for the other - * reinit() function. - * - * The elements of V are not - * copied, i.e. this function is - * the same as calling reinit - * (V.size(), fast). - * - * Note that you must call this - * (or the other reinit() - * functions) function, rather - * than calling the reinit() - * functions of an individual - * block, to allow the block - * vector to update its caches of - * vector sizes. If you call - * reinit() on one of the - * blocks, then subsequent - * actions on this object may - * yield unpredictable results - * since they may be routed to - * the wrong block. - */ - void reinit (const BlockVector &V, - const bool fast = false); - - /** - * Change the number of blocks to - * num_blocks. The individual - * blocks will get initialized with - * zero size, so it is assumed that - * the user resizes the - * individual blocks by herself - * in an appropriate way, and - * calls collect_sizes - * afterwards. - */ - void reinit (const unsigned int num_blocks); - - /** - * This reinit function is meant to - * be used for parallel - * calculations where some - * non-local data has to be - * used. The typical situation - * where one needs this function is - * the call of the - * FEValues::get_function_values - * function (or of some - * derivatives) in parallel. Since - * it is usually faster to retrieve - * the data in advance, this - * function can be called before - * the assembly forks out to the - * different processors. What this - * function does is the following: - * It takes the information in the - * columns of the given matrix and - * looks which data couples between - * the different processors. That - * data is then queried from the - * input vector. Note that you - * should not write to the - * resulting vector any more, since - * the some data can be stored - * several times on different - * processors, leading to - * unpredictable results. In - * particular, such a vector cannot - * be used for matrix-vector - * products as for example done - * during the solution of linear - * systems. - */ - void import_nonlocal_data_for_fe (const TrilinosWrappers::BlockSparseMatrix &m, - const BlockVector &v); - - /** - * Compress the underlying - * representation of the Trilinos - * object, i.e. flush the buffers - * of the vector object if it has - * any. This function is - * necessary after writing into a - * vector element-by-element and - * before anything else can be - * done on it. - * - * The (defaulted) argument can - * be used to specify the - * compress mode - * (Add or - * Insert) in case - * the vector has not been - * written to since the last - * time this function was - * called. The argument is - * ignored if the vector has - * been added or written to - * since the last time - * compress() was called. - * - * See @ref GlossCompress "Compressing distributed objects" - * for more information. - * more information. - */ - void compress (const Epetra_CombineMode last_action = Zero); - - /** - * Returns the state of the - * vector, i.e., whether - * compress() needs to be - * called after an operation - * requiring data - * exchange. Does only return - * non-true values when used in - * debug mode, since - * it is quite expensive to - * keep track of all operations - * that lead to the need for - * compress(). - */ - bool is_compressed () const; - - /** - * Swap the contents of this - * vector and the other vector - * v. One could do this - * operation with a temporary - * variable and copying over the - * data elements, but this - * function is significantly more - * efficient since it only swaps - * the pointers to the data of - * the two vectors and therefore - * does not need to allocate - * temporary storage and move - * data around. - * - * Limitation: right now this - * function only works if both - * vectors have the same number - * of blocks. If needed, the - * numbers of blocks should be - * exchanged, too. - * - * This function is analog to the - * the swap() function of all C++ - * standard containers. Also, - * there is a global function - * swap(u,v) that simply calls - * u.swap(v), again in analogy - * to standard functions. - */ - void swap (BlockVector &v); - - /** - * Print to a stream. - */ - void print (std::ostream &out, - const unsigned int precision = 3, - const bool scientific = true, - const bool across = true) const; - - /** - * Exception - */ - DeclException0 (ExcIteratorRangeDoesNotMatchVectorSize); - - /** - * Exception - */ - DeclException0 (ExcNonMatchingBlockVectors); - }; - - - -/*----------------------- Inline functions ----------------------------------*/ - - - inline - BlockVector::BlockVector () - {} - - - - inline - BlockVector::BlockVector (const std::vector ¶llel_partitioning) - { - reinit (parallel_partitioning, false); - } - - - - inline - BlockVector::BlockVector (const std::vector ¶llel_partitioning, - const MPI_Comm &communicator) - { - reinit (parallel_partitioning, communicator, false); - } - - - - inline - BlockVector::BlockVector (const unsigned int num_blocks) - { - reinit (num_blocks); - } - - - - inline - BlockVector::BlockVector (const BlockVector& v) - : - BlockVectorBase () - { - this->components.resize (v.n_blocks()); - this->block_indices = v.block_indices; - - for (unsigned int i=0; in_blocks(); ++i) - this->components[i] = v.components[i]; - } - - - - inline - bool - BlockVector::is_compressed () const - { - bool compressed = true; - for (unsigned int row=0; row - BlockVector & - BlockVector::operator = (const ::dealii::BlockVector &v) - { - if (n_blocks() != v.n_blocks()) - { - std::vector block_sizes (v.n_blocks(), 0); - block_indices.reinit (block_sizes); - if (components.size() != n_blocks()) - components.resize(n_blocks()); - } - - for (unsigned int i=0; in_blocks(); ++i) - this->components[i] = v.block(i); - - collect_sizes(); - - return *this; - } - - - inline - void - BlockVector::swap (BlockVector &v) - { - Assert (n_blocks() == v.n_blocks(), - ExcDimensionMismatch(n_blocks(),v.n_blocks())); - - for (unsigned int row=0; row + +#ifdef DEAL_II_USE_TRILINOS + +# include +# include +# include +# include + +DEAL_II_NAMESPACE_OPEN + + // forward declaration +template class BlockVector; + +/*! @addtogroup TrilinosWrappers + *@{ + */ + +namespace TrilinosWrappers +{ + // forward declaration + namespace MPI + { + class BlockVector; + } + class BlockVector; + class BlockSparseMatrix; + + + namespace MPI + { +/** + * An implementation of block vectors based on the vector class + * implemented in TrilinosWrappers. While the base class provides for + * most of the interface, this class handles the actual allocation of + * vectors and provides functions that are specific to the underlying + * vector type. + * + * The model of distribution of data is such that each of the blocks + * is distributed across all MPI processes named in the MPI + * communicator. I.e. we don't just distribute the whole vector, but + * each component. In the constructors and reinit() functions, one + * therefore not only has to specify the sizes of the individual + * blocks, but also the number of elements of each of these blocks to + * be stored on the local process. + * + * @ingroup Vectors + * @ingroup TrilinosWrappers + * @see @ref GlossBlockLA "Block (linear algebra)" + * @author Martin Kronbichler, Wolfgang Bangerth, 2008, 2009 + */ + class BlockVector : public BlockVectorBase + { + public: + /** + * Typedef the base class for simpler + * access to its own typedefs. + */ + typedef BlockVectorBase BaseClass; + + /** + * Typedef the type of the underlying + * vector. + */ + typedef BaseClass::BlockType BlockType; + + /** + * Import the typedefs from the base + * class. + */ + typedef BaseClass::value_type value_type; + typedef BaseClass::pointer pointer; + typedef BaseClass::const_pointer const_pointer; + typedef BaseClass::reference reference; + typedef BaseClass::const_reference const_reference; + typedef BaseClass::size_type size_type; + typedef BaseClass::iterator iterator; + typedef BaseClass::const_iterator const_iterator; + + /** + * Default constructor. Generate an + * empty vector without any blocks. + */ + BlockVector (); + + /** + * Constructor. Generate a block + * vector with as many blocks as + * there are entries in @p + * partitioning. Each Epetra_Map + * contains the layout of the + * distribution of data among the MPI + * processes. + */ + BlockVector (const std::vector ¶llel_partitioning); + + /** + * Constructor. Generate a block + * vector with as many blocks as + * there are entries in + * @p partitioning. Each IndexSet + * together with the MPI communicator + * contains the layout of the + * distribution of data among the MPI + * processes. + */ + BlockVector (const std::vector ¶llel_partitioning, + const MPI_Comm &communicator = MPI_COMM_WORLD); + + /** + * Copy-Constructor. Set all the + * properties of the parallel vector + * to those of the given argument and + * copy the elements. + */ + BlockVector (const BlockVector &V); + + /** + * Creates a block vector + * consisting of + * num_blocks + * components, but there is no + * content in the individual + * components and the user has to + * fill appropriate data using a + * reinit of the blocks. + */ + BlockVector (const unsigned int num_blocks); + + /** + * Destructor. Clears memory + */ + ~BlockVector (); + + /** + * Copy operator: fill all + * components of the vector that + * are locally stored with the + * given scalar value. + */ + BlockVector & + operator = (const value_type s); + + /** + * Copy operator for arguments of + * the same type. + */ + BlockVector & + operator = (const BlockVector &V); + + /** + * Copy operator for arguments of + * the localized Trilinos vector + * type. + */ + BlockVector & + operator = (const ::dealii::TrilinosWrappers::BlockVector &V); + + /** + * Another copy function. This + * one takes a deal.II block + * vector and copies it into a + * TrilinosWrappers block + * vector. Note that the number + * of blocks has to be the same + * in the vector as in the input + * vector. Use the reinit() + * command for resizing the + * BlockVector or for changing + * the internal structure of the + * block components. + * + * Since Trilinos only works on + * doubles, this function is + * limited to accept only one + * possible number type in the + * deal.II vector. + */ + template + BlockVector & + operator = (const ::dealii::BlockVector &V); + + /** + * Reinitialize the BlockVector to + * contain as many blocks as there + * are Epetra_Maps given in the input + * argument, according to the + * parallel distribution of the + * individual components described + * in the maps. + * + * If fast==false, the vector + * is filled with zeros. + */ + void reinit (const std::vector ¶llel_partitioning, + const bool fast = false); + + /** + * Reinitialize the BlockVector to + * contain as many blocks as there + * are index sets given in the input + * argument, according to the + * parallel distribution of the + * individual components described + * in the maps. + * + * If fast==false, the vector + * is filled with zeros. + */ + void reinit (const std::vector ¶llel_partitioning, + const MPI_Comm &communicator = MPI_COMM_WORLD, + const bool fast = false); + + /** + * Change the dimension to that + * of the vector V. The same + * applies as for the other + * reinit() function. + * + * The elements of V are not + * copied, i.e. this function is + * the same as calling reinit + * (V.size(), fast). + * + * Note that you must call this + * (or the other reinit() + * functions) function, rather + * than calling the reinit() + * functions of an individual + * block, to allow the block + * vector to update its caches of + * vector sizes. If you call + * reinit() on one of the + * blocks, then subsequent + * actions on this object may + * yield unpredictable results + * since they may be routed to + * the wrong block. + */ + void reinit (const BlockVector &V, + const bool fast = false); + + /** + * Change the number of blocks to + * num_blocks. The individual + * blocks will get initialized with + * zero size, so it is assumed that + * the user resizes the + * individual blocks by herself + * in an appropriate way, and + * calls collect_sizes + * afterwards. + */ + void reinit (const unsigned int num_blocks); + + /** + * This reinit function is meant to + * be used for parallel + * calculations where some + * non-local data has to be + * used. The typical situation + * where one needs this function is + * the call of the + * FEValues::get_function_values + * function (or of some + * derivatives) in parallel. Since + * it is usually faster to retrieve + * the data in advance, this + * function can be called before + * the assembly forks out to the + * different processors. What this + * function does is the following: + * It takes the information in the + * columns of the given matrix and + * looks which data couples between + * the different processors. That + * data is then queried from the + * input vector. Note that you + * should not write to the + * resulting vector any more, since + * the some data can be stored + * several times on different + * processors, leading to + * unpredictable results. In + * particular, such a vector cannot + * be used for matrix-vector + * products as for example done + * during the solution of linear + * systems. + */ + void import_nonlocal_data_for_fe (const TrilinosWrappers::BlockSparseMatrix &m, + const BlockVector &v); + + /** + * Compress the underlying + * representation of the Trilinos + * object, i.e. flush the buffers + * of the vector object if it has + * any. This function is + * necessary after writing into a + * vector element-by-element and + * before anything else can be + * done on it. + * + * The (defaulted) argument can + * be used to specify the + * compress mode + * (Add or + * Insert) in case + * the vector has not been + * written to since the last + * time this function was + * called. The argument is + * ignored if the vector has + * been added or written to + * since the last time + * compress() was called. + * + * See @ref GlossCompress "Compressing distributed objects" + * for more information. + * more information. + */ + void compress (const Epetra_CombineMode last_action = Zero); + + /** + * Returns the state of the + * vector, i.e., whether + * compress() needs to be + * called after an operation + * requiring data + * exchange. Does only return + * non-true values when used in + * debug mode, since + * it is quite expensive to + * keep track of all operations + * that lead to the need for + * compress(). + */ + bool is_compressed () const; + + /** + * Swap the contents of this + * vector and the other vector + * v. One could do this + * operation with a temporary + * variable and copying over the + * data elements, but this + * function is significantly more + * efficient since it only swaps + * the pointers to the data of + * the two vectors and therefore + * does not need to allocate + * temporary storage and move + * data around. + * + * Limitation: right now this + * function only works if both + * vectors have the same number + * of blocks. If needed, the + * numbers of blocks should be + * exchanged, too. + * + * This function is analog to the + * the swap() function of all C++ + * standard containers. Also, + * there is a global function + * swap(u,v) that simply calls + * u.swap(v), again in analogy + * to standard functions. + */ + void swap (BlockVector &v); + + /** + * Print to a stream. + */ + void print (std::ostream &out, + const unsigned int precision = 3, + const bool scientific = true, + const bool across = true) const; + + /** + * Exception + */ + DeclException0 (ExcIteratorRangeDoesNotMatchVectorSize); + + /** + * Exception + */ + DeclException0 (ExcNonMatchingBlockVectors); + }; + + + +/*----------------------- Inline functions ----------------------------------*/ + + + inline + BlockVector::BlockVector () + {} + + + + inline + BlockVector::BlockVector (const std::vector ¶llel_partitioning) + { + reinit (parallel_partitioning, false); + } + + + + inline + BlockVector::BlockVector (const std::vector ¶llel_partitioning, + const MPI_Comm &communicator) + { + reinit (parallel_partitioning, communicator, false); + } + + + + inline + BlockVector::BlockVector (const unsigned int num_blocks) + { + reinit (num_blocks); + } + + + + inline + BlockVector::BlockVector (const BlockVector& v) + : + BlockVectorBase () + { + this->components.resize (v.n_blocks()); + this->block_indices = v.block_indices; + + for (unsigned int i=0; in_blocks(); ++i) + this->components[i] = v.components[i]; + } + + + + inline + bool + BlockVector::is_compressed () const + { + bool compressed = true; + for (unsigned int row=0; row + BlockVector & + BlockVector::operator = (const ::dealii::BlockVector &v) + { + if (n_blocks() != v.n_blocks()) + { + std::vector block_sizes (v.n_blocks(), 0); + block_indices.reinit (block_sizes); + if (components.size() != n_blocks()) + components.resize(n_blocks()); + } + + for (unsigned int i=0; in_blocks(); ++i) + this->components[i] = v.block(i); + + collect_sizes(); + + return *this; + } + + + inline + void + BlockVector::swap (BlockVector &v) + { + Assert (n_blocks() == v.n_blocks(), + ExcDimensionMismatch(n_blocks(),v.n_blocks())); + + for (unsigned int row=0; row