Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Test_SuperLU/cxx_main.cpp
Go to the documentation of this file.
1 #include "Amesos_ConfigDefs.h"
2 
3 #ifdef HAVE_MPI
4 #include "mpi.h"
5 #include "Epetra_MpiComm.h"
6 #else
7 #include "Epetra_SerialComm.h"
8 #endif
9 #include "Epetra_Map.h"
10 #include "Epetra_Vector.h"
11 #include "Epetra_Util.h"
12 #include "Epetra_CrsMatrix.h"
13 #include "Amesos_Superlu.h"
14 #include "Amesos_TestRowMatrix.h"
16 
17 //=============================================================================
19  const Epetra_MultiVector& x,
20  const Epetra_MultiVector& b,
21  const Epetra_MultiVector& x_exact)
22 {
23  std::vector<double> Norm;
24  int NumVectors = x.NumVectors();
25  Norm.resize(NumVectors);
26  Epetra_MultiVector Ax(x);
27  A.Multiply(false,x,Ax);
28  Ax.Update(1.0,b,-1.0);
29  Ax.Norm2(&Norm[0]);
30  bool TestPassed = false;
31  double TotalNorm = 0.0;
32  for (int i = 0 ; i < NumVectors ; ++i) {
33  TotalNorm += Norm[i];
34  }
35  if (A.Comm().MyPID() == 0)
36  std::cout << "||Ax - b|| = " << TotalNorm << std::endl;
37  if (TotalNorm < 1e-5 )
38  TestPassed = true;
39  else
40  TestPassed = false;
41 
42  Ax.Update (1.0,x,-1.0,x_exact,0.0);
43  Ax.Norm2(&Norm[0]);
44  for (int i = 0 ; i < NumVectors ; ++i) {
45  TotalNorm += Norm[i];
46  }
47  if (A.Comm().MyPID() == 0)
48  std::cout << "||Ax - b|| = " << TotalNorm << std::endl;
49  if (TotalNorm < 1e-5 )
50  TestPassed = true;
51  else
52  TestPassed = false;
53 
54  return(TestPassed);
55 }
56 
57 //=============================================================================
58 int main(int argc, char *argv[])
59 {
60 #ifdef HAVE_MPI
61  MPI_Init(&argc, &argv);
62  Epetra_MpiComm Comm(MPI_COMM_WORLD);
63 #else
64  Epetra_SerialComm Comm;
65 #endif
66 
67  int NumGlobalElements = 1000;
68  int NumVectors = 7;
69 
70  // =================== //
71  // create a random map //
72  // =================== //
73 
74  int* part = new int[NumGlobalElements];
75 
76  if (Comm.MyPID() == 0) {
77  Epetra_Util Util;
78 
79  for( int i=0 ; i<NumGlobalElements ; ++i ) {
80  unsigned int r = Util.RandomInt();
81  part[i] = r%(Comm.NumProc());
82  }
83  }
84 
85  Comm.Broadcast(part,NumGlobalElements,0);
86 
87  // count the elements assigned to this proc
88  int NumMyElements = 0;
89  for (int i = 0 ; i < NumGlobalElements ; ++i) {
90  if (part[i] == Comm.MyPID())
91  NumMyElements++;
92  }
93 
94  // get the loc2global list
95  int* MyGlobalElements = new int[NumMyElements];
96  int count = 0;
97  for (int i = 0 ; i < NumGlobalElements ; ++i) {
98  if (part[i] == Comm.MyPID() )
99  MyGlobalElements[count++] = i;
100  }
101 
102  Epetra_Map Map(NumGlobalElements,NumMyElements,MyGlobalElements,
103  0,Comm);
104 
105  delete [] part;
106 
107  // ===================== //
108  // Create a dense matrix //
109  // ===================== //
110 
111  Epetra_CrsMatrix Matrix(Copy,Map,NumGlobalElements);
112 
113  int* Indices = new int[NumGlobalElements];
114  double* Values = new double[NumGlobalElements];
115 
116  for (int i = 0 ; i < NumGlobalElements ; ++i)
117  Indices[i] = i;
118 
119  for (int i = 0 ; i < NumMyElements ; ++i) {
120  int iGlobal = MyGlobalElements[i];
121  for (int jGlobal = 0 ; jGlobal < NumGlobalElements ; ++jGlobal) {
122  if (iGlobal == jGlobal)
123  Values[jGlobal] = 1.0 * (NumGlobalElements + 1 ) *
124  (NumGlobalElements + 1);
125  else if (iGlobal > jGlobal)
126  Values[jGlobal] = -1.0*(jGlobal+1);
127  else
128  Values[jGlobal] = 1.0*(iGlobal+1);
129  }
130  Matrix.InsertGlobalValues(MyGlobalElements[i],
131  NumGlobalElements, Values, Indices);
132 
133  }
134 
135  Matrix.FillComplete();
136 
137  delete [] MyGlobalElements;
138  delete [] Indices;
139  delete [] Values;
140 
141  // ======================== //
142  // other data for this test //
143  // ======================== //
144 
145  Amesos_TestRowMatrix A(&Matrix);
146  Epetra_MultiVector x(Map,NumVectors);
147  Epetra_MultiVector x_exact(Map,NumVectors);
148  Epetra_MultiVector b(Map,NumVectors);
149  x_exact.Random();
150  A.Multiply(false,x_exact,b);
151 
152  // =========== //
153  // AMESOS PART //
154  // =========== //
155 
156  Epetra_LinearProblem Problem;
157  Amesos_Superlu Solver(Problem);
158 
159  Problem.SetOperator(&A);
160  Problem.SetLHS(&x);
161  Problem.SetRHS(&b);
162 
165  AMESOS_CHK_ERR(Solver.Solve());
166 
167  bool TestPassed = true;
168 
169  TestPassed = TestPassed &&
170  CheckError(A,x,b,x_exact);
171 
172  AMESOS_CHK_ERR( ! TestPassed ) ;
173 
174 #ifdef HAVE_MPI
175  MPI_Finalize();
176 #endif
177 
178 
179  return(EXIT_SUCCESS);
180 
181 }
void SetLHS(Epetra_MultiVector *X)
void SetOperator(Epetra_RowMatrix *A)
int Solve()
Solves A X = B (or AT x = B)
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
Amesos_TestRowMatrix: a class to test Epetra_RowMatrix based codes.
int MyPID() const
Amesos_Superlu: Amesos interface to Xioye Li&#39;s SuperLU 3.0 serial code.
virtual int MyPID() const =0
int FillComplete(bool OptimizeDataStorage=true)
unsigned int RandomInt()
virtual int Multiply(bool TransA, const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Returns the result of a Epetra_RowMatrix multiplied by a Epetra_MultiVector X in Y.
virtual const Epetra_Comm & Comm() const =0
#define AMESOS_CHK_ERR(a)
int SymbolicFactorization()
Performs SymbolicFactorization on the matrix A.
int main(int argc, char *argv[])
int NumProc() const
virtual int Multiply(bool TransA, const Epetra_MultiVector &X, Epetra_MultiVector &Y) const =0
void SetRHS(Epetra_MultiVector *B)
bool CheckError(const std::string SolverType, const std::string Descriptor, const Epetra_RowMatrix &A, const Epetra_MultiVector &x, const Epetra_MultiVector &b, const Epetra_MultiVector &x_exact)
int Broadcast(double *MyVals, int Count, int Root) const
int NumericFactorization()
Performs NumericFactorization on the matrix A.