gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
linearSystemMUMPS.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 "linearSystemMUMPS.h"
9 
10 #if defined(HAVE_MUMPS)
11 
12 #define USE_COMM_WORLD -987654
13 
14 void mumpserror(int id, int subid)
15 {
16  if(id < 0) {
17  Msg::Error("MUMPS INFO(1) = %d, INFO(2) = %d", id, subid);
18 
19  switch(id) {
20  case -6:
21  Msg::Error("Matrix is singular in structure, structural rank: %d", subid);
22  break;
23  case -10: Msg::Error("Matrix is numerically singular"); break;
24  case -13: Msg::Error("Not enough memory"); break;
25  case -40: Msg::Error("Matrix is not symmetric positive definite"); break;
26  default: Msg::Error("Check MUMPS user's guide"); break;
27  }
28  }
29 }
30 
31 linearSystemMUMPS<double>::linearSystemMUMPS()
32 {
33  _n = 0;
34  _nz = 0;
35 }
36 
37 bool linearSystemMUMPS<double>::isAllocated() const
38 {
39  if(_n > 0)
40  return true;
41  else
42  return false;
43 }
44 
46 {
47  _n = nbRows;
48  _b.resize(_n);
49  _x.resize(_n);
50  _a.reserve(10 * _n);
51  _irn.reserve(10 * _n);
52  _jcn.reserve(10 * _n);
53  _ij.reserve(_n);
54 }
55 
56 void linearSystemMUMPS<double>::clear()
57 {
58  _x.clear();
59  _a.clear();
60  _b.clear();
61  _n = 0;
62  _nz = 0;
63  _irn.clear();
64  _jcn.clear();
65  _ij.clear();
66 }
67 
68 void linearSystemMUMPS<double>::zeroMatrix()
69 {
70  _nz = 0;
71  _a.clear();
72  _ij.clear();
73  _irn.clear();
74  _jcn.clear();
75 }
76 
77 void linearSystemMUMPS<double>::zeroRightHandSide()
78 {
79  for(std::size_t i = 0; i < _b.size(); i++) _b[i] = 0.;
80 }
81 
82 void linearSystemMUMPS<double>::zeroSolution()
83 {
84  for(std::size_t i = 0; i < _x.size(); i++) _x[i] = 0.;
85 }
86 
87 int linearSystemMUMPS<double>::systemSolve()
88 {
89  // MUMPS will overwrite _b with the solution
90  std::vector<DMUMPS_REAL> b = _b;
91 
92  DMUMPS_STRUC_C id;
93 
94  id.par = 1;
95  const std::string sym = getParameter("symmetry");
96  if(sym == "spd")
97  id.sym = 1;
98  else if(sym == "symmetric")
99  id.sym = 2;
100  else
101  id.sym = 0;
102 
103  id.comm_fortran = USE_COMM_WORLD;
104 
105  Msg::Debug("MUMPS initialization");
106  id.job = -1;
107  dmumps_c(&id);
108  mumpserror(id.info[0], id.info[1]);
109 
110  id.n = _n;
111  id.nz = _nz;
112  // Fortran indices start from 1
113  for(std::size_t i = 0; i < _irn.size(); i++) _irn[i]++;
114  for(std::size_t i = 0; i < _jcn.size(); i++) _jcn[i]++;
115  id.irn = &*_irn.begin();
116  id.jcn = &*_jcn.begin();
117  id.a = &*_a.begin();
118  id.rhs = &*_b.begin();
119 
120  // Fortran indices start from 1
121  id.icntl[1 - 1] = -1;
122  id.icntl[2 - 1] = -1;
123  id.icntl[3 - 1] = -1;
124  id.icntl[4 - 1] = 0;
125  id.icntl[5 - 1] = 0;
126  id.icntl[18 - 1] = 0;
127 
128  Msg::Debug("MUMPS analysis, LU factorization, and back substitution");
129  id.job = 6;
130  dmumps_c(&id);
131  mumpserror(id.info[0], id.info[1]);
132 
133  Msg::Debug("MUMPS destroy");
134  id.job = -2;
135  dmumps_c(&id);
136  Msg::Debug("MUMPS end");
137  mumpserror(id.info[0], id.info[1]);
138 
139  _x.clear();
140  _x = _b;
141  _b = b;
142  for(std::size_t i = 0; i < _irn.size(); i++) _irn[i]--;
143  for(std::size_t i = 0; i < _jcn.size(); i++) _jcn[i]--;
144 
145  return 1;
146 }
147 
148 void linearSystemMUMPS<double>::insertInSparsityPattern(int row, int col) {}
149 
150 double linearSystemMUMPS<double>::normInfRightHandSide() const
151 {
152  DMUMPS_REAL norm = 0.;
153  for(std::size_t i = 0; i < _b.size(); i++) {
154  DMUMPS_REAL temp = fabs(_b[i]);
155  if(temp > norm) norm = temp;
156  }
157  return norm;
158 }
159 
160 double linearSystemMUMPS<double>::normInfSolution() const
161 {
162  DMUMPS_REAL norm = 0.;
163  for(std::size_t i = 0; i < _x.size(); i++) {
164  DMUMPS_REAL temp = fabs(_x[i]);
165  if(temp > norm) norm = temp;
166  }
167  return norm;
168 }
169 
170 void linearSystemMUMPS<double>::addToMatrix(int row, int col, const double &val)
171 {
172  // MUMPS will sum entries with duplicate (row, col)
173  /*_a.push_back(val);
174  _irn.push_back(row);
175  _jcn.push_back(col);
176  _nz++;*/
177  if((int)_ij.size() <= row) {
178  _a.push_back(val);
179  _irn.push_back(row);
180  _jcn.push_back(col);
181  _ij.resize(row + 1);
182  _ij[row][col] = _a.size() - 1;
183  _nz++;
184  return;
185  }
186  auto it = _ij[row].find(col);
187  if(it == _ij[row].end()) {
188  _a.push_back(val);
189  _irn.push_back(row);
190  _jcn.push_back(col);
191  _ij[row][col] = _a.size() - 1;
192  _nz++;
193  }
194  else {
195  _a[it->second] += val;
196  }
197 }
198 
199 void linearSystemMUMPS<double>::getFromMatrix(int row, int col,
200  double &val) const
201 {
202  // Msg::Error("getFromMatrix not implemented for linearSystemMUMPS");
203  if((int)_ij.size() <= row) {
204  val = 0.;
205  return;
206  }
207  auto it = _ij[row].find(col);
208  if(it == _ij[row].end())
209  val = 0.;
210  else
211  val = _a[it->second];
212 }
213 
214 void linearSystemMUMPS<double>::addToRightHandSide(int row, const double &val,
215  int ith)
216 {
217  // printf("adding %g to %d\n",val,row);
218  if((int)_b.size() <= row) {
219  _b.resize(row + 1);
220  _b[row] = val;
221  }
222  else {
223  _b[row] += val;
224  }
225 }
226 
227 void linearSystemMUMPS<double>::getFromRightHandSide(int row, double &val) const
228 {
229  if((int)_b.size() <= row) val = 0.;
230  val = _b[row];
231 }
232 
233 void linearSystemMUMPS<double>::getFromSolution(int row, double &val) const
234 {
235  // printf("x[%d] = %g\n",row,_x[row]);
236  if((int)_x.size() <= row)
237  val = 0.;
238  else
239  val = _x[row];
240 }
241 
242 void linearSystemMUMPS<double>::addToSolution(int row, const double &val)
243 {
244  if((int)_x.size() <= row) {
245  _x.resize(row + 1);
246  _x[row] = val;
247  }
248  else {
249  _x[row] += val;
250  }
251 }
252 
253 #endif
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
nanoflann::allocate
T * allocate(size_t count=1)
Definition: nanoflann.hpp:442
linearSystemMUMPS.h
norm
void norm(const double *vec, double *norm)
Definition: gmshLevelset.cpp:202