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_->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 const 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 const 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 const 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 const 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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines