Epetra Package Browser (Single Doxygen Collection) Development
Epetra_FECrsGraph.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 #include "Epetra_FECrsGraph.h"
00044 #include "Epetra_Import.h"
00045 #include "Epetra_Export.h"
00046 #include "Epetra_Distributor.h"
00047 #include "Epetra_Util.h"
00048 #include "Epetra_Comm.h"
00049 #include "Epetra_HashTable.h"
00050 #include "Epetra_BlockMap.h"
00051 #include "Epetra_Map.h"
00052 #include "Epetra_RowMatrix.h"
00053 #include "Epetra_IntSerialDenseVector.h"
00054 #include "Epetra_SerialDenseVector.h"
00055 #include "Epetra_OffsetIndex.h"
00056 
00057 //-------------------------------------------------------------------------------
00058 Epetra_FECrsGraph::Epetra_FECrsGraph(Epetra_DataAccess CV,
00059              const Epetra_BlockMap& rowMap,
00060              int* numIndicesPerRow,
00061              bool ignoreNonLocalEntries,
00062              bool buildNonlocalGraph)
00063   : Epetra_CrsGraph(CV, rowMap, numIndicesPerRow),
00064     myFirstRow_(0),
00065     myNumRows_(0),
00066     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00067     nonlocalGraph_ (NULL),
00068     buildNonlocalGraph_ (buildNonlocalGraph)
00069 {
00070 }
00071 
00072 //-------------------------------------------------------------------------------
00073 Epetra_FECrsGraph::Epetra_FECrsGraph(Epetra_DataAccess CV,
00074              const Epetra_BlockMap& rowMap,
00075              int numIndicesPerRow,
00076              bool ignoreNonLocalEntries,
00077              bool buildNonlocalGraph)
00078   : Epetra_CrsGraph(CV, rowMap, numIndicesPerRow),
00079     myFirstRow_(0),
00080     myNumRows_(0),
00081     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00082     nonlocalGraph_ (NULL),
00083     buildNonlocalGraph_ (buildNonlocalGraph)
00084 {
00085   myFirstRow_ = rowMap.MinMyGID();
00086   myNumRows_ = rowMap.NumMyElements();
00087 }
00088 
00089 //-------------------------------------------------------------------------------
00090 Epetra_FECrsGraph::Epetra_FECrsGraph(Epetra_DataAccess CV,
00091              const Epetra_BlockMap& rowMap,
00092              const Epetra_BlockMap& colMap,
00093              int* numIndicesPerRow,
00094              bool ignoreNonLocalEntries,
00095              bool buildNonlocalGraph)
00096   : Epetra_CrsGraph(CV, rowMap, colMap, numIndicesPerRow),
00097     myFirstRow_(0),
00098     myNumRows_(0),
00099     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00100     nonlocalGraph_ (NULL),
00101     buildNonlocalGraph_ (buildNonlocalGraph)
00102 {
00103   myFirstRow_ = rowMap.MinMyGID();
00104   myNumRows_ = rowMap.NumMyElements();
00105 }
00106 
00107 //-------------------------------------------------------------------------------
00108 Epetra_FECrsGraph::Epetra_FECrsGraph(Epetra_DataAccess CV,
00109              const Epetra_BlockMap& rowMap,
00110              const Epetra_BlockMap& colMap,
00111              int numIndicesPerRow,
00112              bool ignoreNonLocalEntries,
00113              bool buildNonlocalGraph)
00114   : Epetra_CrsGraph(CV, rowMap, colMap, numIndicesPerRow),
00115     myFirstRow_(0),
00116     myNumRows_(0),
00117     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00118     nonlocalGraph_ (NULL),
00119     buildNonlocalGraph_ (buildNonlocalGraph)
00120 {
00121   myFirstRow_ = rowMap.MinMyGID();
00122   myNumRows_ = rowMap.NumMyElements();
00123 }
00124 
00125 //-------------------------------------------------------------------------------
00126 Epetra_FECrsGraph::~Epetra_FECrsGraph()
00127 {
00128   DeleteMemory();
00129 }
00130 
00131 //----------------------------------------------------------------------------
00132 void Epetra_FECrsGraph::DeleteMemory()
00133 {
00134   if (nonlocalGraph_ != 0)
00135     delete nonlocalGraph_;
00136   // nothing else to do here, since the STL map has an appropriate
00137   // destructor
00138 }
00139 
00140 //----------------------------------------------------------------------------
00141 int Epetra_FECrsGraph::InsertGlobalIndices(int numRows, const int* rows,
00142              int numCols, const int* cols)
00143 {
00144   int returncode = 0;
00145   int err = 0;
00146 
00147   Epetra_CrsGraph* thisgraph = static_cast<Epetra_CrsGraph*>(this);
00148 
00149   for(int i=0; i<numRows; ++i) {
00150     const int LID = thisgraph->LRID(rows[i]);
00151     if (LID > -1) {
00152       thisgraph->SetIndicesAreGlobal(true);
00153       err = thisgraph->InsertIndicesIntoSorted(LID, numCols,
00154           const_cast<int*>(cols));
00155     }
00156     else {
00157       nonlocalRowData_[rows[i]].AddEntries(numCols,cols);
00158     }
00159 
00160     if (err < 0) return (err);
00161     if (err > 0) returncode = err;
00162   }
00163 
00164   return(returncode);
00165 }
00166 
00167 //----------------------------------------------------------------------------
00168 int Epetra_FECrsGraph::GlobalAssemble(bool callFillComplete)
00169 {
00170   return GlobalAssemble (static_cast<Epetra_Map&>(this->CrsGraphData_->RowMap_), 
00171       static_cast<Epetra_Map&>(this->CrsGraphData_->RowMap_),
00172       callFillComplete);
00173 }
00174 
00175 //----------------------------------------------------------------------------
00176 int Epetra_FECrsGraph::GlobalAssemble(const Epetra_Map& domain_map,
00177                                       const Epetra_Map& range_map,
00178                                       bool callFillComplete)
00179 {
00180   if (Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
00181     if (callFillComplete) {
00182       EPETRA_CHK_ERR( FillComplete(domain_map, range_map) );
00183     }
00184     return(0);
00185   }
00186 
00187   //In this method we need to gather all the non-local (overlapping) data
00188   //that's been input on each processor, into the
00189   //non-overlapping distribution defined by the map that 'this' graph was
00190   //constructed with.
00191 
00192   // First build a map that describes our nonlocal data.
00193   // We'll use the arbitrary distribution constructor of Map.
00194   // Start by extracting the column numbers from the STL map.
00195 
00196   const int numRows = nonlocalRowData_.size();
00197   int * presentRowIndices = new int[numRows];
00198   std::map<int,Epetra_CrsGraphData::EntriesInOneRow>::iterator nonlocalRows 
00199     = nonlocalRowData_.begin();
00200   for (int i=0 ; nonlocalRows != nonlocalRowData_.end(); ++nonlocalRows, ++i)
00201     presentRowIndices[i] = nonlocalRows->first;
00202 
00203   Epetra_Map* sourceMap = new Epetra_Map(-1, nonlocalRowData_.size(),
00204           presentRowIndices,
00205                                          Map().IndexBase(), Map().Comm());
00206 
00207   //If sourceMap has global size 0, then no nonlocal data exists and we can
00208   //skip most of this function.
00209   if (sourceMap->NumGlobalElements() < 1) {
00210     if (callFillComplete) {
00211       EPETRA_CHK_ERR( FillComplete(domain_map, range_map) );
00212     }
00213     delete [] presentRowIndices;
00214     delete sourceMap;
00215     return(0);
00216   }
00217 
00218   //We also need to build a column-map, containing the columns in our
00219   //nonlocal data. To do that, create a list of all column-indices that
00220   //occur in our nonlocal rows. This is most easily done using the
00221   //EntriesInOneRow struct, since that is sorted.
00222   Epetra_CrsGraphData::EntriesInOneRow allColumns;
00223   for (nonlocalRows = nonlocalRowData_.begin(); 
00224        nonlocalRows != nonlocalRowData_.end(); ++nonlocalRows)
00225     allColumns.AddEntries(nonlocalRows->second.entries_.size(),
00226        &nonlocalRows->second.entries_[0]);
00227 
00228   Epetra_Map* colMap = new Epetra_Map(-1, allColumns.entries_.size(),
00229              &allColumns.entries_[0],
00230                                       Map().IndexBase(), Map().Comm());
00231 
00232   //now we need to create a graph with sourceMap and colMap, and fill it with
00233   //our nonlocal data so we can then export it to the correct owning processors
00234 
00235   int * rowLengths = new int[numRows];
00236   {
00237     int i = 0;
00238     for (nonlocalRows = nonlocalRowData_.begin(); 
00239   nonlocalRows != nonlocalRowData_.end() ; ++nonlocalRows, ++i)
00240       rowLengths[i] = nonlocalRows->second.entries_.size();
00241   }
00242 
00243   Epetra_CrsGraph* tempGrph = NULL;
00244   if (buildNonlocalGraph_) {
00245     nonlocalGraph_ = new Epetra_CrsGraph(Copy, *sourceMap, *colMap, rowLengths);
00246     tempGrph = nonlocalGraph_;
00247   }
00248   else
00249     tempGrph = new Epetra_CrsGraph(Copy, *sourceMap, *colMap, rowLengths);
00250 
00251   //Next we need to make sure the 'indices-are-global' attribute of tempGrph
00252   //is set to true, in case this processor doesn't end up calling the
00253   //InsertGlobalIndices method...
00254 
00255   tempGrph->SetIndicesAreGlobal(true);
00256 
00257   for (nonlocalRows = nonlocalRowData_.begin(); 
00258        nonlocalRows != nonlocalRowData_.end(); ++nonlocalRows)
00259     EPETRA_CHK_ERR( tempGrph->InsertGlobalIndices(nonlocalRows->first,
00260              nonlocalRows->second.entries_.size(),
00261              &nonlocalRows->second.entries_[0]) );
00262 
00263 
00264   //Now we need to call FillComplete on our temp graph. We need to
00265   //pass a DomainMap and RangeMap.
00266 
00267   EPETRA_CHK_ERR(tempGrph->FillComplete(domain_map, range_map));
00268 
00269   if (buildNonlocalGraph_)
00270     tempGrph->OptimizeStorage();
00271 
00272   Epetra_Export* exporter = new Epetra_Export(*sourceMap, RowMap());
00273 
00274   EPETRA_CHK_ERR(Export(*tempGrph, *exporter, Add));
00275 
00276   if(callFillComplete) {
00277     EPETRA_CHK_ERR(FillComplete(domain_map, range_map));
00278   }
00279 
00280   //now reset the values in our nonlocal data
00281   for (nonlocalRows = nonlocalRowData_.begin(); 
00282        nonlocalRows != nonlocalRowData_.end(); ++nonlocalRows)
00283     nonlocalRows->second.entries_.clear();
00284   nonlocalRowData_.clear();
00285 
00286   delete [] rowLengths;
00287   delete [] presentRowIndices;
00288   delete exporter;
00289   if (!buildNonlocalGraph_)
00290     delete tempGrph;
00291   delete sourceMap;
00292   delete colMap;
00293 
00294   return(0);
00295 }
00296 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines