Tpetra Matrix/Vector Services Version of the Day
Tpetra_BlockCrsGraph_def.hpp
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //          Tpetra: Templated Linear Algebra Services Package
00005 //                 Copyright (2008) Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 // 
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00038 // 
00039 // ************************************************************************
00040 // @HEADER
00041 
00042 #ifndef TPETRA_BLOCKCRSGRAPH_DEF_HPP
00043 #define TPETRA_BLOCKCRSGRAPH_DEF_HPP
00044 
00045 #include "Tpetra_ConfigDefs.hpp"
00046 #include "Tpetra_Vector.hpp"
00047 
00048 #ifdef DOXYGEN_USE_ONLY
00049 #include "Tpetra_BlockCrsGraph_decl.hpp"
00050 #endif
00051 
00052 namespace Tpetra {
00053 
00054 //-----------------------------------------------------------------
00055 template<class LocalOrdinal,class GlobalOrdinal,class Node>
00056 Teuchos::RCP<const Tpetra::BlockMap<LocalOrdinal,GlobalOrdinal,Node> >
00057 makeBlockColumnMap(
00058     const Teuchos::RCP<const Tpetra::BlockMap<LocalOrdinal,GlobalOrdinal,Node> >& blockMap,
00059     const Teuchos::RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> >& ptColMap)
00060 {
00061   global_size_t numGlobalBlocks = Teuchos::OrdinalTraits<global_size_t>::invalid();
00062   Teuchos::ArrayView<const GlobalOrdinal> blockIDs = ptColMap->getNodeElementList();
00063   Teuchos::ArrayRCP<const LocalOrdinal> firstPoints = blockMap->getNodeFirstPointInBlocks();
00064   Teuchos::Array<GlobalOrdinal> points(firstPoints.size()-1);
00065   Teuchos::Array<LocalOrdinal> blockSizes(firstPoints.size()-1);
00066 
00067   typedef typename Teuchos::ArrayView<const LocalOrdinal>::size_type Tsize_t;
00068   for(Tsize_t i=0; i<blockSizes.size(); ++i) {
00069     points[i] = blockMap->getFirstGlobalPointInLocalBlock(i);
00070     blockSizes[i] = firstPoints[i+1]-firstPoints[i];
00071   }
00072 
00073   //We will create a block-map where each block corresponds to a point in
00074   //the input-map 'ptColMap', and where each block's size is obtained from
00075   //the input-block-map 'blockMap'.
00076 
00077   //if we are running on a single processor, then it's easy because
00078   //we know that blockMap is distributed the same as ptColMap:
00079   int numProcessors = ptColMap->getComm()->getSize();
00080   if (numProcessors == 1) {
00081     return Teuchos::rcp(new Tpetra::BlockMap<LocalOrdinal,GlobalOrdinal,Node>(
00082         numGlobalBlocks, blockIDs, points(), blockSizes(),
00083         ptColMap->getIndexBase(), ptColMap->getComm(), ptColMap->getNode()
00084     ));
00085   }
00086 
00087   //If we get to here, we're running on multiple processors, and blockMap
00088   //is probably not distributed the same as ptColMap, so we have to do
00089   //some communication to get the block-sizes from blockMap corresponding
00090   //to the blockIDs we got from ptColMap.
00091   //We also have to do communication to get the global first-points-in-block
00092   //for the blocks in the new block-column-map.
00093   //
00094   //I think the simplest way to do this is to create vectors where the values
00095   //are block-sizes (or first-points-in-block), and import one to the other.
00096   typedef Tpetra::Vector<GlobalOrdinal,LocalOrdinal,GlobalOrdinal,Node> GOVec;
00097   typedef Tpetra::Vector<LocalOrdinal,LocalOrdinal,GlobalOrdinal,Node> LOVec;
00098 
00099   Teuchos::RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > blkPtMap =
00100       convertBlockMapToPointMap(*blockMap);
00101 
00102   LOVec source_sizes(blkPtMap, blockSizes());
00103   GOVec source_points(blkPtMap, points());
00104   LOVec target_sizes(ptColMap);
00105   GOVec target_points(ptColMap);
00106 
00107   Tpetra::Import<LocalOrdinal,GlobalOrdinal,Node> importer(blkPtMap, ptColMap);
00108   target_sizes.doImport(source_sizes, importer, REPLACE);
00109   target_points.doImport(source_points, importer, REPLACE);
00110 
00111   //now we can create our block-column-map:
00112   return Teuchos::rcp(new Tpetra::BlockMap<LocalOrdinal,GlobalOrdinal,Node>(
00113     numGlobalBlocks, blockIDs, target_points.get1dView()(), target_sizes.get1dView()(),
00114     ptColMap->getIndexBase(), ptColMap->getComm(), ptColMap->getNode()
00115   ));
00116 }
00117 
00118 template<class LocalOrdinal,class GlobalOrdinal,class Node>
00119 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::BlockCrsGraph(
00120    const Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> >& blkRowMap,
00121    size_t maxNumEntriesPerRow, ProfileType pftype
00122     )
00123  : ptGraph_(),
00124    blkRowMap_(blkRowMap),
00125    blkColMap_(),
00126    blkDomainMap_(),
00127    blkRangeMap_()
00128 {
00129   ptGraph_ = Teuchos::rcp(new CrsGraph<LocalOrdinal,GlobalOrdinal,Node>(
00130           convertBlockMapToPointMap(*blkRowMap), maxNumEntriesPerRow, pftype));
00131 }
00132 
00133 //-------------------------------------------------------------------
00134 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00135 void
00136 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::insertGlobalIndices(GlobalOrdinal row, const Teuchos::ArrayView<const GlobalOrdinal> &indices)
00137 {
00138   ptGraph_->insertGlobalIndices(row, indices);
00139 }
00140 
00141 //-------------------------------------------------------------------
00142 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00143 Teuchos::ArrayRCP<const size_t>
00144 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getNodeRowOffsets() const
00145 {
00146   return ptGraph_->getNodeRowBegs();
00147 }
00148 
00149 //-------------------------------------------------------------------
00150 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00151 Teuchos::ArrayRCP<const LocalOrdinal>
00152 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getNodePackedIndices() const
00153 {
00154   return ptGraph_->getNodePackedIndices();
00155 }
00156 
00157 //-------------------------------------------------------------------
00158 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00159 void
00160 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::globalAssemble()
00161 {
00162   ptGraph_->globalAssemble();
00163 }
00164 
00165 //-------------------------------------------------------------------
00166 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00167 void
00168 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::fillComplete(const Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > &blkDomainMap, const Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > &blkRangeMap, OptimizeOption os)
00169 {
00170   blkDomainMap_ = blkDomainMap;
00171   blkRangeMap_  = blkRangeMap;
00172 
00173   ptGraph_->fillComplete(convertBlockMapToPointMap(*blkDomainMap),
00174                          convertBlockMapToPointMap(*blkRangeMap), os);
00175 
00176   //Now we need to take the point-column-map from ptGraph_ and create a
00177   //corresponding block-column-map.
00178   //Our block-column-map will have the same distribution as
00179   //blkGraph_->getColMap, and we'll get block-size info from the
00180   //blkDomainMap_. This will require some communication in cases
00181   //where blkDomainMap is distributed differently.
00182   blkColMap_ = makeBlockColumnMap(blkDomainMap_, ptGraph_->getColMap());
00183 }
00184 
00185 //-------------------------------------------------------------------
00186 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00187 void
00188 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::fillComplete(OptimizeOption os)
00189 {
00190   fillComplete(getBlockRowMap(), getBlockRowMap(), os);
00191 }
00192 
00193 //-------------------------------------------------------------------
00194 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00195 void
00196 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::optimizeStorage()
00197 {
00198   if (ptGraph_->isFillComplete()) {
00199     ptGraph_->resumeFill();
00200   }
00201   ptGraph_->fillComplete(DoOptimizeStorage);
00202 }
00203 
00204 //-------------------------------------------------------------------
00205 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00206 bool
00207 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::isFillComplete() const
00208 {
00209   return ptGraph_->isFillComplete();
00210 }
00211 
00212 //-------------------------------------------------------------------
00213 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00214 bool
00215 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::isUpperTriangular() const
00216 {
00217   return ptGraph_->isUpperTriangular();
00218 }
00219 
00220 //-------------------------------------------------------------------
00221 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00222 bool
00223 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::isLowerTriangular() const
00224 {
00225   return ptGraph_->isLowerTriangular();
00226 }
00227 
00228 //-------------------------------------------------------------------
00229 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00230 bool
00231 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::isLocallyIndexed() const
00232 {
00233   return ptGraph_->isLocallyIndexed();
00234 }
00235 
00236 //-------------------------------------------------------------------
00237 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00238 size_t
00239 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getNodeNumBlockEntries() const
00240 {
00241   return ptGraph_->getNodeNumEntries();
00242 }
00243 
00244 //-------------------------------------------------------------------
00245 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00246 size_t
00247 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getGlobalBlockRowLength(GlobalOrdinal row) const
00248 {
00249   return ptGraph_->getNumEntriesInGlobalRow(row);
00250 }
00251 
00252 //-------------------------------------------------------------------
00253 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00254 void
00255 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getGlobalBlockRowView(GlobalOrdinal row,
00256                              Teuchos::ArrayView<const GlobalOrdinal>& blockCols) const
00257 {
00258   ptGraph_->getGlobalRowView(row, blockCols);
00259 }
00260 
00261 //-------------------------------------------------------------------
00262 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00263 void
00264 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getLocalBlockRowView(LocalOrdinal row,
00265                              Teuchos::ArrayView<const LocalOrdinal>& blockCols) const
00266 {
00267   ptGraph_->getLocalRowView(row, blockCols);
00268 }
00269 
00270 //-------------------------------------------------------------------
00271 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00272 size_t
00273 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getNodeNumBlockRows() const
00274 {
00275   return ptGraph_->getNodeNumRows();
00276 }
00277 
00278 //-------------------------------------------------------------------
00279 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00280 size_t
00281 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getGlobalNumBlockRows() const
00282 {
00283   return ptGraph_->getGlobalNumRows();
00284 }
00285 
00286 //-------------------------------------------------------------------
00287 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00288 size_t
00289 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getNodeNumBlockDiags() const
00290 {
00291   return ptGraph_->getNodeNumDiags();
00292 }
00293 
00294 //-------------------------------------------------------------------
00295 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00296 const Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > &
00297 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getBlockRowMap() const
00298 {
00299   return blkRowMap_;
00300 }
00301 
00302 //-------------------------------------------------------------------
00303 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00304 const Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > &
00305 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getBlockColMap() const
00306 {
00307   return blkColMap_;
00308 }
00309 
00310 //-------------------------------------------------------------------
00311 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00312 const Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > &
00313 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getBlockDomainMap() const
00314 {
00315   return blkDomainMap_;
00316 }
00317 
00318 //-------------------------------------------------------------------
00319 template<class LocalOrdinal, class GlobalOrdinal, class Node>
00320 const Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > &
00321 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getBlockRangeMap() const
00322 {
00323   return blkRangeMap_;
00324 }
00325 
00326 //
00327 // Explicit instantiation macro
00328 //
00329 // Must be expanded from within the Tpetra namespace!
00330 //
00331 
00332 #define TPETRA_BLOCKCRSGRAPH_INSTANT(LO,GO,NODE) \
00333   \
00334   template class BlockCrsGraph< LO , GO , NODE >;
00335 
00336 
00337 }//namespace Tpetra
00338 
00339 #endif
00340 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines