|
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_->getNodeRowPtrs(); 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 RCP<ParameterList> params = parameterList(); 00174 if (os == DoOptimizeStorage) params->set("Optimize Storage",true); 00175 else params->set("Optimize Storage",false); 00176 ptGraph_->fillComplete(convertBlockMapToPointMap(*blkDomainMap), 00177 convertBlockMapToPointMap(*blkRangeMap), params); 00178 00179 //Now we need to take the point-column-map from ptGraph_ and create a 00180 //corresponding block-column-map. 00181 //Our block-column-map will have the same distribution as 00182 //blkGraph_->getColMap, and we'll get block-size info from the 00183 //blkDomainMap_. This will require some communication in cases 00184 //where blkDomainMap is distributed differently. 00185 blkColMap_ = makeBlockColumnMap(blkDomainMap_, ptGraph_->getColMap()); 00186 } 00187 00188 //------------------------------------------------------------------- 00189 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00190 void 00191 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::fillComplete(OptimizeOption os) 00192 { 00193 fillComplete(getBlockRowMap(), getBlockRowMap(), os); 00194 } 00195 00196 //------------------------------------------------------------------- 00197 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00198 void 00199 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::optimizeStorage() 00200 { 00201 if (ptGraph_->isFillComplete()) { 00202 ptGraph_->resumeFill(); 00203 } 00204 RCP<ParameterList> params = parameterList(); 00205 params->set("Optimize Storage",true); 00206 ptGraph_->fillComplete(params); 00207 } 00208 00209 //------------------------------------------------------------------- 00210 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00211 bool 00212 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::isFillComplete() const 00213 { 00214 return ptGraph_->isFillComplete(); 00215 } 00216 00217 //------------------------------------------------------------------- 00218 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00219 bool 00220 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::isUpperTriangular() const 00221 { 00222 return ptGraph_->isUpperTriangular(); 00223 } 00224 00225 //------------------------------------------------------------------- 00226 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00227 bool 00228 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::isLowerTriangular() const 00229 { 00230 return ptGraph_->isLowerTriangular(); 00231 } 00232 00233 //------------------------------------------------------------------- 00234 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00235 bool 00236 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::isLocallyIndexed() const 00237 { 00238 return ptGraph_->isLocallyIndexed(); 00239 } 00240 00241 //------------------------------------------------------------------- 00242 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00243 size_t 00244 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getNodeNumBlockEntries() const 00245 { 00246 return ptGraph_->getNodeNumEntries(); 00247 } 00248 00249 //------------------------------------------------------------------- 00250 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00251 size_t 00252 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getGlobalBlockRowLength(GlobalOrdinal row) const 00253 { 00254 return ptGraph_->getNumEntriesInGlobalRow(row); 00255 } 00256 00257 //------------------------------------------------------------------- 00258 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00259 void 00260 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getGlobalBlockRowView(GlobalOrdinal row, 00261 Teuchos::ArrayView<const GlobalOrdinal>& blockCols) const 00262 { 00263 ptGraph_->getGlobalRowView(row, blockCols); 00264 } 00265 00266 //------------------------------------------------------------------- 00267 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00268 void 00269 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getLocalBlockRowView(LocalOrdinal row, 00270 Teuchos::ArrayView<const LocalOrdinal>& blockCols) const 00271 { 00272 ptGraph_->getLocalRowView(row, blockCols); 00273 } 00274 00275 //------------------------------------------------------------------- 00276 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00277 size_t 00278 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getNodeNumBlockRows() const 00279 { 00280 return ptGraph_->getNodeNumRows(); 00281 } 00282 00283 //------------------------------------------------------------------- 00284 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00285 size_t 00286 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getGlobalNumBlockRows() const 00287 { 00288 return ptGraph_->getGlobalNumRows(); 00289 } 00290 00291 //------------------------------------------------------------------- 00292 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00293 size_t 00294 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getNodeNumBlockDiags() const 00295 { 00296 return ptGraph_->getNodeNumDiags(); 00297 } 00298 00299 //------------------------------------------------------------------- 00300 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00301 Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > 00302 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getBlockRowMap() const 00303 { 00304 return blkRowMap_; 00305 } 00306 00307 //------------------------------------------------------------------- 00308 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00309 Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > 00310 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getBlockColMap() const 00311 { 00312 return blkColMap_; 00313 } 00314 00315 //------------------------------------------------------------------- 00316 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00317 Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > 00318 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getBlockDomainMap() const 00319 { 00320 return blkDomainMap_; 00321 } 00322 00323 //------------------------------------------------------------------- 00324 template<class LocalOrdinal, class GlobalOrdinal, class Node> 00325 Teuchos::RCP<const BlockMap<LocalOrdinal,GlobalOrdinal,Node> > 00326 BlockCrsGraph<LocalOrdinal,GlobalOrdinal,Node>::getBlockRangeMap() const 00327 { 00328 return blkRangeMap_; 00329 } 00330 00331 // 00332 // Explicit instantiation macro 00333 // 00334 // Must be expanded from within the Tpetra namespace! 00335 // 00336 00337 #define TPETRA_BLOCKCRSGRAPH_INSTANT(LO,GO,NODE) \ 00338 \ 00339 template class BlockCrsGraph< LO , GO , NODE >; 00340 00341 00342 }//namespace Tpetra 00343 00344 #endif 00345
1.7.6.1