Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Test_UMFPACK/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_Umfpack.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  {
78  Epetra_Util Util;
79 
80  for( int i=0 ; i<NumGlobalElements ; ++i )
81  {
82  unsigned int r = Util.RandomInt();
83  part[i] = r%(Comm.NumProc());
84  }
85  }
86 
87  Comm.Broadcast(part,NumGlobalElements,0);
88 
89  // count the elements assigned to this proc
90  int NumMyElements = 0;
91  for (int i = 0 ; i < NumGlobalElements ; ++i)
92  {
93  if (part[i] == Comm.MyPID())
94  NumMyElements++;
95  }
96 
97  // get the loc2global list
98  int* MyGlobalElements = new int[NumMyElements];
99  int count = 0;
100  for (int i = 0 ; i < NumGlobalElements ; ++i)
101  {
102  if (part[i] == Comm.MyPID() )
103  MyGlobalElements[count++] = i;
104  }
105 
106  Epetra_Map Map(NumGlobalElements,NumMyElements,MyGlobalElements,
107  0,Comm);
108 
109  delete [] part;
110 
111  // ===================== //
112  // Create a dense matrix //
113  // ===================== //
114 
115  Epetra_CrsMatrix Matrix(Copy,Map,NumGlobalElements);
116 
117  int* Indices = new int[NumGlobalElements];
118  double* Values = new double[NumGlobalElements];
119 
120  for (int i = 0 ; i < NumGlobalElements ; ++i)
121  Indices[i] = i;
122 
123  for (int i = 0 ; i < NumMyElements ; ++i) {
124  int iGlobal = MyGlobalElements[i];
125  for (int jGlobal = 0 ; jGlobal < NumGlobalElements ; ++jGlobal) {
126  if (iGlobal == jGlobal)
127  Values[jGlobal] = 1.0 * (NumGlobalElements + 1 ) *
128  (NumGlobalElements + 1);
129  else if (iGlobal > jGlobal)
130  Values[jGlobal] = -1.0*(jGlobal+1);
131  else
132  Values[jGlobal] = 1.0*(iGlobal+1);
133  }
134  Matrix.InsertGlobalValues(MyGlobalElements[i],
135  NumGlobalElements, Values, Indices);
136 
137  }
138 
139  Matrix.FillComplete();
140 
141  delete[] MyGlobalElements;
142  delete[] Indices;
143  delete[] Values;
144 
145  // ======================== //
146  // other data for this test //
147  // ======================== //
148 
149  Amesos_TestRowMatrix A(&Matrix);
150  Epetra_MultiVector x(Map,NumVectors);
151  Epetra_MultiVector x_exact(Map,NumVectors);
152  Epetra_MultiVector b(Map,NumVectors);
153  x_exact.Random();
154  A.Multiply(false,x_exact,b);
155 
156  // =========== //
157  // AMESOS PART //
158  // =========== //
159 
160  Epetra_LinearProblem Problem(&A, &x, &b);
161  Amesos_Umfpack Solver(Problem);
162 
165  AMESOS_CHK_ERR(Solver.Solve());
166 
167  if (!CheckError(A,x,b,x_exact))
168  AMESOS_CHK_ERR(-1);
169 
170 #ifdef HAVE_MPI
171  MPI_Finalize();
172 #endif
173  return(EXIT_SUCCESS);
174 }
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
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
int Solve()
Solves A X = B (or AT x = B)
int NumericFactorization()
Performs NumericFactorization on the matrix A.
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
Class Amesos_Umfpack: An object-oriented wrapper for UMFPACK.