Ifpack2 Templated Preconditioning Package Version 1.0
Ifpack2_SingletonFilter_def.hpp
00001 /*@HEADER
00002 // ***********************************************************************
00003 //
00004 //       Ifpack2: Tempated Object-Oriented Algebraic Preconditioner Package
00005 //                 Copyright (2009) 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 
00030 #ifndef IFPACK2_SINGLETONFILTER_DEF_HPP
00031 #define IFPACK2_SINGLETONFILTER_DEF_HPP
00032 #include "Ifpack2_SingletonFilter_decl.hpp"
00033 
00034 #include "Tpetra_ConfigDefs.hpp"
00035 #include "Tpetra_RowMatrix.hpp"
00036 #include "Tpetra_Map.hpp"
00037 #include "Tpetra_MultiVector.hpp"
00038 #include "Tpetra_Vector.hpp"
00039 
00040 namespace Ifpack2 {
00041 
00042 //==========================================================================
00043 template<class MatrixType>
00044 SingletonFilter<MatrixType>::SingletonFilter(const Teuchos::RCP<const Tpetra::RowMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >& Matrix):
00045   A_(Matrix),
00046   NumSingletons_(0),
00047   NumRows_(0),
00048   NumNonzeros_(0),
00049   MaxNumEntries_(0),
00050   MaxNumEntriesA_(0)
00051 {
00052 
00053   // use this filter only on serial matrices
00054   if (A_->getComm()->getSize() != 1 || A_->getNodeNumRows() != A_->getGlobalNumRows()) {
00055     throw std::runtime_error("Ifpack2::SingeltonFilter can be used with Comm().getSize() == 1 only. This class is a tool for Ifpack2_AdditiveSchwarz, and it is not meant to be used otherwise.");
00056   }
00057 
00058   // Number of rows in A
00059   size_t NumRowsA_ = A_->getNodeNumRows();
00060 
00061   // tentative value for MaxNumEntries. This is the number of
00062   // nonzeros in the local matrix
00063   MaxNumEntriesA_ = A_->getNodeMaxNumRowEntries();
00064 
00065   // ExtractMyRowCopy() will use these vectors
00066   Indices_.resize(MaxNumEntriesA_);
00067   Values_.resize(MaxNumEntriesA_);
00068 
00069   // Initialize reordering vector to -1
00070   Reorder_.resize(NumRowsA_);
00071   Reorder_.assign(Reorder_.size(),-1);
00072 
00073   // first check how may singletons I do have
00074   NumRows_=0;
00075   for (size_t i = 0 ; i < NumRowsA_ ; ++i) {
00076     size_t Nnz;
00077     A_->getLocalRowCopy(i,Indices_,Values_,Nnz);
00078     if (Nnz != 1) {
00079       Reorder_[i] = NumRows_++;
00080     }
00081     else {
00082       NumSingletons_++;
00083     }
00084   }
00085 
00086   // build the inverse reordering
00087   InvReorder_.resize(NumRows_);
00088   for (size_t i = 0 ; i < NumRowsA_ ; ++i) {
00089     if (Reorder_[i] < 0)
00090       continue;
00091     InvReorder_[Reorder_[i]] = i;
00092   }
00093   NumEntries_.resize(NumRows_);
00094   SingletonIndex_.resize(NumSingletons_);
00095 
00096   
00097   // now compute the nonzeros per row
00098   size_t count = 0;
00099   for (size_t i = 0 ; i < NumRowsA_ ; ++i) {
00100     size_t Nnz;
00101     A_->getLocalRowCopy(i,Indices_,Values_,Nnz);
00102     LocalOrdinal ii = Reorder_[i];
00103     if (ii >= 0) {
00104       NumEntries_[ii] = Nnz;
00105       NumNonzeros_ += Nnz;
00106       if (Nnz > MaxNumEntries_)
00107   MaxNumEntries_ = Nnz;
00108     }
00109     else {
00110       SingletonIndex_[count] = i;
00111       count++;
00112     }
00113   }
00114 
00115   // Build the reduced map.  This map should be serial
00116   ReducedMap_ = Teuchos::rcp( new Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node>(NumRows_,0,A_->getComm()) );
00117 
00118   // and finish up with the diagonal entry
00119   Diagonal_ = Teuchos::rcp( new Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(ReducedMap_) );
00120 
00121   Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> DiagonalA(A_->getRowMap());
00122   A_->getLocalDiagCopy(DiagonalA);
00123   const Teuchos::ArrayRCP<const Scalar> & DiagonalAview = DiagonalA.get1dView();
00124   for (size_t i = 0 ; i < NumRows_ ; ++i) {
00125     LocalOrdinal ii = InvReorder_[i];
00126     Diagonal_->replaceLocalValue((LocalOrdinal)i,DiagonalAview[ii]);
00127   }
00128 }
00129 
00130 //=========================================================================
00131 template<class MatrixType>
00132 SingletonFilter<MatrixType>::~SingletonFilter() { }
00133 
00134 //==========================================================================
00135 template<class MatrixType>
00136 const Teuchos::RCP<const Teuchos::Comm<int> > & SingletonFilter<MatrixType>::getComm() const
00137 {
00138   return A_->getComm();
00139 }
00140 
00141 //==========================================================================
00142 template<class MatrixType>
00143 Teuchos::RCP <typename MatrixType::node_type> SingletonFilter<MatrixType>::getNode() const
00144 {
00145   return A_->getNode();
00146 }
00147 
00148 //==========================================================================
00149 template<class MatrixType>
00150 const Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
00151                                      typename MatrixType::global_ordinal_type,
00152                                      typename MatrixType::node_type> >&
00153 SingletonFilter<MatrixType>::getRowMap() const
00154 {
00155   return ReducedMap_;
00156 }
00157 
00158 //==========================================================================
00159 template<class MatrixType>
00160 const Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
00161                                      typename MatrixType::global_ordinal_type,
00162                                      typename MatrixType::node_type> >&
00163 SingletonFilter<MatrixType>::getColMap() const
00164 {
00165   return ReducedMap_;
00166 }
00167 
00168 //==========================================================================
00169 template<class MatrixType>
00170 const Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
00171                                      typename MatrixType::global_ordinal_type,
00172                                      typename MatrixType::node_type> >&
00173 SingletonFilter<MatrixType>::getDomainMap() const
00174 {
00175   return ReducedMap_;
00176 }
00177 
00178 //==========================================================================
00179 template<class MatrixType>
00180 const Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
00181                                      typename MatrixType::global_ordinal_type,
00182                                      typename MatrixType::node_type> >&
00183 SingletonFilter<MatrixType>::getRangeMap() const
00184 {
00185   return ReducedMap_;
00186 }
00187 
00188 //==========================================================================
00189 template<class MatrixType>
00190 Teuchos::RCP<const Tpetra::RowGraph<typename MatrixType::local_ordinal_type,
00191                                      typename MatrixType::global_ordinal_type,
00192                                      typename MatrixType::node_type> >
00193 SingletonFilter<MatrixType>::getGraph() const
00194 {
00195   throw std::runtime_error("Ifpack2::SingletonFilter: does not support getGraph.");
00196 }
00197 
00198 //==========================================================================
00199 template<class MatrixType>
00200 global_size_t SingletonFilter<MatrixType>::getGlobalNumRows() const
00201 {
00202   return NumRows_;
00203 }
00204 
00205 //==========================================================================
00206 template<class MatrixType>
00207 global_size_t SingletonFilter<MatrixType>::getGlobalNumCols() const
00208 {
00209   return NumRows_;
00210 }
00211 
00212 //==========================================================================
00213 template<class MatrixType>
00214 size_t SingletonFilter<MatrixType>::getNodeNumRows() const
00215 {
00216   return NumRows_;
00217 }
00218 
00219 //==========================================================================
00220  
00221 template<class MatrixType>
00222 size_t SingletonFilter<MatrixType>::getNodeNumCols() const
00223 {
00224   return NumRows_;
00225 }
00226 
00227 //==========================================================================  
00228 template<class MatrixType>
00229 typename MatrixType::global_ordinal_type SingletonFilter<MatrixType>::getIndexBase() const
00230 {
00231   return A_->getIndexBase();
00232 }
00233 
00234 //========================================================================== 
00235 template<class MatrixType>
00236 global_size_t SingletonFilter<MatrixType>::getGlobalNumEntries() const
00237 {
00238   return NumNonzeros_;
00239 }
00240 
00241 //========================================================================== 
00242 template<class MatrixType>
00243 size_t SingletonFilter<MatrixType>::getNodeNumEntries() const
00244 {
00245   return NumNonzeros_;
00246 }
00247 
00248 //==========================================================================
00249 template<class MatrixType> 
00250 size_t SingletonFilter<MatrixType>::getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
00251 {
00252   throw std::runtime_error("Ifpack2::SingletonFilter does not implement getNumEntriesInGlobalRow.");
00253 }
00254 
00255 //==========================================================================  
00256 template<class MatrixType> 
00257 size_t SingletonFilter<MatrixType>::getNumEntriesInLocalRow(LocalOrdinal localRow) const
00258 {
00259   return NumEntries_[localRow];
00260 }
00261 
00262 //==========================================================================  
00263 template<class MatrixType>   
00264 global_size_t SingletonFilter<MatrixType>::getGlobalNumDiags() const
00265 {
00266   return A_->getGlobalNumDiags();
00267 }
00268 
00269 //==========================================================================  
00270 template<class MatrixType>   
00271 size_t SingletonFilter<MatrixType>::getNodeNumDiags() const
00272 {
00273   return A_->getNodeNumDiags();
00274 }
00275 
00276 //==========================================================================  
00277 template<class MatrixType>   
00278 size_t SingletonFilter<MatrixType>::getGlobalMaxNumRowEntries() const
00279 {
00280   return MaxNumEntries_;
00281 }
00282 
00283 //==========================================================================  
00284 template<class MatrixType>   
00285 size_t SingletonFilter<MatrixType>::getNodeMaxNumRowEntries() const
00286 {
00287   return MaxNumEntries_;
00288 }
00289 
00290 //==========================================================================  
00291 template<class MatrixType>   
00292 bool SingletonFilter<MatrixType>::hasColMap() const
00293 {
00294   return true;
00295 }
00296 
00297 //==========================================================================  
00298 template<class MatrixType>   
00299 bool SingletonFilter<MatrixType>::isLowerTriangular() const
00300 {
00301   return A_->isLowerTriangular();
00302 }
00303 
00304 //==========================================================================  
00305 template<class MatrixType>   
00306 bool SingletonFilter<MatrixType>::isUpperTriangular() const
00307 {
00308   return A_->isUpperTriangular();
00309 }
00310 
00311 //==========================================================================  
00312 template<class MatrixType>   
00313 bool SingletonFilter<MatrixType>::isLocallyIndexed() const
00314 {
00315   return A_->isLocallyIndexed();
00316 }
00317 
00318 //==========================================================================  
00319 template<class MatrixType>   
00320 bool SingletonFilter<MatrixType>::isGloballyIndexed() const
00321 {
00322   return A_->isGloballyIndexed();
00323 }
00324 
00325 //==========================================================================  
00326 template<class MatrixType>   
00327 bool SingletonFilter<MatrixType>::isFillComplete() const
00328 {
00329   return A_->isFillComplete();
00330 }
00331   
00332 //==========================================================================
00333 template<class MatrixType> 
00334 void SingletonFilter<MatrixType>::getGlobalRowCopy(GlobalOrdinal GlobalRow,
00335               const Teuchos::ArrayView<GlobalOrdinal> &Indices,
00336               const Teuchos::ArrayView<Scalar> &Values,
00337               size_t &NumEntries) const
00338 {
00339   throw std::runtime_error("Ifpack2::SingletonFilter does not implement getGlobalRowCopy.");
00340 }
00341 
00342 //==========================================================================  
00343 template<class MatrixType> 
00344 void SingletonFilter<MatrixType>::getLocalRowCopy(LocalOrdinal LocalRow, 
00345                 const Teuchos::ArrayView<LocalOrdinal> &Indices, 
00346                 const Teuchos::ArrayView<Scalar> &Values,
00347                 size_t &NumEntries) const 
00348 { 
00349   TEUCHOS_TEST_FOR_EXCEPTION((LocalRow < 0 || (size_t) LocalRow >=  NumRows_ || (size_t) Indices.size() <  NumEntries_[LocalRow]), std::runtime_error, "Ifpack2::SingletonFilter::getLocalRowCopy invalid row or array size.");
00350 
00351   size_t Nnz;
00352   LocalOrdinal ARow = InvReorder_[LocalRow];
00353   A_->getLocalRowCopy(ARow,Indices_(),Values_(),Nnz);
00354 
00355   // populate the user's vectors
00356   NumEntries = 0;
00357   for (size_t i = 0 ; i < Nnz ; ++i) {
00358     LocalOrdinal ii = Reorder_[Indices_[i]];
00359     if ( ii >= 0) {
00360       Indices[NumEntries] = ii;
00361       Values[NumEntries] = Values_[i];
00362       NumEntries++;
00363     }
00364   }
00365 
00366 }
00367 
00368 //==========================================================================  
00369 template<class MatrixType> 
00370 void SingletonFilter<MatrixType>::getGlobalRowView(GlobalOrdinal GlobalRow, 
00371               Teuchos::ArrayView<const GlobalOrdinal> &indices, 
00372               Teuchos::ArrayView<const Scalar> &values) const
00373 {
00374   throw std::runtime_error("Ifpack2::SingletonFilter: does not support getGlobalRowView.");
00375 }
00376 
00377 //==========================================================================  
00378 template<class MatrixType> 
00379 void SingletonFilter<MatrixType>::getLocalRowView(LocalOrdinal LocalRow, 
00380              Teuchos::ArrayView<const LocalOrdinal> &indices, 
00381              Teuchos::ArrayView<const Scalar> &values) const
00382 {
00383   throw std::runtime_error("Ifpack2::SingletonFilter: does not support getLocalRowView.");
00384 }
00385 
00386 //==========================================================================  
00387 template<class MatrixType> 
00388 void SingletonFilter<MatrixType>::getLocalDiagCopy(Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &diag) const
00389 {
00390   // This is somewhat dubious as to how the maps match.
00391   return A_->getLocalDiagCopy(diag);
00392 }
00393 
00394 //========================================================================== 
00395 template<class MatrixType> 
00396 void SingletonFilter<MatrixType>::leftScale(const Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& x) 
00397 {
00398   throw std::runtime_error("Ifpack2::SingletonFilter does not support leftScale.");
00399 }
00400 
00401 //==========================================================================  
00402 template<class MatrixType> 
00403 void SingletonFilter<MatrixType>::rightScale(const Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& x) 
00404 {
00405   throw std::runtime_error("Ifpack2::SingletonFilter does not support rightScale.");
00406 }
00407 
00408 //==========================================================================  
00409 template<class MatrixType> 
00410 void SingletonFilter<MatrixType>::apply(const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &X, 
00411                Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y, 
00412                Teuchos::ETransp mode, 
00413                Scalar alpha,
00414                Scalar beta) const
00415 {  
00416   // Note: This isn't AztecOO compliant.  But neither was Ifpack's version.
00417 
00418   TEUCHOS_TEST_FOR_EXCEPTION(X.getNumVectors() != Y.getNumVectors(), std::runtime_error,
00419            "Ifpack2::SingletonFilter::apply ERROR: X.getNumVectors() != Y.getNumVectors().");
00420 
00421   Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
00422   Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > x_ptr = X.get2dView();
00423   Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> >       y_ptr = Y.get2dViewNonConst();
00424 
00425   Y.putScalar(zero);
00426   size_t NumVectors = Y.getNumVectors();
00427 
00428 
00429   for (size_t i = 0 ; i < NumRows_ ; ++i) {
00430     size_t Nnz;
00431     // Use this class's getrow to make the below code simpler
00432     getLocalRowCopy(i,Indices_(),Values_(),Nnz);
00433     if (mode==Teuchos::NO_TRANS){
00434       for (size_t j = 0 ; j < Nnz ; ++j) 
00435   for (size_t k = 0 ; k < NumVectors ; ++k)
00436     y_ptr[k][i] += Values_[j] * x_ptr[k][Indices_[j]];      
00437     }
00438     else if (mode==Teuchos::TRANS){
00439       for (size_t j = 0 ; j < Nnz ; ++j) 
00440   for (size_t k = 0 ; k < NumVectors ; ++k)
00441     y_ptr[k][Indices_[j]] += Values_[j] * x_ptr[k][i];
00442     }
00443     else { //mode==Teuchos::CONJ_TRANS
00444       for (size_t j = 0 ; j < Nnz ; ++j) 
00445   for (size_t k = 0 ; k < NumVectors ; ++k)
00446     y_ptr[k][Indices_[j]] += Teuchos::ScalarTraits<Scalar>::conjugate(Values_[j]) * x_ptr[k][i];
00447     }
00448   }
00449 }
00450   
00451 
00452 //==========================================================================  
00453 template<class MatrixType> 
00454 bool SingletonFilter<MatrixType>::hasTransposeApply() const
00455 {
00456   return true;
00457 }
00458 
00459 //==========================================================================  
00460 template<class MatrixType> 
00461 bool SingletonFilter<MatrixType>::supportsRowViews() const
00462 {
00463   return false;
00464 }
00465 
00466 //==============================================================================
00467 template<class MatrixType> 
00468 void SingletonFilter<MatrixType>::SolveSingletons(const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& RHS, 
00469               Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& LHS)
00470 {
00471   Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > RHS_ptr = RHS.get2dView();
00472   Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> >       LHS_ptr = LHS.get2dViewNonConst();
00473 
00474   for (size_t i = 0 ; i < NumSingletons_ ; ++i) {
00475     LocalOrdinal ii = SingletonIndex_[i];
00476     // get the diagonal value for the singleton
00477     size_t Nnz;
00478     A_->getLocalRowCopy(ii,Indices_(),Values_(),Nnz);
00479     for (size_t j = 0 ; j < Nnz ; ++j) {
00480       if (Indices_[j] == ii) {
00481   for (size_t k = 0 ; k < LHS.getNumVectors() ; ++k)
00482     LHS_ptr[k][ii] = RHS_ptr[k][ii] / Values_[j];
00483       }
00484     }
00485   }
00486 }
00487 
00488 //==============================================================================
00489 template<class MatrixType> 
00490 void SingletonFilter<MatrixType>::CreateReducedRHS(const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& LHS,
00491                const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& RHS, 
00492                Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& ReducedRHS)
00493 {
00494   Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > RHS_ptr = RHS.get2dView();
00495   Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > LHS_ptr = LHS.get2dView();
00496   Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> >       ReducedRHS_ptr = ReducedRHS.get2dViewNonConst();
00497 
00498   size_t NumVectors = LHS.getNumVectors();
00499 
00500   for (size_t i = 0 ; i < NumRows_ ; ++i)
00501     for (size_t k = 0 ; k < NumVectors ; ++k)
00502       ReducedRHS_ptr[k][i] = RHS_ptr[k][InvReorder_[i]];
00503 
00504   for (size_t i = 0 ; i < NumRows_ ; ++i) {
00505     LocalOrdinal ii = InvReorder_[i];
00506     size_t Nnz; 
00507     A_->getLocalRowCopy(ii,Indices_(),Values_(),Nnz);
00508 
00509     for (size_t j = 0 ; j < Nnz ; ++j) {
00510       if (Reorder_[Indices_[j]] == -1) {
00511   for (size_t k = 0 ; k < NumVectors ; ++k)
00512     ReducedRHS_ptr[k][i] -= Values_[j] * LHS_ptr[k][Indices_[j]];
00513       }
00514     }
00515   }
00516 }
00517 
00518 //==============================================================================
00519 template<class MatrixType> 
00520 void SingletonFilter<MatrixType>::UpdateLHS(const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& ReducedLHS,
00521               Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& LHS)
00522 {
00523   
00524   Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> >        LHS_ptr = LHS.get2dViewNonConst();
00525   Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> >  ReducedLHS_ptr = ReducedLHS.get2dView();
00526 
00527   for (size_t i = 0 ; i < NumRows_ ; ++i)
00528     for (size_t k = 0 ; k < LHS.getNumVectors() ; ++k)
00529       LHS_ptr[k][InvReorder_[i]] = ReducedLHS_ptr[k][i];
00530 }
00531 
00532 //==========================================================================  
00533 template<class MatrixType> 
00534 typename Teuchos::ScalarTraits<typename MatrixType::scalar_type>::magnitudeType SingletonFilter<MatrixType>::getFrobeniusNorm() const
00535 {
00536   throw std::runtime_error("Ifpack2::SingletonFilter does not implement getFrobeniusNorm.");
00537 }
00538 
00539 //==========================================================================  
00540 template<class MatrixType> 
00541 TPETRA_DEPRECATED  void SingletonFilter<MatrixType>::getGlobalRowView(GlobalOrdinal GlobalRow, 
00542                      Teuchos::ArrayRCP<const GlobalOrdinal> &indices,
00543                      Teuchos::ArrayRCP<const Scalar>        &values) const
00544 {
00545   throw std::runtime_error("Ifpack2::SingletonFilter does not implement getGlobalRowView.");
00546 }
00547 
00548 //==========================================================================  
00549 template<class MatrixType> 
00550 TPETRA_DEPRECATED  void SingletonFilter<MatrixType>::getLocalRowView(LocalOrdinal LocalRow,
00551                     Teuchos::ArrayRCP<const LocalOrdinal> &indices,
00552                     Teuchos::ArrayRCP<const Scalar>       &values) const
00553 {
00554   throw std::runtime_error("Ifpack2::SingletonFilter does not implement getLocalRowView.");
00555 }
00556 
00557 
00558 
00559 
00560 }// namespace Ifpack2
00561 
00562 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends