Epetra Package Browser (Single Doxygen Collection) Development
Epetra_FECrsMatrix.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_ConfigDefs.h>
00044 #include <Epetra_FECrsMatrix.h>
00045 #include <Epetra_IntSerialDenseVector.h>
00046 #include <Epetra_SerialDenseMatrix.h>
00047 #include <Epetra_FECrsGraph.h>
00048 #include <Epetra_Export.h>
00049 #include <Epetra_Comm.h>
00050 #include <Epetra_Map.h>
00051 #include <Epetra_Util.h>
00052 
00053 //----------------------------------------------------------------------------
00054 Epetra_FECrsMatrix::Epetra_FECrsMatrix(Epetra_DataAccess CV,
00055                const Epetra_Map& rowMap,
00056                int* NumEntriesPerRow,
00057                bool ignoreNonLocalEntries)
00058   : Epetra_CrsMatrix(CV, rowMap, NumEntriesPerRow),
00059     myFirstRow_(0),
00060     myNumRows_(0),
00061     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00062 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00063     nonlocalRows_int_(),
00064     nonlocalCols_int_(),
00065 #endif
00066 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00067     nonlocalRows_LL_(),
00068     nonlocalCols_LL_(),
00069 #endif
00070     nonlocalCoefs_(),
00071     workData_(128),
00072     useNonlocalMatrix_ (false),
00073     nonlocalMatrix_ (NULL),
00074     sourceMap_(NULL),
00075     colMap_(NULL),
00076     exporter_(NULL),
00077     tempMat_(NULL)
00078 {
00079   myFirstRow_ = rowMap.MinMyGID64();
00080   myNumRows_ = rowMap.NumMyElements();
00081 }
00082 
00083 //----------------------------------------------------------------------------
00084 Epetra_FECrsMatrix::Epetra_FECrsMatrix(Epetra_DataAccess CV,
00085                const Epetra_Map& rowMap,
00086                int NumEntriesPerRow,
00087                bool ignoreNonLocalEntries)
00088   : Epetra_CrsMatrix(CV, rowMap, NumEntriesPerRow),
00089     myFirstRow_(0),
00090     myNumRows_(0),
00091     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00092 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00093     nonlocalRows_int_(),
00094     nonlocalCols_int_(),
00095 #endif
00096 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00097     nonlocalRows_LL_(),
00098     nonlocalCols_LL_(),
00099 #endif
00100     nonlocalCoefs_(),
00101     workData_(128),
00102     useNonlocalMatrix_ (false),
00103     nonlocalMatrix_ (NULL),
00104     sourceMap_(NULL),
00105     colMap_(NULL),
00106     exporter_(NULL),
00107     tempMat_(NULL)
00108 {
00109   myFirstRow_ = rowMap.MinMyGID64();
00110   myNumRows_ = rowMap.NumMyElements();
00111 }
00112 
00113 //----------------------------------------------------------------------------
00114 Epetra_FECrsMatrix::Epetra_FECrsMatrix(Epetra_DataAccess CV,
00115                const Epetra_Map& rowMap,
00116                const Epetra_Map& colMap,
00117                int* NumEntriesPerRow,
00118                bool ignoreNonLocalEntries)
00119   : Epetra_CrsMatrix(CV, rowMap, colMap, NumEntriesPerRow),
00120     myFirstRow_(0),
00121     myNumRows_(0),
00122     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00123 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00124     nonlocalRows_int_(),
00125     nonlocalCols_int_(),
00126 #endif
00127 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00128     nonlocalRows_LL_(),
00129     nonlocalCols_LL_(),
00130 #endif
00131     nonlocalCoefs_(),
00132     workData_(128),
00133     useNonlocalMatrix_ (false),
00134     nonlocalMatrix_ (NULL),
00135     sourceMap_(NULL),
00136     colMap_(NULL),
00137     exporter_(NULL),
00138     tempMat_(NULL)
00139 {
00140   myFirstRow_ = rowMap.MinMyGID64();
00141   myNumRows_ = rowMap.NumMyElements();
00142 }
00143 
00144 //----------------------------------------------------------------------------
00145 Epetra_FECrsMatrix::Epetra_FECrsMatrix(Epetra_DataAccess CV,
00146                const Epetra_Map& rowMap,
00147                const Epetra_Map& colMap,
00148                int NumEntriesPerRow,
00149                bool ignoreNonLocalEntries)
00150   : Epetra_CrsMatrix(CV, rowMap, colMap, NumEntriesPerRow),
00151     myFirstRow_(0),
00152     myNumRows_(0),
00153     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00154 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00155     nonlocalRows_int_(),
00156     nonlocalCols_int_(),
00157 #endif
00158 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00159     nonlocalRows_LL_(),
00160     nonlocalCols_LL_(),
00161 #endif
00162     nonlocalCoefs_(),
00163     workData_(128),
00164     useNonlocalMatrix_ (false),
00165     nonlocalMatrix_ (NULL),
00166     sourceMap_(NULL),
00167     colMap_(NULL),
00168     exporter_(NULL),
00169     tempMat_(NULL)
00170 {
00171   myFirstRow_ = rowMap.MinMyGID64();
00172   myNumRows_ = rowMap.NumMyElements();
00173 }
00174 
00175 //----------------------------------------------------------------------------
00176 Epetra_FECrsMatrix::Epetra_FECrsMatrix(Epetra_DataAccess CV,
00177                const Epetra_CrsGraph& graph,
00178                bool ignoreNonLocalEntries)
00179   : Epetra_CrsMatrix(CV, graph),
00180     myFirstRow_(0),
00181     myNumRows_(0),
00182     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00183 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00184     nonlocalRows_int_(),
00185     nonlocalCols_int_(),
00186 #endif
00187 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00188     nonlocalRows_LL_(),
00189     nonlocalCols_LL_(),
00190 #endif
00191     nonlocalCoefs_(),
00192     workData_(128),
00193     useNonlocalMatrix_ (false),
00194     nonlocalMatrix_ (NULL),
00195     sourceMap_(NULL),
00196     colMap_(NULL),
00197     exporter_(NULL),
00198     tempMat_(NULL)
00199 {
00200   myFirstRow_ = RowMap().MinMyGID64();
00201   myNumRows_ = RowMap().NumMyElements();
00202 }
00203    
00204 //----------------------------------------------------------------------------
00205 Epetra_FECrsMatrix::Epetra_FECrsMatrix(Epetra_DataAccess CV,
00206               const Epetra_FECrsGraph& graph,
00207               bool ignoreNonLocalEntries)
00208   : Epetra_CrsMatrix(CV, graph),
00209     myFirstRow_(0),
00210     myNumRows_(0),
00211     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00212 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00213     nonlocalRows_int_(),
00214     nonlocalCols_int_(),
00215 #endif
00216 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00217     nonlocalRows_LL_(),
00218     nonlocalCols_LL_(),
00219 #endif
00220     nonlocalCoefs_(),
00221     workData_(128),
00222     useNonlocalMatrix_ (graph.UseNonlocalGraph() && graph.nonlocalGraph_ != 0),
00223     nonlocalMatrix_ (useNonlocalMatrix_ ? 
00224         new Epetra_CrsMatrix(Copy,*graph.nonlocalGraph_) : NULL),
00225     sourceMap_(NULL),
00226     colMap_(NULL),
00227     exporter_(NULL),
00228     tempMat_(NULL)
00229 {
00230   myFirstRow_ = RowMap().MinMyGID64();
00231   myNumRows_ = RowMap().NumMyElements();
00232 }
00233    
00234 //----------------------------------------------------------------------------
00235 Epetra_FECrsMatrix::Epetra_FECrsMatrix(const Epetra_FECrsMatrix& src)
00236  : Epetra_CrsMatrix(src),
00237    myFirstRow_(0),
00238    myNumRows_(0),
00239    ignoreNonLocalEntries_(false),
00240 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00241    nonlocalRows_int_(),
00242    nonlocalCols_int_(),
00243 #endif
00244 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00245    nonlocalRows_LL_(),
00246    nonlocalCols_LL_(),
00247 #endif
00248    nonlocalCoefs_(),
00249    workData_(128),
00250    nonlocalMatrix_ (NULL),
00251    sourceMap_(NULL),
00252    colMap_(NULL),
00253    exporter_(NULL),
00254     tempMat_(NULL)
00255 {
00256   operator=(src);
00257 }
00258 
00259 //----------------------------------------------------------------------------
00260 Epetra_FECrsMatrix& Epetra_FECrsMatrix::operator=(const Epetra_FECrsMatrix& src)
00261 {
00262   if (this == &src) {
00263     return( *this );
00264   }
00265 
00266   DeleteMemory();
00267 
00268   Epetra_CrsMatrix::operator=(src);
00269 
00270   useNonlocalMatrix_ = src.useNonlocalMatrix_;
00271 
00272   myFirstRow_ = src.myFirstRow_;
00273   myNumRows_ = src.myNumRows_;
00274   ignoreNonLocalEntries_ = src.ignoreNonLocalEntries_;
00275 
00276 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00277   if (src.RowMap().GlobalIndicesInt() && nonlocalRows_int_.size() < 1) {
00278     return( *this );
00279   }
00280 #endif
00281 
00282 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00283   if (src.RowMap().GlobalIndicesLongLong() && nonlocalRows_LL_.size() < 1) {
00284     return( *this );
00285   }
00286 #endif
00287 
00288   if (useNonlocalMatrix_ && src.nonlocalMatrix_ != 0) {
00289     *nonlocalMatrix_ = *src.nonlocalMatrix_;
00290     return( *this );
00291   }
00292 
00293 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00294   if (src.RowMap().GlobalIndicesInt()) {
00295     nonlocalRows_int_ = src.nonlocalRows_int_;
00296     nonlocalCols_int_ = src.nonlocalCols_int_;
00297   }
00298 #endif
00299 
00300 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00301   if (src.RowMap().GlobalIndicesLongLong()) {
00302     nonlocalRows_LL_ = src.nonlocalRows_LL_;
00303     nonlocalCols_LL_ = src.nonlocalCols_LL_;
00304   }
00305 #endif
00306 
00307   nonlocalCoefs_= src.nonlocalCoefs_;
00308 
00309   return( *this );
00310 }
00311 
00312 //----------------------------------------------------------------------------
00313 Epetra_FECrsMatrix::~Epetra_FECrsMatrix()
00314 {
00315   DeleteMemory();
00316 }
00317 
00318 //----------------------------------------------------------------------------
00319 void Epetra_FECrsMatrix::DeleteMemory()
00320 {
00321 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00322   if (RowMap().GlobalIndicesInt()) {
00323     nonlocalRows_int_.clear();
00324     nonlocalCols_int_.clear();
00325   }
00326 #endif
00327 
00328 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00329   if (RowMap().GlobalIndicesLongLong()) {
00330     nonlocalRows_LL_.clear();
00331     nonlocalCols_LL_.clear();
00332   }
00333 #endif
00334 
00335   nonlocalCoefs_.clear();
00336 
00337   if (nonlocalMatrix_ != 0)
00338     delete nonlocalMatrix_;
00339 
00340   if ( sourceMap_ )
00341   delete sourceMap_;
00342   if ( colMap_ )
00343   delete colMap_;
00344   if ( exporter_ )
00345   delete exporter_;
00346   if ( tempMat_ )
00347   delete tempMat_;
00348 
00349 }
00350 
00351 //----------------------------------------------------------------------------
00352 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00353 int Epetra_FECrsMatrix::SumIntoGlobalValues(int numIndices, const int* indices,
00354               const double* const* values,
00355               int format)
00356 {
00357   return(InputGlobalValues(numIndices, indices,
00358                            numIndices, indices,
00359                            values, format, SUMINTO));
00360 }
00361 #endif
00362 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00363 int Epetra_FECrsMatrix::SumIntoGlobalValues(int numIndices, const long long* indices,
00364               const double* const* values,
00365               int format)
00366 {
00367   return(InputGlobalValues(numIndices, indices,
00368                            numIndices, indices,
00369                            values, format, SUMINTO));
00370 }
00371 #endif
00372 //----------------------------------------------------------------------------
00373 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00374 int Epetra_FECrsMatrix::SumIntoGlobalValues(int numRows, const int* rows,
00375               int numCols, const int* cols,
00376               const double* const* values,
00377               int format)
00378 {
00379   return(InputGlobalValues(numRows, rows,
00380                            numCols, cols,
00381                            values, format, SUMINTO));
00382 }
00383 #endif
00384 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00385 int Epetra_FECrsMatrix::SumIntoGlobalValues(int numRows, const long long* rows,
00386               int numCols, const long long* cols,
00387               const double* const* values,
00388               int format)
00389 {
00390   return(InputGlobalValues(numRows, rows,
00391                            numCols, cols,
00392                            values, format, SUMINTO));
00393 }
00394 #endif
00395 //----------------------------------------------------------------------------
00396 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00397 int Epetra_FECrsMatrix::SumIntoGlobalValues(int numIndices, const int* indices,
00398               const double* values,
00399               int format)
00400 {
00401   return(InputGlobalValues(numIndices, indices,
00402                            numIndices, indices,
00403                            values, format, SUMINTO));
00404 }
00405 #endif
00406 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00407 int Epetra_FECrsMatrix::SumIntoGlobalValues(int numIndices, const long long* indices,
00408               const double* values,
00409               int format)
00410 {
00411   return(InputGlobalValues(numIndices, indices,
00412                            numIndices, indices,
00413                            values, format, SUMINTO));
00414 }
00415 #endif
00416 //----------------------------------------------------------------------------
00417 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00418 int Epetra_FECrsMatrix::SumIntoGlobalValues(int numRows, const int* rows,
00419               int numCols, const int* cols,
00420               const double* values,
00421               int format)
00422 {
00423   return(InputGlobalValues(numRows, rows,
00424                            numCols, cols,
00425                            values, format, SUMINTO));
00426 }
00427 
00428 #endif
00429 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00430 int Epetra_FECrsMatrix::SumIntoGlobalValues(int numRows, const long long* rows,
00431               int numCols, const long long* cols,
00432               const double* values,
00433               int format)
00434 {
00435   return(InputGlobalValues(numRows, rows,
00436                            numCols, cols,
00437                            values, format, SUMINTO));
00438 }
00439 #endif
00440 //----------------------------------------------------------------------------
00441 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00442 int Epetra_FECrsMatrix::SumIntoGlobalValues(const Epetra_IntSerialDenseVector& indices,
00443               const Epetra_SerialDenseMatrix& values,
00444               int format)
00445 {
00446   if (indices.Length() != values.M() || indices.Length() != values.N()) {
00447     return(-1);
00448   }
00449 
00450   return( SumIntoGlobalValues(indices.Length(), indices.Values(),
00451             values.A(), format) );
00452 }
00453 
00454 #endif
00455 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00456 int Epetra_FECrsMatrix::SumIntoGlobalValues(const Epetra_LongLongSerialDenseVector& indices,
00457               const Epetra_SerialDenseMatrix& values,
00458               int format)
00459 {
00460   if (indices.Length() != values.M() || indices.Length() != values.N()) {
00461     return(-1);
00462   }
00463 
00464   return( SumIntoGlobalValues(indices.Length(), indices.Values(),
00465             values.A(), format) );
00466 }
00467 #endif
00468 //----------------------------------------------------------------------------
00469 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00470 int Epetra_FECrsMatrix::InsertGlobalValues(const Epetra_IntSerialDenseVector& indices,
00471               const Epetra_SerialDenseMatrix& values,
00472               int format)
00473 {
00474   if (indices.Length() != values.M() || indices.Length() != values.N()) {
00475     return(-1);
00476   }
00477 
00478   return( InsertGlobalValues(indices.Length(), indices.Values(),
00479             values.A(), format) );
00480 }
00481 #endif
00482 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00483 int Epetra_FECrsMatrix::InsertGlobalValues(const Epetra_LongLongSerialDenseVector& indices,
00484               const Epetra_SerialDenseMatrix& values,
00485               int format)
00486 {
00487   if (indices.Length() != values.M() || indices.Length() != values.N()) {
00488     return(-1);
00489   }
00490 
00491   return( InsertGlobalValues(indices.Length(), indices.Values(),
00492             values.A(), format) );
00493 }
00494 #endif
00495 //----------------------------------------------------------------------------
00496 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00497 int Epetra_FECrsMatrix::ReplaceGlobalValues(const Epetra_IntSerialDenseVector& indices,
00498               const Epetra_SerialDenseMatrix& values,
00499               int format)
00500 {
00501   if (indices.Length() != values.M() || indices.Length() != values.N()) {
00502     return(-1);
00503   }
00504 
00505   return( ReplaceGlobalValues(indices.Length(), indices.Values(),
00506             values.A(), format) );
00507 }
00508 #endif
00509 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00510 int Epetra_FECrsMatrix::ReplaceGlobalValues(const Epetra_LongLongSerialDenseVector& indices,
00511               const Epetra_SerialDenseMatrix& values,
00512               int format)
00513 {
00514   if (indices.Length() != values.M() || indices.Length() != values.N()) {
00515     return(-1);
00516   }
00517 
00518   return( ReplaceGlobalValues(indices.Length(), indices.Values(),
00519             values.A(), format) );
00520 }
00521 #endif
00522 //----------------------------------------------------------------------------
00523 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00524 int Epetra_FECrsMatrix::SumIntoGlobalValues(const Epetra_IntSerialDenseVector& rows,
00525               const Epetra_IntSerialDenseVector& cols,
00526               const Epetra_SerialDenseMatrix& values,
00527               int format)
00528 {
00529   if (rows.Length() != values.M() || cols.Length() != values.N()) {
00530     return(-1);
00531   }
00532 
00533   return( SumIntoGlobalValues(rows.Length(), rows.Values(),
00534             cols.Length(), cols.Values(),
00535             values.A(), format) );
00536 }
00537 #endif
00538 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00539 int Epetra_FECrsMatrix::SumIntoGlobalValues(const Epetra_LongLongSerialDenseVector& rows,
00540               const Epetra_LongLongSerialDenseVector& cols,
00541               const Epetra_SerialDenseMatrix& values,
00542               int format)
00543 {
00544   if (rows.Length() != values.M() || cols.Length() != values.N()) {
00545     return(-1);
00546   }
00547 
00548   return( SumIntoGlobalValues(rows.Length(), rows.Values(),
00549             cols.Length(), cols.Values(),
00550             values.A(), format) );
00551 }
00552 #endif
00553 //----------------------------------------------------------------------------
00554 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00555 int Epetra_FECrsMatrix::InsertGlobalValues(const Epetra_IntSerialDenseVector& rows,
00556              const Epetra_IntSerialDenseVector& cols,
00557              const Epetra_SerialDenseMatrix& values,
00558              int format)
00559 {
00560   if (rows.Length() != values.M() || cols.Length() != values.N()) {
00561     return(-1);
00562   }
00563 
00564   return( InsertGlobalValues(rows.Length(), rows.Values(),
00565            cols.Length(), cols.Values(),
00566             values.A(), format) );
00567 }
00568 #endif
00569 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00570 int Epetra_FECrsMatrix::InsertGlobalValues(const Epetra_LongLongSerialDenseVector& rows,
00571              const Epetra_LongLongSerialDenseVector& cols,
00572              const Epetra_SerialDenseMatrix& values,
00573              int format)
00574 {
00575   if (rows.Length() != values.M() || cols.Length() != values.N()) {
00576     return(-1);
00577   }
00578 
00579   return( InsertGlobalValues(rows.Length(), rows.Values(),
00580            cols.Length(), cols.Values(),
00581             values.A(), format) );
00582 }
00583 #endif
00584 //----------------------------------------------------------------------------
00585 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00586 int Epetra_FECrsMatrix::ReplaceGlobalValues(const Epetra_IntSerialDenseVector& rows,
00587               const Epetra_IntSerialDenseVector& cols,
00588               const Epetra_SerialDenseMatrix& values,
00589               int format)
00590 {
00591   if (rows.Length() != values.M() || cols.Length() != values.N()) {
00592     return(-1);
00593   }
00594 
00595   return( ReplaceGlobalValues(rows.Length(), rows.Values(),
00596             cols.Length(), cols.Values(),
00597             values.A(), format) );
00598 }
00599 #endif
00600 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00601 
00602 int Epetra_FECrsMatrix::ReplaceGlobalValues(const Epetra_LongLongSerialDenseVector& rows,
00603               const Epetra_LongLongSerialDenseVector& cols,
00604               const Epetra_SerialDenseMatrix& values,
00605               int format)
00606 {
00607   if (rows.Length() != values.M() || cols.Length() != values.N()) {
00608     return(-1);
00609   }
00610 
00611   return( ReplaceGlobalValues(rows.Length(), rows.Values(),
00612             cols.Length(), cols.Values(),
00613             values.A(), format) );
00614 }
00615 #endif
00616 //----------------------------------------------------------------------------
00617 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00618 int Epetra_FECrsMatrix::InsertGlobalValues(int numIndices, const int* indices,
00619             const double* const* values,
00620             int format)
00621 {
00622   return(InputGlobalValues(numIndices, indices,
00623                            numIndices, indices,
00624                            values, format, INSERT));
00625 }
00626 #endif
00627 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00628 
00629 int Epetra_FECrsMatrix::InsertGlobalValues(int numIndices, const long long* indices,
00630             const double* const* values,
00631             int format)
00632 {
00633   return(InputGlobalValues(numIndices, indices,
00634                            numIndices, indices,
00635                            values, format, INSERT));
00636 }
00637 #endif
00638 //----------------------------------------------------------------------------
00639 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00640 int Epetra_FECrsMatrix::InsertGlobalValues(int numRows, const int* rows,
00641             int numCols, const int* cols,
00642             const double* const* values,
00643             int format)
00644 {
00645   return(InputGlobalValues(numRows, rows,
00646                            numCols, cols,
00647                            values, format, INSERT));
00648 }
00649 #endif
00650 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00651 
00652 int Epetra_FECrsMatrix::InsertGlobalValues(int numRows, const long long* rows,
00653             int numCols, const long long* cols,
00654             const double* const* values,
00655             int format)
00656 {
00657   return(InputGlobalValues(numRows, rows,
00658                            numCols, cols,
00659                            values, format, INSERT));
00660 }
00661 #endif
00662 //----------------------------------------------------------------------------
00663 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00664 int Epetra_FECrsMatrix::InsertGlobalValues(int numIndices, const int* indices,
00665               const double* values,
00666               int format)
00667 {
00668   return(InputGlobalValues(numIndices, indices,
00669                            numIndices, indices,
00670                            values, format, INSERT));
00671 }
00672 #endif
00673 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00674 
00675 int Epetra_FECrsMatrix::InsertGlobalValues(int numIndices, const long long* indices,
00676               const double* values,
00677               int format)
00678 {
00679   return(InputGlobalValues(numIndices, indices,
00680                            numIndices, indices,
00681                            values, format, INSERT));
00682 }
00683 #endif
00684 //----------------------------------------------------------------------------
00685 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00686 int Epetra_FECrsMatrix::InsertGlobalValues(int numRows, const int* rows,
00687               int numCols, const int* cols,
00688               const double* values,
00689               int format)
00690 {
00691   return(InputGlobalValues(numRows, rows,
00692                            numCols, cols,
00693                            values, format, INSERT));
00694 }
00695 #endif
00696 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00697 
00698 int Epetra_FECrsMatrix::InsertGlobalValues(int numRows, const long long* rows,
00699               int numCols, const long long* cols,
00700               const double* values,
00701               int format)
00702 {
00703   return(InputGlobalValues(numRows, rows,
00704                            numCols, cols,
00705                            values, format, INSERT));
00706 }
00707 #endif
00708 //----------------------------------------------------------------------------
00709 template<typename int_type>
00710 int Epetra_FECrsMatrix::SumIntoGlobalValues(int_type GlobalRow, int NumEntries,
00711                                             const double* values, const int_type* Indices)
00712 {
00713   if (Map().MyGID(GlobalRow))
00714     return Epetra_CrsMatrix::SumIntoGlobalValues(GlobalRow, NumEntries,
00715             values, Indices);
00716   else if (useNonlocalMatrix_)
00717     return nonlocalMatrix_->SumIntoGlobalValues(GlobalRow,
00718            NumEntries, values, Indices);
00719   else
00720     return InputNonlocalGlobalValues(GlobalRow, NumEntries, Indices, values, SUMINTO);
00721 }
00722 
00723 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00724 int Epetra_FECrsMatrix::SumIntoGlobalValues(int GlobalRow, int NumEntries,
00725                                             const double* values, const int* Indices)
00726 {
00727   if(RowMap().GlobalIndicesInt())
00728   return SumIntoGlobalValues<int>(GlobalRow, NumEntries, values, Indices);
00729   else
00730   throw ReportError("Epetra_FECrsMatrix::SumIntoGlobalValues int version called for a matrix that is not int.", -1);
00731 }
00732 #endif
00733 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00734 
00735 
00736 int Epetra_FECrsMatrix::SumIntoGlobalValues(long long GlobalRow, int NumEntries,
00737                                             const double* values, const long long* Indices)
00738 {
00739   if(RowMap().GlobalIndicesLongLong())
00740   return SumIntoGlobalValues<long long>(GlobalRow, NumEntries, values, Indices);
00741   else
00742   throw ReportError("Epetra_FECrsMatrix::SumIntoGlobalValues long long version called for a matrix that is not long long.", -1);
00743 }
00744 #endif
00745 //----------------------------------------------------------------------------
00746 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00747 int Epetra_FECrsMatrix::InsertGlobalValues(int GlobalRow, int NumEntries,
00748                                             const double* values, const int* Indices)
00749 {
00750   return(InputGlobalValues(1, &GlobalRow,
00751                            NumEntries, Indices, values,
00752                            Epetra_FECrsMatrix::ROW_MAJOR, INSERT));
00753 }
00754 #endif
00755 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00756 
00757 int Epetra_FECrsMatrix::InsertGlobalValues(long long GlobalRow, int NumEntries,
00758                                             const double* values, const long long* Indices)
00759 {
00760   return(InputGlobalValues(1, &GlobalRow,
00761                            NumEntries, Indices, values,
00762                            Epetra_FECrsMatrix::ROW_MAJOR, INSERT));
00763 }
00764 #endif
00765 //----------------------------------------------------------------------------
00766 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00767 int Epetra_FECrsMatrix::InsertGlobalValues(int GlobalRow, int NumEntries,
00768                                             double* values, int* Indices)
00769 {
00770   return(InputGlobalValues(1, &GlobalRow,
00771                            NumEntries, Indices, values,
00772                            Epetra_FECrsMatrix::ROW_MAJOR, INSERT));
00773 }
00774 #endif
00775 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00776 int Epetra_FECrsMatrix::InsertGlobalValues(long long GlobalRow, int NumEntries,
00777                                             double* values, long long* Indices)
00778 {
00779   return(InputGlobalValues(1, &GlobalRow,
00780                            NumEntries, Indices, values,
00781                            Epetra_FECrsMatrix::ROW_MAJOR, INSERT));
00782 }
00783 #endif
00784 //----------------------------------------------------------------------------
00785 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00786 int Epetra_FECrsMatrix::ReplaceGlobalValues(int GlobalRow, int NumEntries,
00787                                             const double* values, const int* Indices)
00788 {
00789   return(InputGlobalValues(1, &GlobalRow,
00790                            NumEntries, Indices, values,
00791                            Epetra_FECrsMatrix::ROW_MAJOR, REPLACE));
00792 }
00793 #endif
00794 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00795 int Epetra_FECrsMatrix::ReplaceGlobalValues(long long GlobalRow, int NumEntries,
00796                                             const double* values, const long long* Indices)
00797 {
00798   return(InputGlobalValues(1, &GlobalRow,
00799                            NumEntries, Indices, values,
00800                            Epetra_FECrsMatrix::ROW_MAJOR, REPLACE));
00801 }
00802 #endif
00803 //----------------------------------------------------------------------------
00804 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00805 int Epetra_FECrsMatrix::ReplaceGlobalValues(int numIndices, const int* indices,
00806               const double* const* values,
00807               int format)
00808 {
00809   return(InputGlobalValues(numIndices, indices,
00810                            numIndices, indices,
00811                            values, format, REPLACE));
00812 }
00813 #endif
00814 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00815 int Epetra_FECrsMatrix::ReplaceGlobalValues(int numIndices, const long long* indices,
00816               const double* const* values,
00817               int format)
00818 {
00819   return(InputGlobalValues(numIndices, indices,
00820                            numIndices, indices,
00821                            values, format, REPLACE));
00822 }
00823 #endif
00824 //----------------------------------------------------------------------------
00825 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00826 int Epetra_FECrsMatrix::ReplaceGlobalValues(int numRows, const int* rows,
00827               int numCols, const int* cols,
00828               const double* const* values,
00829               int format)
00830 {
00831   return(InputGlobalValues(numRows, rows,
00832                            numCols, cols,
00833                            values, format, REPLACE));
00834 }
00835 #endif
00836 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00837 int Epetra_FECrsMatrix::ReplaceGlobalValues(int numRows, const long long* rows,
00838               int numCols, const long long* cols,
00839               const double* const* values,
00840               int format)
00841 {
00842   return(InputGlobalValues(numRows, rows,
00843                            numCols, cols,
00844                            values, format, REPLACE));
00845 }
00846 #endif
00847 //----------------------------------------------------------------------------
00848 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00849 int Epetra_FECrsMatrix::ReplaceGlobalValues(int numIndices, const int* indices,
00850               const double* values,
00851               int format)
00852 {
00853   return(InputGlobalValues(numIndices, indices,
00854                            numIndices, indices,
00855                            values, format, REPLACE));
00856 }
00857 #endif
00858 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00859 int Epetra_FECrsMatrix::ReplaceGlobalValues(int numIndices, const long long* indices,
00860               const double* values,
00861               int format)
00862 {
00863   return(InputGlobalValues(numIndices, indices,
00864                            numIndices, indices,
00865                            values, format, REPLACE));
00866 }
00867 #endif
00868 //----------------------------------------------------------------------------
00869 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00870 int Epetra_FECrsMatrix::ReplaceGlobalValues(int numRows, const int* rows,
00871               int numCols, const int* cols,
00872               const double* values,
00873               int format)
00874 {
00875   return(InputGlobalValues(numRows, rows,
00876                            numCols, cols,
00877                            values, format, REPLACE));
00878 }
00879 #endif
00880 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00881 int Epetra_FECrsMatrix::ReplaceGlobalValues(int numRows, const long long* rows,
00882               int numCols, const long long* cols,
00883               const double* values,
00884               int format)
00885 {
00886   return(InputGlobalValues(numRows, rows,
00887                            numCols, cols,
00888                            values, format, REPLACE));
00889 }
00890 #endif
00891 //----------------------------------------------------------------------------
00892 int Epetra_FECrsMatrix::GlobalAssemble(bool callFillComplete, Epetra_CombineMode combineMode,
00893                                        bool save_off_and_reuse_map_exporter)
00894 {
00895   return( GlobalAssemble(DomainMap(), RangeMap(), callFillComplete, combineMode, save_off_and_reuse_map_exporter));
00896 }
00897 
00898 //----------------------------------------------------------------------------
00899 template<typename int_type>
00900 int Epetra_FECrsMatrix::GlobalAssemble(const Epetra_Map& domain_map,
00901                                        const Epetra_Map& range_map,
00902                                        bool callFillComplete,
00903                                        Epetra_CombineMode combineMode,
00904                                        bool save_off_and_reuse_map_exporter)
00905 {
00906   if (Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
00907     if (callFillComplete) {
00908       EPETRA_CHK_ERR( FillComplete(domain_map, range_map) );
00909     }
00910     return(0);
00911   }
00912 
00913   std::vector<int_type>& nonlocalRows_var = nonlocalRows<int_type>();
00914   std::vector<std::vector<int_type> >& nonlocalCols_var = nonlocalCols<int_type>();
00915 
00916   if (useNonlocalMatrix_) {
00917     tempMat_ = nonlocalMatrix_;
00918   }
00919   else {
00920     //In this method we need to gather all the non-local (overlapping) data
00921     //that's been input on each processor, into the
00922     //non-overlapping distribution defined by the map that 'this' matrix was
00923     //constructed with.
00924 
00925     //First build a map that describes our nonlocal data.
00926     //We'll use the arbitrary distribution constructor of Map.
00927 
00928     int_type* nlr_ptr = nonlocalRows_var.size() > 0 ? &nonlocalRows_var[0] : 0;
00929     if (sourceMap_ == NULL)
00930       sourceMap_ = new Epetra_Map((int_type) -1, (int) nonlocalRows_var.size(), nlr_ptr,
00931             (int_type) Map().IndexBase64(), Map().Comm());
00932 
00933     //If sourceMap has global size 0, then no nonlocal data exists and we can
00934     //skip most of this function.
00935     if (sourceMap_->NumGlobalElements64() < 1) {
00936       if (callFillComplete) {
00937         EPETRA_CHK_ERR( FillComplete(domain_map, range_map) );
00938       }
00939       if (!save_off_and_reuse_map_exporter) {
00940         delete sourceMap_;
00941         sourceMap_ = NULL;
00942       }
00943       return(0);
00944     }
00945 
00946     //We also need to build a column-map, containing the columns in our
00947     //nonlocal data. To do that, create a list of all column-indices that
00948     //occur in our nonlocal rows.
00949     bool first_time=!save_off_and_reuse_map_exporter;
00950     if ( colMap_ == NULL ) {
00951       first_time = true;
00952       std::vector<int_type> cols;
00953 
00954       for(size_t i=0; i<nonlocalRows_var.size(); ++i) {
00955         for(size_t j=0; j<nonlocalCols_var[i].size(); ++j) {
00956           int_type col = nonlocalCols_var[i][j];
00957           typename std::vector<int_type>::iterator it =
00958             std::lower_bound(cols.begin(), cols.end(), col);
00959           if (it == cols.end() || *it != col) {
00960             cols.insert(it, col);
00961           }
00962         }
00963       }
00964 
00965       int_type* cols_ptr = cols.size() > 0 ? &cols[0] : 0;
00966 
00967       colMap_ = new Epetra_Map((int_type) -1, (int) cols.size(), cols_ptr,
00968                                (int_type) Map().IndexBase64(), Map().Comm());
00969     }
00970     //now we need to create a matrix with sourceMap and colMap, and fill it with
00971     //our nonlocal data so we can then export it to the correct owning processors.
00972 
00973     std::vector<int> nonlocalRowLengths(nonlocalRows_var.size());
00974     for(size_t i=0; i<nonlocalRows_var.size(); ++i) {
00975       nonlocalRowLengths[i] = (int) nonlocalCols_var[i].size();
00976     }
00977 
00978     int* nlRLptr = nonlocalRowLengths.size()>0 ? &nonlocalRowLengths[0] : NULL;
00979     if ( first_time && tempMat_ == NULL )
00980       tempMat_ = new Epetra_CrsMatrix(Copy, *sourceMap_, *colMap_, nlRLptr);
00981     else
00982       tempMat_->PutScalar(0.);
00983 
00984     for(size_t i=0; i<nonlocalRows_var.size(); ++i) {
00985       if ( first_time ) {
00986         EPETRA_CHK_ERR( tempMat_->InsertGlobalValues(nonlocalRows_var[i],
00987                                                     (int) nonlocalCols_var[i].size(),
00988                                                     &nonlocalCoefs_[i][0],
00989                                                     &nonlocalCols_var[i][0]) );
00990       } else {
00991         EPETRA_CHK_ERR( tempMat_->SumIntoGlobalValues(nonlocalRows_var[i],
00992                                                      (int) nonlocalCols_var[i].size(),
00993                                                      &nonlocalCoefs_[i][0],
00994                                                      &nonlocalCols_var[i][0]) );
00995       }
00996     }
00997 
00998     if (!save_off_and_reuse_map_exporter) {
00999       delete sourceMap_;
01000       delete colMap_;
01001       sourceMap_ = colMap_ = NULL;
01002     }
01003 
01004     //Next we need to make sure the 'indices-are-global' attribute of tempMat's
01005     //graph is set to true, in case this processor doesn't end up calling the
01006     //InsertGlobalValues method...
01007 
01008     if (first_time) {
01009       const Epetra_CrsGraph& graph = tempMat_->Graph();
01010       Epetra_CrsGraph& nonconst_graph = const_cast<Epetra_CrsGraph&>(graph);
01011       nonconst_graph.SetIndicesAreGlobal(true);
01012 
01013       //Now we need to call FillComplete on our temp matrix. We need to
01014       //pass a DomainMap and RangeMap, which are not the same as the RowMap
01015       //and ColMap that we constructed the matrix with.
01016       EPETRA_CHK_ERR(tempMat_->FillComplete(domain_map, range_map));
01017     }
01018 
01019     if (exporter_ == NULL)
01020       exporter_ = new Epetra_Export(tempMat_->RowMap(), RowMap());
01021 
01022     EPETRA_CHK_ERR(Export(*tempMat_, *exporter_, combineMode));
01023 
01024     if(callFillComplete) {
01025       EPETRA_CHK_ERR(FillComplete(domain_map, range_map));
01026     }
01027 
01028     //now reset the values in our nonlocal data
01029     if (!useNonlocalMatrix_) {
01030       for(size_t i=0; i<nonlocalRows_var.size(); ++i) {
01031         nonlocalCols_var[i].resize(0); 
01032         nonlocalCoefs_[i].resize(0);
01033       }
01034     }
01035 
01036   }
01037 
01038   if (!save_off_and_reuse_map_exporter) {
01039     delete exporter_;
01040     exporter_ = NULL;
01041     if (!useNonlocalMatrix_) 
01042       delete tempMat_;
01043     tempMat_ = NULL;
01044   }
01045   return(0);
01046 }
01047 
01048 int Epetra_FECrsMatrix::GlobalAssemble(const Epetra_Map& domain_map,
01049                                        const Epetra_Map& range_map,
01050                                        bool callFillComplete,
01051                                        Epetra_CombineMode combineMode,
01052                                        bool save_off_and_reuse_map_exporter)
01053 {
01054   if(!domain_map.GlobalIndicesTypeMatch(range_map))
01055     throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: cannot be called with different indices types for domainMap and rangeMap", -1);
01056 
01057   if(!RowMap().GlobalIndicesTypeMatch(domain_map))
01058     throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: cannot be called with different indices types for row map and incoming rangeMap", -1);
01059 
01060   if(RowMap().GlobalIndicesInt())
01061 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
01062     return GlobalAssemble<int>(domain_map, range_map, callFillComplete, combineMode, save_off_and_reuse_map_exporter);
01063 #else
01064     throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: ERROR, GlobalIndicesInt but no API for it.",-1);
01065 #endif
01066 
01067   if(RowMap().GlobalIndicesLongLong())
01068 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
01069     return GlobalAssemble<long long>(domain_map, range_map, callFillComplete, combineMode, save_off_and_reuse_map_exporter);
01070 #else
01071     throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: ERROR, GlobalIndicesLongLong but no API for it.",-1);
01072 #endif
01073 
01074   throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: Internal error, unable to determine global index type of maps", -1);
01075 }
01076 
01077 //----------------------------------------------------------------------------
01078 template<typename int_type>
01079 int Epetra_FECrsMatrix::InputGlobalValues_RowMajor(
01080             int numRows, const int_type* rows,
01081             int numCols, const int_type* cols,
01082             const double* values,
01083             int mode)
01084 {
01085   if(!RowMap().template GlobalIndicesIsType<int_type>())
01086   throw ReportError("Epetra_FECrsMatrix::InputGlobalValues_RowMajor mismatch between argument types (int/long long) and map type.", -1);
01087 
01088   int returncode = 0;
01089   int err = 0;
01090 
01091   for(int i=0; i<numRows; ++i) {
01092     double* valuesptr = (double*)values + i*numCols;
01093 
01094     int local_row_id = Map().LID(rows[i]);
01095     if (local_row_id >= 0) {
01096       switch(mode) {
01097         case Epetra_FECrsMatrix::SUMINTO:
01098           err = this->Epetra_CrsMatrix::SumIntoGlobalValues(rows[i], numCols,
01099               valuesptr, (int_type*)cols);
01100           if (err<0) return(err);
01101           if (err>0) returncode = err;
01102           break;
01103         case Epetra_FECrsMatrix::REPLACE:
01104           err = this->Epetra_CrsMatrix::ReplaceGlobalValues(rows[i], numCols,
01105               valuesptr, (int_type*)cols);
01106           if (err<0) return(err);
01107           if (err>0) returncode = err;
01108           break;
01109         case Epetra_FECrsMatrix::INSERT:
01110           err = this->Epetra_CrsMatrix::InsertGlobalValues(rows[i], numCols,
01111               valuesptr, (int_type*)cols);
01112           if (err<0) return(err);
01113           if (err>0) returncode = err;
01114           break;
01115         default:
01116           std::cerr << "Epetra_FECrsMatrix: internal error, bad input mode."<< std::endl;
01117           return(-1);
01118       }
01119     }
01120     else {
01121 #ifdef EPETRA_HAVE_OMP
01122 #ifdef EPETRA_HAVE_OMP_NONASSOCIATIVE
01123       if (! ignoreNonLocalEntries_) {
01124 #endif
01125 #endif
01126           err = InputNonlocalGlobalValues(rows[i], numCols, cols,
01127               valuesptr, mode);
01128           if (err<0) return(err);
01129           if (err>0) returncode = err;
01130 #ifdef EPETRA_HAVE_OMP
01131 #ifdef EPETRA_HAVE_OMP_NONASSOCIATIVE
01132       }
01133 #endif
01134 #endif
01135     }
01136   }
01137 
01138   return(returncode);
01139 }
01140 
01141 //----------------------------------------------------------------------------
01142 template<typename int_type>
01143 int Epetra_FECrsMatrix::InputGlobalValues(int numRows, const int_type* rows,
01144             int numCols, const int_type* cols,
01145             const double*const* values,
01146             int format, int mode)
01147 {
01148   if(!RowMap().template GlobalIndicesIsType<int_type>())
01149   throw ReportError("Epetra_FECrsMatrix::InputGlobalValues mismatch between argument types (int/long long) and map type.", -1);
01150 
01151   if (format != Epetra_FECrsMatrix::ROW_MAJOR &&
01152       format != Epetra_FECrsMatrix::COLUMN_MAJOR) {
01153     std::cerr << "Epetra_FECrsMatrix: unrecognized format specifier."<< std::endl;
01154     return(-1);
01155   }
01156 
01157   if (format == Epetra_FECrsMatrix::COLUMN_MAJOR) {
01158     workData_.resize(numCols);
01159   }
01160 
01161   int returncode = 0;
01162 
01163   for(int i=0; i<numRows; ++i) {
01164     if (format == Epetra_FECrsMatrix::ROW_MAJOR) {
01165       returncode += InputGlobalValues_RowMajor(1, &rows[i], numCols, cols,
01166                                           values[i], mode);
01167       if (returncode < 0) return returncode;
01168       continue;
01169     }
01170 
01171     //If we get to here, the data is in column-major order.
01172 
01173     double* valuesptr = &workData_[0];
01174 
01175     //Since the data is in column-major order, then we copy the i-th row
01176     //of the values table into workData_, in order to have the row in
01177     //contiguous memory.
01178     //This is slow and not thread-safe.
01179 
01180     for(int j=0; j<numCols; ++j) {
01181       valuesptr[j] = values[j][i];
01182     }
01183 
01184     returncode += InputGlobalValues_RowMajor(1, &rows[i], numCols, cols, valuesptr, mode);
01185     if (returncode < 0) return returncode;
01186   }
01187 
01188   return(returncode);
01189 }
01190 
01191 //----------------------------------------------------------------------------
01192 template<typename int_type>
01193 int Epetra_FECrsMatrix::InputGlobalValues(int numRows, const int_type* rows,
01194             int numCols, const int_type* cols,
01195             const double* values,
01196             int format, int mode)
01197 {
01198   if(!RowMap().template GlobalIndicesIsType<int_type>())
01199   throw ReportError("Epetra_FECrsMatrix::InputGlobalValues mismatch between argument types (int/long long) and map type.", -1);
01200 
01201   if (format == Epetra_FECrsMatrix::ROW_MAJOR) {
01202     return InputGlobalValues_RowMajor(numRows, rows, numCols, cols, values, mode);
01203   }
01204 
01205   workData_.resize(numCols);
01206 
01207   int returncode = 0;
01208   for(int i=0; i<numRows; ++i) {
01209     //copy each row out of the column-major values array, so we can pass it
01210     //to a row-major input function.
01211     for(int j=0; j<numCols; ++j) {
01212       workData_[j] = values[i+j*numRows];
01213     }
01214     int err = InputGlobalValues_RowMajor(1, &rows[i], numCols, cols, &workData_[0], mode);
01215     if (err < 0) return err;
01216     returncode += err;
01217   }
01218 
01219   return(returncode);
01220 }
01221 
01222 //----------------------------------------------------------------------------
01223 template<typename int_type>
01224 int Epetra_FECrsMatrix::InputNonlocalGlobalValues(int_type row,
01225               int numCols, const int_type* cols,
01226               const double* values,
01227               int mode)
01228 {
01229   if(!RowMap().template GlobalIndicesIsType<int_type>())
01230   throw ReportError("Epetra_FECrsMatrix::InputNonlocalGlobalValues mismatch between argument types (int/long long) and map type.", -1);
01231 
01232   // if we already have a nonlocal matrix object, this is easier...
01233   if (useNonlocalMatrix_) {
01234     int err, returncode = 0;
01235     double* valuesptr = (double*)values;
01236     switch(mode) {
01237     case Epetra_FECrsMatrix::SUMINTO:
01238       err = nonlocalMatrix_->SumIntoGlobalValues(row, numCols,
01239             valuesptr, (int_type*)cols);
01240       if (err<0) return(err);
01241       if (err>0) returncode = err;
01242       break;
01243     case Epetra_FECrsMatrix::REPLACE:
01244       err = nonlocalMatrix_->ReplaceGlobalValues(row, numCols,
01245             valuesptr, (int_type*)cols);
01246       if (err<0) return(err);
01247       if (err>0) returncode = err;
01248       break;
01249     case Epetra_FECrsMatrix::INSERT:
01250       err = nonlocalMatrix_->InsertGlobalValues(row, numCols,
01251            valuesptr, (int_type*)cols);
01252       if (err<0) return(err);
01253       if (err>0) returncode = err;
01254       break;
01255     default:
01256       std::cerr << "Epetra_FECrsMatrix: internal error, bad input mode."<< std::endl;
01257       return(-1);
01258     }
01259     return (returncode);
01260   }
01261   int ierr1 = 0, ierr2 = 0;
01262 #ifdef EPETRA_HAVE_OMP
01263 #ifdef EPETRA_HAVE_OMP_NONASSOCIATIVE
01264 #pragma omp critical
01265 #endif
01266 #endif
01267   {
01268   std::vector<int_type>& nonlocalRows_var = nonlocalRows<int_type>();
01269 
01270   //find offset of this row in our list of nonlocal rows.
01271   typename std::vector<int_type>::iterator it =
01272       std::lower_bound(nonlocalRows_var.begin(), nonlocalRows_var.end(), row);
01273 
01274   int rowoffset = (int) (it - nonlocalRows_var.begin());
01275   if (it == nonlocalRows_var.end() || *it != row) {
01276     ierr1 = InsertNonlocalRow(row, it);
01277   }
01278 
01279   for(int i=0; i<numCols; ++i) {
01280     ierr2 = InputNonlocalValue(rowoffset, cols[i], values[i], mode);
01281   }
01282   }
01283   EPETRA_CHK_ERR(ierr1);
01284   EPETRA_CHK_ERR(ierr2);
01285 
01286   return(0);
01287 }
01288 
01289 //----------------------------------------------------------------------------
01290 template<typename int_type>
01291 int Epetra_FECrsMatrix::InsertNonlocalRow(int_type row, typename std::vector<int_type>::iterator iter)
01292 {
01293   if(!RowMap().template GlobalIndicesIsType<int_type>())
01294   throw ReportError("Epetra_FECrsMatrix::InsertNonlocalRow mismatch between argument types (int/long long) and map type.", -1);
01295 
01296   std::vector<int_type>& nonlocalRows_var = nonlocalRows<int_type>();
01297   std::vector<std::vector<int_type> >& nonlocalCols_var = nonlocalCols<int_type>();
01298 
01299   int offset = (int) (iter - nonlocalRows_var.begin());
01300   nonlocalRows_var.insert(iter, row);
01301   typename std::vector<std::vector<int_type> >::iterator cols_iter = nonlocalCols_var.begin() + offset;
01302   nonlocalCols_var.insert(cols_iter, std::vector<int_type>());
01303   std::vector<std::vector<double> >::iterator coefs_iter = nonlocalCoefs_.begin() + offset;
01304   nonlocalCoefs_.insert(coefs_iter, std::vector<double>());
01305 
01306   return(0);
01307 }
01308 
01309 //----------------------------------------------------------------------------
01310 template<typename int_type>
01311 int Epetra_FECrsMatrix::InputNonlocalValue(int rowoffset,
01312              int_type col, double value,
01313              int mode)
01314 {
01315   if(!RowMap().template GlobalIndicesIsType<int_type>())
01316   throw ReportError("Epetra_FECrsMatrix::InputNonlocalValue mismatch between argument types (int/long long) and map type.", -1);
01317 
01318   std::vector<int_type>& colIndices = nonlocalCols<int_type>()[rowoffset];
01319   std::vector<double>& coefs = nonlocalCoefs_[rowoffset];
01320 
01321   typename std::vector<int_type>::iterator it =
01322      std::lower_bound(colIndices.begin(), colIndices.end(), col);
01323 
01324   if (it == colIndices.end() || *it != col) {
01325     int offset = (int) (it - colIndices.begin());
01326     colIndices.insert(it, col);
01327     std::vector<double>::iterator dit = coefs.begin()+offset;
01328     coefs.insert(dit, value);
01329     return 0;
01330   }
01331 
01332   int coloffset = (int) (it - colIndices.begin());
01333   if (mode == SUMINTO || mode == INSERT) {
01334     coefs[coloffset] += value;
01335   }
01336   else {
01337     coefs[coloffset] = value;
01338   }
01339 
01340   return(0);
01341 }
01342 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines