Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Test_LAPACK/cxx_main.cpp
Go to the documentation of this file.
1 #include "Amesos_ConfigDefs.h"
2 #ifdef HAVE_AMESOS_LAPACK
3 
4 #ifdef HAVE_MPI
5 #include "mpi.h"
6 #include "Epetra_MpiComm.h"
7 #else
8 #include "Epetra_SerialComm.h"
9 #endif
10 #include "Epetra_Map.h"
11 #include "Epetra_Vector.h"
12 #include "Epetra_Time.h"
13 #include "Epetra_Util.h"
14 #include "Amesos_Lapack.h"
15 #include "Amesos_TestRowMatrix.h"
17 
18 //=============================================================================
19 bool CheckError(const Epetra_RowMatrix& A,
20  const Epetra_MultiVector& x,
21  const Epetra_MultiVector& b,
22  const Epetra_MultiVector& x_exact)
23 {
24  std::vector<double> Norm;
25  int NumVectors = x.NumVectors();
26  Norm.resize(NumVectors);
27  Epetra_MultiVector Ax(x);
28  A.Multiply(false,x,Ax);
29  Ax.Update(1.0,b,-1.0);
30  Ax.Norm2(&Norm[0]);
31  bool TestPassed = false;
32  double TotalNorm = 0.0;
33  for (int i = 0 ; i < NumVectors ; ++i) {
34  TotalNorm += Norm[i];
35  }
36  if (A.Comm().MyPID() == 0)
37  std::cout << "||Ax - b|| = " << TotalNorm << std::endl;
38  if (TotalNorm < 1e-5 )
39  TestPassed = true;
40  else
41  TestPassed = false;
42 
43  Ax.Update (1.0,x,-1.0,x_exact,0.0);
44  Ax.Norm2(&Norm[0]);
45  for (int i = 0 ; i < NumVectors ; ++i) {
46  TotalNorm += Norm[i];
47  }
48  if (A.Comm().MyPID() == 0)
49  std::cout << "||Ax - b|| = " << TotalNorm << std::endl;
50  if (TotalNorm < 1e-5 )
51  TestPassed = true;
52  else
53  TestPassed = false;
54 
55  return(TestPassed);
56 }
57 
58 //=============================================================================
59 int main(int argc, char *argv[])
60 {
61 #ifdef HAVE_MPI
62  MPI_Init(&argc, &argv);
63  Epetra_MpiComm Comm(MPI_COMM_WORLD);
64 #else
65  Epetra_SerialComm Comm;
66 #endif
67 
68  int NumGlobalElements = 1000;
69  int NumVectors = 7;
70 
71  // =================== //
72  // create a random map //
73  // =================== //
74 
75  int* part = new int[NumGlobalElements];
76 
77  if (Comm.MyPID() == 0) {
78  Epetra_Util Util;
79 
80  for( int i=0 ; i<NumGlobalElements ; ++i ) {
81  unsigned int r = Util.RandomInt();
82  part[i] = r%(Comm.NumProc());
83  }
84  }
85 
86  Comm.Broadcast(part,NumGlobalElements,0);
87 
88  // count the elements assigned to this proc
89  int NumMyElements = 0;
90  for (int i = 0 ; i < NumGlobalElements ; ++i) {
91  if (part[i] == Comm.MyPID())
92  NumMyElements++;
93  }
94 
95  // get the loc2global list
96  int* MyGlobalElements = new int[NumMyElements];
97  int count = 0;
98  for (int i = 0 ; i < NumGlobalElements ; ++i) {
99  if (part[i] == Comm.MyPID() )
100  MyGlobalElements[count++] = i;
101  }
102 
103  Epetra_Map Map(NumGlobalElements,NumMyElements,MyGlobalElements,
104  0,Comm);
105 
106  delete [] part;
107 
108  // ===================== //
109  // Create a dense matrix //
110  // ===================== //
111 
112  Epetra_CrsMatrix Matrix(Copy,Map,NumGlobalElements);
113 
114  int* Indices = new int[NumGlobalElements];
115  double* Values = new double[NumGlobalElements];
116 
117  for (int i = 0 ; i < NumGlobalElements ; ++i)
118  Indices[i] = i;
119 
120  for (int i = 0 ; i < NumMyElements ; ++i) {
121  int iGlobal = MyGlobalElements[i];
122  for (int jGlobal = 0 ; jGlobal < NumGlobalElements ; ++jGlobal) {
123  if (iGlobal == jGlobal)
124  Values[jGlobal] = 1.0 * (NumGlobalElements + 1 ) *
125  (NumGlobalElements + 1);
126  else if (iGlobal > jGlobal)
127  Values[jGlobal] = -1.0*(jGlobal+1);
128  else
129  Values[jGlobal] = 1.0*(iGlobal+1);
130  }
131  Matrix.InsertGlobalValues(MyGlobalElements[i],
132  NumGlobalElements, Values, Indices);
133 
134  }
135 
136  Matrix.FillComplete();
137 
138  delete [] MyGlobalElements;
139  delete [] Indices;
140  delete [] Values;
141 
142  // ======================== //
143  // other data for this test //
144  // ======================== //
145 
146  Amesos_TestRowMatrix A(&Matrix);
147  Epetra_MultiVector x(Map,NumVectors);
148  Epetra_MultiVector x_exact(Map,NumVectors);
149  Epetra_MultiVector b(Map,NumVectors);
150  x_exact.Random();
151  A.Multiply(false,x_exact,b);
152 
153  // =========== //
154  // AMESOS PART //
155  // =========== //
156 
157  Epetra_LinearProblem Problem;
158  Amesos_Lapack Solver(Problem);
159 
160  Problem.SetOperator(&A);
161  Problem.SetLHS(&x);
162  Problem.SetRHS(&b);
163 
164  Solver.SetUseTranspose(false);
165  AMESOS_CHK_ERR(Solver.SymbolicFactorization());
166  AMESOS_CHK_ERR(Solver.NumericFactorization());
167  AMESOS_CHK_ERR(Solver.Solve());
168 
169  if (!CheckError(A,x,b,x_exact))
170  AMESOS_CHK_ERR(-1);
171 
172 #ifdef HAVE_MPI
173  MPI_Finalize();
174 #endif
175 
176  return(EXIT_SUCCESS);
177 
178 }
179 
180 #else
181 
182 // Triutils is not available. Sorry, we have to give up.
183 
184 #include <stdlib.h>
185 #include <stdio.h>
186 #ifdef HAVE_MPI
187 #include "mpi.h"
188 #else
189 #endif
190 
191 int main(int argc, char *argv[])
192 {
193 #ifdef HAVE_MPI
194  MPI_Init(&argc, &argv);
195 #endif
196 
197  puts("Please configure AMESOS with --enable-amesos-lapack");
198  puts("to run this example");
199 
200 #ifdef HAVE_MPI
201  MPI_Finalize();
202 #endif
203  return(EXIT_SUCCESS);
204 }
205 
206 #endif
207 
208 
void SetLHS(Epetra_MultiVector *X)
void SetOperator(Epetra_RowMatrix *A)
Amesos_TestRowMatrix: a class to test Epetra_RowMatrix based codes.
int MyPID() const
virtual int MyPID() const =0
unsigned int RandomInt()
virtual const Epetra_Comm & Comm() const =0
#define AMESOS_CHK_ERR(a)
int main(int argc, char *argv[])
int NumProc() const
virtual int Multiply(bool TransA, const Epetra_MultiVector &X, Epetra_MultiVector &Y) const =0
Amesos_Lapack: an interface to LAPACK.
Definition: Amesos_Lapack.h:65
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