gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
linearSystemEigen.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <stdio.h>
7 #include <math.h>
8 #include "linearSystemEigen.h"
9 
10 #if defined(HAVE_EIGEN)
11 
12 linearSystemEigen<double>::linearSystemEigen() { solverType = EigenSparseLU; }
13 
14 bool linearSystemEigen<double>::isAllocated() const
15 {
16  if(A.rows() > 0)
17  return true;
18  else
19  return false;
20 }
21 
23 {
24  A.resize(nbRows, nbRows);
25  B.resize(nbRows);
26  X.resize(nbRows);
27  B.fill(0.);
28  X.fill(0.);
29 }
30 
31 void linearSystemEigen<double>::clear()
32 {
33  A.setZero();
34  B.setZero();
35  X.setZero();
36 }
37 
38 void linearSystemEigen<double>::zeroMatrix()
39 {
40  A.setZero();
41  B.setZero();
42  X.setZero();
43 }
44 
45 void linearSystemEigen<double>::zeroRightHandSide() { B.fill(0.); }
46 
47 void linearSystemEigen<double>::zeroSolution() { X.fill(0.); }
48 
49 void linearSystemEigen<double>::setSolverType(
50  linearSystemEigenSolver solverName)
51 {
52  solverType = solverName;
53 }
54 
55 int linearSystemEigen<double>::systemSolve()
56 {
57  if(solverType == EigenCholeskyLLT) {
58  Eigen::SimplicialLLT<Eigen::SparseMatrix<double> > solver;
59  solver.compute(A);
60  if(solver.info() != Eigen::ComputationInfo::Success) {
61  Msg::Warning("Eigen: failed to solve linear system with CholeskyLLT");
62  return -1;
63  }
64  X = solver.solve(B);
65  if(solver.info() != Eigen::ComputationInfo::Success) {
66  Msg::Warning("Eigen: failed to solve linear system with CholeskyLLT");
67  return -1;
68  }
69  }
70  else if(solverType == EigenCholeskyLDLT) {
71  Eigen::SimplicialLDLT<Eigen::SparseMatrix<double> > solver;
72  solver.compute(A);
73  if(solver.info() != Eigen::ComputationInfo::Success) {
74  Msg::Warning("Eigen: failed to solve linear system with CholeskyLDLT");
75  return -1;
76  }
77  X = solver.solve(B);
78  if(solver.info() != Eigen::ComputationInfo::Success) {
79  Msg::Warning("Eigen: failed to solve linear system with CholeskyLDLT");
80  return -1;
81  }
82  }
83  else if(solverType == EigenSparseLU) {
84  Eigen::SparseLU<Eigen::SparseMatrix<double> > solver;
85  solver.compute(A);
86  if(solver.info() != Eigen::ComputationInfo::Success) {
87  Msg::Warning("Eigen: failed to solve linear system with SparseLU");
88  return -1;
89  }
90  X = solver.solve(B);
91  if(solver.info() != Eigen::ComputationInfo::Success) {
92  Msg::Warning("Eigen: failed to solve linear system with SparseLU");
93  return -1;
94  }
95  }
96  else if(solverType == EigenSparseQR) {
97  /* Note: maybe another ordering method is better, see Eigen documentation */
98  Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::NaturalOrdering<int> >
99  solver;
100  solver.compute(A);
101  if(solver.info() != Eigen::ComputationInfo::Success) {
102  Msg::Warning("Eigen: failed to solve linear system with SparseQR");
103  return -1;
104  }
105  X = solver.solve(B);
106  if(solver.info() != Eigen::ComputationInfo::Success) {
107  Msg::Warning("Eigen: failed to solve linear system with SparseQR");
108  return -1;
109  }
110  }
111  else if(solverType == EigenCG) {
112  Eigen::ConjugateGradient<Eigen::SparseMatrix<double> > solver;
113  solver.compute(A);
114  if(solver.info() != Eigen::ComputationInfo::Success) {
115  Msg::Warning(
116  "Eigen: failed to solve linear system with Conjugate Gradient");
117  return -1;
118  }
119  X = solver.solve(B);
120  if(solver.info() != Eigen::ComputationInfo::Success) {
121  Msg::Warning(
122  "Eigen: failed to solve linear system with Conjugate Gradient");
123  return -1;
124  }
125  }
126  else if(solverType == EigenCGLeastSquare) {
127  Eigen::LeastSquaresConjugateGradient<Eigen::SparseMatrix<double> > solver;
128  solver.compute(A);
129  if(solver.info() != Eigen::ComputationInfo::Success) {
130  Msg::Warning("Eigen: failed to solve linear system with Least Square "
131  "Conjugate Gradient");
132  return -1;
133  }
134  X = solver.solve(B);
135  if(solver.info() != Eigen::ComputationInfo::Success) {
136  Msg::Warning("Eigen: failed to solve linear system with Least Square "
137  "Conjugate Gradient");
138  return -1;
139  }
140  }
141  else if(solverType == EigenBiCGSTAB) {
142  Eigen::BiCGSTAB<Eigen::SparseMatrix<double> > solver;
143  solver.compute(A);
144  if(solver.info() != Eigen::ComputationInfo::Success) {
145  Msg::Warning("Eigen: failed to solve linear system with BiCGSTAB");
146  return -1;
147  }
148  X = solver.solve(B);
149  if(solver.info() != Eigen::ComputationInfo::Success) {
150  Msg::Warning("Eigen: failed to solve linear system with BiCGSTAB");
151  return -1;
152  }
153  }
154  return 1;
155 }
156 
157 void linearSystemEigen<double>::insertInSparsityPattern(int row, int col) {}
158 
159 double linearSystemEigen<double>::normInfRightHandSide() const
160 {
161  return B.maxCoeff();
162 }
163 
164 double linearSystemEigen<double>::normInfSolution() const
165 {
166  return X.maxCoeff();
167 }
168 
169 void linearSystemEigen<double>::addToMatrix(int row, int col, const double &val)
170 {
171  A.coeffRef(row, col) += val; /* slow ! */
172 }
173 
174 void linearSystemEigen<double>::getFromMatrix(int row, int col,
175  double &val) const
176 {
177  val = A.coeff(row, col);
178 }
179 
180 void linearSystemEigen<double>::addToRightHandSide(int row, const double &val,
181  int ith)
182 {
183  if((int)B.size() <= row) {
184  B.resize(row + 1);
185  B[row] = val;
186  }
187  else {
188  B[row] += val;
189  }
190 }
191 
192 void linearSystemEigen<double>::getFromRightHandSide(int row, double &val) const
193 {
194  if((int)B.size() <= row) val = 0.;
195  val = B[row];
196 }
197 
198 void linearSystemEigen<double>::getFromSolution(int row, double &val) const
199 {
200  if((int)X.size() <= row)
201  val = 0.;
202  else
203  val = X[row];
204 }
205 
206 void linearSystemEigen<double>::addToSolution(int row, const double &val)
207 {
208  if((int)X.size() <= row) {
209  X.resize(row + 1);
210  X[row] = val;
211  }
212  else {
213  X[row] += val;
214  }
215 }
216 
217 #endif
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
nanoflann::allocate
T * allocate(size_t count=1)
Definition: nanoflann.hpp:442
linearSystemEigen.h