EpetraExt Package Browser (Single Doxygen Collection) Development
EpetraExt_CrsMatrixIn.cpp
Go to the documentation of this file.
00001 //@HEADER
00002 // ***********************************************************************
00003 //
00004 //     EpetraExt: Epetra Extended - Linear Algebra Services Package
00005 //                 Copyright (2011) Sandia Corporation
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 //@HEADER
00041 #include "EpetraExt_CrsMatrixIn.h"
00042 #include "Epetra_Comm.h"
00043 #include "Epetra_CrsMatrix.h"
00044 #include "Epetra_Map.h"
00045 #include "Epetra_IntVector.h"
00046 #include "Epetra_IntSerialDenseVector.h"
00047 #include "Epetra_Import.h"
00048 #include "Epetra_Time.h"
00049 #include "Epetra_Util.h"
00050 
00053 // Functions to read a MatrixMarket file and load it into a matrix.
00054 // Adapted from 
00055 //    Trilinos/packages/epetraext/src/inout/EpetraExt_CrsMatrixIn.cpp
00056 // Modified by Jon Berry and Karen Devine to make matrix reallocations 
00057 // more efficient; rather than insert each non-zero separately, we 
00058 // collect rows of non-zeros for insertion.
00059 // Modified by Karen Devine and Steve Plimpton to prevent all processors 
00060 // from reading the same file at the same time (ouch!); chunks of the file 
00061 // are read and broadcast by processor zero; each processor then extracts 
00062 // its nonzeros from the chunk, sorts them by row, and inserts them into 
00063 // the matrix.
00064 // The variable "chunk_read" can be changed to modify the size of the chunks
00065 // read from the file.  Larger values of chunk_read lead to faster execution
00066 // and greater memory use.
00069 
00070 using namespace EpetraExt;
00071 namespace EpetraExt {
00072 
00073 static void sort_three(int* list, int *parlista, double *parlistb, 
00074                        int start, int end);
00076 int MatrixMarketFileToCrsMatrix(const char *filename, 
00077     const Epetra_Comm & comm, Epetra_CrsMatrix * & A)
00078 {
00079   EPETRA_CHK_ERR(MatrixMarketFileToCrsMatrixHandle(filename, comm, A));
00080   return(0);
00081 }
00082 
00084 int MatrixMarketFileToCrsMatrix(const char *filename, 
00085     const Epetra_Comm & comm, Epetra_CrsMatrix * & A, const bool transpose)
00086 {
00087   EPETRA_CHK_ERR(MatrixMarketFileToCrsMatrixHandle(filename, comm, A,
00088                                                    0, 0, 0, 0, transpose));
00089   return(0);
00090 }
00092   
00093 int MatrixMarketFileToCrsMatrix(const char *filename, 
00094     const Epetra_Comm & comm, Epetra_CrsMatrix * & A, const bool transpose,
00095     const bool verbose) 
00096 {
00097   EPETRA_CHK_ERR(MatrixMarketFileToCrsMatrixHandle(filename, comm, A,
00098                                                    0, 0, 0, 0,
00099                                                    transpose, verbose));
00100   return(0);
00101 }
00102   
00104 int MatrixMarketFileToCrsMatrix(const char *filename, 
00105     const Epetra_Map & rowMap, const Epetra_Map& rangeMap, 
00106     const Epetra_Map& domainMap, Epetra_CrsMatrix * & A, const bool transpose,
00107     const bool verbose) 
00108 {
00109   EPETRA_CHK_ERR(MatrixMarketFileToCrsMatrixHandle(filename, 
00110                                                    rowMap.Comm(), A,
00111                                                    &rowMap, 0, 
00112                                                    &rangeMap, &domainMap,
00113                                                    transpose, verbose));
00114   return(0);
00115 }
00116 
00118 int MatrixMarketFileToCrsMatrix(const char *filename, 
00119     const Epetra_Map & rowMap, Epetra_CrsMatrix * & A, const bool transpose,
00120     const bool verbose) 
00121 {
00122   EPETRA_CHK_ERR(MatrixMarketFileToCrsMatrixHandle(filename, 
00123                                                    rowMap.Comm(), A,
00124                                                    &rowMap, 0, 0, 0, 
00125                                                    transpose, verbose));
00126   return(0);
00127 }
00128 
00130 int MatrixMarketFileToCrsMatrix(const char *filename, 
00131     const Epetra_Map & rowMap, const Epetra_Map & colMap, 
00132     Epetra_CrsMatrix * & A, const bool transpose,
00133     const bool verbose) 
00134 {
00135   EPETRA_CHK_ERR(MatrixMarketFileToCrsMatrixHandle(filename, 
00136                                                    rowMap.Comm(), A,
00137                                                    &rowMap, &colMap, 0, 0,
00138                                                    transpose, verbose));
00139   return(0);
00140 }
00141 
00143 int MatrixMarketFileToCrsMatrix(const char *filename, 
00144     const Epetra_Map & rowMap, const Epetra_Map & colMap,
00145     const Epetra_Map& rangeMap, const Epetra_Map& domainMap, 
00146     Epetra_CrsMatrix * & A, const bool transpose,
00147     const bool verbose) 
00148 {
00149   EPETRA_CHK_ERR(MatrixMarketFileToCrsMatrixHandle(filename, 
00150                                                    rowMap.Comm(), A, 
00151                                                    &rowMap, &colMap, 
00152                                                    &rangeMap, &domainMap,
00153                                                    transpose, verbose));
00154   return(0);
00155 }
00156 
00158 int MatrixMarketFileToCrsMatrixHandle(const char *filename,
00159   const Epetra_Comm & comm,
00160   Epetra_CrsMatrix * & A,
00161   const Epetra_Map * rowMap,
00162   const Epetra_Map * colMap,
00163   const Epetra_Map * rangeMap,
00164   const Epetra_Map * domainMap,
00165   const bool transpose,
00166   const bool verbose
00167 )
00168 {
00169   const int chunk_read = 500000;  //  Modify this variable to change the
00170                                   //  size of the chunks read from the file.
00171   const int headerlineLength = 257;
00172   const int lineLength = 81;
00173   const int tokenLength = 35;
00174   char line[headerlineLength];
00175   char token1[tokenLength];
00176   char token2[tokenLength];
00177   char token3[tokenLength];
00178   char token4[tokenLength];
00179   char token5[tokenLength];
00180   int M, N, NZ;      // Matrix dimensions
00181   int i;
00182   int me = comm.MyPID();
00183 
00184   Epetra_Time timer(comm);
00185 
00186   // Make sure domain and range maps are either both defined or undefined 
00187   if ((domainMap!=0 && rangeMap==0) || (domainMap==0 && rangeMap!=0)) {
00188     EPETRA_CHK_ERR(-3);
00189   }
00190 
00191   // check maps to see if domain and range are 1-to-1
00192 
00193   if (domainMap!=0) {
00194     if (!domainMap->UniqueGIDs()) {EPETRA_CHK_ERR(-2);}
00195     if (!rangeMap->UniqueGIDs()) {EPETRA_CHK_ERR(-2);}
00196   }
00197   else {
00198     // If domain and range are not specified, 
00199     // rowMap becomes both and must be 1-to-1 if specified
00200     if (rowMap!=0) {
00201       if (!rowMap->UniqueGIDs()) {EPETRA_CHK_ERR(-2);}
00202     }
00203   }
00204       
00205   FILE * handle = 0;
00206   if (me == 0) {
00207     if (verbose) cout << "Reading MatrixMarket file " << filename << endl;
00208     handle = fopen(filename,"r");  // Open file
00209     if (handle == 0)
00210       EPETRA_CHK_ERR(-1); // file not found
00211 
00212     // Check first line, which should be 
00213     // %%MatrixMarket matrix coordinate real general
00214     if(fgets(line, headerlineLength, handle)==0) {
00215       if (handle!=0) fclose(handle); 
00216       EPETRA_CHK_ERR(-1);
00217     }
00218     if(sscanf(line, "%s %s %s %s %s", token1,token2,token3,token4,token5)==0) {
00219       if (handle!=0) fclose(handle); 
00220       EPETRA_CHK_ERR(-1);
00221     }
00222     if (strcmp(token1, "%%MatrixMarket") ||
00223         strcmp(token2, "matrix") ||
00224         strcmp(token3, "coordinate") ||
00225         strcmp(token4, "real") ||
00226         strcmp(token5, "general")) {
00227       if (handle!=0) fclose(handle); 
00228       EPETRA_CHK_ERR(-1);
00229     }
00230 
00231     // Next, strip off header lines (which start with "%")
00232     do {
00233       if(fgets(line, headerlineLength, handle)==0) {
00234         if (handle!=0) fclose(handle); 
00235         EPETRA_CHK_ERR(-1);
00236       }
00237     } while (line[0] == '%');
00238 
00239     // Next get problem dimensions: M, N, NZ
00240     if(sscanf(line, "%d %d %d", &M, &N, &NZ)==0) {
00241       if (handle!=0) fclose(handle); 
00242       EPETRA_CHK_ERR(-1);
00243     }
00244   }
00245   comm.Broadcast(&M, 1, 0);
00246   comm.Broadcast(&N, 1, 0);
00247   comm.Broadcast(&NZ, 1, 0);
00248 
00249   // Now create matrix using user maps if provided.
00250 
00251 
00252   // Now read in chunks of triplets and broadcast them to other processors.
00253   char *buffer = new char[chunk_read*lineLength];
00254   int nchunk; 
00255   int nmillion = 0;
00256   int nread = 0;
00257   int rlen;
00258 
00259   // Storage for this processor's nonzeros.
00260   const int localblock = 100000;
00261   int localsize = NZ / comm.NumProc() + localblock;
00262   int *iv = (int *) malloc(localsize * sizeof(int));
00263   int *jv = (int *) malloc(localsize * sizeof(int));
00264   double *vv = (double *) malloc(localsize * sizeof(double));
00265   int lnz = 0;   //  Number of non-zeros on this processor.
00266 
00267   if (!iv || !jv || !vv) 
00268     EPETRA_CHK_ERR(-1);
00269 
00270   Epetra_Map *rowMap1;
00271   bool allocatedHere=false;
00272   if (rowMap != 0) 
00273     rowMap1 = const_cast<Epetra_Map *>(rowMap);
00274   else {
00275     rowMap1 = new Epetra_Map(M, 0, comm);
00276     allocatedHere = true;
00277   }
00278   int ioffset = rowMap1->IndexBase()-1;
00279   int joffset = (colMap != 0 ? colMap->IndexBase()-1 : ioffset);
00280 
00281   int rowmajor = 1;  // Assume non-zeros are listed in row-major order, 
00282   int prevrow = -1;  // but test to detect otherwise.  If non-zeros
00283                      // are row-major, we can avoid the sort.
00284 
00285   while (nread < NZ) {
00286     if (NZ-nread > chunk_read) nchunk = chunk_read;
00287     else nchunk = NZ - nread;
00288 
00289     if (me == 0) {
00290       char *eof;
00291       rlen = 0;
00292       for (int i = 0; i < nchunk; i++) {
00293         eof = fgets(&buffer[rlen],lineLength,handle);
00294         if (eof == NULL) {
00295           fprintf(stderr, "%s", "Unexpected end of matrix file.");
00296           EPETRA_CHK_ERR(-1);
00297         }
00298         rlen += strlen(&buffer[rlen]);
00299       }
00300       buffer[rlen++]='\n';
00301     }
00302     comm.Broadcast(&rlen, 1, 0);
00303     comm.Broadcast(buffer, rlen, 0);
00304 
00305     buffer[rlen++] = '\0';
00306     nread += nchunk;
00307 
00308     // Process the received data, saving non-zeros belonging on this proc.
00309     char *lineptr = buffer;
00310     for (rlen = 0; rlen < nchunk; rlen++) {
00311       char *next = strchr(lineptr,'\n');
00312       int I = atoi(strtok(lineptr," \t\n")) + ioffset;
00313       int J = atoi(strtok(NULL," \t\n")) + joffset;
00314       double V = atof(strtok(NULL," \t\n"));
00315       lineptr = next + 1;
00316       if (transpose) {
00317         // swap I and J indices.
00318         int tmp = I;
00319         I = J;
00320         J = tmp;
00321       }
00322       if (rowMap1->MyGID(I)) {
00323         //  This processor keeps this non-zero.
00324         if (lnz >= localsize) {  
00325           // Need more memory to store nonzeros.
00326           localsize += localblock;
00327           iv = (int *) realloc(iv, localsize * sizeof(int));
00328           jv = (int *) realloc(jv, localsize * sizeof(int));
00329           vv = (double *) realloc(vv, localsize * sizeof(double));
00330         }
00331         iv[lnz] = I;
00332         jv[lnz] = J;
00333         vv[lnz] = V;
00334         lnz++;
00335         if (I < prevrow) rowmajor = 0;
00336         prevrow = I;
00337       }
00338     }
00339 
00340     // Status check
00341     if (nread / 1000000 > nmillion) {
00342       nmillion++;
00343       if (verbose && me == 0) cout << nmillion << "M ";
00344     }
00345   }
00346 
00347   delete [] buffer;
00348 
00349   if (!rowmajor) {
00350     // Sort into row-major order (by iv) so can insert entire rows at once.
00351     // Reorder jv and vv to parallel iv.
00352     if (verbose && me == 0) cout << endl << "   Sorting local nonzeros" << endl;
00353     sort_three(iv, jv, vv, 0, lnz-1);
00354   }
00355 
00356   //  Compute number of entries per local row for use in constructor;
00357   //  saves reallocs in FillComplete.
00358 
00359   //  Now construct the matrix.
00360   //  Count number of entries in each row so can use StaticProfile=2.
00361   if (verbose && me == 0) cout << endl << "   Constructing the matrix" << endl;
00362   int numRows = rowMap1->NumMyElements();
00363   int *numNonzerosPerRow = new int[numRows];
00364   for (i = 0; i < numRows; i++) numNonzerosPerRow[i] = 0;
00365   for (i = 0; i < lnz; i++) 
00366     numNonzerosPerRow[rowMap1->LID(iv[i])]++;
00367 
00368   if (rowMap!=0 && colMap !=0) 
00369     A = new Epetra_CrsMatrix(Copy, *rowMap, *colMap, numNonzerosPerRow);
00370   else if (rowMap!=0) {
00371     // Construct with StaticProfile=true since we know numNonzerosPerRow.
00372     // Less memory will be needed in FillComplete.
00373     A = new Epetra_CrsMatrix(Copy, *rowMap, numNonzerosPerRow, true);
00374   }
00375   else {
00376     // Construct with StaticProfile=true since we know numNonzerosPerRow.
00377     // Less memory will be needed in FillComplete.
00378     A = new Epetra_CrsMatrix(Copy, *rowMap1, numNonzerosPerRow, true);
00379   }
00380   A->SetTracebackMode(1);
00381 
00382   // Rows are inserted in ascending global number, and the insertion uses numNonzerosPerRow.
00383   // Therefore numNonzerosPerRow must be permuted, as it was created in ascending local order.
00384   int *gidList = new int[numRows];
00385   for (i = 0; i < numRows; i++) gidList[i] = rowMap1->GID(i);
00386   Epetra_Util::Sort(true,numRows,gidList,0,0,1,&numNonzerosPerRow);
00387   delete [] gidList;
00388 
00389   //  Insert the global values into the matrix row-by-row.
00390   if (verbose && me == 0) cout << "   Inserting global values" << endl;
00391   for (int sum = 0, i = 0; i < numRows; i++) {
00392     if (numNonzerosPerRow[i]) {
00393       int ierr = A->InsertGlobalValues(iv[sum], numNonzerosPerRow[i], 
00394                                        &vv[sum], &jv[sum]);
00395       if (ierr<0) EPETRA_CHK_ERR(ierr);
00396       sum += numNonzerosPerRow[i];
00397     }
00398   }
00399 
00400   delete [] numNonzerosPerRow;
00401   free(iv);
00402   free(jv);
00403   free(vv);
00404     
00405   if (verbose && me == 0) cout << "   Completing matrix fill" << endl;
00406   if (rangeMap != 0 && domainMap != 0) {
00407     EPETRA_CHK_ERR(A->FillComplete(*domainMap, *rangeMap));
00408   }
00409   else if (M!=N) {
00410     Epetra_Map newDomainMap(N,rowMap1->IndexBase(), comm);
00411     EPETRA_CHK_ERR(A->FillComplete(newDomainMap, *rowMap1));
00412   }
00413   else {
00414     EPETRA_CHK_ERR(A->FillComplete());
00415   }
00416 
00417   if (allocatedHere) delete rowMap1;
00418   
00419   if (handle!=0) fclose(handle);
00420   double dt = timer.ElapsedTime();
00421   if (verbose && me == 0) cout << "File Read time (secs):  " << dt << endl;
00422   return(0);
00423 }
00424 
00426 // Sorting values in array list in increasing order. Criteria is int. 
00427 // Also rearrange values in arrays parlista and partlistb
00428 // to match the new order of list. 
00429 
00430 static void quickpart_list_inc_int (
00431   int *list, int *parlista, double *parlistb,
00432   int start, int end, int *equal, int *larger)
00433 {
00434 int i, key, itmp;
00435 double dtmp;
00436 
00437   key = list ? list[(end+start)/2] : 1;
00438 
00439   *equal = *larger = start;
00440   for (i = start; i <= end; i++)
00441     if (list[i] < key) {
00442       itmp                = parlista[i];
00443       parlista[i]         = parlista[*larger];
00444       parlista[(*larger)] = parlista[*equal];
00445       parlista[(*equal)]  = itmp;
00446       dtmp                = parlistb[i];
00447       parlistb[i]         = parlistb[*larger];
00448       parlistb[(*larger)] = parlistb[*equal];
00449       parlistb[(*equal)]  = dtmp;
00450       itmp                = list[i];
00451       list[i]             = list[*larger];
00452       list[(*larger)++]   = list[*equal];
00453       list[(*equal)++]    = itmp;
00454     }
00455     else if (list[i] == key) {
00456       itmp                = parlista[i];
00457       parlista[i]         = parlista[*larger];
00458       parlista[(*larger)] = itmp;
00459       dtmp                = parlistb[i];
00460       parlistb[i]         = parlistb[*larger];
00461       parlistb[(*larger)] = dtmp;
00462       list[i]             = list[*larger];
00463       list[(*larger)++]   = key;
00464     }
00465 }
00466 
00468 static void sort_three(int* list, int *parlista, double *parlistb, 
00469                        int start, int end)
00470 {
00471 int  equal, larger;
00472 
00473   if (start < end) {
00474     quickpart_list_inc_int(list, parlista, parlistb, start, end, 
00475                            &equal, &larger);
00476     sort_three(list, parlista, parlistb, start,  equal-1);
00477     sort_three(list, parlista, parlistb, larger, end);
00478   }
00479 }
00480 
00482 int MatlabFileToCrsMatrix(const char *filename,
00483         const Epetra_Comm & comm,
00484         Epetra_CrsMatrix * & A)
00485 {
00486   const int lineLength = 1025;
00487   char line[lineLength];
00488   int I, J;
00489   double V;
00490 
00491   FILE * handle = 0;
00492 
00493   handle = fopen(filename,"r");  // Open file
00494   if (handle == 0)
00495     EPETRA_CHK_ERR(-1); // file not found
00496 
00497   int numGlobalRows = 0;
00498   int numGlobalCols = 0;
00499   while(fgets(line, lineLength, handle)!=0) {
00500     if(sscanf(line, "%d %d %lg\n", &I, &J, &V)==0) {if (handle!=0) fclose(handle); EPETRA_CHK_ERR(-1);}
00501     if (I>numGlobalRows) numGlobalRows = I;
00502     if (J>numGlobalCols) numGlobalCols = J;
00503   }
00504 
00505   if (handle!=0) fclose(handle);
00506   Epetra_Map rangeMap(numGlobalRows, 0, comm);
00507   Epetra_Map domainMap(numGlobalCols, 0, comm);
00508   A = new Epetra_CrsMatrix(Copy, rangeMap, 0);
00509 
00510   // Now read in each triplet and store to the local portion of the matrix if the row is owned.
00511   const Epetra_Map & rowMap1 = A->RowMap();
00512   
00513   handle = 0;
00514 
00515   handle = fopen(filename,"r");  // Open file
00516   if (handle == 0)
00517     EPETRA_CHK_ERR(-1); // file not found
00518 
00519   while (fgets(line, lineLength, handle)!=0) {
00520     if(sscanf(line, "%d %d %lg\n", &I, &J, &V)==0) {if (handle!=0) fclose(handle); EPETRA_CHK_ERR(-1);}
00521     I--; J--; // Convert to Zero based
00522     if (rowMap1.MyGID(I)) {
00523       int ierr = A->InsertGlobalValues(I, 1, &V, &J);
00524       if (ierr<0) EPETRA_CHK_ERR(ierr);
00525     }
00526   }
00527     
00528   EPETRA_CHK_ERR(A->FillComplete(domainMap, rangeMap));
00529 
00530   if (handle!=0) fclose(handle);
00531   return(0);
00532 }
00533 
00534 int HypreFileToCrsMatrix(const char *filename, const Epetra_Comm &comm, Epetra_CrsMatrix *&Matrix){
00535   int MyPID = comm.MyPID();
00536   // This double will be in the format we want for the extension besides the leading zero
00537   double filePID = (double)MyPID/(double)100000;
00538   std::ostringstream stream;
00539   // Using setprecision() puts it in the string
00540   stream << std::setiosflags(std::ios::fixed) << std::setprecision(5) << filePID;
00541   // Then just ignore the first character
00542   std::string fileName(filename);
00543   fileName += stream.str().substr(1,7);
00544   // Open the file
00545   std::ifstream file(fileName.c_str());
00546   string line;
00547   if(file.is_open()){
00548     std::getline(file, line);
00549     int ilower, iupper;
00550     std::istringstream istream(line);
00551     // The first line of the file has the beginning and ending rows
00552     istream >> ilower;
00553     istream >> iupper;
00554     // Using those we can create a row map
00555     Epetra_Map RowMap(-1, iupper-ilower+1, 0, comm);
00556     Matrix = new Epetra_CrsMatrix(Copy, RowMap, 0);
00557     int currRow = -1;
00558     int counter = 0;
00559     std::vector<int> indices;
00560     std::vector<double> values;
00561     while(!file.eof()){
00562       std::getline(file, line);
00563       std::istringstream lineStr(line);
00564       int row, col;
00565       double val;
00566       lineStr >> row;
00567       lineStr >> col;
00568       lineStr >> val;
00569       if(currRow == -1) currRow = row; // First line
00570       if(row == currRow){
00571         // add to the vector
00572         counter = counter + 1;
00573         indices.push_back(col);
00574         values.push_back(val);
00575       } else {
00576         Matrix->InsertGlobalValues(currRow, counter, &values[0], &indices[0]);
00577         indices.clear();
00578         values.clear();
00579         counter = 0;
00580         currRow = row;
00581         // make a new vector
00582         indices.push_back(col);
00583         values.push_back(val);
00584         counter = counter + 1;
00585       }
00586     }
00587     Matrix->InsertGlobalValues(currRow, counter, &values[0], &indices[0]);
00588     Matrix->Comm().Barrier();
00589     Matrix->FillComplete();
00590     file.close();
00591     return 0;
00592   } else {
00593     cout << "\nERROR:\nCouldn't open " << fileName << ".\n";
00594     return -1;
00595   }
00596 }
00597 
00598 } // namespace EpetraExt
00599 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines