|
Tpetra Matrix/Vector Services Version of the Day
|
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
1.7.4