OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
28template<typename T>
30{
31public:
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
45template<>
46class umfpack_solver<double>
47{
48
49 Eigen::UmfPackLU<Eigen::SparseMatrix<double,0,int> > solver;
50
51 Eigen::SparseMatrix<double,0,int> mat_ei;
52
53public:
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
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
192template<typename T>
194{
195public:
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
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
217template<>
218class umfpack_solver<double>
219{
220
221public:
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
229
230 return x;
231 }
232
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";
244 }
245};
246
247#endif
248
249
250#endif /* OPENFPM_NUMERICS_SRC_SOLVERS_UMFPACK_SOLVER_HPP_ */
Sparse Matrix implementation.
size_t getProcessUnitID()
Get the process unit id.
Implementation of VCluster class.
Definition VCluster.hpp:59
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
Definition Vector.hpp:40
static Vector< double > solve(SparseMatrix< double, id_type, impl > &A, const Vector< double > &b, size_t opt=UMFPACK_NONE)
stub solve
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
stub when library compiled without eigen
static Vector< T > solve(const SparseMatrix< T, id_type, impl > &A, const Vector< T, impl > &b)
stub solve
void best_solve()
stub solve
static Vector< T, impl > try_solve(SparseMatrix< T, id_type, impl > &A, const Vector< T, impl > &b, size_t opt=UMFPACK_NONE)
stub solve