Epetra Package Browser (Single Doxygen Collection) Development
Epetra_CrsGraphData.cpp
Go to the documentation of this file.
00001 /*
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //               Epetra: Linear Algebra Services Package
00006 //                 Copyright 2011 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ************************************************************************
00041 //@HEADER
00042 */
00043 
00044 #include "Epetra_ConfigDefs.h"
00045 #include "Epetra_CrsGraphData.h"
00046 #include "Epetra_Import.h"
00047 #include "Epetra_Export.h"
00048 //#include "Epetra_ConfigDefs.h" //DATA_DEBUG
00049 
00050 //=============================================================================
00051 Epetra_CrsGraphData::Epetra_CrsGraphData(Epetra_DataAccess CV, const Epetra_BlockMap& RowMap, bool StaticProfile)
00052   // maps
00053   : RowMap_(RowMap),
00054     ColMap_(RowMap),
00055     DomainMap_(RowMap),
00056     RangeMap_(RowMap),
00057     // importer & exporter
00058     Importer_(0),
00059     Exporter_(0),
00060     // booleans
00061     HaveColMap_(false),
00062     Filled_(false),
00063     Allocated_(false),
00064     // for non-static profile, we insert always into sorted lists, so the
00065     // graph will always be sorted. The same holds for the redundancies.
00066     Sorted_(!StaticProfile),
00067     StorageOptimized_(false),
00068     NoRedundancies_(!StaticProfile),
00069     IndicesAreGlobal_(false),
00070     IndicesAreLocal_(false),
00071     IndicesAreContiguous_(false),
00072     LowerTriangular_(true),
00073     UpperTriangular_(true),
00074     NoDiagonal_(true),
00075     GlobalConstantsComputed_(false),
00076     StaticProfile_(StaticProfile),
00077     SortGhostsAssociatedWithEachProcessor_(false),
00078 
00079     // ints
00080     IndexBase_(RowMap.IndexBase64()),
00081     NumGlobalEntries_(0),
00082     NumGlobalBlockRows_(RowMap.NumGlobalElements64()),
00083     NumGlobalBlockCols_(NumGlobalBlockRows_),
00084     NumGlobalBlockDiagonals_(0),
00085     NumMyEntries_(0),
00086     NumMyBlockRows_(RowMap.NumMyElements()),
00087     NumMyBlockCols_(NumMyBlockRows_),
00088     NumMyBlockDiagonals_(0),
00089     MaxRowDim_(RowMap.MaxElementSize()),
00090     MaxColDim_(MaxRowDim_),
00091     GlobalMaxRowDim_(RowMap.MaxElementSize()),
00092     GlobalMaxColDim_(GlobalMaxRowDim_),
00093     MaxNumNonzeros_(0),
00094     GlobalMaxNumNonzeros_(0),
00095     NumGlobalNonzeros_(0),
00096     NumGlobalRows_(RowMap.NumGlobalPoints64()),
00097     NumGlobalCols_(NumGlobalRows_),
00098     NumGlobalDiagonals_(0),
00099     NumMyNonzeros_(0),
00100     NumMyRows_(RowMap.NumMyPoints()),
00101     NumMyCols_(NumMyRows_),
00102     NumMyDiagonals_(0),
00103     MaxNumIndices_(0),
00104     GlobalMaxNumIndices_(0),
00105     NumTempColIndices_(0),
00106     NumAllocatedIndicesPerRow_(0),
00107     NumIndicesPerRow_(0),
00108     IndexOffset_(0),
00109     CV_(CV),
00110     data(0)
00111 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00112   ,LL_data(0)
00113 #endif
00114 {
00115   if(RowMap.GlobalIndicesInt() == false && RowMap.GlobalIndicesLongLong() == false)
00116     throw "Epetra_CrsGraphData::Epetra_CrsGraphData: cannot be called without any index type for RowMap";
00117 
00118   data = new IndexData<int>(NumMyBlockRows_, ! StaticProfile);
00119 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00120   LL_data = new IndexData<long long>(RowMap.GlobalIndicesLongLong() ? NumMyBlockRows_ : 0, ! StaticProfile);
00121 #endif
00122   //cout << "--CRSGD created(rowmap ctr), addr: " << this << std::endl; //DATA_DEBUG
00123 }
00124 
00125 //=============================================================================
00126 Epetra_CrsGraphData::Epetra_CrsGraphData(Epetra_DataAccess CV,
00127            const Epetra_BlockMap& RowMap,
00128            const Epetra_BlockMap& ColMap, bool StaticProfile)
00129   // maps
00130   : RowMap_(RowMap),
00131     ColMap_(ColMap),
00132     DomainMap_(ColMap),
00133     RangeMap_(RowMap),
00134     // importer & exporter
00135     Importer_(0),
00136     Exporter_(0),
00137     // booleans
00138     HaveColMap_(true),
00139     Filled_(false),
00140     Allocated_(false),
00141     Sorted_(!StaticProfile),
00142     StorageOptimized_(false),
00143     NoRedundancies_(!StaticProfile),
00144     IndicesAreGlobal_(false),
00145     IndicesAreLocal_(false),
00146     IndicesAreContiguous_(false),
00147     LowerTriangular_(true),
00148     UpperTriangular_(true),
00149     NoDiagonal_(true),
00150     GlobalConstantsComputed_(false),
00151     StaticProfile_(StaticProfile),
00152     SortGhostsAssociatedWithEachProcessor_(false),
00153     // ints
00154     IndexBase_(RowMap.IndexBase64()),
00155     NumGlobalEntries_(0),
00156     NumGlobalBlockRows_(RowMap.NumGlobalElements64()),
00157     NumGlobalBlockCols_(ColMap.NumGlobalElements64()),
00158     NumGlobalBlockDiagonals_(0),
00159     NumMyEntries_(0),
00160     NumMyBlockRows_(RowMap.NumMyElements()),
00161     NumMyBlockCols_(ColMap.NumMyElements()),
00162     NumMyBlockDiagonals_(0),
00163     MaxRowDim_(RowMap.MaxElementSize()),
00164     MaxColDim_(ColMap.MaxElementSize()),
00165     GlobalMaxRowDim_(RowMap.MaxElementSize()),
00166     GlobalMaxColDim_(ColMap.MaxElementSize()),
00167     MaxNumNonzeros_(0),
00168     GlobalMaxNumNonzeros_(0),
00169     NumGlobalNonzeros_(0),
00170     NumGlobalRows_(RowMap.NumGlobalPoints64()),
00171     NumGlobalCols_(ColMap.NumGlobalPoints64()),
00172     NumGlobalDiagonals_(0),
00173     NumMyNonzeros_(0),
00174     NumMyRows_(RowMap.NumMyPoints()),
00175     NumMyCols_(ColMap.NumMyPoints()),
00176     NumMyDiagonals_(0),
00177     MaxNumIndices_(0),
00178     GlobalMaxNumIndices_(0),
00179     NumTempColIndices_(0),
00180     NumAllocatedIndicesPerRow_(0),
00181     NumIndicesPerRow_(0),
00182     IndexOffset_(0),
00183     CV_(CV),
00184     data(0)
00185 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00186   ,LL_data(0)
00187 #endif
00188 {
00189   if(RowMap.GlobalIndicesInt() == false && RowMap.GlobalIndicesLongLong() == false)
00190     throw "Epetra_CrsGraphData::Epetra_CrsGraphData: cannot be called without any index type for RowMap";
00191 
00192   if(!RowMap.GlobalIndicesTypeMatch(ColMap))
00193     throw "Epetra_CrsGraphData::Epetra_CrsGraphData: cannot be called with different indices types for RowMap and ColMap";
00194 
00195   data = new IndexData<int>(NumMyBlockRows_, ! StaticProfile);
00196 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00197   LL_data = new IndexData<long long>(RowMap.GlobalIndicesLongLong() ? NumMyBlockRows_ : 0, ! StaticProfile);
00198 #endif
00199   //cout << "--CRSGD created(rowmap&colmap ctr), addr: " << this << std::endl; //DATA_DEBUG
00200 }
00201 
00202 //=============================================================================
00203 Epetra_CrsGraphData::~Epetra_CrsGraphData() {
00204 
00205   if(data->Indices_ != 0 && !StorageOptimized_) {
00206     for (int i=0; i<NumMyBlockRows_; i++) {
00207       data->Indices_[i] = 0;
00208     }
00209     delete[] data->Indices_;
00210     data->Indices_ = 0;
00211   }
00212 
00213 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00214   if(LL_data->Indices_ != 0 && !StorageOptimized_) {
00215     for (int i=0; i<NumMyBlockRows_; i++) {
00216       LL_data->Indices_[i] = 0;
00217     }
00218     delete[] LL_data->Indices_;
00219     LL_data->Indices_ = 0;
00220   }
00221 #endif
00222 
00223   if (data->TempColIndices_ != 0) {
00224     delete [] data->TempColIndices_;
00225     data->TempColIndices_ = 0;
00226   }
00227 
00228 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00229   if (LL_data->TempColIndices_ != 0) {
00230     delete [] LL_data->TempColIndices_;
00231     LL_data->TempColIndices_ = 0;
00232   }
00233 #endif
00234 
00235   delete data;
00236 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00237   delete LL_data;
00238 #endif
00239 
00240   if(Importer_ != 0) {
00241     delete Importer_;
00242     Importer_ = 0;
00243   }
00244   if(Exporter_ != 0) {
00245     delete Exporter_;
00246     Importer_ = 0;
00247   }
00248 
00249   NumMyBlockRows_ = 0;  // are these needed?
00250   Filled_ = false;      // they're about to go out of scope, after all
00251   Allocated_ = false;
00252 
00253   //cout << "--CRSGD destroyed, addr: " << this << std::endl; //DATA_DEBUG
00254 }
00255 
00256 //==========================================================================
00257 int Epetra_CrsGraphData::MakeImportExport() {
00258   // Create Import object for use by matrix classes.    This is only needed if ColMap and DomainMap are different
00259   if (!ColMap_.SameAs(DomainMap_)) {
00260     if (Importer_ != 0) {
00261       delete Importer_;
00262       Importer_ = 0;
00263     }
00264     Importer_ = new Epetra_Import(ColMap_, DomainMap_);
00265   }
00266 
00267   // Now see if we need to define an export map.  This is only needed if RowMap and RangeMap are different
00268   if (!RowMap_.SameAs(RangeMap_)) {
00269     if (Exporter_ != 0) {
00270       delete Exporter_;
00271       Exporter_ = 0;
00272     }
00273     Exporter_ = new Epetra_Export(RowMap_, RangeMap_); // Create Export object.
00274   }
00275 
00276   return(0);
00277 }
00278 
00279 //==========================================================================
00280 int Epetra_CrsGraphData::ReAllocateAndCast(char*& UserPtr, int& Length, const int IntPacketSizeTimesNumTrans) {
00281   if(IntPacketSizeTimesNumTrans > Length) {
00282     if(Length > 0)
00283       delete[] UserPtr;
00284     Length = IntPacketSizeTimesNumTrans;
00285     int* newPtr = new int[Length];
00286     UserPtr = reinterpret_cast<char*> (newPtr);
00287   }
00288   return(0);
00289 }
00290 
00291 //==========================================================================
00292 void Epetra_CrsGraphData::Print(std::ostream& os, int level) const {
00293   bool four_bit = (level >= 4);      // 4-bit = BlockMaps
00294   bool two_bit = ((level % 4) >= 2); // 2-bit = Indices
00295   bool one_bit = ((level % 2) == 1); // 1-bit = Everything else
00296 
00297   os << "\n***** CrsGraphData (output level " << level << ") *****" << std::endl;
00298 
00299   if(four_bit) {
00300     os << "RowMap_:\n" << RowMap_ << std::endl;
00301     os << "ColMap_:\n" << ColMap_ << std::endl;
00302     os << "DomainMap_:\n" << DomainMap_ << std::endl;
00303     os << "RangeMap_:\n" << RangeMap_ << std::endl;
00304   }
00305 
00306   if(one_bit) {
00307     os.width(26); os << "HaveColMap_: "              << HaveColMap_;
00308     os.width(25); os << "Filled_: "                  << Filled_;
00309     os.width(25); os << "Allocated_: "               << Allocated_;
00310     os.width(25); os << "Sorted_: "                  << Sorted_ << std::endl;
00311     os.width(26); os << "StorageOptimized_: "        << StorageOptimized_;
00312     os.width(25); os << "SortGhostsAssociatedWithEachProcessor_: " << SortGhostsAssociatedWithEachProcessor_;
00313     os.width(25); os << "NoRedundancies_: "          << NoRedundancies_;
00314     os.width(25); os << "IndicesAreGlobal_: "        << IndicesAreGlobal_;
00315     os.width(25); os << "IndicesAreLocal_: "         << IndicesAreLocal_ << std::endl;
00316     os.width(26); os << "IndicesAreContiguous_: "    << IndicesAreContiguous_;
00317     os.width(25); os << "LowerTriangular_: "         << LowerTriangular_;
00318     os.width(25); os << "UpperTriangular_: "         << UpperTriangular_;
00319     os.width(25); os << "NoDiagonal_: "              << NoDiagonal_ << std::endl;
00320     os.width(25); os << "GlobalConstantsComputed_: " << GlobalConstantsComputed_ << std::endl;
00321     os.width(25); os << "StaticProfile_: " << StaticProfile_ << std::endl << std::endl;
00322 
00323     os.width(10); os << "NGBR_: " << NumGlobalBlockRows_;
00324     os.width(10); os << "NGBC_: " << NumGlobalBlockCols_;
00325     os.width(10); os << "NGBD_: " << NumGlobalBlockDiagonals_;
00326     os.width(10); os << "NGE_: "  << NumGlobalEntries_;
00327     os.width(10); os << "NGR_: "  << NumGlobalRows_;
00328     os.width(10); os << "NGC_: "  << NumGlobalCols_;
00329     os.width(10); os << "NGD_: "  << NumGlobalDiagonals_;
00330     os.width(10); os << "NGN_: "  << NumGlobalNonzeros_;
00331     os.width(10); os << "IB_: "   << IndexBase_ << std::endl;
00332     os.width(10); os << "GMRD_: " << GlobalMaxRowDim_;
00333     os.width(11); os << "GMCD_: " << GlobalMaxColDim_;
00334     os.width(11); os << "GMNI_: " << GlobalMaxNumIndices_;
00335     os.width(11); os << "NMBR_: " << NumMyBlockRows_;
00336     os.width(10); os << "NMBC_: " << NumMyBlockCols_;
00337     os.width(10); os << "NMBD_: " << NumMyBlockDiagonals_;
00338     os.width(10); os << "NME_: "  << NumMyEntries_;
00339     os.width(10); os << "NMR_: "  << NumMyRows_;
00340     os.width(10); os << "CV_: " << CV_ << std::endl;
00341     os.width(10); os << "NMC_: "  << NumMyCols_;
00342     os.width(10); os << "NMD_: "  << NumMyDiagonals_;
00343     os.width(10); os << "NMN_: "  << NumMyNonzeros_;
00344     os.width(10); os << "MRD_: "  << MaxRowDim_;
00345     os.width(11); os << "MCD_: "  << MaxColDim_;
00346     os.width(11); os << "MNI_: "  << MaxNumIndices_;
00347     os.width(11); os << "MNN_: "  << MaxNumNonzeros_;
00348     os.width(11); os << "GMNN_: " << GlobalMaxNumNonzeros_;
00349     os.width(11); os << "RC: " << ReferenceCount() << std::endl << std::endl;
00350 
00351     os << "NIPR_: " << NumIndicesPerRow_ << std::endl;
00352     os << "NAIPR_: " << NumAllocatedIndicesPerRow_ << std::endl;
00353     os << "IndexOffset_: " << IndexOffset_ << std::endl;
00354   if(RowMap_.GlobalIndicesInt() || (RowMap_.GlobalIndicesLongLong() && IndicesAreLocal_))
00355       os << "All_Indices_: " << data->All_Indices_ << std::endl;
00356 
00357   if(RowMap_.GlobalIndicesLongLong() && IndicesAreGlobal_)
00358 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00359       os << "All_Indices_: " << LL_data->All_Indices_ << std::endl;
00360 #else
00361       throw "Epetra_CrsGraphData::Print: GlobalIndicesLongLong but no long long API";
00362 #endif
00363   }
00364 
00365   if(two_bit) {
00366   if(RowMap_.GlobalIndicesInt() || (RowMap_.GlobalIndicesLongLong() && IndicesAreLocal_))
00367   {
00368       os << "Indices_: " << data->Indices_ << std::endl;
00369     if(data->Indices_ != 0) {
00370         for(int i = 0; i < NumMyBlockRows_; i++) {
00371     os << "Indices_[" << i << "]: (" << data->Indices_[i] << ") ";
00372     if(data->Indices_[i] != 0) {
00373       for(int j = 0; j < NumAllocatedIndicesPerRow_[i]; j++)
00374         os << data->Indices_[i][j] << " ";
00375     }
00376     os << std::endl;
00377       }
00378    }
00379   }
00380 
00381   if(RowMap_.GlobalIndicesLongLong() && IndicesAreGlobal_)
00382   {
00383 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00384       os << "Indices_: " << LL_data->Indices_ << std::endl;
00385     if(LL_data->Indices_ != 0) {
00386         for(int i = 0; i < NumMyBlockRows_; i++) {
00387     os << "Indices_[" << i << "]: (" << LL_data->Indices_[i] << ") ";
00388     if(LL_data->Indices_[i] != 0) {
00389       for(int j = 0; j < NumAllocatedIndicesPerRow_[i]; j++)
00390         os << LL_data->Indices_[i][j] << " ";
00391     }
00392     os << std::endl;
00393       }
00394   }
00395 #else
00396       throw "Epetra_CrsGraphData::Print: GlobalIndicesLongLong but no long long API";
00397 #endif
00398    }
00399   }
00400 
00401   os << "***** End CrsGraphData *****" << std::endl;
00402 }
00403 
00404 
00405 //==========================================================================
00406 template<typename int_type>
00407 void
00408 Epetra_CrsGraphData::EntriesInOneRow<int_type>::AddEntry (const int_type Col)
00409 {
00410   // first check the last element (or if line is still empty)
00411   if ( (entries_.size()==0) || ( entries_.back() < Col) )
00412     {
00413       entries_.push_back(Col);
00414       return;
00415     }
00416 
00417   // do a binary search to find the place where to insert:
00418   typename std::vector<int_type>::iterator it = std::lower_bound(entries_.begin(),
00419                 entries_.end(),
00420                 Col);
00421 
00422   // If this entry is a duplicate, exit immediately
00423   if (*it == Col)
00424     return;
00425 
00426   // Insert at the right place in the vector. Vector grows automatically to
00427   // fit elements. Always doubles its size.
00428   entries_.insert(it, Col);
00429 }
00430 
00431 
00432 //==========================================================================
00433 template<typename int_type>
00434 void
00435 Epetra_CrsGraphData::EntriesInOneRow<int_type>::AddEntries (const int  numCols,
00436              const int_type *Indices)
00437 {
00438   if (numCols == 0)
00439     return;
00440 
00441   // Check whether the indices are sorted. Can do more efficient then.
00442   bool indicesAreSorted = true;
00443   for (int i=1; i<numCols; ++i)
00444     if (Indices[i] <= Indices[i-1]) {
00445       indicesAreSorted = false;
00446       break;
00447     }
00448 
00449   if (indicesAreSorted && numCols > 3) {
00450     const int_type * curInput = &Indices[0];
00451     int_type col = *curInput;
00452     const int_type * endInput = &Indices[numCols];
00453 
00454     // easy case: list of entries is empty or all entries are smaller than
00455     // the ones to be inserted
00456     if (entries_.size() == 0 || entries_.back() < col)
00457     {
00458       entries_.insert(entries_.end(), &Indices[0], &Indices[numCols]);
00459       return;
00460     }
00461 
00462     // find a possible insertion point for the first entry. check whether
00463     // the first entry is a duplicate before actually doing something.
00464     typename std::vector<int_type>::iterator it =
00465       std::lower_bound(entries_.begin(), entries_.end(), col);
00466     while (*it == col) {
00467       ++curInput;
00468       if (curInput == endInput)
00469         break;
00470       col = *curInput;
00471 
00472       // check the very next entry in the current array
00473       ++it;
00474       if (it == entries_.end())
00475         break;
00476       if (*it > col)
00477         break;
00478       if (*it == col)
00479         continue;
00480 
00481       // ok, it wasn't the very next one, do a binary search to find the
00482       // insert point
00483       it = std::lower_bound(it, entries_.end(), col);
00484       if (it == entries_.end())
00485         break;
00486     }
00487 
00488     // all input entries were duplicates.
00489     if (curInput == endInput)
00490       return;
00491 
00492     // Resize vector by just inserting the list at the correct point. Note
00493     // that the list will not yet be sorted, but rather have the insert
00494     // indices in the middle and the old indices from the list on the
00495     // end. Next we will have to merge the two lists.
00496     const int pos1 = (int) (it - entries_.begin());
00497     entries_.insert (it, curInput, endInput);
00498     it = entries_.begin() + pos1;
00499 
00500     // Now merge the two lists...
00501     typename std::vector<int_type>::iterator it2 = it + (endInput - curInput);
00502 
00503     // As long as there are indices both in the end of the entries list and
00504     // in the input list, always continue with the smaller index.
00505     while (curInput != endInput && it2 != entries_.end())
00506     {
00507       if (*curInput < *it2)
00508         *it++ = *curInput++;
00509       else if (*curInput == *it2)
00510       {
00511         *it++ = *it2++;
00512         ++curInput;
00513       }
00514       else
00515         *it++ = *it2++;
00516     }
00517     // in case there are indices left in the input list or in the end of
00518     // entries, we have to use the entries that are left. Only one of the
00519     // two while loops will actually be entered.
00520     while (curInput != endInput)
00521       *it++ = *curInput++;
00522 
00523     while (it2 != entries_.end())
00524       *it++ = *it2++;
00525 
00526     // resize and return
00527     const int new_size = (int) (it - entries_.begin());
00528     entries_.resize (new_size);
00529     return;
00530   }
00531 
00532   // for unsorted or just a few indices, go to the one-by-one entry
00533   // function.
00534   for (int i=0; i<numCols; ++i)
00535     AddEntry(Indices[i]);
00536 }
00537 
00538 // explicit instantiation.
00539 template void Epetra_CrsGraphData::EntriesInOneRow<int>::AddEntry(const int Col);
00540 template void Epetra_CrsGraphData::EntriesInOneRow<int>::AddEntries(const int numCols, const int *Indices);
00541 
00542 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00543 template void Epetra_CrsGraphData::EntriesInOneRow<long long>::AddEntry(const long long Col);
00544 template void Epetra_CrsGraphData::EntriesInOneRow<long long>::AddEntries(const int numCols, const long long *Indices);
00545 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines