b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2mumps_solver.H
Go to the documentation of this file.
1//------------------------------------------------------------------------
2// b2mumps_solver.H --
3//
4// written by Mathias Doreille
5// Harald Klimach <harald.klimach@dlr.de>
6//
7// (c) 2011-2016 SMR Engineering & Development SA
8// 2502 Bienne, Switzerland
9//
10// (c) 2021-2023 Deutsches Zentrum für Luft- und Raumfahrt (DLR) e.V.
11// Linder Höhe, 51147 Köln
12//
13// All Rights Reserved. Proprietary source code. The contents of
14// this file may not be disclosed to third parties, copied or
15// duplicated in any form, in whole or in part, without the prior
16// written permission of SMR or DLR.
17//
18//------------------------------------------------------------------------
19
20#ifndef B2MUMPS_SOLVER_H_
21#define B2MUMPS_SOLVER_H_
22
23#include <type_traits>
24
25#include "b2sparse_solver.H"
26#include "utils/b2timing.H"
27
28#ifdef HAVE_UPMUMPS_DMUMPS_C_H
29#include "MUMPS/dmumps_c.h"
30#else
31#ifdef HAVE_MUMPS_DMUMPS_C_H
32#include "mumps/dmumps_c.h"
33#else
34#ifdef HAVE_DMUMPS_C_H
35#include "dmumps_c.h"
36#endif // HAVE_DMUMPS_C_H
37#endif // HAVE_MUMPS_DMUMPS_C_H
38#endif // HAVE_UPMUMPS_DMUMPS_C_H
39
40#ifdef HAVE_UPMUMPS_ZMUMPS_C_H
41#include "MUMPS/zmumps_c.h"
42#else
43#ifdef HAVE_MUMPS_ZMUMPS_C_H
44#include "mumps/zmumps_c.h"
45#else
46#ifdef HAVE_ZMUMPS_C_H
47#include "zmumps_c.h"
48#endif // HAVE_ZMUMPS_C_H
49#endif // HAVE_MUMPS_ZMUMPS_C_H
50#endif // HAVE_UPMUMPS_ZMUMPS_C_H
51
52#include "b2blaslapack.H"
53#include "b2linalg_solver_slave.H"
54#include "utils/b2logging.H"
55
56//------------------------------------------------------------------------
57//
61//------------------------------------------------------------------------
62
63namespace b2000 { namespace b2linalg {
64
66
69enum MUMPSICNTL : int {
70 MUMPS_ErrStream = 1 - 1,
71 MUMPS_DiagStream = 2 - 1,
72 MUMPS_GlobStream = 3 - 1,
73 MUMPS_LogLevel = 4 - 1,
74 MUMPS_MatrixForm = 5 - 1,
75 MUMPS_ZeroFreeScale = 6 - 1,
76 MUMPS_SymPerm = 7 - 1,
77 MUMPS_Scaling = 8 - 1,
78 MUMPS_Transposed = 9 - 1,
79 MUMPS_MaxIterRefine = 10 - 1,
80 MUMPS_ErrStats = 11 - 1,
81 MUMPS_OrdStrategy = 12 - 1,
82 MUMPS_RootParallel = 13 - 1,
83 MUMPS_WsIncrease = 14 - 1,
84 MUMPS_nThreads = 16 - 1,
85 MUMPS_MatrixDist = 18 - 1,
86 MUMPS_SchurComp = 19 - 1,
87 MUMPS_RhsForm = 20 - 1,
88 MUMPS_SolDist = 21 - 1,
89 MUMPS_OOC = 22 - 1,
90 MUMPS_MaxWorkMem = 23 - 1,
91 MUMPS_NullPivotRows = 24 - 1,
92 MUMPS_Deficient = 25 - 1,
93 MUMPS_SchurPhase = 26 - 1,
94 MUMPS_RhsBlockSize = 27 - 1,
95 MUMPS_SeqOrPar = 28 - 1,
96 MUMPS_ParOrderTool = 29 - 1,
97 MUMPS_Subset = 30 - 1,
98 MUMPS_DiscardFacts = 31 - 1,
99 MUMPS_ForwardInFact = 32 - 1,
100 MUMPS_Determinant = 33 - 1,
101 MUMPS_DelFiles = 34 - 1,
102 MUMPS_BLR = 35 - 1,
103 MUMPS_BlrVariant = 36 - 1,
104 MUMPS_Compression = 38 - 1,
105};
106
108
111enum class MUMPSACTION : unsigned int {
112 NewObject = 1,
113 Continued = 2,
114};
115
122template <class T>
124
125template <>
126struct B2MUMPS_STRUC<double> {
127 using type = DMUMPS_STRUC_C;
128 using numtype = DMUMPS_REAL;
129};
130template <>
131struct B2MUMPS_STRUC<std::complex<double>> {
132 using type = ZMUMPS_STRUC_C;
133 using numtype = mumps_double_complex;
134};
135template <>
136struct B2MUMPS_STRUC<b2000::csda<double>> {
137 using type = ZMUMPS_STRUC_C;
138 using numtype = mumps_double_complex;
139};
140
142template <class T>
144
146template <class T>
148
150
165inline void mumps_error_handler(const int* const info, bool autospc = false) {
166 const int error = info[0];
167 if (error == 0) {
168 if (!autospc && info[27] > 0) {
169 SingularMatrixError e;
170 e.null_space_size = info[27];
171 e << "Numerically singular matrix: " << info[27] << " null pivot found\n";
172 e << "Note: You may want to reduce the threshold for null pivots\n";
173 e << " by adding a mumps_cntl(3) statement to your case definition.\n";
174 e << " Try `mumps_cntl '3:1.1e-21'`.\n";
175 e << "See the section on the mumps_cntl parameter in the user guide for\n";
176 e << "further reference.\n";
177 e << THROW;
178 }
179 } else if (error > 0) {
180 logging::Logger logger =
181 logging ::get_logger("linear_algebra.sparse_symmetric_solver.mumps");
182 logger << logging::warning << "warning code " << error << ": ";
183 if (error & 1) { logger << "Index (in IRN or JCN) out of range. "; }
184 if (error & 2) {
185 logger << "During error analysis the max-norm of the computed "
186 "solution was found to be zero. ";
187 }
188 if (error & 4) {
189 logger << "User data JCN has been modified (internally) by the"
190 " solver. ";
191 }
192 if (error & 8) { logger << "More than ICNTL(10) iterations refinement are required."; }
193 logger << logging::LOGFLUSH;
194 } else {
195 Exception e;
196 e << "error code " << error << ": ";
197 switch (error) {
198 case -6:
199 e << "Matrix is singular in structure.";
200 break;
201 case -10:
202 e << "Numerically singular matrix.";
203 break;
204 case -13:
205 e << "out of memory error";
206 break;
207 case -40:
208 e << "The matrix was indicated to be positive definite but a"
209 " negative or null pivot was encountered";
210 break;
211 default:
212 break;
213 }
214 e << THROW;
215 }
216}
217
219
228template <typename MUMPS_STRUC_C>
229inline void decode_mumps_cntl(const Dictionary& d, MUMPS_STRUC_C& mumps_struct) {
230 std::string icntl = d.get_string("MUMPS_ICNTL", "");
231 if (icntl != "") {
232 std::istringstream iss(icntl);
233 for (;;) {
234 int k, v;
235 char c;
236 if (iss >> k && iss >> c && iss >> v) {
237 if (c != ':' || (k < 1 || k > 33)) {
238 Exception() << "Cannot parse the MUMPS_ICNTL analysis directive " << icntl
239 << THROW;
240 }
241 if (MUMPS_MatrixForm == k - 1) {
242 Exception() << "Not allowed to modify the Matrix form "
243 "(5) in MUMPS_ICNTL: "
244 << icntl << THROW;
245 }
246 if (MUMPS_MatrixDist == k - 1) {
247 Exception() << "Not allowed to modify the Matrix "
248 "distribution (18) in MUMPS_ICNTL: "
249 << icntl << THROW;
250 }
251 mumps_struct.icntl[k - 1] = v;
252 } else {
253 Exception() << "Cannot parse the MUMPS_ICNTL analysis directive " << icntl << THROW;
254 }
255 iss >> c;
256 if (!iss) { break; }
257 if (c != ',') {
258 Exception() << "Cannot parse the MUMPS_ICNTL analysis directive " << icntl << THROW;
259 }
260 }
261 }
262 std::string cntl = d.get_string("MUMPS_CNTL", "");
263 if (cntl != "") {
264 std::istringstream dss(cntl);
265 for (;;) {
266 int k;
267 double v;
268 char c;
269 if (dss >> k && dss >> c && dss >> v) {
270 if (c != ':' || (k < 1 || k > 5)) {
271 Exception() << "Cannot parse the MUMPS_CNTL analysis directive " << cntl
272 << THROW;
273 }
274 mumps_struct.cntl[k - 1] = v;
275 } else {
276 Exception() << "Cannot parse the MUMPS_CNTL analysis directive " << cntl << THROW;
277 }
278 dss >> c;
279 if (!dss) { break; }
280 if (c != ',') {
281 Exception() << "Cannot parse the MUMPS_CNTL analysis directive " << cntl << THROW;
282 }
283 }
284 }
285}
286
288
293template <typename MUMPS_STRUC_C>
294inline void b2_mumps_call(
295 MUMPS_STRUC_C& mumps_struct, MUMPSACTION action = MUMPSACTION::Continued) {
296 constexpr bool is_dmumps = std::is_same<MUMPS_STRUC_C, DMUMPS_STRUC_C>::value;
297 constexpr unsigned int numtype = is_dmumps ? 0 : 1;
298
299 unsigned int act = static_cast<unsigned int>(action);
300 unsigned int sym_job = 1 == act ? mumps_struct.sym : mumps_struct.job;
301 auto mumpstimer = obtain_timer("mumps");
302 (*mumpstimer).second.start();
303 SolverSlave::MumpsSend(act, numtype, &mumps_struct, sym_job);
304 if constexpr (is_dmumps) {
305 dmumps_c(&mumps_struct);
306 } else {
307 zmumps_c(&mumps_struct);
308 }
309 (*mumpstimer).second.stop();
310}
311
313
325template <typename MUMPS_STRUC_C>
326inline void b2_mumps_new(MUMPS_STRUC_C& mumps_struct, MUMPS_INT sym) {
327 mumps_struct.sym = sym;
328 mumps_struct.par = 1;
329 mumps_struct.job = -1;
330 mumps_struct.comm_fortran = (MUMPS_INT)SolverSlave::GetFcomm();
331 b2_mumps_call(mumps_struct, MUMPSACTION::NewObject);
332 mumps_error_handler(mumps_struct.infog);
333 mumps_struct.irn = 0;
334 mumps_struct.jcn = 0;
335
336 logging::Logger logger = logging::get_logger("linear_algebra.sparse_symmetric_solver.mumps");
337 if (logger.is_enabled_for(logging::debug)) {
338 mumps_struct.icntl[MUMPS_LogLevel] = 3;
339 mumps_struct.icntl[MUMPS_ErrStream] = 6;
340 mumps_struct.icntl[MUMPS_DiagStream] = 6;
341 mumps_struct.icntl[MUMPS_GlobStream] = 6;
342 mumps_struct.icntl[MUMPS_ErrStats] = 1;
343 } else {
344 mumps_struct.icntl[MUMPS_LogLevel] = 0;
345 mumps_struct.icntl[MUMPS_ErrStream] = 0;
346 mumps_struct.icntl[MUMPS_DiagStream] = 0;
347 mumps_struct.icntl[MUMPS_GlobStream] = 0;
348 }
349}
350
352
357template <typename MUMPS_STRUC_C>
358inline void b2_mumps_delete(MUMPS_STRUC_C& mumps_struct) {
359 mumps_struct.job = -2;
360 b2_mumps_call(mumps_struct);
361 mumps_error_handler(mumps_struct.infog, true);
362 delete[] mumps_struct.irn;
363 delete[] mumps_struct.jcn;
364}
365
367
372template <typename MUMPS_STRUC_C>
373inline void b2_mumps_call_wsgrow(MUMPS_STRUC_C& mumps_struct) {
374 logging::Logger logger = logging::get_logger("linear_algebra.sparse_symmetric_solver.mumps");
375 for (;;) {
376 b2_mumps_call(mumps_struct);
377 if (mumps_struct.infog[0] == -8 || mumps_struct.infog[0] == -9) {
378 mumps_struct.icntl[MUMPS_WsIncrease] *= 2;
379 if (4 == mumps_struct.job) { mumps_struct.job = 2; }
380 logger << "resolve: work array is too small, increasing size "
381 "of work array and retrying resolution."
382 << logging::LOGFLUSH;
383 } else {
384 break;
385 }
386 }
387}
388
390
412template <typename T>
414 B2MUMPS_STRUC_t<T>& mumps_struct, bool& autospc, bool& updated, size_t s, size_t nnz,
415 const size_t* const colind, const size_t* const rowind, const T* const value,
416 const Dictionary& dictionary) {
417 autospc = dictionary.get_bool("AUTOSPC", false);
418 mumps_struct.icntl[MUMPS_NullPivotRows] = 1;
419 mumps_struct.icntl[MUMPS_OOC] = dictionary.get_bool("MUMPS_OOC", 0);
420 mumps_struct.icntl[MUMPS_Scaling] = dictionary.get_int("MUMPS_SCALING", 77);
421 mumps_struct.icntl[MUMPS_MaxIterRefine] =
422 dictionary.get_int("MUMPS_MAX_ITERATIVE_REFINEMENT", 0);
423 mumps_struct.cntl[2] = dictionary.get_double("AUTOSPC_THRESHOLD", 0.0);
424 mumps_struct.cntl[4] = dictionary.get_double("AUTOSPC_VALUE", 0.0);
425 decode_mumps_cntl(dictionary, mumps_struct);
426
427 if (mumps_struct.icntl[MUMPS_OOC] != 0) {
428 std::string tmp = dictionary.get_string("MUMPS_OOC_TMPDIR", "");
429 if (!tmp.empty()) {
430 if (tmp.size() > 255) {
431 Exception() << "The MUMPS_OOC_TMPDIR string is limited to 255"
432 " characters."
433 << THROW;
434 }
435 strncpy(mumps_struct.ooc_tmpdir, tmp.c_str(), 256);
436 }
437 tmp = dictionary.get_string("MUMPS_OOC_PREFIX", "");
438 if (!tmp.empty()) {
439 if (tmp.size() > 63) {
440 Exception() << "The MUMPS_OOC_PREFIX string is limited to 63"
441 " characters."
442 << THROW;
443 }
444 strncpy(mumps_struct.ooc_prefix, tmp.c_str(), 64);
445 }
446 }
447
448 mumps_struct.job = 4;
449 mumps_struct.n = s;
450 mumps_struct.nz = nnz;
451 mumps_struct.irn = new int[nnz];
452 mumps_struct.jcn = new int[nnz];
453 if (s == 0) { return; }
454 size_t ptr = colind[0];
455 for (size_t j = 1; j <= s; ++j) {
456 const size_t ptr_end = colind[j];
457 for (; ptr != ptr_end; ++ptr) {
458 mumps_struct.irn[ptr] = rowind[ptr] + 1;
459 mumps_struct.jcn[ptr] = j;
460 }
461 }
462 mumps_struct.a =
463 const_cast<B2MUMPS_NUM_t<T>*>(reinterpret_cast<const B2MUMPS_NUM_t<T>*>(value));
464 b2_mumps_call_wsgrow(mumps_struct);
465 if ((mumps_struct.sym > 0) && (mumps_struct.infog[0] == -6)) {
466 std::vector<bool> dof_nn(s, false);
467 size_t r = colind[0];
468 for (size_t j = 0; j != s; ++j) {
469 for (size_t r_end = colind[j + 1]; r != r_end; ++r) {
470 dof_nn[j] = dof_nn[rowind[r]] = (value[r] != T{0.0});
471 }
472 }
473 SingularMatrixError e;
474 for (size_t j = 0; j != s; ++j) {
475 if (!dof_nn[j]) { e.singular_dofs.push_back(j); }
476 }
477 e << "Matrix is singular in structure. The involved " << e.singular_dofs.size()
478 << " dof's can be visualized by means of the DISP_NS dataset." << THROW;
479 }
480 mumps_error_handler(mumps_struct.infog, autospc);
481 updated = false;
482}
483
485
502template <typename T>
504 B2MUMPS_STRUC_t<T>& mumps_, bool& updated_value, bool autospc, size_t s, size_t nrhs,
505 const T* const b, size_t ldb, T* const x, size_t ldx) {
506 if (s == 0) { return; }
507 mumps_.job = updated_value ? 5 : 3;
508 updated_value = false;
509
510 if (nrhs == 1 || mumps_.icntl[MUMPS_ErrStats] == 0) {
511 mumps_.rhs = reinterpret_cast<B2MUMPS_NUM_t<T>*>(x);
512 mumps_.nrhs = nrhs;
513 mumps_.lrhs = ldx;
514 if (b != x) {
515 for (size_t i = 0; i != nrhs; ++i) {
516 std::copy(b + i * ldb, b + i * ldb + s, x + i * ldx);
517 }
518 }
519 b2_mumps_call_wsgrow(mumps_);
520 mumps_error_handler(mumps_.infog, autospc);
521 } else {
522 // solve the multiple rhs separately to get the error analyse on
523 // each system
524 mumps_.nrhs = 1;
525 mumps_.lrhs = s;
526 for (size_t i = 0; i != nrhs; ++i) {
527 mumps_.rhs = reinterpret_cast<B2MUMPS_NUM_t<T>*>(x + i * ldx);
528 if (b != x) { std::copy(b + i * ldb, b + i * ldb + s, x + i * ldx); }
529 b2_mumps_call_wsgrow(mumps_);
530 mumps_error_handler(mumps_.infog, autospc);
531 }
532 }
533}
534
535//
536// LDLt
537//
538
540template <typename T>
541class MUMPS_LDLt_seq_sparse_direct_solver : public LDLt_sparse_solver<T> {
542public:
544
550 explicit MUMPS_LDLt_seq_sparse_direct_solver(bool definit_positive = false) {
551 b2_mumps_new(mumps_, definit_positive ? 1 : 2);
552 }
553
556
557 void init(
558 size_t s, size_t nnz, const size_t* colind, const size_t* rowind, const T* value,
559 const int connectivity, const Dictionary& dictionary) override {
561 mumps_, autospc, updated_value, s, nnz, colind, rowind, value, dictionary);
562 }
563
564 void update_value() override { updated_value = true; }
565
566 void resolve(
567 size_t s, size_t nrhs, const T* b, size_t ldb, T* x, size_t ldx,
568 char left_or_right = ' ') override {
569 mumps_solve(mumps_, updated_value, autospc, s, nrhs, b, ldb, x, ldx);
570 }
571
572 size_t get_null_space_size() override { return mumps_.infog[27]; }
573
574 void get_null_space(size_t s, size_t nv, T* m, size_t lm) override {
575 if (s == 0) { return; }
576
577 mumps_.job = updated_value ? 5 : 3;
578 updated_value = false;
579 mumps_.icntl[MUMPS_NullPivotRows] = 1;
580 mumps_.icntl[MUMPS_Deficient] = nv == 1 ? 1 : -1;
581 mumps_.rhs = reinterpret_cast<B2MUMPS_NUM_t<T>*>(m);
582 mumps_.nrhs = nv;
583 mumps_.lrhs = lm;
584 b2_mumps_call_wsgrow(mumps_);
585 mumps_.icntl[MUMPS_Deficient] = 0;
586 mumps_error_handler(mumps_.infog, true);
587 }
588
589private:
590 bool updated_value = false;
591 bool autospc = false;
592 B2MUMPS_STRUC_t<T> mumps_;
593}; // class MUMPS_LDLt_seq_sparse_direct_solver
594
596template <typename T>
598 : public LDLt_extension_sparse_solver<T>,
600public:
602
608 explicit MUMPS_LDLt_seq_extension_sparse_direct_solver(bool definit_positive = false)
609 : MUMPS_LDLt_seq_sparse_direct_solver<T>(definit_positive) {}
610
611 void init(
612 size_t size_, size_t nnz_, const size_t* colind_, const size_t* rowind_, const T* value_,
613 size_t size_ext_, const int connectivity, const Dictionary& dictionary) override {
614 if (size_ext_ != 1) { UnimplementedError() << THROW; }
615
617 size_, nnz_, colind_, rowind_, value_, connectivity, dictionary);
618 m_ab.resize(size_ * 2);
619 }
620
621 void update_value() override { MUMPS_LDLt_seq_sparse_direct_solver<T>::update_value(); }
622
623 void resolve(
624 size_t s, size_t nrhs, const T* b, size_t ldb, T* x, size_t ldx, const T* ma_ = 0,
625 const T* mb_ = 0, const T* mc_ = 0, char left_or_right = ' ') override {
626 if (mc_ != 0) {
627 std::copy(ma_, ma_ + s - 1, &m_ab[0]);
628 std::copy(mb_, mb_ + s - 1, &m_ab[s - 1]);
629 MUMPS_LDLt_seq_sparse_direct_solver<T>::resolve(
630 s - 1, 2, &m_ab[0], s - 1, &m_ab[0], s - 1);
631 m_div = T{1.0} / (*mc_ - blas::dot(s - 1, ma_, 1, &m_ab[s - 1], 1));
632 }
633
634 for (size_t i = 0; i != nrhs; ++i) {
635 const T x2 = x[ldx * i + s - 1] =
636 m_div * (b[ldb * i + s - 1] - blas::dot(s - 1, b + ldb * i, 1, &m_ab[s - 1], 1));
637 MUMPS_LDLt_seq_sparse_direct_solver<T>::resolve(
638 s - 1, 1, b + ldb * i, ldb, x + ldx * i, ldx);
639 blas::axpy(s - 1, -x2, &m_ab[0], 1, x + ldx * i, 1);
640 }
641 }
642
643 size_t get_null_space_size() override {
644 return MUMPS_LDLt_seq_sparse_direct_solver<T>::get_null_space_size();
645 }
646
647 void get_null_space(size_t s, size_t nv, T* m, size_t lm) override {
648 MUMPS_LDLt_seq_sparse_direct_solver<T>::get_null_space(s, nv, m, lm);
649 }
650
651protected:
652 std::vector<T> m_ab;
653 T m_div{0.0};
654}; // class MUMPS_LDLt_seq_extension_sparse_direct_solver
655
656//
657// LU
658//
659
661template <typename T>
662class MUMPS_LU_seq_sparse_direct_solver : public LU_sparse_solver<T> {
663public:
667
670
671 void init(
672 size_t s, size_t nnz, const size_t* colind, const size_t* rowind, const T* value,
673 const int connectivity, const Dictionary& dictionary) override {
675 mumps_, autospc, updated_value, s, nnz, colind, rowind, value, dictionary);
676 }
677
678 void update_value() override { updated_value = true; }
679
680 void resolve(
681 size_t s, size_t nrhs, const T* b, size_t ldb, T* x, size_t ldx,
682 char left_or_right = ' ') override {
683 mumps_solve(mumps_, updated_value, autospc, s, nrhs, b, ldb, x, ldx);
684 }
685
686protected:
687 bool updated_value = false;
688 bool autospc = false;
689 B2MUMPS_STRUC_t<T> mumps_;
690}; // class MUMPS_LU_seq_sparse_direct_solver
691
693template <typename T>
694class MUMPS_LU_seq_extension_sparse_direct_solver : public LU_extension_sparse_solver<T>,
696public:
697 void init(
698 size_t size_, size_t nnz_, const size_t* colind_, const size_t* rowind_, const T* value_,
699 size_t size_ext_, const int connectivity, const Dictionary& dictionary) override {
700 if (size_ext_ != 1) { UnimplementedError() << THROW; }
701
703 size_, nnz_, colind_, rowind_, value_, connectivity, dictionary);
704 m_ab.resize(size_ * 2);
705 }
706
707 void update_value() override { MUMPS_LU_seq_sparse_direct_solver<T>::update_value(); }
708
709 void resolve(
710 size_t s, size_t nrhs, const T* b, size_t ldb, T* x, size_t ldx, const T* ma_ = 0,
711 const T* mb_ = 0, const T* mc_ = 0, char left_or_right = ' ') override {
712 if (mc_ != 0) {
713 std::copy(ma_, ma_ + s - 1, &m_ab[0]);
714 std::copy(mb_, mb_ + s - 1, &m_ab[s - 1]);
716 s - 1, 2, &m_ab[0], s - 1, &m_ab[0], s - 1);
717 m_div = T{1.0} / (*mc_ - blas::dot(s - 1, ma_, 1, &m_ab[s - 1], 1));
718 }
719
720 for (size_t i = 0; i != nrhs; ++i) {
721 const T x2 = x[ldx * i + s - 1] =
722 m_div * (b[ldb * i + s - 1] - blas::dot(s - 1, b + ldb * i, 1, &m_ab[s - 1], 1));
724 s - 1, 1, b + ldb * i, s - 1, x + ldx * i, s - 1);
725 blas::axpy(s - 1, -x2, &m_ab[0], 1, x + ldx * i, 1);
726 }
727 }
728
729protected:
730 std::vector<T> m_ab;
731 T m_div{};
732}; // class MUMPS_LU_seq_extension_sparse_direct_solver
733
734}} // namespace b2000::b2linalg
735
736#endif // B2MUMPS_SOLVER_H_
#define THROW
Definition b2exception.H:198
MUMPSICNTL
MUMPS control constants for icntl.
Definition b2mumps_solver.H:69
void b2_mumps_init_struct(B2MUMPS_STRUC_t< T > &mumps_struct, bool &autospc, bool &updated, size_t s, size_t nnz, const size_t *const colind, const size_t *const rowind, const T *const value, const Dictionary &dictionary)
Complete the MUMPS interface and define the matrix structure.
Definition b2mumps_solver.H:413
void mumps_solve(B2MUMPS_STRUC_t< T > &mumps_, bool &updated_value, bool autospc, size_t s, size_t nrhs, const T *const b, size_t ldb, T *const x, size_t ldx)
Solving the equation system with MUMPS.
Definition b2mumps_solver.H:503
void b2_mumps_delete(MUMPS_STRUC_C &mumps_struct)
Delete the MUMPS object.
Definition b2mumps_solver.H:358
void mumps_error_handler(const int *const info, bool autospc=false)
Handling errors that may occur during the execution of MUMPS.
Definition b2mumps_solver.H:165
typename B2MUMPS_STRUC< T >::type B2MUMPS_STRUC_t
Convenience alias to refer to the B2MUMPS_STRUC type trait.
Definition b2mumps_solver.H:143
typename B2MUMPS_STRUC< T >::numtype B2MUMPS_NUM_t
Convenience alias to refer to the B2MUMPS_STRUC numtype trait.
Definition b2mumps_solver.H:147
void b2_mumps_call(MUMPS_STRUC_C &mumps_struct, MUMPSACTION action=MUMPSACTION::Continued)
Encapsulate calls to MUMPS.
Definition b2mumps_solver.H:294
MUMPSACTION
Actions to take when running a MUMPS call.
Definition b2mumps_solver.H:111
void decode_mumps_cntl(const Dictionary &d, MUMPS_STRUC_C &mumps_struct)
Decode user configurations for cntl and icntl.
Definition b2mumps_solver.H:229
void b2_mumps_new(MUMPS_STRUC_C &mumps_struct, MUMPS_INT sym)
Initialize a new MUMPS interface structure.
Definition b2mumps_solver.H:326
void b2_mumps_call_wsgrow(MUMPS_STRUC_C &mumps_struct)
Calling MUMPS with MUMPSACTION::Continued and grow its workspace as needed.
Definition b2mumps_solver.H:373
Definition b2dictionary.H:48
virtual bool get_bool(const std::string &key) const =0
virtual std::string get_string(const std::string &key) const =0
virtual double get_double(const std::string &key) const =0
virtual int get_int(const std::string &key) const =0
Definition b2exception.H:131
Implementation of the LDLt extension sparse solver interface with MUMPS.
Definition b2mumps_solver.H:599
MUMPS_LDLt_seq_extension_sparse_direct_solver(bool definit_positive=false)
The constructor creates a new MUMPS interface datastructure.
Definition b2mumps_solver.H:608
Implementation of the LDLt sparse solver interface with MUMPS.
Definition b2mumps_solver.H:541
MUMPS_LDLt_seq_sparse_direct_solver(bool definit_positive=false)
The constructor creates a new MUMPS interface datastructure.
Definition b2mumps_solver.H:550
~MUMPS_LDLt_seq_sparse_direct_solver() override
The destructor instructs MUMPS to close down on all processes.
Definition b2mumps_solver.H:555
Implementation of the LU extension sparse solver interface with MUMPS.
Definition b2mumps_solver.H:695
Implementation of the LU sparse solver interface with MUMPS.
Definition b2mumps_solver.H:662
~MUMPS_LU_seq_sparse_direct_solver() override
The destructor instructs MUMPS to close down on all processes.
Definition b2mumps_solver.H:669
MUMPS_LU_seq_sparse_direct_solver()
Definition b2mumps_solver.H:666
Definition b2logging.H:495
Logger & get_logger(const std::string &logger_name="")
Definition b2logging.H:829
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
timer_map_t::iterator obtain_timer(std::string name)
Definition b2timing.H:139
GenericException< UnimplementedError_name > UnimplementedError
Definition b2exception.H:314
Definition b2mumps_solver.H:123