|
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_BLOCKMAP_DEF_HPP 00043 #define TPETRA_BLOCKMAP_DEF_HPP 00044 00045 #include "Tpetra_ConfigDefs.hpp" 00046 #include "Tpetra_Distributor.hpp" 00047 00048 #ifdef DOXYGEN_USE_ONLY 00049 #include "Tpetra_BlockMap_decl.hpp" 00050 #endif 00051 00052 namespace Tpetra { 00053 00054 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00055 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::BlockMap( 00056 global_size_t numGlobalBlocks, 00057 LocalOrdinal blockSize, 00058 GlobalOrdinal indexBase, 00059 const Teuchos::RCP<const Teuchos::Comm<int> > &comm, 00060 const Teuchos::RCP<Node> &node) 00061 : pointMap_(), 00062 globalNumBlocks_(numGlobalBlocks), 00063 myGlobalBlockIDs_(), 00064 pbuf_firstPointInBlock_(), 00065 view_firstPointInBlock_(), 00066 blockIDsAreContiguous_(true), 00067 constantBlockSize_(blockSize) 00068 { 00069 TEUCHOS_TEST_FOR_EXCEPTION( blockSize <= 0, std::runtime_error, 00070 "Tpetra::BlockMap::BlockMap ERROR: blockSize must be greater than 0."); 00071 00072 global_size_t numGlobalPoints = numGlobalBlocks*blockSize; 00073 00074 //we compute numLocalPoints to make sure that Tpetra::Map doesn't split 00075 //numGlobalPoints in a way that would separate the points within a block 00076 //onto different mpi processors. 00077 00078 size_t numLocalPoints = numGlobalBlocks/comm->getSize(); 00079 int remainder = numGlobalBlocks%comm->getSize(); 00080 int localProc = comm->getRank(); 00081 if (localProc < remainder) ++numLocalPoints; 00082 numLocalPoints *= blockSize; 00083 00084 //now create the point-map specifying both numGlobalPoints and numLocalPoints: 00085 pointMap_ = Teuchos::rcp(new Map<LocalOrdinal,GlobalOrdinal,Node>(numGlobalPoints, numLocalPoints, indexBase, comm, node)); 00086 00087 size_t numLocalBlocks = pointMap_->getNodeNumElements()/blockSize; 00088 size_t checkLocalBlocks = numLocalPoints/blockSize; 00089 //can there be an inconsistency here??? 00090 TEUCHOS_TEST_FOR_EXCEPTION(numLocalBlocks != checkLocalBlocks, std::runtime_error, 00091 "Tpetra::BlockMap::BlockMap ERROR: internal failure, numLocalBlocks not consistent with point-map."); 00092 00093 myGlobalBlockIDs_.resize(numLocalBlocks); 00094 pbuf_firstPointInBlock_ = node->template allocBuffer<LocalOrdinal>(numLocalBlocks+1); 00095 Teuchos::ArrayRCP<LocalOrdinal> v_firstPoints = node->template viewBufferNonConst<LocalOrdinal>(KokkosClassic::WriteOnly, numLocalBlocks+1, pbuf_firstPointInBlock_); 00096 00097 LocalOrdinal firstPoint = pointMap_->getMinLocalIndex(); 00098 GlobalOrdinal blockID = pointMap_->getMinGlobalIndex()/blockSize; 00099 for(size_t i=0; i<numLocalBlocks; ++i) { 00100 myGlobalBlockIDs_[i] = blockID++; 00101 v_firstPoints[i] = firstPoint; 00102 firstPoint += blockSize; 00103 } 00104 v_firstPoints[numLocalBlocks] = firstPoint; 00105 v_firstPoints = Teuchos::null; 00106 view_firstPointInBlock_ = node->template viewBuffer<LocalOrdinal>(numLocalBlocks+1, pbuf_firstPointInBlock_); 00107 } 00108 00109 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00110 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::BlockMap( 00111 global_size_t numGlobalBlocks, 00112 size_t numLocalBlocks, 00113 LocalOrdinal blockSize, 00114 GlobalOrdinal indexBase, 00115 const Teuchos::RCP<const Teuchos::Comm<int> > &comm, 00116 const Teuchos::RCP<Node> &node) 00117 : pointMap_(), 00118 globalNumBlocks_(numGlobalBlocks), 00119 myGlobalBlockIDs_(), 00120 pbuf_firstPointInBlock_(), 00121 view_firstPointInBlock_(), 00122 blockIDsAreContiguous_(true), 00123 constantBlockSize_(blockSize) 00124 { 00125 TEUCHOS_TEST_FOR_EXCEPTION( blockSize <= 0, std::runtime_error, 00126 "Tpetra::BlockMap::BlockMap ERROR: blockSize must be greater than 0."); 00127 00128 global_size_t numGlobalPoints = numGlobalBlocks*blockSize; 00129 if (numGlobalBlocks == Teuchos::OrdinalTraits<global_size_t>::invalid()) { 00130 numGlobalPoints = Teuchos::OrdinalTraits<global_size_t>::invalid(); 00131 } 00132 00133 size_t numLocalPoints = numLocalBlocks*blockSize; 00134 00135 //now create the point-map specifying both numGlobalPoints and numLocalPoints: 00136 pointMap_ = Teuchos::rcp(new Map<LocalOrdinal,GlobalOrdinal,Node>(numGlobalPoints, numLocalPoints, indexBase, comm, node)); 00137 00138 if (numGlobalBlocks == Teuchos::OrdinalTraits<global_size_t>::invalid()) { 00139 Teuchos::reduceAll<int, global_size_t>(*comm, Teuchos::REDUCE_SUM, 00140 1, &numLocalBlocks, &globalNumBlocks_); 00141 } 00142 00143 myGlobalBlockIDs_.resize(numLocalBlocks); 00144 pbuf_firstPointInBlock_ = node->template allocBuffer<LocalOrdinal>(numLocalBlocks+1); 00145 Teuchos::ArrayRCP<LocalOrdinal> v_firstPoints = node->template viewBufferNonConst<LocalOrdinal>(KokkosClassic::WriteOnly, numLocalBlocks+1, pbuf_firstPointInBlock_); 00146 00147 LocalOrdinal firstPoint = pointMap_->getMinLocalIndex(); 00148 GlobalOrdinal blockID = pointMap_->getMinGlobalIndex()/blockSize; 00149 for(size_t i=0; i<numLocalBlocks; ++i) { 00150 myGlobalBlockIDs_[i] = blockID++; 00151 v_firstPoints[i] = firstPoint; 00152 firstPoint += blockSize; 00153 } 00154 v_firstPoints[numLocalBlocks] = firstPoint; 00155 v_firstPoints = Teuchos::null; 00156 view_firstPointInBlock_ = node->template viewBuffer<LocalOrdinal>(numLocalBlocks+1, pbuf_firstPointInBlock_); 00157 } 00158 00159 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00160 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::BlockMap( 00161 global_size_t numGlobalBlocks, 00162 const Teuchos::ArrayView<const GlobalOrdinal>& myGlobalBlockIDs, 00163 const Teuchos::ArrayView<const GlobalOrdinal>& myFirstGlobalPointInBlocks, 00164 const Teuchos::ArrayView<const LocalOrdinal>& blockSizes, 00165 GlobalOrdinal indexBase, 00166 const Teuchos::RCP<const Teuchos::Comm<int> > &comm, 00167 const Teuchos::RCP<Node> &node) 00168 : pointMap_(), 00169 globalNumBlocks_(numGlobalBlocks), 00170 myGlobalBlockIDs_(myGlobalBlockIDs), 00171 pbuf_firstPointInBlock_(), 00172 view_firstPointInBlock_(), 00173 blockIDsAreContiguous_(false), 00174 constantBlockSize_(0) 00175 { 00176 TEUCHOS_TEST_FOR_EXCEPTION(myGlobalBlockIDs_.size()!=blockSizes.size(), std::runtime_error, 00177 "Tpetra::BlockMap::BlockMap ERROR: input myGlobalBlockIDs and blockSizes arrays must have the same length."); 00178 00179 size_t sum_blockSizes = 0; 00180 Teuchos::Array<GlobalOrdinal> myGlobalPoints; 00181 typename Teuchos::ArrayView<const LocalOrdinal>::const_iterator 00182 iter = blockSizes.begin(), iend = blockSizes.end(); 00183 size_t i = 0; 00184 for(; iter!=iend; ++iter) { 00185 LocalOrdinal bsize = *iter; 00186 sum_blockSizes += bsize; 00187 GlobalOrdinal firstPoint = myFirstGlobalPointInBlocks[i++]; 00188 for(LocalOrdinal j=0; j<bsize; ++j) { 00189 myGlobalPoints.push_back(firstPoint+j); 00190 } 00191 } 00192 00193 pointMap_ = Teuchos::rcp(new Map<LocalOrdinal,GlobalOrdinal,Node>(Teuchos::OrdinalTraits<global_size_t>::invalid(), myGlobalPoints(), indexBase, comm, node)); 00194 00195 global_size_t global_sum; 00196 Teuchos::reduceAll<int,global_size_t>(*comm, Teuchos::REDUCE_SUM, 00197 Teuchos::as<global_size_t>(myGlobalBlockIDs.size()), Teuchos::outArg(global_sum)); 00198 globalNumBlocks_ = global_sum; 00199 00200 iter = blockSizes.begin(); 00201 LocalOrdinal firstBlockSize = iter==iend ? 0 : *iter; 00202 LocalOrdinal firstPoint = pointMap_->getMinLocalIndex(); 00203 LocalOrdinal numLocalBlocks = myGlobalBlockIDs.size(); 00204 pbuf_firstPointInBlock_ = node->template allocBuffer<LocalOrdinal>(numLocalBlocks+1); 00205 Teuchos::ArrayRCP<LocalOrdinal> v_firstPoints = node->template viewBufferNonConst<LocalOrdinal>(KokkosClassic::WriteOnly, numLocalBlocks+1, pbuf_firstPointInBlock_); 00206 00207 bool blockSizesAreConstant = true; 00208 i=0; 00209 for(; iter!=iend; ++iter, ++i) { 00210 v_firstPoints[i] = firstPoint; 00211 firstPoint += *iter; 00212 if (*iter != firstBlockSize) { 00213 blockSizesAreConstant = false; 00214 } 00215 } 00216 v_firstPoints[i] = firstPoint; 00217 v_firstPoints = Teuchos::null; 00218 if (blockSizesAreConstant) constantBlockSize_ = firstBlockSize; 00219 00220 size_t num_points = pointMap_->getNodeNumElements(); 00221 TEUCHOS_TEST_FOR_EXCEPTION(sum_blockSizes != num_points, std::runtime_error, 00222 "Tpetra::BlockMap::BlockMap ERROR: internal failure, sum of block-sizes must equal pointMap->getNodeNumElements()."); 00223 00224 typename Teuchos::Array<GlobalOrdinal>::const_iterator 00225 b_iter = myGlobalBlockIDs_.begin(), b_end = myGlobalBlockIDs_.end(); 00226 GlobalOrdinal id = b_iter==b_end ? 0 : *b_iter; 00227 if (b_iter != b_end) ++b_iter; 00228 blockIDsAreContiguous_ = true; 00229 for(; b_iter != b_end; ++b_iter) { 00230 if (*b_iter != id+1) { 00231 blockIDsAreContiguous_ = false; 00232 break; 00233 } 00234 ++id; 00235 } 00236 if (blockIDsAreContiguous_ == false) { 00237 setup_noncontig_mapping(); 00238 } 00239 00240 view_firstPointInBlock_ = node->template viewBuffer<LocalOrdinal>(numLocalBlocks+1, pbuf_firstPointInBlock_); 00241 } 00242 00243 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00244 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::BlockMap(const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& pointMap, const Teuchos::ArrayView<const GlobalOrdinal>& myGlobalBlockIDs, const Teuchos::ArrayView<const LocalOrdinal>& blockSizes, const Teuchos::RCP<Node>& node) 00245 : pointMap_(pointMap), 00246 globalNumBlocks_(Teuchos::OrdinalTraits<LocalOrdinal>::invalid()), 00247 myGlobalBlockIDs_(myGlobalBlockIDs), 00248 pbuf_firstPointInBlock_(), 00249 view_firstPointInBlock_(), 00250 blockIDsAreContiguous_(false), 00251 constantBlockSize_(0) 00252 { 00253 TEUCHOS_TEST_FOR_EXCEPTION(myGlobalBlockIDs_.size()!=blockSizes.size(), std::runtime_error, 00254 "Tpetra::BlockMap::BlockMap ERROR: input myGlobalBlockIDs and blockSizes arrays must have the same length."); 00255 00256 global_size_t numLocalBlocks = myGlobalBlockIDs.size(); 00257 Teuchos::reduceAll<int,global_size_t>(*pointMap->getComm(), Teuchos::REDUCE_SUM, 1, &numLocalBlocks, &globalNumBlocks_); 00258 00259 LocalOrdinal firstPoint = pointMap->getMinLocalIndex(); 00260 size_t sum_blockSizes = 0; 00261 typename Teuchos::ArrayView<const LocalOrdinal>::const_iterator 00262 iter = blockSizes.begin(), iend = blockSizes.end(); 00263 LocalOrdinal firstBlockSize = *iter; 00264 00265 pbuf_firstPointInBlock_ = node->template allocBuffer<LocalOrdinal>(myGlobalBlockIDs.size()+1); 00266 Teuchos::ArrayRCP<LocalOrdinal> v_firstPoints = node->template viewBufferNonConst<LocalOrdinal>(KokkosClassic::WriteOnly, numLocalBlocks+1, pbuf_firstPointInBlock_); 00267 00268 bool blockSizesAreConstant = true; 00269 size_t i=0; 00270 for(; iter!=iend; ++iter, ++i) { 00271 sum_blockSizes += *iter; 00272 v_firstPoints[i] = firstPoint; 00273 firstPoint += *iter; 00274 if (*iter != firstBlockSize) { 00275 blockSizesAreConstant = false; 00276 } 00277 } 00278 v_firstPoints[i] = firstPoint; 00279 v_firstPoints = Teuchos::null; 00280 if (blockSizesAreConstant) constantBlockSize_ = firstBlockSize; 00281 00282 size_t num_points = pointMap->getNodeNumElements(); 00283 TEUCHOS_TEST_FOR_EXCEPTION(sum_blockSizes != num_points, std::runtime_error, 00284 "Tpetra::BlockMap::BlockMap ERROR: sum of block-sizes must equal pointMap->getNodeNumElements()."); 00285 00286 typename Teuchos::Array<GlobalOrdinal>::const_iterator 00287 b_iter = myGlobalBlockIDs_.begin(), b_end = myGlobalBlockIDs_.end(); 00288 GlobalOrdinal id = *b_iter; 00289 ++b_iter; 00290 blockIDsAreContiguous_ = true; 00291 for(; b_iter != b_end; ++b_iter) { 00292 if (*b_iter != id+1) { 00293 blockIDsAreContiguous_ = false; 00294 break; 00295 } 00296 ++id; 00297 } 00298 if (blockIDsAreContiguous_ == false) { 00299 setup_noncontig_mapping(); 00300 } 00301 00302 view_firstPointInBlock_ = node->template viewBuffer<LocalOrdinal>(numLocalBlocks+1, pbuf_firstPointInBlock_); 00303 } 00304 00305 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00306 void 00307 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getRemoteBlockInfo( 00308 const Teuchos::ArrayView<const GlobalOrdinal>& GBIDs, 00309 const Teuchos::ArrayView<GlobalOrdinal>& firstGlobalPointInBlocks, 00310 const Teuchos::ArrayView<LocalOrdinal>& blockSizes) const 00311 { 00312 Teuchos::RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > pbmap = 00313 convertBlockMapToPointMap(*this); 00314 00315 Teuchos::Array<int> remoteProcs(GBIDs.size()); 00316 pbmap->getRemoteIndexList(GBIDs(), remoteProcs()); 00317 00318 Tpetra::Distributor distor(pbmap->getComm()); 00319 00320 Tpetra::Array<GlobalOrdinal> exportGBIDs; 00321 Tpetra::Array<int> exportProcs; 00322 00323 distor.createFromRecvs(GBIDs(), remoteProcs(), exportGBIDs, exportProcs); 00324 00325 Tpetra::Array<GlobalOrdinal> exportFirstPointInBlocks(exportGBIDs.size()); 00326 Tpetra::Array<LocalOrdinal> exportSizes(exportGBIDs.size()); 00327 00328 typename Teuchos::Array<GlobalOrdinal>::const_iterator 00329 iter = exportGBIDs.begin(), 00330 iter_end = exportGBIDs.end(); 00331 for(int i=0; iter!=iter_end; ++iter, ++i) { 00332 GlobalOrdinal gbid = *iter; 00333 LocalOrdinal lbid = getLocalBlockID(gbid); 00334 exportFirstPointInBlocks[i] = getFirstGlobalPointInLocalBlock(lbid); 00335 exportSizes[i] = getLocalBlockSize(lbid); 00336 } 00337 00338 size_t numPackets = 1; 00339 distor.doPostsAndWaits(exportFirstPointInBlocks().getConst(), 00340 numPackets, firstGlobalPointInBlocks); 00341 00342 distor.doPostsAndWaits(exportSizes().getConst(), numPackets, blockSizes); 00343 } 00344 00345 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00346 void 00347 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::setup_noncontig_mapping() 00348 { 00349 typedef typename Teuchos::Array<GlobalOrdinal>::size_type Tsize_t; 00350 for(Tsize_t i=0; i<myGlobalBlockIDs_.size(); ++i) { 00351 LocalOrdinal li = i; 00352 // TODO: Use Tpetra::Details::HashTable here instead of std::map. 00353 map_global_to_local_.insert(std::make_pair(myGlobalBlockIDs_[i],li)); 00354 } 00355 } 00356 00357 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00358 global_size_t 00359 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getGlobalNumBlocks() const 00360 { 00361 return globalNumBlocks_; 00362 } 00363 00364 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00365 size_t 00366 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getNodeNumBlocks() const 00367 { 00368 return myGlobalBlockIDs_.size(); 00369 } 00370 00371 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00372 Teuchos::ArrayView<const GlobalOrdinal> 00373 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getNodeBlockIDs() const 00374 { 00375 return myGlobalBlockIDs_(); 00376 } 00377 00378 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00379 bool 00380 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::isBlockSizeConstant() const 00381 { return constantBlockSize_ != 0; } 00382 00383 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00384 Teuchos::ArrayRCP<const LocalOrdinal> 00385 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getNodeFirstPointInBlocks() const 00386 { 00387 return view_firstPointInBlock_; 00388 } 00389 00390 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00391 Teuchos::ArrayRCP<const LocalOrdinal> 00392 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getNodeFirstPointInBlocks_Device() const 00393 { 00394 return pbuf_firstPointInBlock_; 00395 } 00396 00397 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00398 GlobalOrdinal 00399 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getGlobalBlockID(LocalOrdinal localBlockID) const 00400 { 00401 LocalOrdinal invalid = Teuchos::OrdinalTraits<LocalOrdinal>::invalid(); 00402 if (localBlockID < 0 || localBlockID >= myGlobalBlockIDs_.size()) { 00403 return invalid; 00404 } 00405 00406 return myGlobalBlockIDs_[localBlockID]; 00407 } 00408 00409 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00410 LocalOrdinal 00411 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getLocalBlockID(GlobalOrdinal globalBlockID) const 00412 { 00413 LocalOrdinal invalid = Teuchos::OrdinalTraits<LocalOrdinal>::invalid(); 00414 if (myGlobalBlockIDs_.size() == 0) { 00415 return invalid; 00416 } 00417 00418 if (blockIDsAreContiguous_ == false) { 00419 // TODO: Use Tpetra::Details::HashTable instead of std::map. 00420 typename std::map<GlobalOrdinal,LocalOrdinal>::const_iterator iter = 00421 map_global_to_local_.find(globalBlockID); 00422 if (iter == map_global_to_local_.end()) return invalid; 00423 return iter->second; 00424 } 00425 00426 LocalOrdinal localBlockID = globalBlockID - myGlobalBlockIDs_[0]; 00427 LocalOrdinal numLocalBlocks = myGlobalBlockIDs_.size(); 00428 00429 if (localBlockID < 0 || localBlockID >= numLocalBlocks) { 00430 return invalid; 00431 } 00432 00433 return localBlockID; 00434 } 00435 00436 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00437 LocalOrdinal 00438 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getLocalBlockSize(LocalOrdinal localBlockID) const 00439 { 00440 if (constantBlockSize_ != 0) { 00441 return constantBlockSize_; 00442 } 00443 00444 //should this be a debug-mode-only range check? 00445 if (localBlockID < 0 || localBlockID >= view_firstPointInBlock_.size()) { 00446 throw std::runtime_error("Tpetra::BlockMap::getLocalBlockSize ERROR: localBlockID out of range."); 00447 } 00448 00449 return view_firstPointInBlock_[localBlockID+1]-view_firstPointInBlock_[localBlockID]; 00450 } 00451 00452 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00453 LocalOrdinal 00454 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getFirstLocalPointInLocalBlock(LocalOrdinal localBlockID) const 00455 { 00456 //should this be a debug-mode-only range check? 00457 if (localBlockID < 0 || localBlockID >= view_firstPointInBlock_.size()) { 00458 throw std::runtime_error("Tpetra::BlockMap::getFirstLocalPointInLocalBlock ERROR: localBlockID out of range."); 00459 } 00460 00461 return view_firstPointInBlock_[localBlockID]; 00462 } 00463 00464 template<class LocalOrdinal,class GlobalOrdinal,class Node> 00465 GlobalOrdinal 00466 BlockMap<LocalOrdinal,GlobalOrdinal,Node>::getFirstGlobalPointInLocalBlock(LocalOrdinal localBlockID) const 00467 { 00468 //should this be a debug-mode-only range check? 00469 if (localBlockID < 0 || localBlockID >= view_firstPointInBlock_.size()) { 00470 throw std::runtime_error("Tpetra::BlockMap::getFirstGlobalPointInLocalBlock ERROR: localBlockID out of range."); 00471 } 00472 00473 return pointMap_->getGlobalElement(view_firstPointInBlock_[localBlockID]); 00474 } 00475 00476 }//namespace Tpetra 00477 00478 // 00479 // Explicit instantiation macro 00480 // 00481 // Must be expanded from within the Tpetra namespace! 00482 // 00483 00484 #define TPETRA_BLOCKMAP_INSTANT(LO,GO,NODE) \ 00485 \ 00486 template class BlockMap< LO , GO , NODE >; 00487 00488 #endif
1.7.6.1