LifeV
MatrixBlockMonolithicEpetra.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 ************************************************************************
4 
5  This file is part of the LifeV Applications.
6  Copyright (C) 2001-2010 EPFL, Politecnico di Milano, INRIA
7 
8  This library is free software; you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as
10  published by the Free Software Foundation; either version 2.1 of the
11  License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  USA
22 
23 ************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file MatrixBlockMonolithicEpetra.hpp
29  @brief The file contains the MatrixBlockMonolithicEpetra class
30 
31  @author Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
32  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
33  @date 2010-10-09
34  */
35 
36 #ifndef _MATRIX_BLOCK_MONOLITHIC_EPETRA_HPP_
37 #define _MATRIX_BLOCK_MONOLITHIC_EPETRA_HPP_
38 
39 #include <boost/shared_ptr.hpp>
40 #include <lifev/core/array/MapEpetra.hpp>
41 #include <lifev/core/array/MapVector.hpp>
42 #include <lifev/core/array/MatrixEpetra.hpp>
43 #include <lifev/core/array/MatrixBlockMonolithicEpetraView.hpp>
44 
45 namespace LifeV
46 {
47 
48 //! MatrixBlockMonolithicEpetra - class of block matrix
49 /*!
50  @author Gwenol Grandperrin
51  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
52 
53  The MatrixBlockMonolithicEpetra class contains data related
54  to block matrix. It is an extension to MatrixEpetra where data about blocks have
55  been set. For an introduction to the block structures in LifeV, see
56  \ref BlockAlgebraPage "this page".
57 
58  There are mainly two ways to define a MatrixBlockMonolithicEpetra:
59  <ul>
60  <li> Construct it using the same syntax as for LifeV::MatrixEpetra and the use
61  a setter for the structure.
62  <li> Construct it directly with the maps of the blocks.
63  </ul>
64  Both ways are equivalent.
65 
66  To access the blocks, one uses then the blockView or block methods.
67 
68  */
69 template <typename DataType>
70 class MatrixBlockMonolithicEpetra : public MatrixEpetra<DataType>
71 {
72 public:
73 
74  typedef MatrixBlockMonolithicEpetraView<DataType> block_type;
75  typedef std::shared_ptr<block_type> block_ptrType;
76 
77  /** @name Constructors, destructor
78  */
79  //@{
80  //! default constructor.
81  MatrixBlockMonolithicEpetra ( const MapEpetra& map, int numEntries = 50);
82 
83  //! Block constructor
84  /*!
85  This is the most complete constructor, as it builds the whole block
86  structure of the matrix, using the maps stored in the vector.
87  */
88  MatrixBlockMonolithicEpetra ( const MapVector<MapEpetra>& vector, int numEntries = 50);
89 
90  //! Casting constructor
91  MatrixBlockMonolithicEpetra ( const MatrixEpetra<DataType>& matrix );
92 
93  //! Copy constructor
94  MatrixBlockMonolithicEpetra ( const MatrixBlockMonolithicEpetra& matrix );
95 
96  //! Destructor
97  ~MatrixBlockMonolithicEpetra();
98 
99  //@}
100 
101 
102  //! @name Set Methods
103  //@{
104 
105  /*! Set the size of the blocks of the matrix
106  * @param blockNumRows Number of rows in the blocks
107  * @param blockNumColumns Number of columns in the blocks
108  */
109  void setBlockStructure ( const std::vector<UInt>& blockNumRows,
110  const std::vector<UInt>& blockNumColumns );
111 
112  /*! Set the size of the blocks of the matrix using the maps stored in the vector
113  of map. The resulting block structure in symmetric (same blocks in the rows
114  and in the columns).
115 
116  This method does not involve large computations. The global size and the map
117  of the matrix cannot be changed with this method (and the block structure has
118  to be compatible with the global size).
119 
120  */
121  void setBlockStructure (const MapVector<MapEpetra>& mapVector);
122 
123  //@}
124 
125 
126  //! @name Get Methods
127  //@{
128 
129  //! Returns the number of rows of the block
130  /*!
131  * @param rowIndex Row index of the block
132  */
133  UInt blockNumRows (const UInt& rowIndex) const;
134 
135  //! Returns the number of columns of the block
136  /*!
137  * @param columnIndex Column index of the block
138  */
139  UInt blockNumColumns (const UInt& columnIndex) const;
140 
141  //! Returns the MatrixBlockMonolithicEpetraView at the (rowIndex,colIndex) location
142  /*!
143  * @param rowIndex Row position of the block in the matrix
144  * @param columnIndex Column position of the block in the matrix
145  * @param mbv MatrixBlockMonolithicEpetraView to be filled
146  */
147  void blockView ( const UInt& rowIndex,
148  const UInt& columnIndex,
149  block_type& mbv);
150 
151  //! Returns the block (rowIndex,columnIndex) of the matrix
152  /*!
153  Remark that the returned block is a shared pointer. This is
154  a limitation due to the non-copiability of the blocks.
155  @param rowIndex The index of the block w.r. to the block structure
156  @param columnIndex The index of the block w.r. to the block structure
157  */
158  block_ptrType block (const UInt& rowIndex, const UInt& columnIndex);
159 
160  //@}
161 
162 private:
163 
164  std::vector<UInt> M_blockNumRows;
165  std::vector<UInt> M_blockNumColumns;
166  std::vector<UInt> M_blockFirstRows;
167  std::vector<UInt> M_blockFirstColumns;
168 };
169 
170 // ===================================================
171 // IMPLEMENTATION
172 // ===================================================
173 
174 // ===================================================
175 // Constructors & Destructor
176 // ===================================================
177 template <typename DataType>
178 MatrixBlockMonolithicEpetra<DataType>::MatrixBlockMonolithicEpetra (const MapEpetra& map, int numEntries) :
179  MatrixEpetra<DataType> (map, numEntries),
180  M_blockNumRows (std::vector<UInt> (1, map.map (Unique)->NumGlobalElements() ) ),
181  M_blockNumColumns (std::vector<UInt> (1, map.map (Unique)->NumGlobalElements() ) ),
182  M_blockFirstRows (std::vector<UInt> (1, 0) ),
183  M_blockFirstColumns (std::vector<UInt> (1, 0) )
184 {
185 }
186 
187 
188 
189 template <typename DataType>
190 MatrixBlockMonolithicEpetra<DataType>::MatrixBlockMonolithicEpetra ( const MapVector<MapEpetra>& vector, int numEntries)
191  :
192  MatrixEpetra<DataType> (vector.totalMap() )
193  //MatrixEpetra<DataType>( typename MatrixEpetra<DataType>::matrix_ptrtype())
194 {
195  ASSERT ( vector.nbMap() > 0 , "Map vector empty, impossible to construct a MatrixBlockMonolithicEpetra!");
196 
197  MapEpetra myMap (vector.map (0) );
198  M_blockNumRows.push_back (vector.mapSize (0) );
199  M_blockNumColumns.push_back (vector.mapSize (0) );
200  M_blockFirstRows.push_back (0);
201  M_blockFirstColumns.push_back (0);
202 
203  UInt totalRows (vector.mapSize (0) );
204  UInt totalColumns (vector.mapSize (0) );
205 
206  for (UInt i (1); i < vector.nbMap(); ++i)
207  {
208  myMap += vector.map (i);
209  M_blockNumRows.push_back (vector.mapSize (i) );
210  M_blockNumColumns.push_back (vector.mapSize (i) );
211  M_blockFirstRows.push_back (totalRows);
212  M_blockFirstColumns.push_back (totalColumns);
213 
214  totalRows += vector.mapSize (i);
215  totalColumns += vector.mapSize (i);
216  }
217 
218  this->mapPtr().reset (new MapEpetra (myMap) );
219  this->matrixPtr().reset ( new typename MatrixEpetra<DataType>::matrix_type ( Copy, *myMap.map ( Unique ), numEntries, false) );
220 }
221 
222 
223 template <typename DataType>
224 MatrixBlockMonolithicEpetra<DataType>::MatrixBlockMonolithicEpetra ( const MatrixEpetra<DataType>& matrix ) :
225  MatrixEpetra<DataType> (matrix),
226  M_blockNumRows(),
227  M_blockNumColumns(),
228  M_blockFirstRows(),
229  M_blockFirstColumns()
230 {}
231 
232 template <typename DataType>
233 MatrixBlockMonolithicEpetra<DataType>::MatrixBlockMonolithicEpetra ( const MatrixBlockMonolithicEpetra& matrix ) :
234  MatrixEpetra<DataType> (matrix),
235  M_blockNumRows (matrix.M_blockNumRows),
236  M_blockNumColumns (matrix.M_blockNumColumns),
237  M_blockFirstRows (matrix.M_blockFirstRows),
238  M_blockFirstColumns (matrix.M_blockFirstColumns)
239 {}
240 
241 template <typename DataType>
242 MatrixBlockMonolithicEpetra<DataType>::~MatrixBlockMonolithicEpetra()
243 {}
244 
245 // ===================================================
246 // Set Methods
247 // ===================================================
248 template <typename DataType>
249 void
250 MatrixBlockMonolithicEpetra<DataType>::setBlockStructure (const std::vector<UInt>& blockNumRows,
251  const std::vector<UInt>& blockNumColumns)
252 {
253  ASSERT ( blockNumRows.size() > 0, "No way to build a matrix with 0 block rows");
254  ASSERT ( blockNumColumns.size() > 0, "No way to build a matrix with 0 block columns")
255 
256 
257  M_blockNumRows = blockNumRows;
258  M_blockNumColumns = blockNumColumns;
259 
260  M_blockFirstRows.resize (M_blockNumRows.size() );
261  M_blockFirstColumns.resize (M_blockNumColumns.size() );
262 
263  UInt currentSize (0);
264  for (UInt i (0); i < blockNumRows.size(); ++i)
265  {
266  M_blockFirstRows[i] = currentSize;
267  currentSize += M_blockNumRows[i];
268  }
269 
270  currentSize = 0;
271  for (UInt i (0); i < blockNumColumns.size(); ++i)
272  {
273  M_blockFirstColumns[i] = currentSize;
274  currentSize += M_blockNumColumns[i];
275  }
276 }
277 
278 template <typename DataType>
279 void
280 MatrixBlockMonolithicEpetra<DataType>::setBlockStructure (const MapVector<MapEpetra>& mapVector)
281 {
282  ASSERT ( mapVector.nbMap() > 0 , "Map vector empty, impossible to set the block structure");
283 
284  M_blockNumRows.resize (mapVector.nbMap() );
285  M_blockNumColumns.resize (mapVector.nbMap() );
286 
287  M_blockFirstRows.resize (mapVector.nbMap() );
288  M_blockFirstColumns.resize (mapVector.nbMap() );
289 
290  UInt totalSize (0);
291 
292  for (UInt i (0); i < mapVector.nbMap(); ++i)
293  {
294  M_blockNumRows[i] = mapVector.mapSize (i);
295  M_blockNumColumns[i] = mapVector.mapSize (i);
296 
297  M_blockFirstRows[i] = totalSize;
298  M_blockFirstColumns[i] = totalSize;
299 
300  totalSize += mapVector.mapSize (i);
301  }
302 
303  ASSERT ( this->matrixPtr()->NumGlobalCols() == totalSize, " Incompatible block structure (global size does not match) ");
304  ASSERT ( this->matrixPtr()->NumGlobalRows() == totalSize, " Incompatible block structure (global size does not match) ");
305 }
306 
307 // ===================================================
308 // Get Methods
309 // ===================================================
310 template <typename DataType>
311 UInt
312 MatrixBlockMonolithicEpetra<DataType>::blockNumRows (const UInt& rowIndex) const
313 {
314  ASSERT (rowIndex < M_blockFirstRows.size(), "Row index out of bound. No block to return");
315 
316  return M_blockNumRows[rowIndex];
317 }
318 
319 template <typename DataType>
320 UInt
321 MatrixBlockMonolithicEpetra<DataType>::blockNumColumns (const UInt& columnIndex) const
322 {
323  ASSERT (columnIndex < M_blockFirstColumns.size(), "Column index out of bound. No block to return");
324 
325  return M_blockNumColumns[columnIndex];
326 }
327 
328 template <typename DataType>
329 void
330 MatrixBlockMonolithicEpetra<DataType>::blockView (const UInt& rowIndex,
331  const UInt& columnIndex,
332  block_type& mbv)
333 {
334  ASSERT (rowIndex < M_blockFirstRows.size(), "Row index out of bound. No block to return");
335  ASSERT (columnIndex < M_blockFirstColumns.size(), "Column index out of bound. No block to return");
336 
337  mbv.setup (M_blockFirstRows[rowIndex],
338  M_blockFirstColumns[columnIndex],
339  M_blockNumRows[rowIndex],
340  M_blockNumColumns[columnIndex],
341  this);
342 }
343 
344 template <typename DataType>
345 typename MatrixBlockMonolithicEpetra<DataType>::block_ptrType
346 MatrixBlockMonolithicEpetra<DataType>::block (const UInt& rowIndex, const UInt& columnIndex)
347 {
348  ASSERT (rowIndex < M_blockFirstRows.size(), "Row index out of bound. No block to return");
349  ASSERT (columnIndex < M_blockFirstColumns.size(), "Column index out of bound. No block to return");
350 
351  block_ptrType mbv (new block_type);
352 
353  mbv->setup (M_blockFirstRows[rowIndex],
354  M_blockFirstColumns[columnIndex],
355  M_blockNumRows[rowIndex],
356  M_blockNumColumns[columnIndex],
357  this);
358 
359  return mbv;
360 }
361 
362 
363 } // namespace LifeV
364 
365 #endif /* MATRIXBLOCK_HPP */
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191