Anasazi  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
driver.cpp
1 // @HEADER
2 // *****************************************************************************
3 // Anasazi: Block Eigensolvers Package
4 //
5 // Copyright 2004 NTESS and the Anasazi contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 // This software is a result of the research described in the report
11 //
12 // "A comparison of algorithms for modal analysis in the absence
13 // of a sparse direct method", P. Arbenz, R. Lehoucq, and U. Hetmaniuk,
14 // Sandia National Laboratories, Technical report SAND2003-1028J.
15 //
16 // It is based on the Epetra, AztecOO, and ML packages defined in the Trilinos
17 // framework ( http://trilinos.org/ ).
18 
19 #include <fstream>
20 
21 #include "Epetra_ConfigDefs.h"
22 #include "Epetra_Map.h"
23 #include "Epetra_MultiVector.h"
24 
25 #ifdef EPETRA_MPI
26 #include "Epetra_MpiComm.h"
27 #include "mpi.h"
28 #else
29 #include "Epetra_SerialComm.h"
30 #endif
31 
32 #include "MyMemory.h"
33 
34 #include "ModalAnalysisSolver.h"
35 
36 #include "BRQMIN.h"
37 #include "BlockDACG.h"
38 #include "LOBPCG.h"
39 #include "LOBPCG_light.h"
40 #include "KnyazevLOBPCG.h"
41 #include "ARPACKm3.h"
42 #include "ModifiedARPACKm3.h"
43 #include "Davidson.h"
44 #include "JDPCG.h"
45 
46 #include "ModalProblem.h"
47 #include "ModeLaplace1DQ1.h"
48 #include "ModeLaplace1DQ2.h"
49 #include "ModeLaplace2DQ1.h"
50 #include "ModeLaplace2DQ2.h"
51 #include "ModeLaplace3DQ1.h"
52 #include "ModeLaplace3DQ2.h"
53 
54 #include "BlockPCGSolver.h"
55 #include "AMGOperator.h"
56 #include "MyIncompleteChol.h"
57 
58 #include <stdexcept>
59 #include <Teuchos_Assert.hpp>
60 
61 const int LOBPCG_CHOL = 1;
62 const int LOBPCG_LIGHT = 2;
63 const int LOBPCG_AK_CHOL = 3;
64 const int ARPACK_ORIG = 5;
65 const int ARPACK_RESI = 6;
66 const int GALDAVIDSON = 7;
67 const int BRQMIN_CHOL = 9;
68 const int DACG_CHOL = 11;
69 const int JD_PCG = 13;
70 
71 const int NO_PREC = 0;
72 const int AMG_POLYNOMIAL = 1;
73 const int AMG_GAUSSSEIDEL = 2;
74 const int INC_CHOL = 3;
75 
76 
77 int main(int argc, char *argv[]) {
78 
79  int i;
80  int myPid = 0;
81  int numProc = 1;
82 
83 #ifdef EPETRA_MPI
84  // Initialize MPI
85  MPI_Init(&argc,&argv);
86  MPI_Comm_size(MPI_COMM_WORLD, &numProc);
87  MPI_Comm_rank(MPI_COMM_WORLD, &myPid);
88  Epetra_MpiComm Comm( MPI_COMM_WORLD );
89 #else
90  Epetra_SerialComm Comm;
91 #endif
92 
93  // Initialize the random number generator
94  srand((unsigned) time(0));
95 
96  // Initialize memory counters
97  initMemCounters();
98 
99  int dimension;
100  double Lx = 1.0, Ly = 1.0, Lz = 1.0;
101  int nX=0, nY=0, nZ=0;
102  int casePb = 0;
103  int algo = 0;
104  int precond = 0, param = 0;
105  int numEigen = 0;
106  int dimSearch = 0;
107  int numBlock = 1;
108  int maxIter = 0;
109  double tol = 0.0;
110  int maxIterCG = 0;
111  double tolCG = 0.0;
112  int verbose = 0;
113 
114  bool paramStop = false;
115  for (i=0; i<numProc; ++i) {
116  Comm.Barrier();
117  if (myPid == i) {
118  ifstream fin("control.driver");
119  char buff[101];
120  TEUCHOS_TEST_FOR_EXCEPTION( !fin, std::runtime_error, "The input file 'control."
121  "driver' could not be opened." );
122  fin >> dimension; fin.getline(buff, 100);
123  switch (dimension) {
124  case 1:
125  fin >> Lx; fin.getline(buff, 100);
126  fin >> nX; fin.getline(buff, 100);
127  fin >> casePb; fin.getline(buff, 100);
128  break;
129  case 2:
130  fin >> Lx >> Ly; fin.getline(buff, 100);
131  fin >> nX >> nY; fin.getline(buff, 100);
132  fin >> casePb; fin.getline(buff, 100);
133  break;
134  case 3:
135  fin >> Lx >> Ly >> Lz; fin.getline(buff, 100);
136  fin >> nX >> nY >> nZ; fin.getline(buff, 100);
137  fin >> casePb; fin.getline(buff, 100);
138  break;
139  default:
140  paramStop = true;
141  }
142  fin >> algo; fin.getline(buff, 100);
143  fin >> precond; fin.getline(buff, 100);
144  fin >> param; fin.getline(buff, 100);
145  fin >> numEigen; fin.getline(buff, 100);
146  fin >> dimSearch; fin.getline(buff, 100);
147  fin >> numBlock; fin.getline(buff, 100);
148  fin >> maxIter; fin.getline(buff, 100);
149  fin >> tol; fin.getline(buff, 100);
150  fin >> maxIterCG; fin.getline(buff, 100);
151  fin >> tolCG; fin.getline(buff, 100);
152  fin >> verbose; fin.getline(buff, 100);
153  }
154  Comm.Barrier();
155  }
156 
157  // Check the input parameters
158  switch (algo) {
159  case LOBPCG_CHOL:
160  case LOBPCG_LIGHT:
161  case LOBPCG_AK_CHOL:
162  case 4:
163  case ARPACK_ORIG:
164  case ARPACK_RESI:
165  case GALDAVIDSON:
166  case BRQMIN_CHOL:
167  case DACG_CHOL:
168  case JD_PCG:
169  break;
170  default:
171  paramStop = true;
172  break;
173  }
174 
175  switch (precond) {
176  case NO_PREC:
177  case AMG_POLYNOMIAL:
178  case AMG_GAUSSSEIDEL:
179  case INC_CHOL:
180  break;
181  default:
182  paramStop = true;
183  break;
184  }
185 
186  if ((dimension < 1) && (dimension > 3))
187  paramStop = true;
188  else {
189  if ((casePb != 1) && (casePb != 2))
190  paramStop = true;
191  }
192 
193  if (paramStop == true) {
194  if (verbose*(myPid==0) > 0) {
195 #ifdef EPETRA_MPI
196  cerr << "Usage: prun -n NP ./driver" << endl;
197 #else
198  cerr << "Usage: ./driver.serial" << endl;
199 #endif
200  cerr << endl;
201  cerr << "Input file: 'control.driver'" << endl;
202  cerr << endl;
203  cerr << "Example of input file" << endl;
204  cerr << endl;
205  cerr << "3 Space dimension (1, 2, 3)" << endl;
206  cerr << "1.0 2.0 3.0 Lx Ly Lz (Dimension of brick in each direction)" << endl;
207  cerr << "10 11 12 nX nY nZ (Number of elements in each direction)" << endl;
208  cerr << "1 Case Problem (1=Q1, 2=Q2)" << endl;
209  cerr << "1 Algorithm (1 .. 15)" << endl;
210  cerr << "1 Preconditioner (0 = None, 1 = AMG Poly, 2 = AMG GS)"
211  << endl;
212  cerr << "1 Parameter for preconditioner: AMG Poly. Deg."
213  << endl;
214  cerr << "10 Number of eigenpairs requested" << endl;
215  cerr << "5 Dimension of block size" << endl;
216  cerr << "4 Number of blocks (ONLY referenced by Davidson (7) and JD-PCG (13))"
217  << endl;
218  cerr << "1000 Maximum number of iterations for eigensolver" << endl;
219  cerr << "1e-06 Tolerance" << endl;
220  cerr << "1000 Maximum number of inner iterations (PCG, QMR)" << endl;
221  cerr << "1e-07 Tolerance for PCG solve (ONLY referenced in ARPACK)" << endl;
222  cerr << "1 Verbose level" << endl;
223  cerr << "----------------------------------------------------------------------" << endl;
224  cerr << endl;
225  cerr << "Eigensolver flags:" << endl;
226  cerr << " 1. LOBPCG (RBL & UH version) with Cholesky-based local eigensolver" << endl;
227  cerr << " 2. LOBPCG (light version) with Cholesky-based local eigensolver" << endl;
228  cerr << " 3. LOBPCG (AK version) with Cholesky-based local eigensolver" << endl;
229  cerr << " 5. ARPACK (original version)" << endl;
230  cerr << " 6. ARPACK (version with user-provided residual)" << endl;
231  cerr << " 7. Generalized Davidson (RBL & UH version)" << endl;
232  cerr << " 9. BRQMIN with Cholesky-based local eigensolver" << endl;
233  cerr << "11. Block DACG with Cholesky-based local eigensolver" << endl;
234  cerr << "13. JDCG (Notay's version of Jacobi-Davidson)" << endl;
235  cerr << endl;
236  cerr << "The dimension of search space corresponds to" << endl;
237  cerr << " * the block size for LOBPCG (1)" << endl;
238  cerr << " * NCV for ARPACK (5, 6)" << endl;
239  cerr << " * one block size for Generalized Davidson (7)" << endl;
240  cerr << " * the block size for BRQMIN (9)" << endl;
241  cerr << " * the block size for Block DACG (11)" << endl;
242  cerr << " * one block size for Jacobi-Davidson JDCG (13)" << endl;
243  cerr << endl;
244  }
245  // mfh 14 Jan 2011: Replaced "exit(1)" with "return 1" since this
246  // is the "main" routine. If you move this part of the code out
247  // of main(), change the line below accordingly.
248  return 1;
249  }
250 
251  double highMem = currentSize();
252 
253  ModalProblem *testCase;
254  if (dimension == 1) {
255  if (casePb == 1)
256  testCase = new ModeLaplace1DQ1(Comm, Lx, nX);
257  if (casePb == 2)
258  testCase = new ModeLaplace1DQ2(Comm, Lx, nX);
259  }
260  if (dimension == 2) {
261  if (casePb == 1)
262  testCase = new ModeLaplace2DQ1(Comm, Lx, nX, Ly, nY);
263  if (casePb == 2)
264  testCase = new ModeLaplace2DQ2(Comm, Lx, nX, Ly, nY);
265  }
266  if (dimension == 3) {
267  if (casePb == 1)
268  testCase = new ModeLaplace3DQ1(Comm, Lx, nX, Ly, nY, Lz, nZ);
269  if (casePb == 2)
270  testCase = new ModeLaplace3DQ2(Comm, Lx, nX, Ly, nY, Lz, nZ);
271  }
272 
273  highMem = (highMem < currentSize()) ? currentSize() : highMem;
274 
275  // Print some information on the problem to solve
276  if (verbose*(myPid==0) > 0) {
277  cout << endl;
278  testCase->problemInfo();
279  }
280 
281  // Get the stiffness and mass matrices
282  const Epetra_Operator *K = testCase->getStiffness();
283  const Epetra_Operator *M = testCase->getMass();
284 
285  // Get the map of the equations across processors
286  const Epetra_Map Map = K->OperatorDomainMap();
287  int localSize = Map.NumMyElements();
288  int globalSize = Map.NumGlobalElements();
289 
290  // Get the first eigenvalue for the mass matrix
291  numEigen = (numEigen > globalSize) ? globalSize : numEigen;
292 
293  double *globalWeight = 0;
294  double globalMassMin = 0.0;
295 
296  if (dynamic_cast<ModeLaplace*>(testCase))
297  globalMassMin = dynamic_cast<ModeLaplace*>(testCase)->getFirstMassEigenValue();
298  else {
299  // Input( Comm, Operator, verbose level, # levels, smoother, parameter, coarse solver)
300  AMGOperator precML(Comm, M, 0, 10, 1, 3, 0);
301  BlockPCGSolver linMassSolver(Comm, M, 1e-06, 20);
302  linMassSolver.setPreconditioner(&precML);
303  ARPACKm3 eigMassSolver(Comm, &linMassSolver, 1e-03, globalSize);
304  double *lTmp = new double[6];
305  Epetra_MultiVector QQ(Map, 6);
306  QQ.Random();
307  int massNEV = eigMassSolver.solve(1, QQ, lTmp);
308 
309  // FIXME (mfh 14 Jan 2011) I'm not sure if std::runtime_error is
310  // the right exception to throw. I'm just replacing exit(1) with
311  // an exception, as per Trilinos coding standards.
312  TEUCHOS_TEST_FOR_EXCEPTION( massNEV < 1, std::runtime_error,
313  "Error in the computation of smallest eigenvalue for "
314  "the mass matrix. Output information from eigensolver"
315  " = " << massNEV );
316  globalMassMin = lTmp[0];
317  delete[] lTmp;
318  }
319 
320  // Note: The following definition of weight results from the definition
321  // of "Epetra_MultiVector::NormWeighted"
322  globalWeight = new double[localSize];
323  for (i = 0; i < localSize; ++i) {
324  globalWeight[i] = sqrt(globalMassMin/globalSize);
325  }
326 
327  if (verbose*(myPid==0) > 0) {
328  cout << endl;
329  cout.precision(2);
330  cout.setf(ios::scientific, ios::floatfield);
331  cout << " Smallest eigenvalue for the mass matrix: " << globalMassMin << endl;
332  cout << endl;
333  }
334 
335  // Define arrays for the eigensolver algorithm
336  int qSize;
337  switch (algo) {
338  case LOBPCG_CHOL:
339  case LOBPCG_LIGHT:
340  qSize = dimSearch + numEigen;
341  break;
342  case LOBPCG_AK_CHOL:
343  qSize = numEigen;
344  dimSearch = numEigen;
345  break;
346  case ARPACK_ORIG:
347  case ARPACK_RESI:
348  if (dimSearch <= numEigen)
349  dimSearch = 2*numEigen;
350  qSize = dimSearch;
351  break;
352  case GALDAVIDSON:
353  numBlock = (numBlock <= 0) ? 1 : numBlock;
354  qSize = dimSearch*(numBlock+1);
355  break;
356  case BRQMIN_CHOL:
357  qSize = dimSearch + numEigen;
358  break;
359  case DACG_CHOL:
360  qSize = dimSearch + numEigen;
361  break;
362  case JD_PCG:
363  numBlock = (numBlock <= 0) ? 1 : numBlock;
364  qSize = dimSearch*(numBlock+1);
365  break;
366  }
367 
368  double *vQ = new (nothrow) double[qSize*localSize];
369  assert(vQ != 0);
370 
371  double *lambda = new (nothrow) double[qSize];
372  assert(lambda != 0);
373 
374  Epetra_MultiVector Q(View, Map, vQ, localSize, qSize);
375  Q.Random();
376 
377  highMem = (highMem > currentSize()) ? highMem : currentSize();
378 
379  char precLabel[100];
380  MyIncompleteChol *ICT = 0;
381  BlockPCGSolver *opStiffness = new BlockPCGSolver(Comm, K, tolCG, maxIterCG,
382  (verbose) ? verbose-1 : 0);
383  AMGOperator *precML = 0;
384  switch (precond) {
385  case NO_PREC:
386  opStiffness->setPreconditioner(0);
387  strcpy(precLabel, " No preconditioner");
388  break;
389  case AMG_POLYNOMIAL:
390  // Use AMG preconditioner with polynomial smoother
391  if (param < 1)
392  param = 2;
393  precML = new AMGOperator(Comm, K, verbose, 10, 1, param, 0);
394  opStiffness->setPreconditioner(precML);
395  strcpy(precLabel, " AMG with polynomial smoother");
396  break;
397  case AMG_GAUSSSEIDEL:
398  // Use AMG preconditioner with Gauss-Seidel smoother
399  precML = new AMGOperator(Comm, K, verbose, 10, 2, param, 0);
400  opStiffness->setPreconditioner(precML);
401  strcpy(precLabel, " AMG with Gauss-Seidel smoother");
402  break;
403  case INC_CHOL:
404  // Use incomplete Cholesky with no-fill in
405  Epetra_Operator *KOp = const_cast<Epetra_Operator*>(K);
406  if (dynamic_cast<Epetra_CrsMatrix*>(KOp)) {
407  ICT = new MyIncompleteChol(Comm, KOp, Epetra_MinDouble, param);
408  }
409  else {
410  cerr << endl;
411  cerr << " !!! The incomplete Cholesky factorization can not be done !!!\n";
412  cerr << " !!! No preconditioner is used !!!\n";
413  cerr << endl;
414  }
415  opStiffness->setPreconditioner(ICT);
416  if (ICT)
417  strcpy(precLabel, " Incomplete Cholesky factorization");
418  break;
419  }
420 
421  // Define the GeneralEigenSolver object
422  ModalAnalysisSolver *mySolver;
423 
424  switch (algo) {
425  case LOBPCG_CHOL:
426  mySolver = new LOBPCG(Comm, opStiffness, M, opStiffness->getPreconditioner(),
427  dimSearch, tol, maxIter, verbose, globalWeight);
428  break;
429  case LOBPCG_LIGHT:
430  mySolver = new LOBPCG_light(Comm, opStiffness, M, opStiffness->getPreconditioner(),
431  dimSearch, tol, maxIter, verbose, globalWeight);
432  break;
433  case LOBPCG_AK_CHOL:
434  mySolver = new KnyazevLOBPCG(Comm, opStiffness, M, opStiffness->getPreconditioner(),
435  tol, maxIter, verbose, globalWeight);
436  break;
437  case ARPACK_ORIG:
438  mySolver = new ARPACKm3(Comm, opStiffness, M, tol, maxIter, verbose);
439  break;
440  case ARPACK_RESI:
441  mySolver = new ModifiedARPACKm3(Comm, opStiffness, M, tol, maxIter, verbose,
442  globalWeight);
443  break;
444  case GALDAVIDSON:
445  mySolver = new Davidson(Comm, opStiffness, M, opStiffness->getPreconditioner(),
446  dimSearch, numBlock, tol, maxIter, verbose, globalWeight);
447  break;
448  case BRQMIN_CHOL:
449  mySolver = new BRQMIN(Comm, opStiffness, M, opStiffness->getPreconditioner(),
450  dimSearch, tol, maxIter, verbose, globalWeight);
451  break;
452  case DACG_CHOL:
453  mySolver = new BlockDACG(Comm, opStiffness, M, opStiffness->getPreconditioner(),
454  dimSearch, tol, maxIter, verbose, globalWeight);
455  break;
456  case JD_PCG:
457  mySolver = new JDPCG(Comm, opStiffness, M, opStiffness->getPreconditioner(),
458  dimSearch, numBlock, tol, maxIter, maxIterCG, verbose, globalWeight);
459  break;
460  }
461 
462  // Solve the eigenproblem
463  int knownEV = mySolver->solve(numEigen, Q, lambda);
464 
465  // Output information on simulation
466 
467  if (knownEV < 0) {
468  if (myPid == 0) {
469  cerr << endl;
470  cerr << " !!! The eigensolver exited with error " << knownEV << " !!! " << endl;
471  cerr << endl;
472  }
473  } // if (knownEV < 0)
474  else {
475 
476  if (verbose*(myPid == 0) > 1) {
477  cout << endl;
478  cout << " ---------------------------------------------------- \n";
479  cout << " History of Computation \n";
480  cout << " ---------------------------------------------------- \n";
481  cout << endl;
482  mySolver->algorithmInfo();
483  cout << " Preconditioner: " << precLabel << endl;
484  cout << endl;
485  testCase->problemInfo();
486  cout << " Number of computed eigenmodes: " << knownEV << endl;
487  mySolver->historyInfo();
488  } // if (verbose*(myPid == 0) > 1)
489 
490  // Eigenpairs accuracy
491  if (knownEV > 0) {
492  int nb = (knownEV > numEigen) ? numEigen : knownEV;
493  Epetra_MultiVector copyQ(View, Q, 0, nb);
494  if (myPid == 0) {
495  cout << endl;
496  cout << " ---------------------------------------------------- \n";
497  cout << " Eigenpairs accuracy \n";
498  cout << " ---------------------------------------------------- \n";
499  cout << endl;
500  mySolver->algorithmInfo();
501  cout << " Preconditioner: " << precLabel << endl;
502  cout << endl;
503  testCase->problemInfo();
504  cout << " Number of computed eigenmodes: " << copyQ.NumVectors() << endl;
505  cout.precision(2);
506  cout.setf(ios::scientific, ios::floatfield);
507  cout << " Tolerance on residuals: " << tol << endl;
508  cout << endl;
509  cout << " Smallest eigenvalue for the mass matrix: " << globalMassMin << endl;
510  cout << endl;
511  } // if (myPid == 0)
512  testCase->eigenCheck(copyQ, lambda, globalWeight);
513  }
514 
515  // Print out statistics: memory, time
516  if (myPid == 0) {
517  cout << endl;
518  cout << " ---------------------------------------------------- \n";
519  cout << " Summary of statistics \n";
520  cout << " ---------------------------------------------------- \n";
521  cout << endl;
522  mySolver->algorithmInfo();
523  cout << " Preconditioner: " << precLabel << endl;
524  cout << endl;
525  testCase->problemInfo();
526  cout << " Number of computed eigenmodes: " << knownEV << endl;
527  cout.precision(2);
528  cout.setf(ios::scientific, ios::floatfield);
529  cout << " Tolerance on residuals: " << tol << endl;
530  if ((algo == ARPACK_ORIG) || (algo == ARPACK_RESI)) {
531  cout << " Size of Search Space: " << dimSearch << endl;
532  cout << endl;
533  cout.precision(2);
534  cout.setf(ios::scientific, ios::floatfield);
535  cout << " Tolerance on PCG solves: " << tolCG << endl;
536  cout << endl;
537  cout << " Minimum number of PCG iterations per solve: ";
538  cout << opStiffness->getMinIter() << endl;
539  cout.setf(ios::fixed, ios::floatfield);
540  cout << " Average number of PCG iterations per solve: ";
541  cout << opStiffness->getAvgIter() << endl;
542  cout << " Maximum number of PCG iterations per solve: ";
543  cout << opStiffness->getMaxIter() << endl;
544  }
545  cout << endl;
546  if (precond == AMG_POLYNOMIAL) {
547  cout << " Number of levels for AMG preconditioner: ";
548  cout << precML->getAMG_NLevels() << endl;
549  cout << " Polynomial degree of AMG preconditioner: " << param << endl;
550  cout << endl;
551  }
552  if (precond == AMG_GAUSSSEIDEL) {
553  cout << " Number of levels for AMG preconditioner: ";
554  cout << precML->getAMG_NLevels() << endl;
555  cout << endl;
556  }
557  if ((precond == INC_CHOL) && (ICT)) {
558  cout << " Level of fill for incomplete Cholesky factorisation: ";
559  cout << param << endl;
560  cout << endl;
561  }
562  cout << " Number of processors: " << numProc << endl;
563  cout << endl;
564  } // if (myPid == 0)
565 
566  // Memory
567  double maxHighMem = 0.0;
568  Comm.MaxAll(&highMem, &maxHighMem, 1);
569  if (myPid == 0) {
570  cout << " --- Memory ---\n";
571  cout << endl;
572  cout.precision(2);
573  cout.setf(ios::fixed, ios::floatfield);
574  cout << " High water mark in set-up = (EST) ";
575  cout << maxHighMem << " MB\n";
576  cout << endl;
577  } // if (myPid == 0)
578 
579  testCase->memoryInfo();
580 
581  if (myPid == 0) {
582  cout.precision(2);
583  cout.setf(ios::fixed, ios::floatfield);
584  cout << " Memory requested per processor for eigenvectors = (EST) ";
585  cout << Q.GlobalLength()*numEigen*sizeof(double)/1024.0/1024.0/numProc;
586  cout << " MB\n";
587  cout << endl;
588  cout << " Memory requested per processor for working space = (EST) ";
589  cout << Q.GlobalLength()*(Q.NumVectors()-numEigen)*sizeof(double)/1024.0/1024.0/numProc;
590  cout << " MB\n";
591  cout << endl;
592  } // if (myPid == 0)
593 
594  mySolver->memoryInfo();
595 
596  mySolver->operationInfo();
597 
598  mySolver->timeInfo();
599 
600  } // if (knownEV < 0)
601 
602  // Release all objects
603  delete opStiffness;
604  delete ICT;
605  delete precML;
606  delete mySolver;
607 
608  delete[] lambda;
609  delete[] vQ;
610  delete[] globalWeight;
611 
612  delete testCase;
613 
614 #ifdef EPETRA_MPI
615  MPI_Finalize() ;
616 #endif
617 
618  return 0;
619 
620 }
int NumGlobalElements() const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual const Epetra_Map & OperatorDomainMap() const =0
int NumMyElements() const
int MaxAll(double *PartialMaxs, double *GlobalMaxs, int Count) const
void Barrier() const