Epetra Package Browser (Single Doxygen Collection) Development
FECrsGraph/ExecuteTestProblems.cpp
Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 // 
00004 //               Epetra: Linear Algebra Services Package 
00005 //                 Copyright 2001 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 
00042 
00043 #include "Epetra_BLAS.h"
00044 #include "ExecuteTestProblems.h"
00045 #include "Epetra_Comm.h"
00046 #include "Epetra_Map.h"
00047 #include "Epetra_Vector.h"
00048 #include "Epetra_FECrsGraph.h"
00049 #include "Epetra_FECrsMatrix.h"
00050 #include "Epetra_IntSerialDenseVector.h"
00051 #include "Epetra_SerialDenseMatrix.h"
00052 
00053 
00054 int Drumm1(const Epetra_Map& map, bool verbose)
00055 {
00056   //Simple 2-element problem (element as in "finite-element") from
00057   //Clif Drumm. Two triangular elements, one per processor, as shown
00058   //here:
00059   //
00060   //   *----*
00061   //  3|\  2|
00062   //   | \  |
00063   //   | 0\1|
00064   //   |   \|
00065   //   *----*
00066   //  0    1
00067   //
00068   //Element 0 on processor 0, element 1 on processor 1.
00069   //Processor 0 will own nodes 0,1 and processor 1 will own nodes 2,3.
00070   //Each processor will pass a 3x3 element-connectivity-matrix to
00071   //Epetra_FECrsGraph.
00072   //After GlobalAssemble(), the graph should be as follows:
00073   //
00074   //         row 0: 2  1  0  1
00075   //proc 0   row 1: 1  4  1  2
00076   //----------------------------------
00077   //         row 2: 0  1  2  1
00078   //proc 1   row 3: 1  2  1  4
00079   //
00080 
00081   int numProcs = map.Comm().NumProc();
00082   int localProc = map.Comm().MyPID();
00083 
00084   if (numProcs != 2) return(0);
00085 
00086   int indexBase = 0, ierr = 0;
00087 
00088   int numMyNodes = 2;
00089   int* myNodes = new int[numMyNodes];
00090 
00091   if (localProc == 0) {
00092     myNodes[0] = 0;
00093     myNodes[1] = 1;
00094   }
00095   else {
00096     myNodes[0] = 2;
00097     myNodes[1] = 3;
00098   }
00099 
00100   Epetra_Map Map(-1, numMyNodes, myNodes, indexBase, map.Comm());
00101 
00102   delete [] myNodes;
00103   numMyNodes = 3;
00104   myNodes = new int[numMyNodes];
00105 
00106   if (localProc == 0) {
00107     myNodes[0] = 0;
00108     myNodes[1] = 1;
00109     myNodes[2] = 3;
00110   }
00111   else {
00112     myNodes[0] = 1;
00113     myNodes[1] = 2;
00114     myNodes[2] = 3;
00115   }
00116 
00117   int rowLengths = 3;
00118   Epetra_FECrsGraph A(Copy, Map, rowLengths);
00119 
00120   EPETRA_TEST_ERR( A.InsertGlobalIndices(numMyNodes, myNodes,
00121            numMyNodes, myNodes),ierr);
00122 
00123   EPETRA_TEST_ERR( A.GlobalAssemble(), ierr );
00124 
00125   if (verbose) {
00126     A.Print(std::cout);
00127   }
00128 
00129   delete [] myNodes;
00130 
00131   return(0);
00132 }
00133 
00134 int Drumm2(const Epetra_Map& map, bool verbose)
00135 {
00136   //Simple 2-element problem (element as in "finite-element") from
00137   //Clif Drumm. Two triangular elements, one per processor, as shown
00138   //here:
00139   //
00140   //   *----*
00141   //  3|\  2|
00142   //   | \  |
00143   //   | 0\1|
00144   //   |   \|
00145   //   *----*
00146   //  0    1
00147   //
00148   //Element 0 on processor 0, element 1 on processor 1.
00149   //Processor 0 will own nodes 0,1,3 and processor 1 will own node 2.
00150   //Each processor will pass a 3x3 element-connectivity-matrix to
00151   //Epetra_FECrsGraph.
00152   //After GlobalAssemble(), the graph should be as follows:
00153   //
00154   //         row 0: 2  1  0  1
00155   //proc 0   row 1: 1  4  1  2
00156   //         row 2: 0  1  2  1
00157   //----------------------------------
00158   //proc 1   row 3: 1  2  1  4
00159   //
00160 
00161   int numProcs = map.Comm().NumProc();
00162   int localProc = map.Comm().MyPID();
00163 
00164   if (numProcs != 2) return(0);
00165 
00166   int indexBase = 0, ierr = 0;
00167   int numMyNodes = 3;
00168   int* myNodes = new int[numMyNodes];
00169 
00170   if (localProc == 0) {
00171     myNodes[0] = 0;
00172     myNodes[1] = 1;
00173     myNodes[2] = 3;
00174   }
00175   else {
00176     numMyNodes = 1;
00177     myNodes[0] = 2;
00178   }
00179 
00180   Epetra_Map Map(-1, numMyNodes, myNodes, indexBase, map.Comm());
00181 
00182   int rowLengths = 3;
00183   Epetra_FECrsGraph A(Copy, Map, rowLengths);
00184 
00185   if (localProc != 0) {
00186     numMyNodes = 3;
00187     myNodes[0] = 1;
00188     myNodes[1] = 2;
00189     myNodes[2] = 3;
00190   }
00191 
00192   EPETRA_TEST_ERR( A.InsertGlobalIndices(numMyNodes, myNodes,
00193            numMyNodes, myNodes),ierr);
00194 
00195   EPETRA_TEST_ERR( A.GlobalAssemble(), ierr );
00196 
00197   if (verbose) {
00198     A.Print(std::cout);
00199   }
00200 
00201   delete [] myNodes;
00202 
00203   return(0);
00204 }
00205 
00206 int four_quads(const Epetra_Comm& Comm, bool preconstruct_graph, bool verbose)
00207 {
00208   if (verbose) {
00209     std::cout << "******************* four_quads ***********************"<<std::endl;
00210   }
00211 
00212   //This function assembles a matrix representing a finite-element
00213   //mesh of four 2-D quad elements. There are 9 nodes in the problem. The
00214   //same problem is assembled no matter how many processors are being used
00215   //(within reason). It may not work if more than 9 processors are used.
00216   //
00217   //  *------*------*
00218   // 6|     7|     8|
00219   //  | E2   | E3   |
00220   //  *------*------*
00221   // 3|     4|     5|
00222   //  | E0   | E1   |
00223   //  *------*------*
00224   // 0      1      2
00225   //
00226   //Nodes are denoted by * with node-numbers below and left of each node.
00227   //E0, E1 and so on are element-numbers.
00228   //
00229   //Each processor will contribute a sub-matrix of size 4x4, filled with 1's,
00230   //for each element. Thus, the coefficient value at position 0,0 should end up
00231   //being 1.0*numProcs, the value at position 4,4 should be 1.0*4*numProcs, etc.
00232   //
00233   //Depending on the number of processors being used, the locations of the
00234   //specific matrix positions (in terms of which processor owns them) will vary.
00235   //
00236 
00237   int numProcs = Comm.NumProc();
00238 
00239   int numNodes = 9;
00240   int numElems = 4;
00241   int numNodesPerElem = 4;
00242 
00243   int indexBase = 0;
00244 
00245   //Create a map using epetra-defined linear distribution.
00246   Epetra_Map map(numNodes, indexBase, Comm);
00247 
00248   Epetra_FECrsGraph* graph = NULL;
00249 
00250   int* nodes = new int[numNodesPerElem];
00251   int i, err = 0;
00252 
00253   if (preconstruct_graph) {
00254     graph = new Epetra_FECrsGraph(Copy, map, 1);
00255 
00256     //we're going to fill the graph with indices, by passing our
00257     //connectivity lists.
00258     //FECrsGraph should accept indices in all rows, regardless of
00259     //whether map.MyGID(row) is true.
00260 
00261     for(i=0; i<numElems; ++i) {
00262       switch(i) {
00263       case 0:
00264   nodes[0] = 0; nodes[1] = 1; nodes[2] = 4; nodes[3] = 3;
00265   break;
00266       case 1:
00267   nodes[0] = 1; nodes[1] = 2; nodes[2] = 5; nodes[3] = 4;
00268   break;
00269       case 2:
00270   nodes[0] = 3; nodes[1] = 4; nodes[2] = 7; nodes[3] = 6;
00271   break;
00272       case 3:
00273   nodes[0] = 4; nodes[1] = 5; nodes[2] = 8; nodes[3] = 7;
00274   break;
00275       }
00276 
00277       err = graph->InsertGlobalIndices(numNodesPerElem, nodes,
00278                                        numNodesPerElem, nodes);
00279       if (err < 0) {
00280         std::cerr << "ERROR, FECrsGraph error in InsertGlobalIndices, err="
00281           << err << std::endl;
00282         return(-1);
00283       }
00284     }
00285 
00286     EPETRA_CHK_ERR( graph->GlobalAssemble() );
00287   }
00288 
00289   Epetra_FECrsMatrix* A = NULL;
00290 
00291   if (preconstruct_graph) {
00292     A = new Epetra_FECrsMatrix(Copy, *graph);
00293   }
00294   else {
00295     A = new Epetra_FECrsMatrix(Copy, map, 1);
00296   }
00297 
00298   EPETRA_CHK_ERR( A->PutScalar(0.0) );
00299 
00300   double* values_1d = new double[numNodesPerElem*numNodesPerElem];
00301   double** values_2d = new double*[numNodesPerElem];
00302 
00303   for(i=0; i<numNodesPerElem*numNodesPerElem; ++i) values_1d[i] = 1.0;
00304 
00305   int offset = 0;
00306   for(i=0; i<numNodesPerElem; ++i) {
00307     values_2d[i] = &(values_1d[offset]);
00308     offset += numNodesPerElem;
00309   }
00310 
00311   int format = Epetra_FECrsMatrix::ROW_MAJOR;
00312   Epetra_IntSerialDenseVector epetra_nodes(View, nodes, numNodesPerElem);
00313   Epetra_SerialDenseMatrix epetra_values(View, values_1d, numNodesPerElem,
00314            numNodesPerElem, numNodesPerElem);
00315 
00316   for(i=0; i<numElems; ++i) {
00317     switch(i) {
00318     case 0:
00319       nodes[0] = 0; nodes[1] = 1; nodes[2] = 4; nodes[3] = 3;
00320       if (preconstruct_graph) {
00321   err = A->SumIntoGlobalValues(epetra_nodes,
00322              epetra_values, format);
00323   if (err<0) return(err);
00324       }
00325       else {
00326   err = A->InsertGlobalValues(epetra_nodes,
00327             epetra_values, format);
00328   if (err<0) return(err);
00329       }
00330       break;
00331 
00332     case 1:
00333       nodes[0] = 1; nodes[1] = 2; nodes[2] = 5; nodes[3] = 4;
00334       if (preconstruct_graph) {
00335   err = A->SumIntoGlobalValues(numNodesPerElem, nodes,
00336              values_2d, format);
00337   if (err<0) return(err);
00338       }
00339       else {
00340   err = A->InsertGlobalValues(numNodesPerElem, nodes,
00341             values_2d, format);
00342   if (err<0) return(err);
00343       }
00344       break;
00345 
00346     case 2:
00347       nodes[0] = 3; nodes[1] = 4; nodes[2] = 7; nodes[3] = 6;
00348       if (preconstruct_graph) {
00349   err = A->SumIntoGlobalValues(numNodesPerElem, nodes,
00350              numNodesPerElem, nodes,
00351              values_1d, format);
00352   if (err<0) return(err);
00353       }
00354       else {
00355   err = A->InsertGlobalValues(numNodesPerElem, nodes,
00356             numNodesPerElem, nodes,
00357             values_1d, format);
00358   if (err<0) return(err);
00359       }
00360       break;
00361 
00362      case 3:
00363       nodes[0] = 4; nodes[1] = 5; nodes[2] = 8; nodes[3] = 7;
00364       if (preconstruct_graph) {
00365   err = A->SumIntoGlobalValues(numNodesPerElem, nodes,
00366              numNodesPerElem, nodes,
00367              values_2d, format);
00368   if (err<0) return(err);
00369       }
00370       else {
00371   err = A->InsertGlobalValues(numNodesPerElem, nodes,
00372             numNodesPerElem, nodes,
00373             values_2d, format);
00374   if (err<0) return(err);
00375       }
00376       break;
00377     }
00378   }
00379 
00380   err = A->GlobalAssemble();
00381   if (err < 0) {
00382     return(err);
00383   }
00384 
00385   Epetra_Vector x(A->RowMap()), y(A->RowMap());
00386 
00387   x.PutScalar(1.0); y.PutScalar(0.0);
00388 
00389   Epetra_FECrsMatrix Acopy(*A);
00390 
00391   Epetra_Vector x2(Acopy.RowMap()), y2(Acopy.RowMap());
00392 
00393   x2.PutScalar(1.0); y2.PutScalar(0.0);
00394 
00395   A->Multiply(false, x, y);
00396 
00397   Acopy.Multiply(false, x2, y2);
00398 
00399   double ynorm2, y2norm2;
00400 
00401   y.Norm2(&ynorm2);
00402   y2.Norm2(&y2norm2);
00403   if (ynorm2 != y2norm2) {
00404     std::cerr << "norm2(A*ones) != norm2(Acopy*ones)"<<std::endl;
00405     return(-99);
00406   }
00407 
00408   err = Acopy.GlobalAssemble();
00409   if (err < 0) {
00410     return(err);
00411   }
00412 
00413   if (verbose) {
00414     std::cout << "A:"<<std::endl<<*A << std::endl;
00415     std::cout << "Acopy:"<<std::endl<<Acopy << std::endl;
00416   }
00417 
00418   Epetra_FECrsMatrix Acopy2(Copy, A->RowMap(), A->ColMap(), 1);
00419 
00420   Acopy2 = Acopy;
00421 
00422   Epetra_Vector x3(Acopy.RowMap()), y3(Acopy.RowMap());
00423 
00424   x3.PutScalar(1.0); y3.PutScalar(0.0);
00425 
00426   Acopy2.Multiply(false, x3, y3);
00427 
00428   double y3norm2;
00429   y3.Norm2(&y3norm2);
00430 
00431   if (y3norm2 != y2norm2) {
00432     std::cerr << "norm2(Acopy*ones) != norm2(Acopy2*ones)"<<std::endl;
00433     return(-999);
00434   }
00435 
00436   int len = 20;
00437   int* indices = new int[len];
00438   double* values = new double[len];
00439   int numIndices;
00440 
00441   if (map.MyGID(0)) {
00442     EPETRA_CHK_ERR( A->ExtractGlobalRowCopy(0, len, numIndices,
00443               values, indices) );
00444     if (numIndices != 4) {
00445       return(-1);
00446     }
00447     if (indices[0] != 0) {
00448       return(-2);
00449     }
00450 
00451     if (values[0] != 1.0*numProcs) {
00452       std::cout << "ERROR: values[0] ("<<values[0]<<") should be "<<numProcs<<std::endl;
00453       return(-3);
00454     }
00455   }
00456 
00457   if (map.MyGID(4)) {
00458     EPETRA_CHK_ERR( A->ExtractGlobalRowCopy(4, len, numIndices,
00459               values, indices) );
00460 
00461     if (numIndices != 9) {
00462       return(-4);
00463     }
00464     int lcid = A->LCID(4);
00465     if (lcid<0) {
00466       return(-5);
00467     }
00468     if (values[lcid] != 4.0*numProcs) {
00469       std::cout << "ERROR: values["<<lcid<<"] ("<<values[lcid]<<") should be "
00470      <<4*numProcs<<std::endl;
00471       return(-6);
00472     }
00473   }
00474 
00475 // now let's do the checks for Acopy...
00476 
00477   if (map.MyGID(0)) {
00478     EPETRA_CHK_ERR( Acopy.ExtractGlobalRowCopy(0, len, numIndices,
00479                                             values, indices) );
00480     if (numIndices != 4) {
00481       return(-1);
00482     }
00483     if (indices[0] != 0) {
00484       return(-2);
00485     }
00486 
00487     if (values[0] != 1.0*numProcs) {
00488       std::cout << "ERROR: Acopy.values[0] ("<<values[0]<<") should be "<<numProcs<<std::endl;
00489       return(-3);
00490     }
00491   }
00492 
00493   if (map.MyGID(4)) {
00494     EPETRA_CHK_ERR( Acopy.ExtractGlobalRowCopy(4, len, numIndices,
00495                                             values, indices) );
00496 
00497     if (numIndices != 9) {
00498       return(-4);
00499     }
00500     int lcid = A->LCID(4);
00501     if (lcid<0) {
00502       return(-5);
00503     }
00504     if (values[lcid] != 4.0*numProcs) {
00505       std::cout << "ERROR: Acopy.values["<<lcid<<"] ("<<values[lcid]<<") should be "
00506            <<4*numProcs<<std::endl;
00507       return(-6);
00508     }
00509   }
00510 
00511 // now let's do the checks for Acopy2...
00512 
00513   if (map.MyGID(0)) {
00514     EPETRA_CHK_ERR( Acopy2.ExtractGlobalRowCopy(0, len, numIndices,
00515                                             values, indices) );
00516     if (numIndices != 4) {
00517       return(-1);
00518     }
00519     if (indices[0] != 0) {
00520       return(-2);
00521     }
00522 
00523     if (values[0] != 1.0*numProcs) {
00524       std::cout << "ERROR: Acopy2.values[0] ("<<values[0]<<") should be "<<numProcs<<std::endl;
00525       return(-3);
00526     }
00527   }
00528 
00529   if (map.MyGID(4)) {
00530     EPETRA_CHK_ERR( Acopy2.ExtractGlobalRowCopy(4, len, numIndices,
00531                                             values, indices) );
00532 
00533     if (numIndices != 9) {
00534       return(-4);
00535     }
00536     int lcid = A->LCID(4);
00537     if (lcid<0) {
00538       return(-5);
00539     }
00540     if (values[lcid] != 4.0*numProcs) {
00541       std::cout << "ERROR: Acopy2.values["<<lcid<<"] ("<<values[lcid]<<") should be "
00542            <<4*numProcs<<std::endl;
00543       return(-6);
00544     }
00545   }
00546 
00547   delete [] values_2d;
00548   delete [] values_1d;
00549   delete [] nodes;
00550   delete [] indices;
00551   delete [] values;
00552 
00553   delete A;
00554   delete graph;
00555 
00556   return(0);
00557 }
00558 
00559 int Young1(const Epetra_Comm& Comm, bool verbose)
00560 {
00561   //This is a test case submitted by Joe Young with bug 2421. It runs
00562   //only on 2 processors.
00563   if (Comm.NumProc() != 2) {
00564     return(0);
00565   }
00566 
00567   // Give rows 0-2 to proc 0 and 3-5 to proc 1
00568   int             RowIndices[3];
00569   if (Comm.MyPID() == 0) {
00570     RowIndices[0] = 0;
00571     RowIndices[1] = 1;
00572     RowIndices[2] = 2;
00573   } else {
00574     RowIndices[0] = 3;
00575     RowIndices[1] = 4;
00576     RowIndices[2] = 5;
00577   }
00578   Epetra_Map      RangeMap(-1, 3, RowIndices, 0, Comm);
00579   Epetra_Map & RowMap = RangeMap;
00580 
00581   // Define a second map that gives col 0 to proc 0 and col 1 to proc 1 
00582   int             ColIndices[1];
00583   if (Comm.MyPID() == 0) {
00584     ColIndices[0] = 0;
00585   }
00586   else {
00587     ColIndices[0] = 1;
00588   }
00589   Epetra_Map      DomainMap(-1, 1, ColIndices, 0, Comm);
00590 
00591   // Construct a graph where both processors only insert into local
00592   // elements
00593   Epetra_FECrsGraph BrokenGraph(Copy, RowMap, 2);
00594   for (int i = 0; i < RangeMap.NumMyElements(); i++) {
00595     int             ig = RowIndices[i];
00596     int             jgs[2] = { 0, 1 };
00597     BrokenGraph.InsertGlobalIndices(1, &ig, 2, jgs);
00598   }
00599   BrokenGraph.GlobalAssemble(DomainMap, RangeMap);
00600 
00601   // Check the size of the matrix that would be created from the graph 
00602   int numCols1 = BrokenGraph.NumGlobalCols();
00603   if (verbose) {
00604     std::cout << "Number of global rows in the graph where only "
00605         "local elements were inserted: " << BrokenGraph.NumGlobalRows()
00606       << std::endl;
00607     std::cout << "Number of global cols in the graph where only "
00608         "local elements were inserted: " << BrokenGraph.NumGlobalCols()
00609       << std::endl;
00610   }
00611   // Construct a graph where both processors insert into global elements
00612   Epetra_FECrsGraph Graph(Copy, RowMap, 2);
00613   for (int i = 0; i < 6; i++) {
00614     int             ig = i;
00615     int             jgs[2] = { 0, 1 };
00616     Graph.InsertGlobalIndices(1, &ig, 2, jgs);
00617   }
00618   Graph.GlobalAssemble(DomainMap, RangeMap);
00619 
00620   // Check the size of the matrix that would be created from the graph 
00621   int numCols2 = Graph.NumGlobalCols();
00622   if (verbose) {
00623     std::cout << "Number of global rows in the graph where "
00624         "global elements were inserted: " << Graph.NumGlobalRows()
00625        << std::endl;
00626     std::cout << "Number of global cols in the graph where "
00627         "global elements were inserted: " << Graph.NumGlobalCols()
00628       << std::endl;
00629   }
00630 
00631   if (numCols1 != numCols2) return(-1);
00632   return(0);
00633 }
00634 
00635 int rectangular(const Epetra_Comm& Comm, bool verbose)
00636 {
00637   int mypid = Comm.MyPID();
00638   int numlocalrows = 3;
00639   Epetra_Map rowmap(-1, numlocalrows, 0, Comm);
00640 
00641   int numglobalrows = numlocalrows*Comm.NumProc();
00642 
00643   int numcols = 2*numglobalrows;
00644 
00645   Epetra_FECrsGraph fegraph(Copy, rowmap, numcols);
00646 
00647   int* cols = new int[numcols];
00648   for(int j=0; j<numcols; ++j) cols[j] = j;
00649 
00650   Epetra_Map domainmap(-1, numcols, 0, Comm);
00651 
00652   int firstlocalrow = numlocalrows*mypid;
00653   int lastlocalrow = numlocalrows*(mypid+1)-1;
00654 
00655   for(int i=0; i<numglobalrows; ++i) {
00656     //if i is a local row, then skip it. We want each processor to only
00657     //load rows that belong on other processors.
00658     if (i >= firstlocalrow && i <= lastlocalrow) continue;
00659 
00660     EPETRA_CHK_ERR( fegraph.InsertGlobalIndices(1, &i, numcols, &(cols[0])) );
00661   }
00662 
00663   EPETRA_CHK_ERR( fegraph.GlobalAssemble(domainmap, rowmap) );
00664 
00665   if (verbose) {
00666     std::cout << "********************** fegraph **********************" << std::endl;
00667     std::cout << fegraph << std::endl;
00668   }
00669 
00670   delete [] cols;
00671 
00672   return(0);
00673 }
00674 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines