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   }
01014       //Now we need to call FillComplete on our temp matrix. We need to
01015       //pass a DomainMap and RangeMap, which are not the same as the RowMap
01016       //and ColMap that we constructed the matrix with.
01017       EPETRA_CHK_ERR(tempMat_->FillComplete(domain_map, range_map));
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   if (!save_off_and_reuse_map_exporter) {
01037     delete exporter_;
01038     exporter_ = NULL;
01039     if (!useNonlocalMatrix_)
01040       delete tempMat_;
01041     tempMat_ = NULL;
01042   }
01043   return(0);
01044 }
01045 
01046 int Epetra_FECrsMatrix::GlobalAssemble(const Epetra_Map& domain_map,
01047                                        const Epetra_Map& range_map,
01048                                        bool callFillComplete,
01049                                        Epetra_CombineMode combineMode,
01050                                        bool save_off_and_reuse_map_exporter)
01051 {
01052   if(!domain_map.GlobalIndicesTypeMatch(range_map))
01053     throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: cannot be called with different indices types for domainMap and rangeMap", -1);
01054 
01055   if(!RowMap().GlobalIndicesTypeMatch(domain_map))
01056     throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: cannot be called with different indices types for row map and incoming rangeMap", -1);
01057 
01058   if(RowMap().GlobalIndicesInt())
01059 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
01060     return GlobalAssemble<int>(domain_map, range_map, callFillComplete, combineMode, save_off_and_reuse_map_exporter);
01061 #else
01062     throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: ERROR, GlobalIndicesInt but no API for it.",-1);
01063 #endif
01064 
01065   if(RowMap().GlobalIndicesLongLong())
01066 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
01067     return GlobalAssemble<long long>(domain_map, range_map, callFillComplete, combineMode, save_off_and_reuse_map_exporter);
01068 #else
01069     throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: ERROR, GlobalIndicesLongLong but no API for it.",-1);
01070 #endif
01071 
01072   throw ReportError("Epetra_FECrsMatrix::GlobalAssemble: Internal error, unable to determine global index type of maps", -1);
01073 }
01074 
01075 //----------------------------------------------------------------------------
01076 template<typename int_type>
01077 int Epetra_FECrsMatrix::InputGlobalValues_RowMajor(
01078             int numRows, const int_type* rows,
01079             int numCols, const int_type* cols,
01080             const double* values,
01081             int mode)
01082 {
01083   if(!RowMap().template GlobalIndicesIsType<int_type>())
01084   throw ReportError("Epetra_FECrsMatrix::InputGlobalValues_RowMajor mismatch between argument types (int/long long) and map type.", -1);
01085 
01086   int returncode = 0;
01087   int err = 0;
01088 
01089   for(int i=0; i<numRows; ++i) {
01090     double* valuesptr = (double*)values + i*numCols;
01091 
01092     int local_row_id = Map().LID(rows[i]);
01093     if (local_row_id >= 0) {
01094       switch(mode) {
01095         case Epetra_FECrsMatrix::SUMINTO:
01096           err = this->Epetra_CrsMatrix::SumIntoGlobalValues(rows[i], numCols,
01097               valuesptr, (int_type*)cols);
01098           if (err<0) return(err);
01099           if (err>0) returncode = err;
01100           break;
01101         case Epetra_FECrsMatrix::REPLACE:
01102           err = this->Epetra_CrsMatrix::ReplaceGlobalValues(rows[i], numCols,
01103               valuesptr, (int_type*)cols);
01104           if (err<0) return(err);
01105           if (err>0) returncode = err;
01106           break;
01107         case Epetra_FECrsMatrix::INSERT:
01108           err = this->Epetra_CrsMatrix::InsertGlobalValues(rows[i], numCols,
01109               valuesptr, (int_type*)cols);
01110           if (err<0) return(err);
01111           if (err>0) returncode = err;
01112           break;
01113         default:
01114           std::cerr << "Epetra_FECrsMatrix: internal error, bad input mode."<< std::endl;
01115           return(-1);
01116       }
01117     }
01118     else {
01119 #ifdef EPETRA_HAVE_OMP
01120 #ifdef EPETRA_HAVE_OMP_NONASSOCIATIVE
01121       if (! ignoreNonLocalEntries_) {
01122 #endif
01123 #endif
01124           err = InputNonlocalGlobalValues(rows[i], numCols, cols,
01125               valuesptr, mode);
01126           if (err<0) return(err);
01127           if (err>0) returncode = err;
01128 #ifdef EPETRA_HAVE_OMP
01129 #ifdef EPETRA_HAVE_OMP_NONASSOCIATIVE
01130       }
01131 #endif
01132 #endif
01133     }
01134   }
01135 
01136   return(returncode);
01137 }
01138 
01139 //----------------------------------------------------------------------------
01140 template<typename int_type>
01141 int Epetra_FECrsMatrix::InputGlobalValues(int numRows, const int_type* rows,
01142             int numCols, const int_type* cols,
01143             const double*const* values,
01144             int format, int mode)
01145 {
01146   if(!RowMap().template GlobalIndicesIsType<int_type>())
01147   throw ReportError("Epetra_FECrsMatrix::InputGlobalValues mismatch between argument types (int/long long) and map type.", -1);
01148 
01149   if (format != Epetra_FECrsMatrix::ROW_MAJOR &&
01150       format != Epetra_FECrsMatrix::COLUMN_MAJOR) {
01151     std::cerr << "Epetra_FECrsMatrix: unrecognized format specifier."<< std::endl;
01152     return(-1);
01153   }
01154 
01155   if (format == Epetra_FECrsMatrix::COLUMN_MAJOR) {
01156     workData_.resize(numCols);
01157   }
01158 
01159   int returncode = 0;
01160 
01161   for(int i=0; i<numRows; ++i) {
01162     if (format == Epetra_FECrsMatrix::ROW_MAJOR) {
01163       returncode += InputGlobalValues_RowMajor(1, &rows[i], numCols, cols,
01164                                           values[i], mode);
01165       if (returncode < 0) return returncode;
01166       continue;
01167     }
01168 
01169     //If we get to here, the data is in column-major order.
01170 
01171     double* valuesptr = &workData_[0];
01172 
01173     //Since the data is in column-major order, then we copy the i-th row
01174     //of the values table into workData_, in order to have the row in
01175     //contiguous memory.
01176     //This is slow and not thread-safe.
01177 
01178     for(int j=0; j<numCols; ++j) {
01179       valuesptr[j] = values[j][i];
01180     }
01181 
01182     returncode += InputGlobalValues_RowMajor(1, &rows[i], numCols, cols, valuesptr, mode);
01183     if (returncode < 0) return returncode;
01184   }
01185 
01186   return(returncode);
01187 }
01188 
01189 //----------------------------------------------------------------------------
01190 template<typename int_type>
01191 int Epetra_FECrsMatrix::InputGlobalValues(int numRows, const int_type* rows,
01192             int numCols, const int_type* cols,
01193             const double* values,
01194             int format, int mode)
01195 {
01196   if(!RowMap().template GlobalIndicesIsType<int_type>())
01197   throw ReportError("Epetra_FECrsMatrix::InputGlobalValues mismatch between argument types (int/long long) and map type.", -1);
01198 
01199   if (format == Epetra_FECrsMatrix::ROW_MAJOR) {
01200     return InputGlobalValues_RowMajor(numRows, rows, numCols, cols, values, mode);
01201   }
01202 
01203   workData_.resize(numCols);
01204 
01205   int returncode = 0;
01206   for(int i=0; i<numRows; ++i) {
01207     //copy each row out of the column-major values array, so we can pass it
01208     //to a row-major input function.
01209     for(int j=0; j<numCols; ++j) {
01210       workData_[j] = values[i+j*numRows];
01211     }
01212     int err = InputGlobalValues_RowMajor(1, &rows[i], numCols, cols, &workData_[0], mode);
01213     if (err < 0) return err;
01214     returncode += err;
01215   }
01216 
01217   return(returncode);
01218 }
01219 
01220 //----------------------------------------------------------------------------
01221 template<typename int_type>
01222 int Epetra_FECrsMatrix::InputNonlocalGlobalValues(int_type row,
01223               int numCols, const int_type* cols,
01224               const double* values,
01225               int mode)
01226 {
01227   if(!RowMap().template GlobalIndicesIsType<int_type>())
01228   throw ReportError("Epetra_FECrsMatrix::InputNonlocalGlobalValues mismatch between argument types (int/long long) and map type.", -1);
01229 
01230   // if we already have a nonlocal matrix object, this is easier...
01231   if (useNonlocalMatrix_) {
01232     int err, returncode = 0;
01233     double* valuesptr = (double*)values;
01234     switch(mode) {
01235     case Epetra_FECrsMatrix::SUMINTO:
01236       err = nonlocalMatrix_->SumIntoGlobalValues(row, numCols,
01237             valuesptr, (int_type*)cols);
01238       if (err<0) return(err);
01239       if (err>0) returncode = err;
01240       break;
01241     case Epetra_FECrsMatrix::REPLACE:
01242       err = nonlocalMatrix_->ReplaceGlobalValues(row, numCols,
01243             valuesptr, (int_type*)cols);
01244       if (err<0) return(err);
01245       if (err>0) returncode = err;
01246       break;
01247     case Epetra_FECrsMatrix::INSERT:
01248       err = nonlocalMatrix_->InsertGlobalValues(row, numCols,
01249            valuesptr, (int_type*)cols);
01250       if (err<0) return(err);
01251       if (err>0) returncode = err;
01252       break;
01253     default:
01254       std::cerr << "Epetra_FECrsMatrix: internal error, bad input mode."<< std::endl;
01255       return(-1);
01256     }
01257     return (returncode);
01258   }
01259   int ierr1 = 0, ierr2 = 0;
01260 #ifdef EPETRA_HAVE_OMP
01261 #ifdef EPETRA_HAVE_OMP_NONASSOCIATIVE
01262 #pragma omp critical
01263 #endif
01264 #endif
01265   {
01266   std::vector<int_type>& nonlocalRows_var = nonlocalRows<int_type>();
01267 
01268   //find offset of this row in our list of nonlocal rows.
01269   typename std::vector<int_type>::iterator it =
01270       std::lower_bound(nonlocalRows_var.begin(), nonlocalRows_var.end(), row);
01271 
01272   int rowoffset = (int) (it - nonlocalRows_var.begin());
01273   if (it == nonlocalRows_var.end() || *it != row) {
01274     ierr1 = InsertNonlocalRow(row, it);
01275   }
01276 
01277   for(int i=0; i<numCols; ++i) {
01278     ierr2 = InputNonlocalValue(rowoffset, cols[i], values[i], mode);
01279   }
01280   }
01281   EPETRA_CHK_ERR(ierr1);
01282   EPETRA_CHK_ERR(ierr2);
01283 
01284   return(0);
01285 }
01286 
01287 //----------------------------------------------------------------------------
01288 template<typename int_type>
01289 int Epetra_FECrsMatrix::InsertNonlocalRow(int_type row, typename std::vector<int_type>::iterator iter)
01290 {
01291   if(!RowMap().template GlobalIndicesIsType<int_type>())
01292   throw ReportError("Epetra_FECrsMatrix::InsertNonlocalRow mismatch between argument types (int/long long) and map type.", -1);
01293 
01294   std::vector<int_type>& nonlocalRows_var = nonlocalRows<int_type>();
01295   std::vector<std::vector<int_type> >& nonlocalCols_var = nonlocalCols<int_type>();
01296 
01297   int offset = (int) (iter - nonlocalRows_var.begin());
01298   nonlocalRows_var.insert(iter, row);
01299   typename std::vector<std::vector<int_type> >::iterator cols_iter = nonlocalCols_var.begin() + offset;
01300   nonlocalCols_var.insert(cols_iter, std::vector<int_type>());
01301   std::vector<std::vector<double> >::iterator coefs_iter = nonlocalCoefs_.begin() + offset;
01302   nonlocalCoefs_.insert(coefs_iter, std::vector<double>());
01303 
01304   return(0);
01305 }
01306 
01307 //----------------------------------------------------------------------------
01308 template<typename int_type>
01309 int Epetra_FECrsMatrix::InputNonlocalValue(int rowoffset,
01310              int_type col, double value,
01311              int mode)
01312 {
01313   if(!RowMap().template GlobalIndicesIsType<int_type>())
01314   throw ReportError("Epetra_FECrsMatrix::InputNonlocalValue mismatch between argument types (int/long long) and map type.", -1);
01315 
01316   std::vector<int_type>& colIndices = nonlocalCols<int_type>()[rowoffset];
01317   std::vector<double>& coefs = nonlocalCoefs_[rowoffset];
01318 
01319   typename std::vector<int_type>::iterator it =
01320      std::lower_bound(colIndices.begin(), colIndices.end(), col);
01321 
01322   if (it == colIndices.end() || *it != col) {
01323     int offset = (int) (it - colIndices.begin());
01324     colIndices.insert(it, col);
01325     std::vector<double>::iterator dit = coefs.begin()+offset;
01326     coefs.insert(dit, value);
01327     return 0;
01328   }
01329 
01330   int coloffset = (int) (it - colIndices.begin());
01331   if (mode == SUMINTO || mode == INSERT) {
01332     coefs[coloffset] += value;
01333   }
01334   else {
01335     coefs[coloffset] = value;
01336   }
01337 
01338   return(0);
01339 }
01340 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines