Ifpack Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Ifpack_SparseContainer.h
Go to the documentation of this file.
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack: Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2002) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 */
42 
43 #ifndef IFPACK_SPARSECONTAINER_H
44 #define IFPACK_SPARSECONTAINER_H
45 
46 #if defined(Ifpack_SHOW_DEPRECATED_WARNINGS)
47 #ifdef __GNUC__
48 #warning "The Ifpack package is deprecated"
49 #endif
50 #endif
51 
52 #include "Ifpack_Container.h"
53 #include "Epetra_IntSerialDenseVector.h"
54 #include "Epetra_MultiVector.h"
55 #include "Epetra_Vector.h"
56 #include "Epetra_Map.h"
57 #include "Epetra_RowMatrix.h"
58 #include "Epetra_CrsMatrix.h"
59 #include "Epetra_LinearProblem.h"
60 #include "Epetra_IntSerialDenseVector.h"
61 #include "Teuchos_ParameterList.hpp"
62 #include "Teuchos_RefCountPtr.hpp"
63 #ifdef HAVE_MPI
64 #include "Epetra_MpiComm.h"
65 #else
66 #include "Epetra_SerialComm.h"
67 #endif
68 
98 template<typename T>
100 
101 public:
102 
104  Ifpack_SparseContainer(const int NumRows, const int NumVectors = 1);
106 
109 
111  virtual ~Ifpack_SparseContainer();
113 
115 
119 
121  virtual int NumRows() const;
123 
125  virtual int NumVectors() const
126  {
127  return(NumVectors_);
128  }
129 
131  virtual int SetNumVectors(const int NumVectors_in)
132  {
133  if (NumVectors_ != NumVectors_in)
134  {
135  NumVectors_=NumVectors_in;
138  }
139  return(0);
140  }
141 
143  virtual double& LHS(const int i, const int Vector = 0);
144 
146  virtual double& RHS(const int i, const int Vector = 0);
147 
149 
158  virtual int& ID(const int i);
159 
161  virtual int SetMatrixElement(const int row, const int col,
162  const double value);
163 
164 
166  virtual bool IsInitialized() const
167  {
168  return(IsInitialized_);
169  }
170 
172  virtual bool IsComputed() const
173  {
174  return(IsComputed_);
175  }
176 
178  virtual int SetParameters(Teuchos::ParameterList& List);
179 
181  virtual const char* Label() const
182  {
183  return(Label_.c_str());
184  }
185 
188  {
189  return(Map_);
190  }
191 
194  {
195  return(LHS_);
196  }
197 
200  {
201  return(RHS_);
202  }
203 
206  {
207  return(Matrix_);
208  }
209 
212  {
213  return(GID_);
214  }
215 
218  {
219  return(Inverse_);
220  }
222 
224 
231  virtual int Initialize();
233  virtual int Compute(const Epetra_RowMatrix& Matrix_in);
235  virtual int Apply();
236 
238  virtual int ApplyInverse();
239 
241 
243  virtual int Destroy();
246 
248  virtual double InitializeFlops() const
249  {
250  if (Inverse_ == Teuchos::null)
251  return (0.0);
252  else
253  return(Inverse_->InitializeFlops());
254  }
255 
257  virtual double ComputeFlops() const
258  {
259  if (Inverse_ == Teuchos::null)
260  return (0.0);
261  else
262  return(Inverse_->ComputeFlops());
263  }
264 
266  virtual double ApplyFlops() const
267  {
268  return(ApplyFlops_);
269  }
270 
272  virtual double ApplyInverseFlops() const
273  {
274  if (Inverse_ == Teuchos::null)
275  return (0.0);
276  else
277  return(Inverse_->ApplyInverseFlops());
278  }
279 
281  virtual std::ostream& Print(std::ostream& os) const;
282 
283 private:
284 
286  virtual int Extract(const Epetra_RowMatrix& Matrix_in);
287 
289  int NumRows_;
293  Teuchos::RefCountPtr<Epetra_Map> Map_;
295  Teuchos::RefCountPtr<Epetra_CrsMatrix> Matrix_;
297  Teuchos::RefCountPtr<Epetra_MultiVector> LHS_;
299  Teuchos::RefCountPtr<Epetra_MultiVector> RHS_;
307  Teuchos::RefCountPtr<Epetra_Comm> SerialComm_;
309  Teuchos::RefCountPtr<T> Inverse_;
311  std::string Label_;
313  double ApplyFlops_;
314 
315 };
316 
317 //==============================================================================
318 template<typename T>
320 Ifpack_SparseContainer(const int NumRows_in, const int NumVectors_in) :
321  NumRows_(NumRows_in),
322  NumVectors_(NumVectors_in),
323  IsInitialized_(false),
324  IsComputed_(false),
325  ApplyFlops_(0.0)
326 {
327 
328 #ifdef HAVE_MPI
329  SerialComm_ = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_SELF) );
330 #else
332 #endif
333 
334 }
335 
336 //==============================================================================
337 template<typename T>
340  NumRows_(rhs.NumRows()),
341  NumVectors_(rhs.NumVectors()),
342  IsInitialized_(rhs.IsInitialized()),
343  IsComputed_(rhs.IsComputed())
344 {
345 
346 #ifdef HAVE_MPI
347  SerialComm_ = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_SELF) );
348 #else
350 #endif
351 
352  if (!rhs.Map().is_null())
353  Map_ = Teuchos::rcp( new Epetra_Map(*rhs.Map()) );
354 
355  if (!rhs.Matrix().is_null())
356  Matrix_ = Teuchos::rcp( new Epetra_CrsMatrix(*rhs.Matrix()) );
357 
358  if (!rhs.LHS().is_null())
359  LHS_ = Teuchos::rcp( new Epetra_MultiVector(*rhs.LHS()) );
360 
361  if (!rhs.RHS().is_null())
362  RHS_ = Teuchos::rcp( new Epetra_MultiVector(*rhs.RHS()) );
363 
364 }
365 //==============================================================================
366 template<typename T>
368 {
369  Destroy();
370 }
371 
372 //==============================================================================
373 template<typename T>
375 {
376  if (IsInitialized() == false)
377  return(0);
378  else
379  return(NumRows_);
380 }
381 
382 //==============================================================================
383 template<typename T>
385 {
386 
387  if (IsInitialized_ == true)
388  Destroy();
389 
390  IsInitialized_ = false;
391 
392 #if !defined(EPETRA_NO_32BIT_GLOBAL_INDICES) || !defined(EPETRA_NO_64BIT_GLOBAL_INDICES)
393  Map_ = Teuchos::rcp( new Epetra_Map(NumRows_,0,*SerialComm_) );
394 #endif
395 
396  LHS_ = Teuchos::rcp( new Epetra_MultiVector(*Map_,NumVectors_) );
397  RHS_ = Teuchos::rcp( new Epetra_MultiVector(*Map_,NumVectors_) );
398  GID_.Reshape(NumRows_,1);
399 
400 #if defined(HAVE_TEUCHOSCORE_CXX11)
401  Matrix_ = Teuchos::rcp( new Epetra_CrsMatrix(Epetra_DataAccess::Copy,*Map_,0) );
402 #else
403  Matrix_ = Teuchos::rcp( new Epetra_CrsMatrix(::Copy,*Map_,0) );
404 #endif
405 
406  // create the inverse
407  Inverse_ = Teuchos::rcp( new T(Matrix_.get()) );
408 
409  if (Inverse_ == Teuchos::null)
410  IFPACK_CHK_ERR(-5);
411 
412  IFPACK_CHK_ERR(Inverse_->SetParameters(List_));
413 
414  // Call Inverse_->Initialize() in Compute(). This saves
415  // some time, because I can extract the diagonal blocks faster,
416  // and only once.
417 
418  Label_ = "Ifpack_SparseContainer";
419 
420  IsInitialized_ = true;
421  return(0);
422 
423 }
424 
425 //==============================================================================
426 template<typename T>
427 double& Ifpack_SparseContainer<T>::LHS(const int i, const int Vector)
428 {
429  return(((*LHS_)(Vector))->Values()[i]);
430 }
431 
432 //==============================================================================
433 template<typename T>
434 double& Ifpack_SparseContainer<T>::RHS(const int i, const int Vector)
435 {
436  return(((*RHS_)(Vector))->Values()[i]);
437 }
438 
439 //==============================================================================
440 template<typename T>
442 SetMatrixElement(const int row, const int col, const double value)
443 {
444  if (!IsInitialized())
445  IFPACK_CHK_ERR(-3); // problem not shaped yet
446 
447  if ((row < 0) || (row >= NumRows())) {
448  IFPACK_CHK_ERR(-2); // not in range
449  }
450 
451  if ((col < 0) || (col >= NumRows())) {
452  IFPACK_CHK_ERR(-2); // not in range
453  }
454 
455 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
456  if(Matrix_->RowMatrixRowMap().GlobalIndicesInt()) {
457  int ierr = Matrix_->InsertGlobalValues((int)row,1,(double*)&value,(int*)&col);
458  if (ierr < 0) {
459  ierr = Matrix_->SumIntoGlobalValues((int)row,1,(double*)&value,(int*)&col);
460  if (ierr < 0)
461  IFPACK_CHK_ERR(-1);
462  }
463  }
464  else
465 #endif
466 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
467  if(Matrix_->RowMatrixRowMap().GlobalIndicesLongLong()) {
468  long long col_LL = col;
469  int ierr = Matrix_->InsertGlobalValues(row,1,(double*)&value,&col_LL);
470  if (ierr < 0) {
471  ierr = Matrix_->SumIntoGlobalValues(row,1,(double*)&value,&col_LL);
472  if (ierr < 0)
473  IFPACK_CHK_ERR(-1);
474  }
475  }
476  else
477 #endif
478  throw "Ifpack_SparseContainer<T>::SetMatrixElement: GlobalIndices type unknown";
479 
480  return(0);
481 
482 }
483 
484 //==============================================================================
485 template<typename T>
487 {
488 
489  IsComputed_ = false;
490  if (!IsInitialized()) {
491  IFPACK_CHK_ERR(Initialize());
492  }
493 
494  // extract the submatrices
495  IFPACK_CHK_ERR(Extract(Matrix_in));
496 
497  // initialize the inverse operator
498  IFPACK_CHK_ERR(Inverse_->Initialize());
499 
500  // compute the inverse operator
501  IFPACK_CHK_ERR(Inverse_->Compute());
502 
503  Label_ = "Ifpack_SparseContainer";
504 
505  IsComputed_ = true;
506 
507  return(0);
508 }
509 
510 //==============================================================================
511 template<typename T>
513 {
514  if (IsComputed() == false) {
515  IFPACK_CHK_ERR(-3); // not yet computed
516  }
517 
518  IFPACK_CHK_ERR(Matrix_->Apply(*RHS_, *LHS_));
519 
520  ApplyFlops_ += 2 * Matrix_->NumGlobalNonzeros64();
521  return(0);
522 }
523 
524 //==============================================================================
525 template<typename T>
527 {
528  if (!IsComputed())
529  IFPACK_CHK_ERR(-1);
530 
531  IFPACK_CHK_ERR(Inverse_->ApplyInverse(*RHS_, *LHS_));
532 
533  return(0);
534 }
535 
536 
537 //==============================================================================
538 template<typename T>
540 {
541  IsInitialized_ = false;
542  IsComputed_ = false;
543  return(0);
544 }
545 
546 //==============================================================================
547 template<typename T>
549 {
550  return(GID_[i]);
551 }
552 
553 //==============================================================================
554 template<typename T>
557 {
558  List_ = List;
559  return(0);
560 }
561 
562 //==============================================================================
563 // FIXME: optimize performances of this guy...
564 template<typename T>
566 {
567 
568  for (int j = 0 ; j < NumRows_ ; ++j) {
569  // be sure that the user has set all the ID's
570  if (ID(j) == -1)
571  IFPACK_CHK_ERR(-1);
572  // be sure that all are local indices
573  if (ID(j) > Matrix_in.NumMyRows())
574  IFPACK_CHK_ERR(-1);
575  }
576 
577  int Length = Matrix_in.MaxNumEntries();
578  std::vector<double> Values;
579  Values.resize(Length);
580  std::vector<int> Indices;
581  Indices.resize(Length);
582 
583  for (int j = 0 ; j < NumRows_ ; ++j) {
584 
585  int LRID = ID(j);
586 
587  int NumEntries;
588 
589  int ierr =
590  Matrix_in.ExtractMyRowCopy(LRID, Length, NumEntries,
591  &Values[0], &Indices[0]);
592  IFPACK_CHK_ERR(ierr);
593 
594  for (int k = 0 ; k < NumEntries ; ++k) {
595 
596  int LCID = Indices[k];
597 
598  // skip off-processor elements
599  if (LCID >= Matrix_in.NumMyRows())
600  continue;
601 
602  // for local column IDs, look for each ID in the list
603  // of columns hosted by this object
604  // FIXME: use STL
605  int jj = -1;
606  for (int kk = 0 ; kk < NumRows_ ; ++kk)
607  if (ID(kk) == LCID)
608  jj = kk;
609 
610  if (jj != -1)
611  SetMatrixElement(j,jj,Values[k]);
612 
613  }
614  }
615 
616  IFPACK_CHK_ERR(Matrix_->FillComplete());
617 
618  return(0);
619 }
620 
621 //==============================================================================
622 template<typename T>
623 std::ostream& Ifpack_SparseContainer<T>::Print(std::ostream & os) const
624 {
625  using std::endl;
626 
627  os << "================================================================================" << endl;
628  os << "Ifpack_SparseContainer" << endl;
629  os << "Number of rows = " << NumRows() << endl;
630  os << "Number of vectors = " << NumVectors() << endl;
631  os << "IsInitialized() = " << IsInitialized() << endl;
632  os << "IsComputed() = " << IsComputed() << endl;
633  os << "Flops in Initialize() = " << InitializeFlops() << endl;
634  os << "Flops in Compute() = " << ComputeFlops() << endl;
635  os << "Flops in ApplyInverse() = " << ApplyInverseFlops() << endl;
636  os << "================================================================================" << endl;
637  os << endl;
638 
639  return(os);
640 }
641 #endif // IFPACK_SPARSECONTAINER_H
virtual double ComputeFlops() const
Returns the flops in Compute().
virtual double InitializeFlops() const
Returns the flops in Compute().
Teuchos::RCP< const Epetra_MultiVector > LHS() const
Returns a pointer to the internally stored solution multi-vector.
virtual int NumRows() const
Returns the number of rows of the matrix and LHS/RHS.
int NumRows_
Number of rows in the local matrix.
Ifpack_SparseContainer & operator=(const Ifpack_SparseContainer< T > &rhs)
Operator =.
Teuchos::RCP< const Epetra_MultiVector > RHS() const
Returns a pointer to the internally stored rhs multi-vector.
virtual int SetParameters(Teuchos::ParameterList &List)
Sets all necessary parameters.
virtual bool IsInitialized() const
Returns true is the container has been successfully initialized.
Teuchos::RCP< const Epetra_CrsMatrix > Matrix() const
Returns a pointer to the internally stored matrix.
Epetra_IntSerialDenseVector GID_
Contains the subrows/subcols of A that will be inserted in Matrix_.
virtual double & LHS(const int i, const int Vector=0)
Returns the i-th component of the vector Vector of LHS.
virtual int Initialize()
Initializes the container, by completing all the operations based on matrix structure.
Teuchos::RefCountPtr< T > Inverse_
Pointer to an Ifpack_Preconditioner object whose ApplyInverse() defined the action of the inverse of ...
bool IsInitialized_
If true, the container has been successfully initialized.
const int NumVectors
Definition: performance.cpp:71
virtual int SetMatrixElement(const int row, const int col, const double value)
Set the matrix element (row,col) to value.
virtual const char * Label() const
Returns the label of this container.
Teuchos::RefCountPtr< Epetra_Map > Map_
Linear map on which the local matrix is based.
Teuchos::RefCountPtr< Epetra_CrsMatrix > Matrix_
Pointer to the local matrix.
virtual double & RHS(const int i, const int Vector=0)
Returns the i-th component of the vector Vector of RHS.
Teuchos::RefCountPtr< Epetra_Comm > SerialComm_
Serial communicator (containing only MPI_COMM_SELF if MPI is used).
Teuchos::ParameterList List_
bool IsComputed_
If true, the container has been successfully computed.
Teuchos::RCP< const Epetra_Map > Map() const
Returns a pointer to the internally stored map.
virtual int MaxNumEntries() const =0
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
std::string Label_
Label for this object.
virtual int NumVectors() const
Returns the number of vectors in LHS/RHS.
bool is_null(const RCP< T > &p)
Ifpack_SparseContainer: a class for storing and solving linear systems using sparse matrices...
virtual int SetNumVectors(const int NumVectors_in)
Sets the number of vectors for LHS/RHS.
virtual int ApplyInverse()
Apply the inverse of the matrix to RHS, result is stored in LHS.
Ifpack_SparseContainer(const int NumRows, const int NumVectors=1)
Constructor.
virtual int NumMyRows() const =0
virtual double ApplyFlops() const
Returns the flops in Apply().
#define false
virtual std::ostream & Print(std::ostream &os) const
Prints basic information on iostream. This function is used by operator&lt;&lt;.
virtual ~Ifpack_SparseContainer()
Destructor.
Teuchos::RCP< const T > Inverse() const
Returns a pointer to the internally stored inverse operator.
int NumVectors_
Number of vectors in the local linear system.
const Epetra_IntSerialDenseVector & ID() const
Returns a pointer to the internally stored ID&#39;s.
Teuchos::RefCountPtr< Epetra_MultiVector > RHS_
right-hand side for local problems.
virtual int Destroy()
Destroys all data.
Teuchos::RefCountPtr< Epetra_MultiVector > LHS_
Solution vector.
Ifpack_Container: a pure virtual class for creating and solving local linear problems.
virtual int ExtractMyRowCopy(int MyRow, int Length, int &NumEntries, double *Values, int *Indices) const =0
virtual bool IsComputed() const
Returns true is the container has been successfully computed.
#define IFPACK_CHK_ERR(ifpack_err)
virtual int Compute(const Epetra_RowMatrix &Matrix_in)
Finalizes the linear system matrix and prepares for the application of the inverse.
virtual double ApplyInverseFlops() const
Returns the flops in ApplyInverse().
virtual int Extract(const Epetra_RowMatrix &Matrix_in)
Extract the submatrices identified by the ID set int ID().
virtual int Apply()
Apply the matrix to RHS, result is stored in LHS.