Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_MatrixAdapter_def.hpp
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //           Amesos2: Templated Direct Sparse Solver Package 
00006 //                  Copyright 2011 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 //
00042 // @HEADER
00043 
00044 
00045 #ifndef AMESOS2_MATRIXADAPTER_DEF_HPP
00046 #define AMESOS2_MATRIXADAPTER_DEF_HPP
00047 #include <Tpetra_Util.hpp>
00048 #include "Amesos2_MatrixAdapter_decl.hpp"
00049 #include "Amesos2_ConcreteMatrixAdapter_def.hpp"
00050 //#include "Amesos2_ConcreteMatrixAdapter.hpp"
00051 
00052 
00053 namespace Amesos2 {
00054 
00055   
00056   template < class Matrix >
00057   MatrixAdapter<Matrix>::MatrixAdapter(const Teuchos::RCP<Matrix> m)
00058     : mat_(m)
00059   {
00060     comm_ = static_cast<const adapter_t*>(this)->getComm_impl();
00061     col_map_ = static_cast<const adapter_t*>(this)->getColMap_impl();
00062     row_map_ = static_cast<const adapter_t*>(this)->getRowMap_impl();
00063   }
00064 
00065   template < class Matrix >
00066   void
00067   MatrixAdapter<Matrix>::getCrs(const Teuchos::ArrayView<scalar_t> nzval,
00068         const Teuchos::ArrayView<global_ordinal_t> colind,
00069         const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> rowptr,
00070         typename MatrixAdapter<Matrix>::global_size_t& nnz,
00071         const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t, global_ordinal_t, node_t> > rowmap,
00072         EStorage_Ordering ordering) const
00073   {
00074     help_getCrs(nzval, colind, rowptr,
00075     nnz, rowmap, ordering,
00076     typename adapter_t::get_crs_spec());
00077   }
00078 
00079   template < class Matrix >
00080   void
00081   MatrixAdapter<Matrix>::getCrs(const Teuchos::ArrayView<scalar_t> nzval,
00082         const Teuchos::ArrayView<global_ordinal_t> colind,
00083         const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> rowptr,
00084         typename MatrixAdapter<Matrix>::global_size_t& nnz,
00085         EDistribution distribution,
00086         EStorage_Ordering ordering) const
00087   {
00088     const Teuchos::RCP<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > rowmap
00089       = Util::getDistributionMap<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(distribution,
00090                       this->getGlobalNumRows(),
00091                       this->getComm());
00092     this->getCrs(nzval, colind, rowptr, nnz, Teuchos::ptrInArg(*rowmap), ordering);
00093   }
00094 
00095   template < class Matrix >
00096   void
00097   MatrixAdapter<Matrix>::getCcs(const Teuchos::ArrayView<scalar_t> nzval,
00098         const Teuchos::ArrayView<global_ordinal_t> rowind,
00099         const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> colptr,
00100         typename MatrixAdapter<Matrix>::global_size_t& nnz,
00101         const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t, global_ordinal_t, node_t> > colmap,
00102         EStorage_Ordering ordering) const
00103   {
00104     help_getCcs(nzval, rowind, colptr,
00105     nnz, colmap, ordering,
00106     typename adapter_t::get_ccs_spec());
00107   }
00108 
00109   template < class Matrix >
00110   void
00111   MatrixAdapter<Matrix>::getCcs(const Teuchos::ArrayView<scalar_t> nzval,
00112         const Teuchos::ArrayView<global_ordinal_t> rowind,
00113         const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> colptr,
00114         typename MatrixAdapter<Matrix>::global_size_t& nnz,
00115         EDistribution distribution,
00116         EStorage_Ordering ordering) const
00117   {
00118     const Teuchos::RCP<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > colmap
00119       = Util::getDistributionMap<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(distribution,
00120                       this->getGlobalNumCols(),
00121                       this->getComm());
00122     this->getCcs(nzval, rowind, colptr, nnz, Teuchos::ptrInArg(*colmap), ordering);
00123   }
00124 
00125   template < class Matrix >
00126   typename MatrixAdapter<Matrix>::global_size_t
00127   MatrixAdapter<Matrix>::getGlobalNumRows() const
00128   {
00129     return static_cast<const adapter_t*>(this)->getGlobalNumRows_impl();
00130   }
00131 
00132   template < class Matrix >
00133   typename MatrixAdapter<Matrix>::global_size_t
00134   MatrixAdapter<Matrix>::getGlobalNumCols() const
00135   {
00136     return static_cast<const adapter_t*>(this)->getGlobalNumCols_impl();
00137   }
00138   
00139   template < class Matrix >
00140   typename MatrixAdapter<Matrix>::global_size_t
00141   MatrixAdapter<Matrix>::getRowIndexBase() const
00142   {
00143     return row_map_->getIndexBase();
00144   }
00145 
00146   template < class Matrix >
00147   typename MatrixAdapter<Matrix>::global_size_t
00148   MatrixAdapter<Matrix>::getColumnIndexBase() const
00149   {
00150     return col_map_->getIndexBase();
00151   }
00152 
00153   template < class Matrix >
00154   typename MatrixAdapter<Matrix>::global_size_t
00155   MatrixAdapter<Matrix>::getGlobalNNZ() const
00156   {
00157     return static_cast<const adapter_t*>(this)->getGlobalNNZ_impl();
00158   }
00159   
00160   template < class Matrix >
00161   size_t
00162   MatrixAdapter<Matrix>::getLocalNumRows() const
00163   {
00164     return row_map_->getNodeNumElements(); // TODO: verify
00165   }
00166 
00167   template < class Matrix >
00168   size_t
00169   MatrixAdapter<Matrix>::getLocalNumCols() const
00170   {
00171     return col_map_->getNodeNumElements();
00172   }
00173   
00174   template < class Matrix >
00175   size_t
00176   MatrixAdapter<Matrix>::getLocalNNZ() const
00177   {
00178     return static_cast<const adapter_t*>(this)->getLocalNNZ_impl();
00179   }
00180 
00181   template < class Matrix >
00182   std::string
00183   MatrixAdapter<Matrix>::description() const
00184   {
00185     std::ostringstream oss;
00186     oss << "Amesos2::MatrixAdapter wrapping: ";
00187     oss << mat_->description();
00188     return oss.str();
00189   }
00190   
00191   template < class Matrix >
00192   void
00193   MatrixAdapter<Matrix>::describe(Teuchos::FancyOStream &out,
00194           const Teuchos::EVerbosityLevel verbLevel) const
00195   {}
00196   
00197 
00198 
00199   /******************************
00200    * Private method definitions *
00201    ******************************/
00202 
00203   template < class Matrix >
00204   void
00205   MatrixAdapter<Matrix>::help_getCrs(const Teuchos::ArrayView<scalar_t> nzval,
00206              const Teuchos::ArrayView<global_ordinal_t> colind,
00207              const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> rowptr,
00208              typename MatrixAdapter<Matrix>::global_size_t& nnz,
00209              const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > rowmap,
00210              EStorage_Ordering ordering,
00211              has_special_impl hsi) const
00212   {
00213     static_cast<const adapter_t*>(this)->getCrs_spec(nzval, colind, rowptr,
00214                  nnz, rowmap, ordering);
00215   }
00216 
00217   template < class Matrix >
00218   void
00219   MatrixAdapter<Matrix>::help_getCrs(const Teuchos::ArrayView<scalar_t> nzval,
00220              const Teuchos::ArrayView<global_ordinal_t> colind,
00221              const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> rowptr,
00222              typename MatrixAdapter<Matrix>::global_size_t& nnz,
00223              const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > rowmap,
00224              EStorage_Ordering ordering,
00225              no_special_impl nsi) const
00226   {
00227     do_getCrs(nzval, colind, rowptr,
00228         nnz, rowmap, ordering,
00229         typename adapter_t::major_access());
00230   }
00231 
00232   template < class Matrix >
00233   void
00234   MatrixAdapter<Matrix>::do_getCrs(const Teuchos::ArrayView<scalar_t> nzval,
00235            const Teuchos::ArrayView<global_ordinal_t> colind,
00236            const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> rowptr,
00237            typename MatrixAdapter<Matrix>::global_size_t& nnz,
00238            const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > rowmap,
00239            EStorage_Ordering ordering,
00240            row_access ra) const
00241   {
00242     using Teuchos::rcp;
00243     using Teuchos::RCP;
00244     using Teuchos::ArrayView;
00245     using Teuchos::OrdinalTraits;
00246     
00247     RCP<const type> get_mat;
00248     if( *rowmap == *this->row_map_ ){
00249       // No need to redistribute
00250       get_mat = rcp(this,false); // non-owning
00251     } else {
00252       get_mat = get(rowmap);
00253     }
00254     // RCP<const type> get_mat = get(rowmap);
00255 
00256     // rmap may not necessarily check same as rowmap because rmap may
00257     // have been constructued with Tpetra's "expert" constructor,
00258     // which assumes that the map points are non-contiguous.
00259     //
00260     // TODO: There may be some more checking between the row map
00261     // compatibility, but things are working fine now.
00262     RCP<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > rmap = get_mat->getRowMap();
00263 
00264     ArrayView<const global_ordinal_t> node_elements = rmap->getNodeElementList();
00265     if( node_elements.size() == 0 ) return; // no more contribution
00266     
00267     typename ArrayView<const global_ordinal_t>::iterator row_it, row_end;
00268     row_end = node_elements.end();
00269 
00270     size_t rowptr_ind = OrdinalTraits<size_t>::zero();
00271     global_ordinal_t rowInd = OrdinalTraits<global_ordinal_t>::zero();
00272     for( row_it = node_elements.begin(); row_it != row_end; ++row_it ){
00273       rowptr[rowptr_ind++] = rowInd;
00274       size_t rowNNZ = get_mat->getGlobalRowNNZ(*row_it);
00275       size_t nnzRet = OrdinalTraits<size_t>::zero();
00276       ArrayView<global_ordinal_t> colind_view = colind.view(rowInd,rowNNZ);
00277       ArrayView<scalar_t> nzval_view = nzval.view(rowInd,rowNNZ);
00278       
00279       get_mat->getGlobalRowCopy(*row_it, colind_view, nzval_view, nnzRet);
00280       for (size_t rr = 0; rr < nnzRet ; rr++)
00281       {
00282           colind_view[rr] = colind_view[rr] - rmap->getIndexBase();
00283       }
00284 
00285       // It was suggested that instead of sorting each row's indices
00286       // individually, that we instead do a double-transpose at the
00287       // end, which would also lead to the indices being sorted.
00288       if( ordering == SORTED_INDICES ){
00289   Tpetra::sort2(colind_view.begin(), colind_view.end(), nzval_view.begin());
00290       }
00291       
00292       TEUCHOS_TEST_FOR_EXCEPTION( rowNNZ != nnzRet,
00293         std::runtime_error,
00294         "Number of values returned different from "
00295                           "number of values reported");
00296       rowInd += rowNNZ;
00297     }
00298     rowptr[rowptr_ind] = nnz = rowInd;
00299   }
00300 
00301   // TODO: This may not work with distributed matrices.
00302   template < class Matrix >
00303   void
00304   MatrixAdapter<Matrix>::do_getCrs(const Teuchos::ArrayView<scalar_t> nzval,
00305            const Teuchos::ArrayView<global_ordinal_t> colind,
00306            const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> rowptr,
00307            typename MatrixAdapter<Matrix>::global_size_t& nnz,
00308            const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > rowmap,
00309            EStorage_Ordering ordering,
00310            col_access ca) const
00311   {
00312     using Teuchos::Array;
00313     // get the ccs and transpose
00314 
00315     Array<scalar_t> nzval_tmp(nzval.size(), 0);
00316     Array<global_ordinal_t> rowind(colind.size(), 0);
00317     Array<global_size_t> colptr(this->getGlobalNumCols() + 1);
00318     this->getCcs(nzval_tmp(), rowind(), colptr(), nnz, rowmap, ordering);
00319     
00320     if( !nzval.is_null() && !colind.is_null() && !rowptr.is_null() )
00321       Util::transpose(nzval_tmp(), rowind(), colptr(), nzval, colind, rowptr);
00322   }
00323 
00324   template < class Matrix >
00325   void
00326   MatrixAdapter<Matrix>::help_getCcs(const Teuchos::ArrayView<scalar_t> nzval,
00327              const Teuchos::ArrayView<global_ordinal_t> rowind,
00328              const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> colptr,
00329              typename MatrixAdapter<Matrix>::global_size_t& nnz,
00330              const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > colmap,
00331              EStorage_Ordering ordering,
00332              has_special_impl hsi) const
00333   {
00334     static_cast<const adapter_t*>(this)->getCcs_spec(nzval, rowind, colptr,
00335                  nnz, colmap, ordering);
00336   }
00337 
00338   template < class Matrix >
00339   void
00340   MatrixAdapter<Matrix>::help_getCcs(const Teuchos::ArrayView<scalar_t> nzval,
00341              const Teuchos::ArrayView<global_ordinal_t> rowind,
00342              const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> colptr,
00343              typename MatrixAdapter<Matrix>::global_size_t& nnz,
00344              const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > colmap,
00345              EStorage_Ordering ordering,
00346              no_special_impl nsi) const
00347   {
00348     do_getCcs(nzval, rowind, colptr,
00349         nnz, colmap, ordering,
00350         typename adapter_t::major_access());
00351   }
00352 
00353   template < class Matrix >
00354   void
00355   MatrixAdapter<Matrix>::do_getCcs(const Teuchos::ArrayView<scalar_t> nzval,
00356            const Teuchos::ArrayView<global_ordinal_t> rowind,
00357            const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> colptr,
00358            typename MatrixAdapter<Matrix>::global_size_t& nnz,
00359            const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > colmap,
00360            EStorage_Ordering ordering,
00361            row_access ra) const
00362   {
00363     using Teuchos::Array;
00364     // get the crs and transpose
00365 
00366     Array<scalar_t> nzval_tmp(nzval.size(), 0);
00367     Array<global_ordinal_t> colind(rowind.size(), 0);
00368     Array<global_size_t> rowptr(this->getGlobalNumRows() + 1);
00369     this->getCrs(nzval_tmp(), colind(), rowptr(), nnz, colmap, ordering);
00370 
00371     if( !nzval.is_null() && !rowind.is_null() && !colptr.is_null() )
00372       Util::transpose(nzval_tmp(), colind(), rowptr(), nzval, rowind, colptr);
00373   }
00374 
00375   template < class Matrix >
00376   void
00377   MatrixAdapter<Matrix>::do_getCcs(const Teuchos::ArrayView<scalar_t> nzval,
00378            const Teuchos::ArrayView<global_ordinal_t> rowind,
00379            const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> colptr,
00380            typename MatrixAdapter<Matrix>::global_size_t& nnz,
00381            const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > colmap,
00382            EStorage_Ordering ordering,
00383            col_access ca) const
00384   {
00385     using Teuchos::RCP;
00386     using Teuchos::ArrayView;
00387     using Teuchos::OrdinalTraits;
00388     
00389     RCP<const type> get_mat;
00390     if( *colmap == *this->col_map_ ){
00391       // No need to redistribute
00392       get_mat = rcp(this,false); // non-owning
00393     } else {
00394       get_mat = get(colmap);
00395     }
00396 
00397     // If all is well and good, then colmap == cmap
00398     RCP<const Tpetra::Map<scalar_t,local_ordinal_t,global_ordinal_t> > cmap = get_mat->getColMap();
00399     TEUCHOS_ASSERT( *colmap == *cmap );
00400 
00401     ArrayView<global_ordinal_t> node_elements = cmap->getNodeElementList();
00402     if( node_elements.size() == 0 ) return; // no more contribution
00403     
00404     typename ArrayView<global_ordinal_t>::iterator col_it, col_end;
00405     col_end = node_elements.end();
00406 
00407     size_t colptr_ind = OrdinalTraits<size_t>::zero();
00408     global_ordinal_t colInd = OrdinalTraits<global_ordinal_t>::zero();
00409     for( col_it = node_elements.begin(); col_it != col_end; ++col_it ){
00410       colptr[colptr_ind++] = colInd;
00411       size_t colNNZ = getGlobalColNNZ(*col_it);
00412       size_t nnzRet = 0;
00413       ArrayView<global_ordinal_t> rowind_view = rowind.view(colInd,colNNZ);
00414       ArrayView<scalar_t> nzval_view = nzval.view(colInd,colNNZ);
00415       getGlobalColCopy(*col_it, rowind_view, nzval_view, nnzRet);
00416       
00417       // It was suggested that instead of sorting each row's indices
00418       // individually, that we instead do a double-transpose at the
00419       // end, which would also lead to the indices being sorted.
00420       if( ordering == SORTED_INDICES ){
00421   Tpetra::sort2(rowind_view.begin(), rowind_view.end(), nzval_view.begin());
00422       }
00423       
00424       TEUCHOS_TEST_FOR_EXCEPTION( colNNZ != nnzRet,
00425         std::runtime_error,
00426         "Number of values returned different from "
00427                           "number of values reported");
00428       colInd += colNNZ;
00429     }
00430     colptr[colptr_ind] = nnz = colInd;
00431   }
00432 
00433   
00434   // These will link to concrete implementations
00435   template < class Matrix >
00436   void
00437   MatrixAdapter<Matrix>::getGlobalRowCopy(global_ordinal_t row,
00438             const Teuchos::ArrayView<global_ordinal_t>& indices,
00439             const Teuchos::ArrayView<scalar_t>& vals,
00440             size_t& nnz) const
00441   {
00442     static_cast<const adapter_t*>(this)->getGlobalRowCopy_impl(row, indices, vals, nnz);
00443   }
00444   
00445   template < class Matrix >
00446   void
00447   MatrixAdapter<Matrix>::getGlobalColCopy(global_ordinal_t col,
00448             const Teuchos::ArrayView<global_ordinal_t>& indices,
00449             const Teuchos::ArrayView<scalar_t>& vals,
00450             size_t& nnz) const
00451   {
00452     static_cast<const adapter_t*>(this)->getGlobalColCopy_impl(col, indices, vals, nnz);
00453   }
00454 
00455   template < class Matrix >
00456   size_t
00457   MatrixAdapter<Matrix>::getMaxRowNNZ() const
00458   {
00459     return static_cast<const adapter_t*>(this)->getMaxRowNNZ_impl();
00460   }
00461 
00462   template < class Matrix >
00463   size_t
00464   MatrixAdapter<Matrix>::getMaxColNNZ() const
00465   {
00466     return static_cast<const adapter_t*>(this)->getMaxColNNZ_impl();
00467   }
00468     
00469   template < class Matrix >
00470   size_t
00471   MatrixAdapter<Matrix>::getGlobalRowNNZ(global_ordinal_t row) const
00472   {
00473     return static_cast<const adapter_t*>(this)->getGlobalRowNNZ_impl(row);
00474   }
00475 
00476   template < class Matrix >
00477   size_t
00478   MatrixAdapter<Matrix>::getLocalRowNNZ(local_ordinal_t row) const
00479   {
00480     return static_cast<const adapter_t*>(this)->getLocalRowNNZ_impl(row);
00481   }
00482 
00483   template < class Matrix >
00484   size_t
00485   MatrixAdapter<Matrix>::getGlobalColNNZ(global_ordinal_t col) const
00486   {
00487     return static_cast<const adapter_t*>(this)->getGlobalColNNZ_impl(col);
00488   }
00489 
00490   template < class Matrix >
00491   size_t
00492   MatrixAdapter<Matrix>::getLocalColNNZ(local_ordinal_t col) const
00493   {
00494     return static_cast<const adapter_t*>(this)->getLocalColNNZ_impl(col);
00495   }
00496 
00497   template < class Matrix >
00498   bool
00499   MatrixAdapter<Matrix>::isLocallyIndexed() const
00500   {
00501     return static_cast<const adapter_t*>(this)->isLocallyIndexed_impl();
00502   }
00503   
00504   template < class Matrix >
00505   bool
00506   MatrixAdapter<Matrix>::isGloballyIndexed() const
00507   {
00508     return static_cast<const adapter_t*>(this)->isGloballyIndexed_impl();
00509   }
00510   
00511   template < class Matrix >
00512   Teuchos::RCP<const MatrixAdapter<Matrix> >
00513   MatrixAdapter<Matrix>::get(const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > map) const
00514   {
00515     return static_cast<const adapter_t*>(this)->get_impl(map);
00516   }
00517 
00518 
00519   template <class Matrix>
00520   Teuchos::RCP<MatrixAdapter<Matrix> >
00521   createMatrixAdapter(Teuchos::RCP<Matrix> m){
00522     using Teuchos::rcp;
00523     using Teuchos::rcp_const_cast;
00524     
00525     if(m.is_null()) return Teuchos::null;
00526     return( rcp(new ConcreteMatrixAdapter<Matrix>(m)) );
00527   }
00528 
00529   template <class Matrix>
00530   Teuchos::RCP<const MatrixAdapter<Matrix> >
00531   createConstMatrixAdapter(Teuchos::RCP<const Matrix> m){
00532     using Teuchos::rcp;
00533     using Teuchos::rcp_const_cast;
00534     
00535     if(m.is_null()) return Teuchos::null;
00536     return( rcp(new ConcreteMatrixAdapter<Matrix>(rcp_const_cast<Matrix,const Matrix>(m))).getConst() );
00537   }
00538 
00539 } // end namespace Amesos2
00540 
00541 #endif  // AMESOS2_MATRIXADAPTER_DEF_HPP