MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
wsmpwrap.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/libraries/libmbwrap/wsmpwrap.cc,v 1.20 2017/01/12 14:44:25 masarati Exp $ */
2 /*
3  * HmFe (C) is a FEM analysis code.
4  *
5  * Copyright (C) 1996-2017
6  *
7  * Marco Morandini <morandini@aero.polimi.it>
8  *
9  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
10  * via La Masa, 34 - 20156 Milano, Italy
11  * http://www.aero.polimi.it
12  *
13  * Changing this copyright notice is forbidden.
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17  *
18  */
19 /* December 2001
20  * Modified to add a Sparse matrix in row form and to implement methods
21  * to be used in the parallel MBDyn Solver.
22  *
23  * Copyright (C) 2001-2017
24  *
25  * Giuseppe Quaranta <quaranta@aero.polimi.it>
26  *
27  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
28  * via La Masa, 34 - 20156 Milano, Italy
29  * http://www.aero.polimi.it
30  *
31  */
32 /*
33  * MBDyn (C) is a multibody analysis code.
34  * http://www.mbdyn.org
35  *
36  * Copyright (C) 1996-2017
37  *
38  * Pierangelo Masarati <masarati@aero.polimi.it>
39  * Paolo Mantegazza <mantegazza@aero.polimi.it>
40  *
41  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
42  * via La Masa, 34 - 20156 Milano, Italy
43  * http://www.aero.polimi.it
44  *
45  * Changing this copyright notice is forbidden.
46  *
47  * This program is free software; you can redistribute it and/or modify
48  * it under the terms of the GNU General Public License as published by
49  * the Free Software Foundation (version 2 of the License).
50  *
51  *
52  * This program is distributed in the hope that it will be useful,
53  * but WITHOUT ANY WARRANTY; without even the implied warranty of
54  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55  * GNU General Public License for more details.
56  *
57  * You should have received a copy of the GNU General Public License
58  * along with this program; if not, write to the Free Software
59  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
60  */
61 
62 /*
63  * Wsmp is used by permission; please read its Copyright,
64  * License and Availability note.
65  */
66 
67 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
68 
69 #ifdef USE_WSMP
70 #include "solman.h"
71 #include "spmapmh.h"
72 #include "ccmh.h"
73 #include "dirccmh.h"
74 #include "wsmpwrap.h"
75 
76 extern "C" {
77 extern void wgsmp_(int *N,
78  int *IA,
79  int *JA,
80  double *AVALS,
81  double *B,
82  int *LDB,
83  int *NRHS,
84  double *RMISC,
85  int *IPARAM,
86  double *DPARAM);
87  extern void wsetmaxthrds_(int *);
88  extern void wsmp_clear_();
89 }
90 
91 
92 /* WsmpSolver - begin */
93 
94 WsmpSolver::WsmpSolver(const integer &size, const doublereal &dPivot,
95  const unsigned blockSize, const unsigned nt)
96 : LinearSolver(0),
97 iSize(size),
98 Axp(0),
99 Aip(0),
100 App(0),
101 ldb(size),
102 nrhs(1),
103 rmisc(0),
104 Symbolic(false)
105 {
106  int tnt = nt;
107  wsetmaxthrds_(&tnt);
108  iparm[0] = 0;
109  iparm[1] = 0;
110  iparm[2] = 0;
111 
112  wgsmp_(&iSize, 0, 0, 0, 0, &ldb, &nrhs, rmisc, iparm, dparm);
113 
114  /* CSC format */
115  iparm[3] = 1;
116  /* 0 index */
117  iparm[4] = 0;
118  /* pivot */
119 
120  if (dPivot != -1. && (dPivot >= 0. && dPivot <= 1.)) {
121  /*
122  * 1.0: true partial pivoting
123  * 0.0: treated as 1.0
124  *
125  * default: 0.1
126  */
127  dparm[10] = dPivot;
128  dparm[21] = dPivot;
129  }
130 
131  if (blockSize > 0) {
132  iparm[31] = blockSize;
133  }
134 }
135 
136 WsmpSolver::~WsmpSolver(void)
137 {
138  wsmp_clear_();
139 }
140 
141 void
142 WsmpSolver::Reset(void)
143 {
144  bHasBeenReset = true;
145 }
146 
147 void
148 WsmpSolver::Solve(void) const
149 {
150  if (bHasBeenReset) {
151  const_cast<WsmpSolver *>(this)->Factor();
152  bHasBeenReset = false;
153  }
154 
155  int status;
156 
157  /*
158  * NOTE: Axp, Aip, App should have been set by * MakeCompactForm()
159  */
160 
161  iparm[1] = 3;
162  iparm[2] = 3;
163 
164  int tsize = iSize;
165 
166  wgsmp_(&tsize, App, Aip, Axp, LinearSolver::pdRhs, &ldb, &nrhs, rmisc, iparm, dparm);
167 
168  status = iparm[63];
169 
170  if (status != 0) {
171  silent_cerr("Wsmp back substitution failed" << std::endl);
172 
173  /* de-allocate memory */
174  wsmp_clear_();
175 
177  }
178 
179  iparm[1] = 4;
180  iparm[2] = 4;
181 
182  wgsmp_(&tsize, App, Aip, Axp, LinearSolver::pdRhs, &ldb, &nrhs, rmisc, iparm, dparm);
183 
184  status = iparm[63];
185 
186  if (status != 0) {
187  silent_cerr("Wsmp iterative refinement failed" << std::endl);
188 
189  /* de-allocate memory */
190  wsmp_clear_();
191 
193  }
194 
195 }
196 
197 void
198 WsmpSolver::Factor(void)
199 {
200  int status;
201 
202  /*
203  * NOTE: Axp, Aip, App should have been set by * MakeCompactForm()
204  */
205 
206  if (!Symbolic && !bPrepareSymbolic()) {
208  }
209 
210  iparm[1] = 2;
211  iparm[2] = 2;
212 
213  int tsize = iSize;
214 
215  wgsmp_(&tsize, App, Aip, Axp, LinearSolver::pdRhs, &ldb, &nrhs, rmisc, iparm, dparm);
216 
217  status = iparm[63];
218 
219  if (status != 0) {
220  silent_cerr("Wsmp factorization failed" << std::endl);
221 
222  /* de-allocate memory */
223  wsmp_clear_();
224 
226  }
227 }
228 
229 void
230 WsmpSolver::MakeCompactForm(SparseMatrixHandler& mh,
231  std::vector<doublereal>& Ax,
232  std::vector<integer>& Ai,
233  std::vector<integer>& Ac,
234  std::vector<integer>& Ap) const
235 {
236  if (!bHasBeenReset) {
237  return;
238  }
239 
240  mh.MakeCompressedColumnForm(Ax, Ai, Ap, 0);
241 
242  Axp = &(Ax[0]);
243  Aip = &(Ai[0]);
244  App = &(Ap[0]);
245 }
246 
247 bool
248 WsmpSolver::bPrepareSymbolic(void)
249 {
250  int status;
251 
252  iparm[1] = 1;
253  iparm[2] = 1;
254 
255  int tsize = iSize;
256 
257  wgsmp_(&tsize, App, Aip, Axp, LinearSolver::pdRhs, &ldb, &nrhs, rmisc, iparm, dparm);
258 
259  status = iparm[63];
260 
261  if (status != 0) {
262  silent_cerr("Wsmp factorization failed" << std::endl);
263 
264  /* de-allocate memory */
265  wsmp_clear_();
266 
268  }
269 
270  Symbolic = true;
271 
272  return true;
273 }
274 
275 /* WsmpSolver - end */
276 
277 /* WsmpSparseSolutionManager - begin */
278 
279 WsmpSparseSolutionManager::WsmpSparseSolutionManager(integer Dim,
280  doublereal dPivot,
281  const unsigned blockSize,
282  const unsigned nt)
283 : A(Dim),
284 xb(Dim),
285 xbVH(Dim, &xb[0])
286 {
287  SAFENEWWITHCONSTRUCTOR(pLS, WsmpSolver,
288  WsmpSolver(Dim, dPivot, blockSize, nt));
289 
290  (void)pLS->pdSetResVec(&xb[0]);
291  (void)pLS->pdSetSolVec(&xb[0]);
292  pLS->SetSolutionManager(this);
293 }
294 
295 WsmpSparseSolutionManager::~WsmpSparseSolutionManager(void)
296 {
297  NO_OP;
298 }
299 
300 void
301 WsmpSparseSolutionManager::MatrReset(void)
302 {
303  pLS->Reset();
304 }
305 
306 void
307 WsmpSparseSolutionManager::MakeCompressedColumnForm(void)
308 {
309  pLS->MakeCompactForm(A, Ax, Ai, Adummy, Ap);
310 }
311 
312 /* Risolve il sistema Fattorizzazione + Backward Substitution */
313 void
314 WsmpSparseSolutionManager::Solve(void)
315 {
316  MakeCompressedColumnForm();
317  pLS->Solve();
318 }
319 
320 /* Rende disponibile l'handler per la matrice */
322 WsmpSparseSolutionManager::pMatHdl(void) const
323 {
324  return &A;
325 }
326 
327 /* Rende disponibile l'handler per il termine noto */
329 WsmpSparseSolutionManager::pResHdl(void) const
330 {
331  return &xbVH;
332 }
333 
334 /* Rende disponibile l'handler per la soluzione */
336 WsmpSparseSolutionManager::pSolHdl(void) const
337 {
338  return &xbVH;
339 }
340 
341 /* WsmpSparseSolutionManager - end */
342 
343 template <class CC>
344 WsmpSparseCCSolutionManager<CC>::WsmpSparseCCSolutionManager(integer Dim,
345  doublereal dPivot,
346  const unsigned& blockSize,
347  const unsigned nt)
348 : WsmpSparseSolutionManager(Dim, dPivot, blockSize, nt),
349 CCReady(false),
350 Ac(0)
351 {
352  NO_OP;
353 }
354 
355 template <class CC>
356 WsmpSparseCCSolutionManager<CC>::~WsmpSparseCCSolutionManager(void)
357 {
358  if (Ac) {
359  SAFEDELETE(Ac);
360  }
361 }
362 
363 template <class CC>
364 void
365 WsmpSparseCCSolutionManager<CC>::MatrReset(void)
366 {
367  pLS->Reset();
368 }
369 
370 template <class CC>
371 void
372 WsmpSparseCCSolutionManager<CC>::MakeCompressedColumnForm(void)
373 {
374  if (!CCReady) {
375  pLS->MakeCompactForm(A, Ax, Ai, Adummy, Ap);
376 
377  if (Ac == 0) {
378  SAFENEWWITHCONSTRUCTOR(Ac, CC, CC(Ax, Ai, Ap));
379  }
380 
381  CCReady = true;
382  }
383 }
384 
385 /* Inizializzatore "speciale" */
386 template <class CC>
387 void
388 WsmpSparseCCSolutionManager<CC>::MatrInitialize()
389 {
390  CCReady = false;
391 
392  MatrReset();
393 }
394 
395 /* Rende disponibile l'handler per la matrice */
396 template <class CC>
398 WsmpSparseCCSolutionManager<CC>::pMatHdl(void) const
399 {
400  if (!CCReady) {
401  return &A;
402  }
403 
404  ASSERT(Ac != 0);
405  return Ac;
406 }
407 
408 template class WsmpSparseCCSolutionManager<CColMatrixHandler<0> >;
409 template class WsmpSparseCCSolutionManager<DirCColMatrixHandler<0> >;
410 
411 /* WsmpSparseCCSolutionManager - end */
412 
413 #endif /* USE_WSMP */
414 
virtual integer MakeCompressedColumnForm(doublereal *const Ax, integer *const Ai, integer *const Ap, int offset=0) const =0
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
#define NO_OP
Definition: myassert.h:74
void Reset(scalar_func_type &d)
Definition: gradient.h:2836
Definition: mbdyn.h:76
#define ASSERT(expression)
Definition: colamd.c:977
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
doublereal * pdRhs
Definition: ls.h:74
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
#define SAFEDELETE(pnt)
Definition: mynewmem.h:710