LifeV
MatrixEpetra.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief MatrixEpetra
30 
31  @author Gilles Fourestey <gilles.fourestey@epfl.ch>
32  @author Simone Deparis <simone.deparis@epfl.ch>
33  @contributor Gwenol Grandperrin <gwenol.grandperrin@epfl.ch> Cristiano Malossi <cristiano.malossi@epfl.ch>
34  @maintainer Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
35 
36  @date 03-11-2009
37  */
38 
39 #ifndef _EPETRAMATRIX_HPP_
40 #define _EPETRAMATRIX_HPP_
41 
42 #include <lifev/core/LifeV.hpp>
43 
44 
45 #include <Epetra_MpiComm.h>
46 #include <Epetra_FECrsMatrix.h>
47 #include <Epetra_FECrsGraph.h>
48 #include <EpetraExt_MatrixMatrix.h>
49 #include <EpetraExt_Transpose_RowMatrix.h>
50 #include <EpetraExt_RowMatrixOut.h>
51 #include <ml_epetra_utils.h>
52 
53 #ifdef HAVE_HDF5
54 #include <EpetraExt_HDF5.h>
55 #endif
56 
57 
58 #include <lifev/core/array/VectorEpetra.hpp>
59 
60 //@@
61 //#define OFFSET 0
62 
63 namespace LifeV
64 {
65 
66 //! MatrixEpetra - The Epetra Matrix format Wrapper
67 /*!
68  @author Gilles Fourestey <gilles.fourestey@epfl.ch>
69  @author Simone Deparis <simone.deparis@epfl.ch>
70  @author Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
71 
72  The MatrixEpetra class provides a general interface for the Epetra_FECrsMatrix of Trilinos.
73 
74  Visit http://trilinos.sandia.gov for more informations about Epetra_FECrsMatrix.
75  */
76 template <typename DataType>
78 {
79 public:
80 
81  //! @name Public Types
82  //@{
83 
88 
89  //@}
90 
91 
92  //! @name Constructors & Destructor
93  //@{
94 
95  //! Constructor from a graph
96  /*!
97  @param map Row map. The column map will be defined in MatrixEpetra<DataType>::GlobalAssemble(...,...)
98  @param graph A sparse compressed row graph.
99  */
100  MatrixEpetra ( const MapEpetra& map, const Epetra_CrsGraph& graph, bool ignoreNonLocalValues = false );
101 
102  //! Constructor from a FE graph
103  /*!
104  @param map Row map. The column map will be defined in MatrixEpetra<DataType>::GlobalAssemble(...,...)
105  @param graph A sparse compressed row FE graph.
106  */
107  MatrixEpetra ( const MapEpetra& map, const Epetra_FECrsGraph& graph, bool ignoreNonLocalValues = false);
108 
109  //! Constructor for square and rectangular matrices
110  /*!
111  @param map Row map. The column map will be defined in MatrixEpetra<DataType>::GlobalAssemble(...,...)
112  @param numEntries The average number of entries for each row.
113  */
114  MatrixEpetra ( const MapEpetra& map, Int numEntries = 50, bool ignoreNonLocalValues = false );
115 
116  //! Constructor for square and rectangular matrices, knowing the number of entries per row
117  /*!
118  @param map Row map. The column map will be defined in MatrixEpetra<DataType>::GlobalAssemble(...,...)
119  @param numEntriesPerRow Contains the number of entries for each row.
120  */
121  MatrixEpetra ( const MapEpetra& map, Int* numEntriesPerRow, bool ignoreNonLocalValues = false );
122 
123  //! Copy Constructor
124  /*!
125  @param matrix Matrix used to create the new occurence
126  */
127  MatrixEpetra ( const MatrixEpetra& matrix);
128 
129  //! Copies the matrix to a matrix which resides only on the processor
130  /*!
131  @param matrix Matrix where the content of the matrix should be stored
132  @param reduceToProc Processor where the matrix should be stored
133  */
134  MatrixEpetra ( const MatrixEpetra& matrix, const UInt reduceToProc );
135 
136  //! Constructs an MatrixEpetra view of an Epetra_FECrsMatrix.
137  /*!
138  This constructor can be used when we need to modify an Epetra_FECrsMatrix
139  using a method of the class MatrixEpetra
140  @param crsMatrixPtr Pointer on a Epetra_FECrsMatrix of Trilinos
141  */
142  LIFEV_DEPRECATED ( MatrixEpetra ( matrix_ptrtype crsMatrixPtr) );
143 
144  //! Constructs an MatrixEpetra view of an Epetra_FECrsMatrix.
145  /*!
146  This constructor can be used when we need to modify an Epetra_FECrsMatrix
147  using a method of the class MatrixEpetra
148  @param map Row map. The column map will be defined in MatrixEpetra<DataType>::GlobalAssemble(...,...)
149  @param crsMatrixPtr Pointer on a Epetra_FECrsMatrix of Trilinos
150  */
151  MatrixEpetra ( const MapEpetra& map, matrix_ptrtype crsMatrixPtr);
152 
153  //! Destructor
154  virtual ~MatrixEpetra() {}
155 
156  //@}
157 
158 
159  //! @name Operators
160  //@{
161 
162  //! Addition operator
163  /*!
164  @param matrix matrix to be added to the current matrix
165  */
166  MatrixEpetra& operator += ( const MatrixEpetra& matrix );
167 
168  //! Subtraction operator
169  /*!
170  @param matrix matrix to be subtracted to the current matrix
171  */
172  MatrixEpetra& operator -= ( const MatrixEpetra& matrix );
173 
174  //! Assignment operator
175  /*!
176  @param matrix matrix to be assigned to the current matrix
177  */
178  MatrixEpetra& operator= ( const MatrixEpetra& matrix );
179 
180  //! Matrix-Vector multiplication
181  /*!
182  @param vector Vector to be multiplied by the current matrix
183  */
184  vector_type operator * ( const vector_type& vector ) const;
185 
186  //! Multiplication operator
187  /*!
188  Multiply by a scalar value the components of the current matrix.
189  (modify the matrix of the class)
190  @param scalar Value for the multiplication
191  */
192  MatrixEpetra& operator *= ( const DataType scalar );
193 
194  //! Multiplication operator
195  /*!
196  Multiply by a scalar value the components of the current matrix.
197  (do not modify the matrix of the class)
198  @param scalar Value for the multiplication
199  */
200  MatrixEpetra operator * ( const DataType scalar ) const;
201 
202  //@}
203 
204 
205  //! @name Methods
206  //@{
207 
208  //! If the matrix has been filled, this function will reopen the Matrix
209  void openCrsMatrix();
210 
211  //! This function removes all the zeros in the matrix and add zero on the diagonal
212  /*!
213  The zeros added on the diagonal are used to impose boundary conditions
214  */
215  void removeZeros();
216 
217  //! Swap the given shared pointer with the one of the matrix
218  /*!
219  @param matrixPtr pointer on the matrix
220  */
221  void swapCrsMatrix ( matrix_ptrtype& matrixPtr );
222 
223  //! Swap the matrix with the one given as argument
224  /*!
225  @param matrix matrix which is swapped
226  */
227  void swapCrsMatrix ( MatrixEpetra<DataType>& matrix );
228 
229  //! Multiply the MatrixEpetra by the first given matrix and put the result in the second given matrix
230  /*!
231  @param transposeCurrent If true, it transposes the MatrixEpetra
232  @param matrix Matrix that multiply the MatrixEpetra
233  @param transposeMatrix if true, it transposes the matrix "matrix"
234  @param result Matrix to store the result
235  @param callFillCompleteOnResult If true, the matrix "result" will be filled (i.e. closed) after the multiplication
236  */
237  Int multiply ( bool transposeCurrent,
238  const MatrixEpetra<DataType>& matrix,
239  bool transposeMatrix,
240  MatrixEpetra<DataType>& result,
241  bool callFillCompleteOnResult = true ) const;
242 
243  //! Multiply the first VectorEpetra given as a parameter by the MatrixEpetra and put the result into the second given VectorEpetra
244  /*!
245  @param transposeCurrent If true, it transposes the MatrixEpetra
246  @param vector1 Vector that will be multiply by the MatrixEpetra
247  @param vector2 Vector that will store the result
248  */
249  Int multiply ( bool transposeCurrent, const vector_type& vector1, vector_type& vector2 ) const;
250 
251  //! Add to the matrix a dyadic product: \f[ C += A \otimes B + \f], where \f[ C \f] is the matrix.
252  /*!
253  * NOTE: This method has been tested only for square matrices and unique vectors
254  * @param vector1 unique vector A
255  * @param vector2 unique vector B
256  */
257  void addDyadicProduct ( const vector_type& uniqueVector1, const vector_type& uniqueVector2 );
258 
259  //! Add a multiple of a given matrix: *this += scalar*matrix
260  /*!
261  @param scalar Scalar which multiplies the matrix
262  @param matrix Matrix to be added
263  */
264  void add ( const DataType scalar, const MatrixEpetra& matrix );
265 
266  //! Returns a pointer to a new matrix which contains the transpose of the current matrix
268 
269  //! Set entries (rVec(i),rVec(i)) to coefficient and the rest of the row entries to zero
270  /*!
271  @param rVec Vector of the Id that should be set to "coefficient"
272  @param coefficient Value to be set on the diagonal
273  @param offset Offset used for the indices
274  */
275  void diagonalize ( std::vector<UInt> rVec, DataType const coefficient, UInt offset = 0 );
276 
277  //! Set entry (entryIndex,entryIndex) to coefficient and the rest of the row to zero
278  /*!
279  @param entryIndex Index of the row where we set the "coefficient"
280  @param coefficient Value to be set on the diagonal
281  @param offset Offset used for the indices
282  */
283  void diagonalize ( UInt const entryIndex, DataType const coefficient, UInt offset = 0 );
284 
285  //! apply constraint on all rows rVec
286  /*!
287  @param rVec vector of rows
288  @param coefficient Value to set entry (r,r) at
289  @param rhs Right hand side Vector of the system to be adapted accordingly
290  @param datumVector vector of values to constrain entry r of the solution at
291  @param offset Offset used for the indices
292  */
293  void diagonalize ( std::vector<UInt> rVec,
294  DataType const coefficient,
295  vector_type& rhs,
296  std::vector<DataType> datumVector,
297  UInt offset = 0 );
298 
299  //! apply constraint on row "row"
300  /*!
301  @param row row number
302  @param coefficient value to set entry (row,row) at
303  @param rhs Right hand side vector of the system to be adapted accordingly
304  @param datumVector value to constrain entry r of the solution at
305  @param offset Offset used for the indices
306  */
307  void diagonalize ( UInt const row, DataType const coefficient, vector_type& rhs,
308  DataType datum,
309  UInt offset = 0 );
310 
311  //! Save the matrix into a MatrixMarket (.mtx) file
312  /*!
313  @param filename file where the matrix will be saved
314  @param headers boolean to write the MM headers or not
315  */
316  void matrixMarket ( std::string const& fileName, const bool headers = true );
317 
318  //! Save the matrix into a Matlab (.m) file
319  /*!
320  @param filename file where the matrix will be saved
321  */
322  void spy ( std::string const& fileName );
323 
324 #ifdef HAVE_HDF5
325  //! Save the matrix into a HDF5 (.h5) file
326  /*!
327  @param fileName Name of the file where the matrix will be saved, without extension (.h5)
328  @param matrixName Name of the matrix in the HDF5 file
329  @param truncate True if the file has to be truncated; False if the file already exist and should not be truncated
330  */
331  void exportToHDF5 ( std::string const& fileName, std::string const& matrixName = "matrix", bool const& truncate = true );
332 
333  //! Read a matrix from a HDF5 (.h5) file
334  /*!
335  @param fileName Name of the file where the matrix will be saved, without extension (.h5)
336  @param matrixName Name of the matrix in the HDF5 file
337  */
338  void importFromHDF5 ( std::string const& fileName, std::string const& matrixName = "matrix" );
339 #endif
340 
341  //! Print the contents of the matrix
342  /*!
343  @param output Stream where the informations must be printed
344  */
345  void showMe ( std::ostream& output = std::cout ) const;
346 
347  //! Global assemble of a square matrix with default domain and range map
348  /*
349  <ol>
350  <li> Calls insertZeroDiagonal and then Epetra_FECsrMatrix::GlobalAssemble();
351  <li> Set M_domainMap and M_rangeMap
352  </ol>
353 
354  EpetraFECsrMatrix will assume that both the domain and range map are the same
355  of the row map defined in the constructor.
356 
357  NOTE: domain and range map must be one-to-one and onto. (Unique map)
358  */
360 
361  //! Global assemble for rectangular matrices.
362  /*
363  <ol>
364  <li> Calls Epetra_FECsrMatrix::GlobalAssemble(Epetra_Map & domainMap, Epetra_Map & rangeMap);
365  <li> Set M_domainMap and M_rangeMap
366  </ol>
367  @param domainMap The domain map
368  @param rangeMap The range map
369  */
370  Int globalAssemble ( const std::shared_ptr<const MapEpetra>& domainMap,
371  const std::shared_ptr<const MapEpetra>& rangeMap );
372 
373  //! Fill complete of a square matrix with default domain and range map
374  Int fillComplete();
375 
376  //! insert the given value into the diagonal
377  /*!
378  Pay intention that this will add values to the diagonal,
379  so for later added values with set_mat_inc, the one
380  will be added.
381  Inserts Value on the local diagonal for diagonal elements specified by the input MapEpetra;
382  This methods works only if matrix is not closed.
383 
384  @param entry The entry that is inserted in the diagonal
385  @param Map The MapEpetra
386  @param offset An offset for the insertion of the diagonal entries
387  */
388 
389  void insertValueDiagonal ( const DataType entry, const MapEpetra& Map, const UInt offset = 0 );
390 
391  //! insert the given value into the diagonal
392  /*!
393  Pay intention that this will add values to the diagonal,
394  so for later added values with set_mat_inc, the one
395  will be added
396 
397  Inserts Value on the local diagonal for diagonal elements >= from and < to;
398  <ol>
399  <li> If from > to, process all diagonal entries entries
400  <li> If from = to, do nothing
401  </ol>
402  This methods works only if matrix is not closed.
403  @param value Value to be inserted on the diagonal
404  @param from Starting row
405  @param to Ending row
406  */
407  void insertValueDiagonal ( const DataType& value, Int from = -1, Int to = -2 );
408 
409  //! insert ones into the diagonal to ensure the matrix' graph has a entry there
410  /*
411  Pay intention that this will add ones to the diagonal,
412  so for later added values with set_mat_inc, the one
413  will be added
414 
415  Inserts Value on the local diagonal for diagonal elements >= from and < to;
416  <ol>
417  <li> If from > to, process all diagonal entries entries
418  <li> If from = to, do nothing
419  </ol>
420  This methods works only if matrix is not closed.
421  @param from Starting row
422  @param to Ending row
423  */
424  void insertOneDiagonal ( Int from = -1, Int to = -2 );
425 
426  //! insert zeros into the diagonal to ensure the matrix' graph has a entry there
427  /*!
428  This method does not remove non zero entries in the diagonal.
429 
430  Inserts Value on the local diagonal for diagonal elements >= from and < to;
431  <ol>
432  <li> If from > to, process all diagonal entries entries
433  <li> If from = to, do nothing
434  </ol>
435  This methods works only if matrix is not closed.
436  @param from Starting row
437  @param to Ending row
438  */
439  void insertZeroDiagonal ( Int from = -1, Int to = -2 );
440 
441  //! Compute the norm 1 of the global matrix
442  /*!
443  @return norm 1
444  */
445  Real norm1() const;
446 
447  //! Compute the norm inf of the global matrix
448  /*!
449  @return norm inf
450  */
451  Real normInf() const;
452 
453  //! Compute the frobenius norm of the global matrix
454  /*!
455  @return norm Frobenius
456  */
457  Real normFrobenius() const;
458 
459  //@}
460 
461 
462  //! @name Set Methods
463  //@{
464 
465  //! set zero in all the matrix entries
466  void zero()
467  {
468  M_epetraCrs->PutScalar (0.);
469  }
470 
471  //! Set a set of values to the corresponding set of coefficient in the matrix
472  /*!
473  @param numRows Number of rows into the list given in "localValues"
474  @param numColumns Number of columns into the list given in "localValues"
475  @param rowIndices List of row indices
476  @param columnIndices List of column indices
477  @param localValues 2D array containing the coefficient related to "rowIndices" and "columnIndices"
478  @param format Format of the matrix (Epetra_FECrsMatrix::COLUMN_MAJOR or Epetra_FECrsMatrix::ROW_MAJOR)
479  */
480  void setCoefficients ( Int const numRows, Int const numColumns,
481  std::vector<Int> const& rowIndices, std::vector<Int> const& columnIndices,
482  DataType* const* const localValues,
483  Int format = Epetra_FECrsMatrix::COLUMN_MAJOR );
484 
485  //! Set a coefficient of the matrix
486  /*!
487  @param row Row index of the coefficient
488  @param column column index of the coefficient
489  */
490  void setCoefficient ( UInt row, UInt column, DataType localValue );
491 
492  //! Add a set of values to the corresponding set of coefficient in the matrix
493  /*!
494  @param numRows Number of rows into the list given in "localValues"
495  @param numColumns Number of columns into the list given in "localValues"
496  @param rowIndices List of row indices
497  @param columnIndices List of column indices
498  @param localValues 2D array containing the coefficient related to "rowIndices" and "columnIndices"
499  @param format Format of the matrix (Epetra_FECrsMatrix::COLUMN_MAJOR or Epetra_FECrsMatrix::ROW_MAJOR)
500  */
501  void addToCoefficients ( Int const numRows, Int const numColumns,
502  std::vector<Int> const& rowIndices, std::vector<Int> const& columnIndices,
503  DataType* const* const localValues,
504  Int format = Epetra_FECrsMatrix::COLUMN_MAJOR );
505 
506  //! Add a set of values to the corresponding set of coefficient in the closed matrix
507  /*!
508  @param numRows Number of rows into the list given in "localValues"
509  @param numColumns Number of columns into the list given in "localValues"
510  @param rowIndices List of row indices
511  @param columnIndices List of column indices
512  @param localValues 2D array containing the coefficient related to "rowIndices" and "columnIndices"
513  @param format Format of the matrix (Epetra_FECrsMatrix::COLUMN_MAJOR or Epetra_FECrsMatrix::ROW_MAJOR)
514  */
515  void sumIntoCoefficients ( Int const numRows, Int const numColumns,
516  std::vector<Int> const& rowIndices,
517  std::vector<Int> const& columnIndices,
518  DataType* const* const localValues,
519  Int format = Epetra_FECrsMatrix::COLUMN_MAJOR );
520 
521  //! Add a value at a coefficient of the matrix
522  /*!
523  @param row Row index of the value to be added
524  @param column Column index of the value to be added
525  @param localValue Value to be added to the coefficient
526  */
527  void addToCoefficient ( UInt const row, UInt const column, DataType const localValue );
528 
529  //! If set true, transpose of this operator will be applied.
530  /*!
531  @param transpose flag to identify whether to transpose or not
532  */
533  void setUseTranspose ( const bool& transpose = false )
534  {
535  M_epetraCrs->SetUseTranspose ( transpose );
536  }
537 
538  //@}
539 
540 
541  //! @name Get Methods
542  //@{
543 
544  //! Return the fill-complete status of the Epetra_FECrsMatrix
545  bool filled() const
546  {
547  return M_epetraCrs->Filled();
548  }
549 
550  //! Return the shared_pointer of the Epetra_FECrsMatrix
552  {
553  return M_epetraCrs;
554  }
555 
556  //! Return the shared_pointer of the Epetra_Map
558  {
559  return M_map;
560  }
561 
562  //! Return the const shared_pointer of the Epetra_FECrsMatrix
563  const matrix_ptrtype& matrixPtr() const
564  {
565  return M_epetraCrs;
566  }
567 
568  //! Return the mean number of entries in the matrix rows
569  Int meanNumEntries() const ;
570 
571  //! Return the Id of the processor
572  Int processorId();
573 
574  //! Return the row MapEpetra of the MatrixEpetra used in the assembling
575  /*!
576  Note: This method should be call when MapEpetra is still open.
577  */
578  const MapEpetra& map() const;
579 
580  //! Return the domain MapEpetra of the MatrixEpetra
581  /*!
582  This function should be called only after MatrixEpetra<DataType>::GlobalAssemble(...) has been called.
583  If this is an open matrix that M_domainMap is an invalid pointer
584  */
585  const MapEpetra& domainMap() const;
586 
587  const boost::shared_ptr< const MapEpetra >& domainMapPtr() const;
588 
589 
590  //! Return the range MapEpetra of the MatrixEpetra
591  /*!
592  This function should be called only after MatrixEpetra<DataType>::GlobalAssemble(...) has been called.
593  If this is an open matrix that M_domainMap is an invalid pointer
594  */
595  const MapEpetra& rangeMap() const;
596  const boost::shared_ptr< const MapEpetra >& rangeMapPtr() const;
597 
598  //! Restrict the matrix to the dofs contained in the input map
599  /*!
600  @param map MapEpetra that contains the indices
601  @param matrix_out Matrix restricted
602  */
603  void restrict ( const std::shared_ptr<MapEpetra>& map,
604  const std::shared_ptr<VectorEpetra>& numeration,
605  const UInt& offset,
606  std::shared_ptr<MatrixEpetra<DataType> > & matrix_out );
607 
608  //@}
609 
610  //! Friend Functions
611  //@{
612  //! RAP matrix matrix multiplication result = R * A * P
613  //! User is responsible to wrap the row pointer returned by this method with his favorite pointer
614  template <typename DType>
615  friend MatrixEpetra<DType>* RAP (const MatrixEpetra<DType>& R, const MatrixEpetra<DType>& A, const MatrixEpetra<DType>& P);
616 
617  //! PtAP matrix matrix multiplication result = Pt * A * P
618  //! User is responsible to wrap the row pointer returned by this method with his favorite pointer
619  template <typename DType>
620  friend MatrixEpetra<DType>* PtAP (const MatrixEpetra<DType>& A, const MatrixEpetra<DType>& P);
621  //@}
622 private:
623 
624 
625  // Shared pointer on the row MapEpetra used in the assembling
627 
628  // Shared pointer on the domain MapEpetra.
629  /*
630  if y = this*x,
631  then x.getMap() is the domain map.
632  NOTE: Epetra assume the domain map to be 1-1 and onto (Unique)
633  M_domainMap is a NULL pointer until MatrixEpetra<DataType> is called.
634  */
636 
637  //! Shared pointer on the range MapEpetra.
638  /*
639  if y = this*x,
640  then y.getMap() is the range map.
641  NOTE: Epetra assume the domain map to be 1-1 and onto (Unique)
642  M_rangeMap is a NULL pointer until MatrixEpetra<DataType> is called.
643  */
645 
646  // Pointer on a Epetra_FECrsMatrix
648 };
649 
650 
651 // ===================================================
652 // Constructors & Destructor
653 // ===================================================
654 template <typename DataType>
655 MatrixEpetra<DataType>::MatrixEpetra ( const MapEpetra& map, const Epetra_CrsGraph& graph, bool ignoreNonLocalValues ) :
656  M_map ( new MapEpetra ( map ) ),
658 {
659 
660 }
661 
662 template <typename DataType>
663 MatrixEpetra<DataType>::MatrixEpetra ( const MapEpetra& map, const Epetra_FECrsGraph& graph, bool ignoreNonLocalValues) :
664  M_map ( new MapEpetra ( map ) ),
666 {
667 
668 }
669 
670 template <typename DataType>
671 MatrixEpetra<DataType>::MatrixEpetra ( const MapEpetra& map, Int numEntries, bool ignoreNonLocalValues ) :
672  M_map ( new MapEpetra ( map ) ),
674 {
675 
676 }
677 
678 template <typename DataType>
679 MatrixEpetra<DataType>::MatrixEpetra ( const MapEpetra& map, int* numEntries, bool ignoreNonLocalValues ) :
680  M_map ( new MapEpetra ( map ) ),
682 {
683 
684 }
685 
686 template <typename DataType>
687 MatrixEpetra<DataType>::MatrixEpetra ( const MatrixEpetra& matrix ) :
688  M_map ( matrix.M_map ),
692 {
693 
694 }
695 
696 template <typename DataType>
697 MatrixEpetra<DataType>::MatrixEpetra ( const MatrixEpetra& matrix, const UInt reduceToProc ) :
699  M_epetraCrs ( new matrix_type ( Copy, *M_map->map ( Unique ),
700  this->numEntries ( matrix.M_epetraCrs->Map().Comm().MyPID() == reduceToProc ) * 20,
701  false ) )
702 {
703  Epetra_Export reducedExport ( M_epetraCrs->Map(), matrix.M_epetraCrs->Map() );
704  M_epetraCrs->Import ( *matrix.M_epetraCrs, reducedExport, Add );
705 
706  if (M_epetraCrs->Filled() )
707  {
708  M_domainMap = matrix.getDomainMap().createRootMap (reduceToProc);
709  M_rangeMap = matrix.getRangeMap().createRootMap (reduceToProc);
710  }
711 }
712 
713 template <typename DataType>
714 MatrixEpetra<DataType>::MatrixEpetra ( matrix_ptrtype CRSMatrixPtr ) :
715  M_map( ),
716  M_domainMap(),
717  M_rangeMap()
718 {
719  M_epetraCrs = CRSMatrixPtr;
720 }
721 
722 template <typename DataType>
723 MatrixEpetra<DataType>::MatrixEpetra (const MapEpetra& map, matrix_ptrtype CRSMatrixPtr ) :
724  M_map ( new MapEpetra (map) ),
725  M_domainMap(),
726  M_rangeMap()
727 {
728  M_epetraCrs = CRSMatrixPtr;
729 }
730 
731 
732 
733 // ===================================================
734 // Operators
735 // ===================================================
736 template <typename DataType>
737 MatrixEpetra<DataType>&
738 MatrixEpetra<DataType>::operator += ( const MatrixEpetra& matrix )
739 {
740  EpetraExt::MatrixMatrix::Add ( *matrix.matrixPtr(), false, 1., *this->matrixPtr(), 1. );
741 
742  return *this;
743 }
744 
745 template <typename DataType>
746 MatrixEpetra<DataType>&
747 MatrixEpetra<DataType>::operator -= ( const MatrixEpetra& matrix )
748 {
749  EpetraExt::MatrixMatrix::Add ( *matrix.matrixPtr(), false, -1., *this->matrixPtr(), 1. );
750 
751  return *this;
752 }
753 
754 template<typename DataType>
755 MatrixEpetra<DataType>& MatrixEpetra<DataType>::operator= ( const MatrixEpetra& matrix )
756 {
757  M_map = matrix.M_map;
758  M_domainMap = matrix.M_domainMap;
759  M_rangeMap = matrix.M_rangeMap;
760  *M_epetraCrs = * ( matrix.M_epetraCrs );
761 
762  return *this;
763 }
764 
765 template<typename DataType>
766 typename MatrixEpetra<DataType>::vector_type
767 MatrixEpetra<DataType>::operator * ( const vector_type& vector ) const
768 {
769  ASSERT_PRE ( M_epetraCrs->Filled(),
770  "MatrixEpetra::Operator*: globalAssemble(...) should be called first" );
771  ASSERT_PRE ( vector.map().mapsAreSimilar (*M_domainMap),
772  "MatrixEpetra::Operator*: the map of vec is not the same of domainMap" );
773  ASSERT_PRE ( M_rangeMap.get(),
774  "MatrixEpetra::Operator*: the rangeMap is not set" );
775 
776  vector_type result (*M_rangeMap);
777  M_epetraCrs->Apply ( vector.epetraVector(), result.epetraVector() );
778 
779  return result;
780 }
781 
782 
783 template<typename DataType>
784 MatrixEpetra<DataType>&
785 MatrixEpetra<DataType>::operator *= ( const DataType value )
786 {
787  M_epetraCrs->Scale ( value );
788  return *this;
789 }
790 
791 template<typename DataType>
792 MatrixEpetra<DataType>
793 MatrixEpetra<DataType>::operator * ( const DataType scalar ) const
794 {
795  MatrixEpetra<DataType> matrix ( *this );
796  return matrix *= scalar;
797 }
798 
799 // ===================================================
800 // Methods
801 // ===================================================
802 template <typename DataType>
803 void MatrixEpetra<DataType>::openCrsMatrix()
804 {
805  if ( M_epetraCrs->Filled() )
806  {
807  Int meanNumEntries = this->meanNumEntries();
808  matrix_ptrtype tmp ( M_epetraCrs );
809  M_epetraCrs.reset ( new matrix_type ( Copy, M_epetraCrs->RowMap(), meanNumEntries ) );
810 
811  EpetraExt::MatrixMatrix::Add ( *tmp, false, 1., *M_epetraCrs, 1. );
812 
813  M_domainMap.reset();
814  M_rangeMap.reset();
815 
816  }
817 }
818 
819 template <typename DataType>
820 void MatrixEpetra<DataType>::removeZeros()
821 {
822  if ( M_epetraCrs->Filled() )
823  {
824  Int meanNumEntries = this->meanNumEntries();
825  matrix_ptrtype tmp ( M_epetraCrs );
826  M_epetraCrs.reset (new matrix_type ( Copy, M_epetraCrs->RowMap(), meanNumEntries ) );
827 
828  //Variables to store the informations
829  Int NumEntries;
830  Real* Values;
831  Int* Indices;
832  Int row (0);
833 
834  for ( Int i (0); i < tmp->NumGlobalRows(); ++i )
835  {
836  row = tmp->LRID ( static_cast<EpetraInt_Type> (i) );
837  // Check if the row belong to this process
838  if (row == -1)
839  {
840  continue;
841  }
842  tmp->ExtractMyRowView ( row, NumEntries, Values, Indices );
843 
844  std::vector<Int> Indices2 ( NumEntries );
845  std::vector<Real> Values2 ( NumEntries );
846  Int NumEntries2 (0);
847 
848  for (Int j (0); j < NumEntries; ++j)
849  {
850  if (Values[j] != 0.0)
851  {
852  Indices2[NumEntries2] = tmp->GCID (Indices[j]);
853  Values2[NumEntries2] = Values[j];
854  NumEntries2++;
855  }
856  }
857  M_epetraCrs->InsertGlobalValues ( i, NumEntries2, &Values2[0], &Indices2[0] );
858  }
860  M_epetraCrs->GlobalAssemble();
861  }
862 }
863 
864 template <typename DataType>
865 void MatrixEpetra<DataType>::swapCrsMatrix ( matrix_ptrtype& matrixPtr )
866 {
867  M_epetraCrs.swap ( matrixPtr );
868 }
869 
870 
871 template <typename DataType>
872 void MatrixEpetra<DataType>::swapCrsMatrix ( MatrixEpetra<DataType>& matrix )
873 {
874  M_epetraCrs.swap ( matrix.M_epetraCrs );
875 }
876 
877 template <typename DataType>
878 Int MatrixEpetra<DataType>::multiply ( bool transposeCurrent,
879  const MatrixEpetra<DataType>& matrix, bool transposeMatrix,
880  MatrixEpetra<DataType>& result, bool callFillCompleteOnResult ) const
881 {
882  Int errCode = EpetraExt::MatrixMatrix::Multiply ( *M_epetraCrs, transposeCurrent,
883  *matrix.matrixPtr(), transposeMatrix,
884  *result.matrixPtr(), false );
885  if (callFillCompleteOnResult)
886  {
887  std::shared_ptr<const MapEpetra> domainMap, rangeMap;
888  if (transposeCurrent)
889  {
890  rangeMap = M_domainMap;
891  }
892  else
893  {
894  rangeMap = M_rangeMap;
895  }
896 
897  if (transposeMatrix)
898  {
899  domainMap = matrix.M_rangeMap;
900  }
901  else
902  {
903  domainMap = matrix.M_domainMap;
904  }
905 
906  result.globalAssemble (domainMap, rangeMap);
907  }
908 
909  return errCode;
910 }
911 
912 template <typename DataType>
913 Int MatrixEpetra<DataType>::multiply ( bool transposeCurrent, const vector_type& vector1, vector_type& vector2 ) const
914 {
915  ASSERT_PRE ( M_epetraCrs->Filled(),
916  "MatrixEpetra<DataType>::Multiply: GlobalAssemble(...) must be called first" );
917  ASSERT_PRE ( transposeCurrent ? vector1.map().mapsAreSimilar (*M_rangeMap) : vector1.map().mapsAreSimilar (*M_domainMap),
918  "MatrixEpetra<DataType>::Multiply: x map is different from M_domainMap (or M_rangeMap if transposeCurrent == true)" );
919  ASSERT_PRE ( transposeCurrent ? vector2.map().mapsAreSimilar (*M_domainMap) : vector2.map().mapsAreSimilar (*M_rangeMap),
920  "MatrixEpetra<DataType>::Multiply: y map is different from M_rangeMap (or M_domainMap if transposeCurrent == true)" );
921 
922 
923  return M_epetraCrs->Multiply ( transposeCurrent, vector1.epetraVector(), vector2.epetraVector() );
924 }
925 
926 template <typename DataType>
927 void MatrixEpetra<DataType>::addDyadicProduct ( const vector_type& uniqueVector1, const vector_type& uniqueVector2 )
928 {
929  // Check if the matrix is open
930  if ( M_epetraCrs->Filled() )
931  {
932  if ( M_epetraCrs->Comm().MyPID() == 0 )
933  {
934  std::cout << "ERROR: Matrix already filled: cannot add dyadic product!" << std::endl;
935  }
936  return;
937  }
938 
939  // Build a repeated list of globalElements
940  std::vector<Int> myGlobalElements ( uniqueVector2.size() );
941  for ( UInt i = 0 ; i < myGlobalElements.size() ; ++i )
942  {
943  myGlobalElements[i] = i;
944  }
945 
946  // Build a repeated map
947  MapEpetra repeatedMap ( -1, static_cast< Int > ( myGlobalElements.size() ), &myGlobalElements[0], uniqueVector2.map().commPtr() );
948 
949  // Create a fully repeated copy of uniqueVector2
950  VectorEpetra repeatedVector2 ( repeatedMap, Repeated );
951  repeatedVector2 = uniqueVector2;
952 
953  // Fill the matrix with the result of the dyadic Product
954  for ( Int row (0); row < M_epetraCrs->NumMyRows(); ++row )
955  for ( Int column (0); column < M_epetraCrs->NumGlobalCols(); ++column )
956  {
957  addToCoefficient ( M_epetraCrs->GRID ( row ), column, uniqueVector1[M_epetraCrs->GRID ( row )] * repeatedVector2[column] );
958  }
959 }
960 
961 template <typename DataType>
962 void MatrixEpetra<DataType>::add ( const DataType scalar, const MatrixEpetra& matrix )
963 {
964  EpetraExt::MatrixMatrix::Add ( *matrix.matrixPtr(), false, scalar, *this->matrixPtr(), 1. );
965 }
966 
967 template <typename DataType>
969 {
970  ASSERT_PRE (M_epetraCrs->Filled(), "The transpose can be formed only if the matrix is already filled!");
971  std::shared_ptr<Epetra_FECrsMatrix> transposedFE;
972  transposedFE.reset (new Epetra_FECrsMatrix (Copy, M_epetraCrs->OperatorDomainMap(), M_epetraCrs->OperatorRangeMap(), 0, false) );
973  EpetraExt::RowMatrix_Transpose transposer;
974  *dynamic_cast<Epetra_CrsMatrix*> (& (*transposedFE) ) = dynamic_cast<Epetra_CrsMatrix&> (transposer (*M_epetraCrs) );
975  transposedFE->FillComplete();
976  std::shared_ptr<MatrixEpetra<DataType> > transposedMatrix (new MatrixEpetra<DataType> (*M_domainMap) );
977  transposedMatrix->globalAssemble (M_rangeMap, M_domainMap);
978  transposedMatrix->matrixPtr() = transposedFE;
979 
980  return transposedMatrix;
981 }
982 
983 template <typename DataType>
984 void MatrixEpetra<DataType>::diagonalize ( std::vector<UInt> rVec, DataType const coefficient, UInt offset )
985 {
986 
987  const Epetra_Comm& Comm ( M_epetraCrs->Comm() );
988  Int numProcs ( Comm.NumProc() );
989  Int MyPID ( Comm.MyPID() );
990  Int i;
991 
992 
993  // Note: Epetra_Comm::broadcast does not support passing of uint, hence
994  // I define an int pointer to make the broadcast but then come back to an
995  // UInt pointer to insert the data
996  Int* r;
997  UInt* Ur;
998 
999 
1000  // loop on all proc
1001  for ( Int p (0); p < numProcs; p++ )
1002  {
1003  Int sizeVec ( rVec.size() );
1004 
1005  Comm.Broadcast ( &sizeVec, 1, p );
1006 
1007  if ( p == MyPID )
1008  {
1009  Ur = &rVec.front();
1010  }
1011  else
1012  {
1013  Ur = new UInt[sizeVec];
1014  }
1015 
1016  r = (Int*) Ur;
1017 
1018  Comm.Broadcast ( r, sizeVec, p );
1019 
1020  for ( i = 0; i < sizeVec; i++ )
1021  {
1022  diagonalize ( Ur[i], coefficient, offset );
1023  }
1024 
1025  if ( p != MyPID )
1026  {
1027  delete[] Ur;
1028  }
1029 
1030  }
1031 
1032 }
1033 
1034 template <typename DataType>
1035 void MatrixEpetra<DataType>::diagonalize ( UInt const row,
1036  DataType const coefficient,
1037  UInt offset )
1038 {
1039 
1040  if ( !M_epetraCrs->Filled() )
1041  {
1042  // if not filled, I do not know how to diagonalize.
1043  ERROR_MSG ( "if not filled, I do not know how to diagonalize\n" );
1044  }
1045 
1046  const Epetra_Map& rowMap ( M_epetraCrs->RowMap() );
1047  const Epetra_Map& colMap ( M_epetraCrs->ColMap() );
1048 
1049 
1050  Int myCol = colMap.LID ( static_cast<EpetraInt_Type> (row + offset) );
1051 
1052  // row: if r is mine, zero out values
1053  Int myRow = rowMap.LID ( static_cast<EpetraInt_Type> (row + offset) );
1054 
1055  if ( myRow >= 0 ) // I have this row
1056  {
1057  Int NumEntries;
1058  Real* Values;
1059  Int* Indices;
1060 
1061  M_epetraCrs->ExtractMyRowView ( myRow, NumEntries, Values, Indices );
1062 
1063  for (Int i (0); i < NumEntries; i++)
1064  {
1065  Values[i] = 0;
1066  }
1067 
1068  DataType coeff ( coefficient );
1069  M_epetraCrs->ReplaceMyValues ( myRow, 1, &coeff, &myCol ); // A(r,r) = coefficient
1070  }
1071 
1072 }
1073 
1074 template <typename DataType>
1075 void MatrixEpetra<DataType>::diagonalize ( std::vector<UInt> rVec,
1076  DataType const coefficient,
1077  vector_type& rhs,
1078  std::vector<DataType> datumVec,
1079  UInt offset )
1080 {
1081 
1082 
1083  const Epetra_Comm& Comm ( M_epetraCrs->Comm() );
1084  Int numProcs ( Comm.NumProc() );
1085  Int MyPID ( Comm.MyPID() );
1086  Int i;
1087 
1088  // Note: Epetra_Comm::broadcast does not support passing of uint, hence
1089  // I define an int pointer to make the broadcast but then come back to an
1090  // UInt pointer to insert the data
1091  Int* r;
1092  UInt* Ur;
1093  DataType* datum;
1094 
1095 #if 1
1096  // 2 arrays to store le local and remote IDs
1097 
1098  Int me = Comm.MyPID();
1099 
1100  std::vector<Int> localIDs;
1101  std::vector<Int> remoteIDs;
1102 
1103  std::vector<Real> localData;
1104  std::vector<Real> remoteData;
1105 
1106  std::map<Int, Real> localBC;
1107  std::map<Int, Real>::iterator im;
1108 
1109  const Epetra_Map& rowMap ( M_epetraCrs->RowMap() );
1110 
1111 
1112  //Comm.Barrier();
1113  // we want to know which IDs are our or not
1114 
1115  for ( Int ii = 0; ii < (Int) rVec.size(); ++ii )
1116  {
1117  Int lID = rowMap.LID ( static_cast<EpetraInt_Type> (rVec[ii]) );
1118  if ( ! ( lID < 0 ) )
1119  {
1120 
1121  localIDs.push_back ( rVec[ii] );
1122  localData.push_back ( datumVec[ii] );
1123  localBC.insert ( std::pair<Int, Real> ( rVec[ii], datumVec[ii] ) );
1124  }
1125  else
1126  {
1127  remoteIDs.push_back ( rVec[ii] );
1128  remoteData.push_back ( datumVec[ii] );
1129  }
1130  }
1131 
1132  // now, we have to fill our localIDs with IDs from other processors
1133  // first, we have to build the map of all the remoteIDs and their processor owner
1134 
1135 
1136  Int numIDs = remoteIDs.size();
1137 
1138  Int* PIDList = new Int[numIDs];
1139  Int* LIDList = new Int[numIDs];
1140 
1141  rowMap.RemoteIDList ( numIDs,
1142  &remoteIDs[0],
1143  PIDList,
1144  LIDList );
1145 
1146  std::vector< std::vector<Int> > procToID ( Comm.NumProc() );
1147  std::vector< std::vector<Real> > procToData ( Comm.NumProc() );
1148 
1149  for ( Int ii = 0; ii < numIDs; ++ii )
1150  {
1151  Int pi = PIDList[ii];
1152  procToID[pi].push_back ( remoteIDs[ii] );
1153  procToData[pi].push_back ( remoteData[ii] );
1154  }
1155 
1156  // then, we send all the nodes where they belong
1157 
1158  const Epetra_MpiComm* comm = dynamic_cast<Epetra_MpiComm const*> ( &Comm );
1159 
1160  assert ( comm != 0 );
1161 
1162  for ( Int ii = 0; ii < (Int) procToID.size(); ++ii )
1163  {
1164  if ( ii != me )
1165  {
1166  Int length;
1167  length = procToID[ii].size();
1168  MPI_Send ( &length, 1, MPI_INT, ii, 666, comm->Comm() );
1169  if ( length > 0 )
1170  {
1171  MPI_Send ( &procToID[ii][0], length, MPI_INT, ii, 667, comm->Comm() );
1172  MPI_Send ( &procToData[ii][0], length, MPI_DOUBLE, ii, 668, comm->Comm() );
1173  }
1174  }
1175 
1176  }
1177 
1178  for ( Int ii = 0; ii < (Int) procToID.size(); ++ii )
1179  {
1180  if ( ii != me )
1181  {
1182  Int length;
1183  MPI_Status status;
1184  MPI_Recv ( &length, 1, MPI_INT, ii, 666, comm->Comm(), &status );
1185 
1186 
1187  if ( length > 0 )
1188  {
1189  Int* bufferID = new Int[length];
1190  Int* ptrID (0); // = new Int[length];
1191 
1192  MPI_Recv ( bufferID, length, MPI_INT, ii, 667, comm->Comm(), &status );
1193 
1194  ptrID = bufferID;
1195 
1196  Real* bufferData = new Real[length];
1197  Real* ptrData (0);
1198 
1199  MPI_Recv ( bufferData, length, MPI_DOUBLE, ii, 668, comm->Comm(), &status );
1200  ptrData = bufferData;
1201 
1202  for ( Int ii = 0; ii < length; ++ii, ++ptrID, ++ptrData )
1203  {
1204  localBC.insert ( std::pair<Int, Real>
1205  ( *ptrID, *ptrData ) );
1206  }
1207 
1208  delete[] bufferID;
1209  delete[] bufferData;
1210 
1211  }
1212 
1213  }
1214  }
1215 
1216  delete[] PIDList;
1217  delete[] LIDList;
1218 
1219  for ( im = localBC.begin(); im != localBC.end(); ++im )
1220  {
1221  diagonalize ( im->first, coefficient, rhs, im->second, offset );
1222  }
1223 
1224  return;
1225 #endif
1226 
1227 
1228  // loop on all proc
1229  for ( Int p (0); p < numProcs; p++ )
1230  {
1231  Int sizeVec (rVec.size() );
1232  if ( sizeVec != Int (datumVec.size() ) )
1233  {
1234  // vectors must be of the same size
1235  ERROR_MSG ( "diagonalize: vectors must be of the same size\n" );
1236  }
1237 
1238  Comm.Broadcast ( &sizeVec, 1, p );
1239 
1240  if ( p == MyPID )
1241  {
1242  Ur = &rVec.front();
1243  datum = &datumVec.front();
1244  }
1245  else
1246  {
1247  Ur = new UInt [sizeVec];
1248  datum = new DataType[sizeVec];
1249  }
1250 
1251  r = (Int*) Ur;
1252 
1253  Comm.Broadcast ( r, sizeVec, p );
1254  Comm.Broadcast ( datum, sizeVec, p );
1255 
1256  for ( i = 0; i < sizeVec; i++ )
1257  {
1258  diagonalize ( Ur[i], coefficient, rhs, datum[i], offset );
1259  }
1260 
1261  if ( p != MyPID )
1262  {
1263  delete[] Ur;
1264  delete[] datum;
1265  }
1266 
1267  }
1268 
1269 }
1270 
1271 template <typename DataType>
1272 void MatrixEpetra<DataType>::diagonalize ( UInt const row,
1273  DataType const coefficient,
1274  vector_type& rhs,
1275  DataType datum,
1276  UInt offset )
1277 {
1278 
1279  if ( !M_epetraCrs->Filled() )
1280  {
1281  // if not filled, I do not know how to diagonalize.
1282  ERROR_MSG ( "if not filled, I do not know how to diagonalize\n" );
1283  }
1284 
1285  const Epetra_Map& rowMap ( M_epetraCrs->RowMap() );
1286  const Epetra_Map& colMap ( M_epetraCrs->ColMap() );
1287 
1288 
1289  Int myCol = colMap.LID ( static_cast<EpetraInt_Type> (row + offset) );
1290 
1291 #ifdef EPETRAMATRIX_SYMMETRIC_DIAGONALIZE
1292  if ( myCol >= 0 ) // I have this column
1293  {
1294  Real zero (0);
1295  for ( Int i (0); i < rowMap.NumMyElements(); i++ )
1296  // Note that if a value is not already present for the specified location in the matrix,
1297  // the input value will be ignored and a positive warning code will be returned.
1298  {
1299  M_epetraCrs->ReplaceMyValues (i, 1, &zero, &myCol);
1300  }
1301  }
1302 #endif
1303 
1304  // row: if r is mine, zero out values
1305  Int myRow = rowMap.LID ( static_cast<EpetraInt_Type> (row + offset) );
1306 
1307  if ( myRow >= 0 ) // I have this row
1308  {
1309  Int NumEntries;
1310  Real* Values;
1311  Int* Indices;
1312 
1313  M_epetraCrs->ExtractMyRowView ( myRow, NumEntries, Values, Indices );
1314 
1315  for ( Int i (0); i < NumEntries; i++ )
1316  {
1317  Values[i] = 0;
1318  }
1319 
1320  DataType coeff ( coefficient );
1321 
1322  M_epetraCrs->ReplaceMyValues ( myRow, 1, &coeff, &myCol ); // A(r,r) = coeff
1323  rhs[row + offset] = coefficient * datum; // correct right hand side for row r
1324 
1325  }
1326 
1327 }
1328 
1329 template <typename DataType>
1330 void MatrixEpetra<DataType>::matrixMarket ( std::string const& fileName, const bool headers )
1331 {
1332  // Purpose: Matlab dumping and spy
1333  std::string name = fileName;
1334  std::string desc = "Created by LifeV";
1335 
1336  name = fileName + ".mtx";
1337 
1338  EpetraExt::RowMatrixToMatrixMarketFile ( name.c_str(),
1339  *M_epetraCrs,
1340  name.c_str(),
1341  desc.c_str(),
1342  headers
1343  );
1344 }
1345 
1346 template <typename DataType>
1347 void MatrixEpetra<DataType>::spy ( std::string const& fileName )
1348 {
1349  // Purpose: Matlab dumping and spy
1350  std::string name = fileName, uti = " , ";
1351 
1352  Int me = M_epetraCrs->Comm().MyPID();
1353  std::ostringstream myStream;
1354  myStream << me;
1355  name = fileName + ".m";
1356 
1357  EpetraExt::RowMatrixToMatlabFile ( name.c_str(), *M_epetraCrs );
1358 
1359 }
1360 
1361 #ifdef HAVE_HDF5
1362 template <typename DataType>
1364 {
1366 
1367  if ( truncate )
1368  {
1369  // Create and open the file / Truncate and open the file
1370  HDF5.Create ( ( fileName + ".h5" ).data() );
1371  }
1372  else
1373  {
1374  // Open an existing file without truncating it
1375  HDF5.Open ( ( fileName + ".h5" ).data() );
1376  }
1377 
1378  // Check if the file is created
1379  if ( !HDF5.IsOpen () )
1380  {
1381  std::cerr << "Unable to create " + fileName + ".h5";
1382  abort();
1383  }
1384 
1385  // Save the matrix into the file
1387 
1388  // Close the file
1389  HDF5.Close();
1390 
1391 } // exportToHDF5
1392 
1393 template <typename DataType>
1395 {
1397 
1398  // Open an existing file
1399  HDF5.Open ( ( fileName + ".h5" ).data() );
1400 
1401  // Check if the file is created
1402  if ( !HDF5.IsOpen () )
1403  {
1404  std::cerr << "Unable to open " + fileName + ".h5";
1405  abort();
1406  }
1407 
1408  // Read the matrix from the file
1411 
1412  // Copy the loaded matrix to the member object
1413  M_epetraCrs.reset ( new matrix_type ( *dynamic_cast< Epetra_FECrsMatrix* > ( importedMatrix ) ) );
1414 
1415  // Close the file
1416  HDF5.Close();
1417 
1418 } // importFromHDF5
1419 #endif
1420 
1421 template <typename DataType>
1422 void MatrixEpetra<DataType>::showMe ( std::ostream& output ) const
1423 {
1424  output << "showMe must be implemented for the MatrixEpetra class" << std::endl;
1425 }
1426 
1427 template <typename DataType>
1429 {
1430  if ( !M_epetraCrs->Filled() )
1431  {
1433  }
1434  M_domainMap = M_map;
1435  M_rangeMap = M_map;
1436  return M_epetraCrs->GlobalAssemble();
1437 }
1438 
1439 template <typename DataType>
1441 {
1442  if ( !M_epetraCrs->Filled() )
1443  {
1445  }
1446  M_domainMap = M_map;
1447  M_rangeMap = M_map;
1448  return M_epetraCrs->FillComplete();
1449 }
1450 
1451 template <typename DataType>
1452 Int MatrixEpetra<DataType>::globalAssemble ( const std::shared_ptr<const MapEpetra>& domainMap,
1453  const std::shared_ptr<const MapEpetra>& rangeMap )
1454 {
1455 
1456  if ( !M_epetraCrs->Filled() && domainMap->mapsAreSimilar ( *rangeMap) )
1457  {
1459  }
1460 
1461 
1462  M_domainMap = domainMap;
1463  M_rangeMap = rangeMap;
1464  return M_epetraCrs->GlobalAssemble ( *domainMap->map (Unique), *rangeMap->map (Unique) );
1465 }
1466 
1467 template <typename DataType>
1468 void MatrixEpetra<DataType>::insertValueDiagonal ( const DataType entry, const MapEpetra& Map, const UInt offset )
1469 {
1470  for ( Int i = 0 ; i < Map.map (Unique)->NumMyElements(); ++i )
1471  {
1472  addToCoefficient ( offset + Map.map (Unique)->GID (i) , offset + Map.map (Unique)->GID (i), entry );
1473  }
1474 }
1475 
1476 template <typename DataType>
1477 void MatrixEpetra<DataType>::insertValueDiagonal ( const DataType& value, Int from, Int to )
1478 {
1479  if ( M_epetraCrs->Filled() )
1480  {
1481  if ( M_epetraCrs->Comm().MyPID() == 0 )
1482  {
1483  std::cout << "Matrix is already filled, it is impossible to insert the diagonal now" << std::endl;
1484  }
1485  return;
1486  }
1487 
1488  if ( to == from )
1489  {
1490  return;
1491  }
1492 
1493  if ( to < from ) // do all entries
1494  {
1495  from = M_epetraCrs->RowMap().MinMyGID ();
1496  to = M_epetraCrs->RowMap().MaxMyGID () + 1;
1497  }
1498 
1499  Int* p = M_epetraCrs->RowMap().MyGlobalElements();
1500  Int ierr;
1501 
1502  for ( Int i (0); i < M_epetraCrs->RowMap().NumMyElements(); ++i, ++p )
1503  {
1504  if ( *p < from || *p >= to )
1505  {
1506  continue;
1507  }
1508 
1509  ierr = M_epetraCrs->InsertGlobalValues ( 1, p, 1, p, &value );
1510 
1511  if ( ierr < 0 )
1512  {
1513  std::cerr << " error in matrix insertion " << ierr << std::endl;
1514  }
1515  }
1516 }
1517 
1518 template <typename DataType>
1519 void MatrixEpetra<DataType>::insertOneDiagonal ( Int from, Int to )
1520 {
1521  insertValueDiagonal ( 1.0, from, to );
1522 }
1523 
1524 template <typename DataType>
1525 void MatrixEpetra<DataType>::insertZeroDiagonal ( Int from, Int to )
1526 {
1527  insertValueDiagonal ( 0.0, from, to );
1528 }
1529 
1530 template <typename DataType>
1531 Real MatrixEpetra<DataType>::norm1() const
1532 {
1533  return M_epetraCrs->NormOne();
1534 }
1535 
1536 template <typename DataType>
1537 Real MatrixEpetra<DataType>::normInf() const
1538 {
1539  return M_epetraCrs->NormInf();
1540 }
1541 
1542 template <typename DataType>
1543 Real MatrixEpetra<DataType>::normFrobenius() const
1544 {
1545  return M_epetraCrs->NormFrobenius();
1546 }
1547 
1548 // ===================================================
1549 // Set Methods
1550 // ===================================================
1551 template <typename DataType>
1552 void MatrixEpetra<DataType>::
1553 setCoefficients ( Int const numRows, Int const numColumns,
1554  std::vector<Int> const& rowIndices, std::vector<Int> const& columnIndices,
1555  DataType* const* const localValues,
1556  Int format )
1557 {
1558  Int ierr;
1559  ierr = M_epetraCrs->ReplaceGlobalValues ( numRows, &rowIndices[0], numColumns, &columnIndices[0], localValues, format );
1560 
1561  if ( ierr < 0 ) std::cout << " error in matrix insertion [setCoefficients] " << ierr
1562  << " when inserting in (" << rowIndices[0] << ", " << columnIndices[0] << ")" << std::endl;
1563 }
1564 
1565 
1566 
1567 template <typename DataType>
1568 void MatrixEpetra<DataType>::
1569 setCoefficient ( UInt row, UInt column, DataType localValue )
1570 {
1571  Int irow ( row );
1572  Int icol ( column );
1573 
1574  Int ierr = M_epetraCrs->ReplaceGlobalValues ( 1, &irow, 1, &icol, &localValue );
1575  if (ierr != 0)
1576  {
1577  std::cerr << " error in matrix replacement " << ierr << std::endl;
1578  }
1579 
1580 }
1581 
1582 template <typename DataType>
1583 void MatrixEpetra<DataType>::
1584 addToCoefficient ( UInt const row, UInt const column, DataType const localValue )
1585 {
1586 
1587  Int irow = static_cast<Int> (row);
1588  Int icol = static_cast<Int> (column);
1589 
1590  Int ierr = ( M_epetraCrs->Filled() ) ?
1591  M_epetraCrs->SumIntoGlobalValues ( 1, &irow, 1, &icol, &localValue )
1592  :
1593  M_epetraCrs->InsertGlobalValues ( 1, &irow, 1, &icol, &localValue );
1594 
1595  std::stringstream errorMessage;
1596  errorMessage << " error in matrix insertion [addToCoefficient] " << ierr
1597  << " when inserting " << localValue << " in (" << irow << ", " << icol << ")" << std::endl;
1598  ASSERT ( ierr >= 0, errorMessage.str() );
1599 
1600 }
1601 
1602 template <typename DataType>
1603 void MatrixEpetra<DataType>::
1604 addToCoefficients ( Int const numRows, Int const numColumns,
1605  std::vector<Int> const& rowIndices, std::vector<Int> const& columnIndices,
1606  DataType* const* const localValues,
1607  Int format )
1608 {
1609  Int ierr = ( M_epetraCrs->Filled() ) ?
1610  M_epetraCrs->SumIntoGlobalValues ( numRows, &rowIndices[0], numColumns,
1611  &columnIndices[0], localValues, format )
1612  :
1613  M_epetraCrs->InsertGlobalValues ( numRows, &rowIndices[0], numColumns,
1614  &columnIndices[0], localValues, format );
1615 
1616  std::stringstream errorMessage;
1617  errorMessage << " error in matrix insertion [addToCoefficients] " << ierr
1618  << " when inserting in (" << rowIndices[0] << ", " << columnIndices[0] << ")" << std::endl;
1619  ASSERT ( ierr >= 0, errorMessage.str() );
1620 
1621 }
1622 
1623 template <typename DataType>
1624 void MatrixEpetra<DataType>::
1625 sumIntoCoefficients ( Int const numRows, Int const numColumns,
1626  std::vector<Int> const& rowIndices, std::vector<Int> const& columnIndices,
1627  DataType* const* const localValues,
1628  Int format )
1629 {
1630  Int ierr;
1631 #ifdef LIFEV_MT_CRITICAL_UPDATES
1632  #pragma omp critical
1633 #endif
1634  {
1635  ierr = M_epetraCrs->SumIntoGlobalValues ( numRows, &rowIndices[0], numColumns,
1636  &columnIndices[0], localValues, format );
1637  }
1638 
1639  std::stringstream errorMessage;
1640  errorMessage << " error in matrix insertion [addToCoefficients] " << ierr
1641  << " when inserting in (" << rowIndices[0] << ", " << columnIndices[0] << ")" << std::endl;
1642  ASSERT ( ierr >= 0, errorMessage.str() );
1643 
1644 }
1645 
1646 // ===================================================
1647 // Get Methods
1648 // ===================================================
1649 template <typename DataType>
1650 Int MatrixEpetra<DataType>::meanNumEntries() const
1651 {
1652  const Int minEntries = M_epetraCrs->MaxNumEntries() / 2;
1653  if ( !M_epetraCrs->NumMyRows() )
1654  {
1655  return minEntries;
1656  }
1657 
1658  Int meanNumEntries = M_epetraCrs->NumMyNonzeros() / M_epetraCrs->NumMyRows();
1659  if ( meanNumEntries < minEntries || meanNumEntries > 2 * minEntries )
1660  {
1661  return minEntries;
1662  }
1663  return meanNumEntries;
1664 }
1665 
1666 template <typename DataType>
1668 {
1669  return M_epetraCrs->Comm().MyPID();
1670 }
1671 
1672 template <typename DataType>
1673 const MapEpetra& MatrixEpetra<DataType>::map() const
1674 {
1675  ASSERT ( M_map.get() != 0, "MatrixEpetra::getMap: Error: M_map pointer is null" );
1676  return *M_map;
1677 }
1678 
1679 template <typename DataType>
1680 const MapEpetra& MatrixEpetra<DataType>::domainMap() const
1681 {
1682  ASSERT ( M_domainMap.get() != 0, "MatrixEpetra::getdomainMap: Error: M_domainMap pointer is null" );
1683  return *M_domainMap;
1684 }
1685 
1686 template <typename DataType>
1687 const boost::shared_ptr< const MapEpetra >& MatrixEpetra<DataType>::domainMapPtr() const
1688 {
1689  return M_domainMap;
1690 }
1691 
1692 template <typename DataType>
1693 const MapEpetra& MatrixEpetra<DataType>::rangeMap() const
1694 {
1695  ASSERT ( M_rangeMap.get() != 0, "MatrixEpetra::getRangeMap: Error: M_rangeMap pointer is null" );
1696  return *M_rangeMap;
1697 }
1698 
1699 template <typename DataType>
1700 const boost::shared_ptr< const MapEpetra >& MatrixEpetra<DataType>::rangeMapPtr() const
1701 {
1702  return M_rangeMap;
1703 }
1704 
1705 template <typename DType>
1706 MatrixEpetra<DType>* RAP (const MatrixEpetra<DType>& R, const MatrixEpetra<DType>& A, const MatrixEpetra<DType>& P)
1707 {
1708  //Optimized implementation requires Trilinos 10.8
1709  /*
1710  typename MatrixEpetra<DType>::matrix_type * result = NULL;
1711  ML_Epetra::ML_Epetra_RAP (*A.matrixPtr(), *P.matrixPtr(), *R.matrixPtr(), result, true);
1712 
1713  MatrixEpetra<DType> * matrix(new MatrixEpetra<DType>(P.map()));
1714  matrix->M_epetraCrs.reset(result);
1715  matrix->M_domainMap = P.M_domainMap;
1716  matrix->M_rangeMap = R.M_rangeMap;
1717 
1718  return result;
1719 
1720  */
1721  // Slower implementation (no prerequisites on Trilinos)
1722  MatrixEpetra<DType>* result (new MatrixEpetra<DType> ( *R.M_rangeMap ) );
1723  MatrixEpetra<DType> tmp (A.map() );
1724  EpetraExt::MatrixMatrix::Multiply (*A.matrixPtr(), false, *P.matrixPtr(), false, *tmp.matrixPtr(), true);
1725  EpetraExt::MatrixMatrix::Multiply (*R.matrixPtr(), false, *tmp.matrixPtr(), false, * (result->matrixPtr() ), true);
1726 
1727  result->M_domainMap = P.M_domainMap;
1728  result->M_rangeMap = R.M_rangeMap;
1729 
1730  return result;
1731 }
1732 
1733 template <typename DType>
1734 MatrixEpetra<DType>* PtAP (const MatrixEpetra<DType>& A, const MatrixEpetra<DType>& P)
1735 {
1736  typename MatrixEpetra<DType>::matrix_type* result = NULL;
1737  ML_Epetra::ML_Epetra_PtAP (*A.matrixPtr(), *P.matrixPtr(), result, true);
1738  MatrixEpetra<DType>* matrix (new MatrixEpetra<DType> (P.M_domainMap) );
1739  matrix->M_epetraCrs.reset (result);
1740  matrix->M_domainMap = P.M_domainMap;
1741  matrix->M_rangeMap = P.M_domainMap;
1742 
1743  return matrix;
1744 }
1745 
1746 template <typename DataType>
1747 void MatrixEpetra<DataType>::restrict ( const std::shared_ptr<MapEpetra>& map,
1748  const std::shared_ptr<VectorEpetra>& numeration,
1749  const UInt& offset,
1750  std::shared_ptr<MatrixEpetra<DataType> > & matrix_out )
1751 {
1752  // 1) create matrix P and R
1753  MatrixEpetra<DataType> P (*M_rangeMap, 50 );
1754  MatrixEpetra<DataType> R (*map, 50 );
1755  double value = 1.0;
1756  int offsetMap = numeration->size();
1757  for(int i = 0; i < numeration->epetraVector().MyLength(); ++i)
1758  {
1759  P.addToCoefficient(numeration->blockMap().GID(i) , (*numeration)[numeration->blockMap().GID(i)] , value);
1760  P.addToCoefficient(numeration->blockMap().GID(i) + offset, (*numeration)[numeration->blockMap().GID(i)] + offsetMap , value);
1761  P.addToCoefficient(numeration->blockMap().GID(i) + 2*offset, (*numeration)[numeration->blockMap().GID(i)] + 2*offsetMap, value);
1762 
1763  R.addToCoefficient((*numeration)[numeration->blockMap().GID(i)] , numeration->blockMap().GID(i) , value);
1764  R.addToCoefficient((*numeration)[numeration->blockMap().GID(i)] + offsetMap , numeration->blockMap().GID(i) + offset , value);
1765  R.addToCoefficient((*numeration)[numeration->blockMap().GID(i)] + 2*offsetMap, numeration->blockMap().GID(i) + 2*offset, value);
1766  }
1767 
1768  P.globalAssemble( map, M_rangeMap );
1769  R.globalAssemble( M_rangeMap, map );
1770 
1771  // 2) Perform tmp = matrix x P
1772  MatrixEpetra<DataType> tmp (*M_rangeMap, 50 );
1773  this->multiply(false, P, false, tmp, false);
1774  tmp.globalAssemble( map, M_rangeMap );
1775 
1776  // 3) Perform restricted_matrix = R x tmp
1777  matrix_out.reset(new MatrixEpetra<DataType> (*map, 50 ));
1778  R.multiply(false, tmp, false, *matrix_out, false);
1779  matrix_out->globalAssemble();
1780 }
1781 
1782 } // end namespace LifeV
1783 //@@
1784 //#undef OFFSET
1785 
1786 #endif
VectorEpetra - The Epetra Vector format Wrapper.
MatrixEpetra & operator*=(const DataType scalar)
Multiplication operator.
void insertZeroDiagonal(Int from=-1, Int to=-2)
insert zeros into the diagonal to ensure the matrix&#39; graph has a entry there
Int fillComplete()
Fill complete of a square matrix with default domain and range map.
void setCoefficient(UInt row, UInt column, DataType localValue)
Set a coefficient of the matrix.
vector_type operator*(const vector_type &vector) const
Matrix-Vector multiplication.
MatrixEpetra & operator=(const MatrixEpetra &matrix)
Assignment operator.
void add(const DataType scalar, const MatrixEpetra &matrix)
Add a multiple of a given matrix: *this += scalar*matrix.
MatrixEpetra(const MapEpetra &map, Int numEntries=50, bool ignoreNonLocalValues=false)
Constructor for square and rectangular matrices.
void showMe(std::ostream &output=std::cout) const
Print the contents of the matrix.
void diagonalize(UInt const row, DataType const coefficient, vector_type &rhs, DataType datum, UInt offset=0)
apply constraint on row "row"
void diagonalize(UInt const entryIndex, DataType const coefficient, UInt offset=0)
Set entry (entryIndex,entryIndex) to coefficient and the rest of the row to zero. ...
void importFromHDF5(std::string const &fileName, std::string const &matrixName="matrix")
Read a matrix from a HDF5 (.h5) file.
const boost::shared_ptr< const MapEpetra > & domainMapPtr() const
void sumIntoCoefficients(Int const numRows, Int const numColumns, std::vector< Int > const &rowIndices, std::vector< Int > const &columnIndices, DataType *const *const localValues, Int format=Epetra_FECrsMatrix::COLUMN_MAJOR)
Add a set of values to the corresponding set of coefficient in the closed matrix. ...
Real normInf() const
Compute the norm inf of the global matrix.
Real normFrobenius() const
Compute the frobenius norm of the global matrix.
Epetra_FECrsMatrix matrix_type
MatrixEpetra(const MapEpetra &map, const Epetra_FECrsGraph &graph, bool ignoreNonLocalValues=false)
Constructor from a FE graph.
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
matrix_ptrtype & matrixPtr()
Return the shared_pointer of the Epetra_FECrsMatrix.
void diagonalize(std::vector< UInt > rVec, DataType const coefficient, UInt offset=0)
Set entries (rVec(i),rVec(i)) to coefficient and the rest of the row entries to zero.
void zero()
set zero in all the matrix entries
matrix_ptrtype M_epetraCrs
VectorEpetra(const MapEpetra &map, const MapEpetraType &mapType=Unique, const combineMode_Type combineMode=Add)
Constructor - Using Maps.
const MapEpetra & domainMap() const
Return the domain MapEpetra of the MatrixEpetra.
void swapCrsMatrix(matrix_ptrtype &matrixPtr)
Swap the given shared pointer with the one of the matrix.
void updateInverseJacobian(const UInt &iQuadPt)
MatrixEpetra & operator+=(const MatrixEpetra &matrix)
Addition operator.
void insertOneDiagonal(Int from=-1, Int to=-2)
insert ones into the diagonal to ensure the matrix&#39; graph has a entry there
Int processorId()
Return the Id of the processor.
void setUseTranspose(const bool &transpose=false)
If set true, transpose of this operator will be applied.
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
Int globalAssemble(const std::shared_ptr< const MapEpetra > &domainMap, const std::shared_ptr< const MapEpetra > &rangeMap)
Global assemble for rectangular matrices.
const MapEpetra & map() const
Return the row MapEpetra of the MatrixEpetra used in the assembling.
const boost::shared_ptr< const MapEpetra > & rangeMapPtr() const
VectorEpetra vector_type
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
const MapEpetra & rangeMap() const
Return the range MapEpetra of the MatrixEpetra.
Real norm1() const
Compute the norm 1 of the global matrix.
#define ASSERT_PRE(X, A)
Definition: LifeAssert.hpp:96
std::shared_ptr< matrix_type > matrix_ptrtype
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
void addToCoefficient(UInt const row, UInt const column, DataType const localValue)
Add a value at a coefficient of the matrix.
friend MatrixEpetra< DType > * RAP(const MatrixEpetra< DType > &R, const MatrixEpetra< DType > &A, const MatrixEpetra< DType > &P)
Friend Functions.
void diagonalize(std::vector< UInt > rVec, DataType const coefficient, vector_type &rhs, std::vector< DataType > datumVector, UInt offset=0)
apply constraint on all rows rVec
std::shared_ptr< MapEpetra > M_map
Int multiply(bool transposeCurrent, const MatrixEpetra< DataType > &matrix, bool transposeMatrix, MatrixEpetra< DataType > &result, bool callFillCompleteOnResult=true) const
Multiply the MatrixEpetra by the first given matrix and put the result in the second given matrix...
std::shared_ptr< MatrixEpetra< DataType > > transpose()
Returns a pointer to a new matrix which contains the transpose of the current matrix.
void insertValueDiagonal(const DataType entry, const MapEpetra &Map, const UInt offset=0)
insert the given value into the diagonal
void addDyadicProduct(const vector_type &uniqueVector1, const vector_type &uniqueVector2)
Add to the matrix a dyadic product: , where is the matrix.
MatrixEpetra< DType > * PtAP(const MatrixEpetra< DType > &A, const MatrixEpetra< DType > &P)
void addToCoefficients(Int const numRows, Int const numColumns, std::vector< Int > const &rowIndices, std::vector< Int > const &columnIndices, DataType *const *const localValues, Int format=Epetra_FECrsMatrix::COLUMN_MAJOR)
Add a set of values to the corresponding set of coefficient in the matrix.
std::shared_ptr< const MapEpetra > M_domainMap
void spy(std::string const &fileName)
Save the matrix into a Matlab (.m) file.
void swapCrsMatrix(MatrixEpetra< DataType > &matrix)
Swap the matrix with the one given as argument.
MatrixEpetra(const MapEpetra &map, Int *numEntriesPerRow, bool ignoreNonLocalValues=false)
Constructor for square and rectangular matrices, knowing the number of entries per row...
void openCrsMatrix()
If the matrix has been filled, this function will reopen the Matrix.
std::shared_ptr< vector_type > vectorPtr_Type
Int meanNumEntries() const
Return the mean number of entries in the matrix rows.
double Real
Generic real data.
Definition: LifeV.hpp:175
void restrict(const std::shared_ptr< MapEpetra > &map, const std::shared_ptr< VectorEpetra > &numeration, const UInt &offset, std::shared_ptr< MatrixEpetra< DataType > > &matrix_out)
Restrict the matrix to the dofs contained in the input map.
std::shared_ptr< MapEpetra > mapPtr()
Return the shared_pointer of the Epetra_Map.
Int multiply(bool transposeCurrent, const vector_type &vector1, vector_type &vector2) const
Multiply the first VectorEpetra given as a parameter by the MatrixEpetra and put the result into the ...
MatrixEpetra(const MapEpetra &map, matrix_ptrtype crsMatrixPtr)
Constructs an MatrixEpetra view of an Epetra_FECrsMatrix.
void removeZeros()
This function removes all the zeros in the matrix and add zero on the diagonal.
MatrixEpetra< DType > * RAP(const MatrixEpetra< DType > &R, const MatrixEpetra< DType > &A, const MatrixEpetra< DType > &P)
#define LIFEV_DEPRECATED(func)
Definition: LifeV.hpp:117
const matrix_ptrtype & matrixPtr() const
Return the const shared_pointer of the Epetra_FECrsMatrix.
void matrixMarket(std::string const &fileName, const bool headers=true)
Save the matrix into a MatrixMarket (.mtx) file.
MatrixEpetra(const MatrixEpetra &matrix)
Copy Constructor.
VectorEpetra & operator=(const VectorEpetra &vector)
Affectation operator.
void insertValueDiagonal(const DataType &value, Int from=-1, Int to=-2)
insert the given value into the diagonal
MatrixEpetra(const MatrixEpetra &matrix, const UInt reduceToProc)
Copies the matrix to a matrix which resides only on the processor.
std::shared_ptr< const MapEpetra > M_rangeMap
Shared pointer on the range MapEpetra.
friend MatrixEpetra< DType > * PtAP(const MatrixEpetra< DType > &A, const MatrixEpetra< DType > &P)
PtAP matrix matrix multiplication result = Pt * A * P User is responsible to wrap the row pointer ret...
MatrixEpetra & operator-=(const MatrixEpetra &matrix)
Subtraction operator.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
data_type & operator[](const UInt row)
Access operators.
void setCoefficients(Int const numRows, Int const numColumns, std::vector< Int > const &rowIndices, std::vector< Int > const &columnIndices, DataType *const *const localValues, Int format=Epetra_FECrsMatrix::COLUMN_MAJOR)
Set a set of values to the corresponding set of coefficient in the matrix.
virtual ~MatrixEpetra()
Destructor.
bool filled() const
Return the fill-complete status of the Epetra_FECrsMatrix.
Int globalAssemble()
Global assemble of a square matrix with default domain and range map.
MatrixEpetra operator*(const DataType scalar) const
Multiplication operator.