EpetraExt_BlockCrsMatrix.cpp

Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 // 
00004 //               EpetraExt: Extended Linear Algebra Services Package 
00005 //                 Copyright (2001) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ************************************************************************
00027 //@HEADER
00028 
00029 #include "EpetraExt_BlockCrsMatrix.h"
00030 #include "EpetraExt_BlockUtility.h"
00031 #include "Epetra_Map.h"
00032 
00033 namespace EpetraExt {
00034 
00035 using std::vector;
00036 
00037 //==============================================================================
00038 BlockCrsMatrix::BlockCrsMatrix(
00039         const Epetra_CrsGraph & BaseGraph,
00040         const vector<int> & RowStencil,
00041         int RowIndex,
00042         const Epetra_Comm & GlobalComm  ) 
00043   : Epetra_CrsMatrix( Copy, *(BlockUtility::GenerateBlockGraph( BaseGraph, vector< vector<int> >(1,RowStencil), vector<int>(1,RowIndex), GlobalComm )) ),
00044     BaseGraph_( BaseGraph ),
00045     RowStencil_( vector< vector<int> >(1,RowStencil) ),
00046     RowIndices_( vector<int>(1,RowIndex) ),
00047     Offset_(BlockUtility::CalculateOffset(BaseGraph.RowMap()))
00048 {
00049 }
00050 
00051 //==============================================================================
00052 BlockCrsMatrix::BlockCrsMatrix(
00053         const Epetra_CrsGraph & BaseGraph,
00054         const vector< vector<int> > & RowStencil,
00055         const vector<int> & RowIndices,
00056         const Epetra_Comm & GlobalComm  ) 
00057   : Epetra_CrsMatrix( Copy, *(BlockUtility::GenerateBlockGraph( BaseGraph, RowStencil, RowIndices, GlobalComm )) ),
00058     BaseGraph_( BaseGraph ),
00059     RowStencil_( RowStencil ),
00060     RowIndices_( RowIndices ),
00061     Offset_(BlockUtility::CalculateOffset(BaseGraph.RowMap()))
00062 {
00063 }
00064 
00065 //==============================================================================
00066 BlockCrsMatrix::BlockCrsMatrix(
00067         const Epetra_RowMatrix & BaseMatrix,
00068         const vector< vector<int> > & RowStencil,
00069         const vector<int> & RowIndices,
00070         const Epetra_Comm & GlobalComm  ) 
00071   : Epetra_CrsMatrix( Copy, *(BlockUtility::GenerateBlockGraph( BaseMatrix, RowStencil, RowIndices, GlobalComm )) ),
00072     BaseGraph_( Copy, BaseMatrix.RowMatrixRowMap(), 1 ), //Junk to satisfy constructor
00073     RowStencil_( RowStencil ),
00074     RowIndices_( RowIndices ),
00075     Offset_(BlockUtility::CalculateOffset(BaseMatrix.RowMatrixRowMap()))
00076 {
00077 }
00078 
00079 //==============================================================================
00080 BlockCrsMatrix::BlockCrsMatrix( const BlockCrsMatrix & Matrix ) 
00081   : Epetra_CrsMatrix( dynamic_cast<const Epetra_CrsMatrix &>( Matrix ) ),
00082     BaseGraph_( Matrix.BaseGraph_ ),
00083     RowStencil_( Matrix.RowStencil_ ),
00084     RowIndices_( Matrix.RowIndices_ ),
00085     Offset_( Matrix.Offset_ )
00086 {
00087 }
00088 
00089 //==============================================================================
00090 BlockCrsMatrix::~BlockCrsMatrix()
00091 {
00092 }
00093 
00094 //==============================================================================
00095 void BlockCrsMatrix::LoadBlock(const Epetra_RowMatrix & BaseMatrix, const int Row, const int Col)
00096 {
00097   int RowOffset = RowIndices_[Row] * Offset_;
00098   int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00099 
00100 //  const Epetra_CrsGraph & BaseGraph = BaseMatrix.Graph();
00101   const Epetra_BlockMap & BaseMap = BaseMatrix.RowMatrixRowMap();
00102   const Epetra_BlockMap & BaseColMap = BaseMatrix.RowMatrixColMap();
00103 
00104   // This routine copies entries of a BaseMatrix into big  BlockCrsMatrix
00105   // It performs the following operation on the global IDs row-by-row
00106   // this->val[i+rowOffset][j+ColOffset] = BaseMatrix.val[i][j]
00107 
00108   int MaxIndices = BaseMatrix.MaxNumEntries();
00109   vector<int> Indices(MaxIndices);
00110   vector<double> Values(MaxIndices);
00111   int NumIndices;
00112   int ierr=0;
00113 
00114   for (int i=0; i<BaseMap.NumMyElements(); i++) {
00115     BaseMatrix.ExtractMyRowCopy( i, MaxIndices, NumIndices, &Values[0], &Indices[0] );
00116 
00117     // Convert to BlockMatrix Global numbering scheme
00118     for( int l = 0; l < NumIndices; ++l )
00119        Indices[l] = ColOffset +  BaseColMap.GID(Indices[l]);
00120 
00121     int BaseRow = BaseMap.GID(i);
00122     ierr = this->ReplaceGlobalValues(BaseRow + RowOffset, NumIndices, &Values[0], &Indices[0]); 
00123     if (ierr != 0) cout << "WARNING BlockCrsMatrix::LoadBlock ReplaceGlobalValues err = " << ierr <<
00124       "\n\t  Row " << BaseRow + RowOffset << "Col start" << Indices[0] << endl;
00125 
00126   }
00127 }
00128 
00129 //==============================================================================
00130 void BlockCrsMatrix::BlockSumIntoGlobalValues(const int BaseRow, int NumIndices,
00131      double* Values, const int* Indices, const int Row, const int Col)
00132 //All arguments could be const, except some were not set as const in CrsMatrix
00133 {
00134   int RowOffset = RowIndices_[Row] * Offset_;
00135   int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00136 
00137   // Convert to BlockMatrix Global numbering scheme
00138   vector<int> OffsetIndices(NumIndices);
00139   for( int l = 0; l < NumIndices; ++l ) OffsetIndices[l] = Indices[l] + ColOffset;
00140 
00141   int ierr = this->SumIntoGlobalValues(BaseRow + RowOffset, NumIndices,
00142                                    Values, &OffsetIndices[0]); 
00143 
00144   if (ierr != 0) cout << "WARNING BlockCrsMatrix::BlockSumIntoGlobalValues err = "
00145      << ierr << "\n\t  Row " << BaseRow + RowOffset << "Col start" << Indices[0] << endl;
00146 }
00147 
00148 //==============================================================================
00149 void BlockCrsMatrix::BlockReplaceGlobalValues(const int BaseRow, int NumIndices,
00150      double* Values, const int* Indices, const int Row, const int Col)
00151 //All arguments could be const, except some were not set as const in CrsMatrix
00152 {
00153   int RowOffset = RowIndices_[Row] * Offset_;
00154   int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00155 
00156   // Convert to BlockMatrix Global numbering scheme
00157   vector<int> OffsetIndices(NumIndices);
00158   for( int l = 0; l < NumIndices; ++l ) OffsetIndices[l] = Indices[l] + ColOffset;
00159 
00160   int ierr = this->ReplaceGlobalValues(BaseRow + RowOffset, NumIndices,
00161                                    Values, &OffsetIndices[0]); 
00162 
00163   if (ierr != 0) cout << "WARNING BlockCrsMatrix::BlockReplaceGlobalValues err = "
00164      << ierr << "\n\t  Row " << BaseRow + RowOffset << "Col start" << Indices[0] << endl;
00165 }
00166 
00167 //==============================================================================
00168 void BlockCrsMatrix::BlockExtractGlobalRowView(const int BaseRow, 
00169                  int& NumEntries, 
00170                  double*& Values, 
00171                  const int Row, 
00172                  const int Col)
00173 //All arguments could be const, except some were not set as const in CrsMatrix
00174 {
00175   int RowOffset = RowIndices_[Row] * Offset_;
00176   int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00177 
00178   // Get the whole row
00179   int ierr = this->ExtractGlobalRowView(BaseRow + RowOffset, NumEntries,
00180           Values); 
00181 
00182   // Adjust for just this block column
00183   Values += ColOffset;
00184   NumEntries -= ColOffset;
00185 
00186   if (ierr != 0) cout << "WARNING BlockCrsMatrix::BlockExtractGlobalRowView err = "
00187      << ierr << "\n\t  Row " << BaseRow + RowOffset << "Col " << Col+ColOffset << endl;
00188 }
00189 
00190 //==============================================================================
00191 void BlockCrsMatrix::ExtractBlock(Epetra_CrsMatrix & BaseMatrix, const int Row, const int Col)
00192 {
00193   int RowOffset = RowIndices_[Row] * Offset_;
00194   int ColOffset = (RowIndices_[Row] + RowStencil_[Row][Col]) * Offset_;
00195 
00196 //  const Epetra_CrsGraph & BaseGraph = BaseMatrix.Graph();
00197   const Epetra_BlockMap & BaseMap = BaseMatrix.RowMatrixRowMap();
00198   //const Epetra_BlockMap & BaseColMap = BaseMatrix.RowMatrixColMap();
00199 
00200   // This routine extracts entries of a BaseMatrix from a big  BlockCrsMatrix
00201   // It performs the following operation on the global IDs row-by-row
00202   // BaseMatrix.val[i][j] = this->val[i+rowOffset][j+ColOffset] 
00203 
00204   int MaxIndices = BaseMatrix.MaxNumEntries();
00205   vector<int> Indices(MaxIndices);
00206   vector<double> Values(MaxIndices);
00207   int NumIndices;
00208   int indx,icol;
00209   double* BlkValues;
00210   int *BlkIndices;
00211   int BlkNumIndices;
00212   int ierr=0;
00213 
00214   for (int i=0; i<BaseMap.NumMyElements(); i++) {
00215 
00216     // Get pointers to values and indices of whole block matrix row
00217     int BaseRow = BaseMap.GID(i);
00218     int myBlkBaseRow = this->RowMatrixRowMap().LID(BaseRow + RowOffset);
00219     ierr = this->ExtractMyRowView(myBlkBaseRow, BlkNumIndices, BlkValues, BlkIndices); 
00220 
00221     NumIndices = 0;
00222     // Grab columns with global indices in correct range for this block
00223     for( int l = 0; l < BlkNumIndices; ++l ) {
00224        icol = this->RowMatrixColMap().GID(BlkIndices[l]);
00225        indx = icol - ColOffset;
00226        if (indx >= 0 && indx < Offset_) {
00227          Indices[NumIndices] = indx;
00228          Values[NumIndices] = BlkValues[l];
00229    NumIndices++;
00230        }
00231     }
00232 
00233     //Load this row into base matrix
00234     BaseMatrix.ReplaceGlobalValues(BaseRow, NumIndices, &Values[0], &Indices[0] );
00235 
00236   }
00237 }
00238 
00239 } //namespace EpetraExt

Generated on Wed May 12 21:40:37 2010 for EpetraExt by  doxygen 1.4.7