From 417d89d5b55dff4f6cd0c2e48f72f6479ea3cf7a Mon Sep 17 00:00:00 2001 From: kronbichler Date: Fri, 22 Aug 2008 15:08:05 +0000 Subject: [PATCH] Added a BlockVector implementation of the Trilinos vector class. git-svn-id: https://svn.dealii.org/trunk@16651 0785d39b-7218-0410-832d-ea1e28bc413d --- .../lac/include/lac/trilinos_block_vector.h | 404 ++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 deal.II/lac/include/lac/trilinos_block_vector.h diff --git a/deal.II/lac/include/lac/trilinos_block_vector.h b/deal.II/lac/include/lac/trilinos_block_vector.h new file mode 100644 index 0000000000..4f25d2ed03 --- /dev/null +++ b/deal.II/lac/include/lac/trilinos_block_vector.h @@ -0,0 +1,404 @@ +//--------------------------------------------------------------------------- +// $Id: trilinos_block_vector.h 14783 2007-06-18 14:52:01Z bangerth $ +// Version: $Name$ +// +// Copyright (C) 2004, 2005, 2006, 2007 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- +#ifndef __deal2__trilinos_parallel_block_vector_h +#define __deal2__trilinos_parallel_block_vector_h + + +#include +#include +#include +#include +#include + +#ifdef DEAL_II_USE_TRILINOS + +DEAL_II_NAMESPACE_OPEN + + +namespace TrilinosWrappers +{ + // forward declaration + class BlockVector; + +/*! @addtogroup TrilinosWrappers + *@{ + */ + +/** + * 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 + * @author Martin Kronbichler, Wolfgang Bangerth, 2008 + */ + 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 Input_Maps. + * Each Epetra_Map already knows + * the distribution of data among + * the MPI processes. + */ + explicit BlockVector (const std::vector &InputMaps); + + /** + * 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); + + /** + * 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 &input_maps); + + /** + * 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); + + /** + * 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); + + /** + * Compresses all the components + * after assembling together all + * elements. + */ + void compress (); + + /** + * 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); + + /** + * Exception + */ + DeclException0 (ExcIteratorRangeDoesNotMatchVectorSize); + /** + * Exception + */ + DeclException0 (ExcNonMatchingBlockVectors); + }; + +/*@}*/ + +/*----------------------- Inline functions ----------------------------------*/ + + + inline + BlockVector::BlockVector () + {} + + + + inline + BlockVector::BlockVector (const std::vector &InputMaps) + { + reinit (InputMaps); + } + + + + inline + BlockVector::BlockVector (const unsigned int num_blocks = 0) + { + 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 + BlockVector & + BlockVector::operator = (const value_type s) + { + BaseClass::operator = (s); + return *this; + } + + + + inline + BlockVector & + BlockVector::operator = (const BlockVector &v) + { + BaseClass::operator = (v); + return *this; + } + + + + inline + BlockVector::~BlockVector () + {} + + + + inline + void + BlockVector::reinit (const std::vector &input_maps) + { + unsigned int no_blocks = input_maps.size(); + std::vector block_sizes (no_blocks); + + for (unsigned int i=0; iblock_indices.reinit (block_sizes); + if (this->components.size() != this->n_blocks()) + this->components.resize(this->n_blocks()); + + for (unsigned int i=0; in_blocks(); ++i) + this->components[i].reinit(input_maps[i]); + + collect_sizes(); + } + + + + inline + void + BlockVector::reinit (const BlockVector& v) + { + this->block_indices = v.get_block_indices(); + if (this->components.size() != this->n_blocks()) + this->components.resize(this->n_blocks()); + + for (unsigned int i=0;in_blocks();++i) + block(i).reinit(v.block(i)); + } + + + + inline + void + BlockVector::reinit (const unsigned int num_blocks) + { + std::vector block_sizes (num_blocks, 0); + this->block_indices.reinit (block_sizes); + if (this->components.size() != this->n_blocks()) + this->components.resize(this->n_blocks()); + + for (unsigned int i=0;in_blocks();++i) + block(i).clear(); + } + + + + inline + void + BlockVector::compress () + { + for (unsigned int i=0; in_blocks() == v.n_blocks(), + ExcDimensionMismatch(this->n_blocks(), v.n_blocks())); + + for (unsigned int i=0; in_blocks(); ++i) + this->components[i].swap (v.components[i]); + ::dealii::swap (this->block_indices, v.block_indices); + } + + + +/** + * Global function which overloads the default implementation + * of the C++ standard library which uses a temporary object. The + * function simply exchanges the data of the two vectors. + * + * @ingroup TrilinosWrappers + * @relates TrilinosWrappers::BlockVector + * @author Martin Kronbichler, Wolfgang Bangerth, 2008 + */ + inline + void swap (BlockVector &u, + BlockVector &v) + { + u.swap (v); + } + +} + +DEAL_II_NAMESPACE_CLOSE + +#endif // DEAL_II_USE_TRILINOS + +#endif -- 2.39.5