OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
umfpack_solver.hpp
1 /*
2  * Umfpack_solver.hpp
3  *
4  * Created on: Nov 27, 2015
5  * Author: i-bird
6  */
7 
8 #ifndef OPENFPM_NUMERICS_SRC_SOLVERS_UMFPACK_SOLVER_HPP_
9 #define OPENFPM_NUMERICS_SRC_SOLVERS_UMFPACK_SOLVER_HPP_
10 
11 #define UMFPACK_NONE 0
12 
13 #define SOLVER_NOOPTION 0
14 #define SOLVER_PRINT_RESIDUAL_NORM_INFINITY 1
15 #define SOLVER_PRINT_DETERMINANT 2
16 #define SOLVER_PRINT 3
17 
18 
19 #if defined(HAVE_EIGEN) && defined(HAVE_SUITESPARSE)
20 
22 
23 #include "Vector/Vector.hpp"
24 #include "Eigen/UmfPackSupport"
25 #include <Eigen/SparseLU>
26 
27 
28 template<typename T>
29 class umfpack_solver
30 {
31 public:
32 
33  template<unsigned int impl, typename id_type> static Vector<T> solve(const SparseMatrix<T,id_type,impl> & A, const Vector<T> & b)
34  {
35  std::cerr << "Error Umfpack only support double precision, and int ad id type" << "/n";
36  }
37 
38  void best_solve()
39  {
40  std::cerr << "Error Umfpack only support double precision, and int ad id type" << "/n";
41  }
42 };
43 
44 
45 template<>
46 class umfpack_solver<double>
47 {
48 
49  Eigen::UmfPackLU<Eigen::SparseMatrix<double,0,int> > solver;
50 
51  Eigen::SparseMatrix<double,0,int> mat_ei;
52 
53 public:
54 
65  {
66  return solve(A,b,opt);
67  }
68 
79  {
80  Vcluster<> & vcl = create_vcluster();
81 
83 
84  // Collect the matrix on master
85  mat_ei = A.getMat();
86 
87  Eigen::Matrix<double, Eigen::Dynamic, 1> x_ei;
88 
89  // Collect the vector on master
90  auto b_ei = b.getVec();
91 
92  // Copy b into x, this also copy the information on how to scatter back the information on x
93  x = b;
94 
95  if (vcl.getProcessUnitID() == 0)
96  {
97  solver.compute(mat_ei);
98 
99  if(solver.info()!=Eigen::Success)
100  {
101  // Linear solver failed
102  std::cout << __FILE__ << ":" << __LINE__ << " solver failed" << "\n";
103 
104  x.scatter();
105 
106  return x;
107  }
108 
109  x_ei = solver.solve(b_ei);
110 
111  //if (opt & SOLVER_PRINT_RESIDUAL_NORM_INFINITY)
112  //{
113  Eigen::Matrix<double, Eigen::Dynamic, 1> res;
114  res = mat_ei * x_ei - b_ei;
115 
116  std::cout << "Infinity norm: " << res.lpNorm<Eigen::Infinity>() << "\n";
117  //}
118 
119  if (opt & SOLVER_PRINT_DETERMINANT)
120  {
121  std::cout << " Determinant: " << solver.determinant() << "\n";
122  }
123  if (opt & SOLVER_PRINT)
124  {
125  std::cout << mat_ei << "\n";
126  std::cout << b_ei << "\n";
127  }
128 
129  x = x_ei;
130  }
131 
132  // Vector is only on master, scatter back the information
133  x.scatter();
134 
135  return x;
136  }
137 
147  Vector<double,EIGEN_BASE> solve(const Vector<double,EIGEN_BASE> & b, size_t opt = UMFPACK_NONE)
148  {
149  Vcluster<> & vcl = create_vcluster();
150 
151  Vector<double> x;
152 
153  Eigen::Matrix<double, Eigen::Dynamic, 1> x_ei;
154 
155  // Collect the vector on master
156  auto b_ei = b.getVec();
157 
158  // Copy b into x, this also copy the information on how to scatter back the information on x
159  x = b;
160 
161  if (vcl.getProcessUnitID() == 0)
162  {
163  x_ei = solver.solve(b_ei);
164 
165  if (opt & SOLVER_PRINT_RESIDUAL_NORM_INFINITY)
166  {
167  std::cout << "umfpack_solver: unsupported you have to pass the matrix for the option SOLVER_PRINT_RESIDUAL_NORM_INFINITY " << "\n";
168  }
169 
170  if (opt & SOLVER_PRINT_DETERMINANT)
171  {
172  std::cout << " Determinant: " << solver.determinant() << "\n";
173  }
174 
175  x = x_ei;
176  }
177 
178  // Vector is only on master, scatter back the information
179  x.scatter();
180 
181  return x;
182  }
183 };
184 
185 #else
186 
188 
189 #include "Vector/Vector.hpp"
190 
192 template<typename T>
194 {
195 public:
196 
198  template<unsigned int impl, typename id_type> static Vector<T> solve(const SparseMatrix<T,id_type,impl> & A, const Vector<T,impl> & b)
199  {
200  std::cerr << __FILE__ << ":" << __LINE__ << " Error Umfpack only support double precision" << "/n";
201  }
202 
204  void best_solve()
205  {
206  std::cerr << __FILE__ << ":" << __LINE__ << " Error Umfpack only support double precision" << "/n";
207  }
208 
210  template<unsigned int impl, typename id_type> static Vector<T,impl> try_solve(SparseMatrix<T,id_type,impl> & A, const Vector<T,impl> & b, size_t opt = UMFPACK_NONE)
211  {
212  std::cerr << __FILE__ << ":" << __LINE__ << " Error Umfpack only support double precision" << "/n";
213  }
214 };
215 
217 template<>
218 class umfpack_solver<double>
219 {
220 
221 public:
222 
224  template<unsigned int impl, typename id_type> static Vector<double> solve(SparseMatrix<double,id_type,impl> & A, const Vector<double> & b, size_t opt = UMFPACK_NONE)
225  {
226  std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use umfpack you must compile OpenFPM with linear algebra support" << "/n";
227 
228  Vector<double> x;
229 
230  return x;
231  }
232 
234  void best_solve()
235  {
236  std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use umfpack you must compile OpenFPM with linear algebra support" << "/n";
237  }
238 
241  {
242  std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use umfpack you must compile OpenFPM with linear algebra support" << "/n";
243  return Vector<double,EIGEN_BASE>();
244  }
245 };
246 
247 #endif
248 
249 
250 #endif /* OPENFPM_NUMERICS_SRC_SOLVERS_UMFPACK_SOLVER_HPP_ */
size_t getProcessUnitID()
Get the process unit id.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
Definition: Vector.hpp:39
static Vector< double, EIGEN_BASE > try_solve(SparseMatrix< double, int, EIGEN_BASE > &A, const Vector< double, EIGEN_BASE > &b, size_t opt=UMFPACK_NONE)
stub solve
Implementation of VCluster class.
Definition: VCluster.hpp:58
static Vector< T, impl > try_solve(SparseMatrix< T, id_type, impl > &A, const Vector< T, impl > &b, size_t opt=UMFPACK_NONE)
stub solve
Sparse Matrix implementation.
static Vector< T > solve(const SparseMatrix< T, id_type, impl > &A, const Vector< T, impl > &b)
stub solve
static Vector< double > solve(SparseMatrix< double, id_type, impl > &A, const Vector< double > &b, size_t opt=UMFPACK_NONE)
stub solve
stub when library compiled without eigen
void best_solve()
stub solve
void best_solve()
stub solve