16#ifndef __B2SUPERLU_SOLVER_H__
17#define __B2SUPERLU_SOLVER_H__
20#include <SuperLU/dsp_defs.h>
23#include "b2sparse_solver.H"
25namespace b2000 {
namespace b2linalg {
26class Generic_SuperLU {
28 void Init_SuperMatrix_Store(SuperMatrix* A) { A->Store = 0; }
30 void Create_CompCol_Matrix(
31 SuperMatrix* A,
int m,
int n,
int nnz,
double* nzval,
int* rowind,
int* colptr,
32 Stype_t stype, Mtype_t mtype) {
33 dCreate_CompCol_Matrix(A, m, n, nnz, nzval, rowind, colptr, stype, SLU_D, mtype);
36 void Destroy_CompCol_Matrix(SuperMatrix* A) {
38 SUPERLU_FREE(((NCformat*)A->Store)->rowind);
39 SUPERLU_FREE(((NCformat*)A->Store)->colptr);
40 SUPERLU_FREE(((NCformat*)A->Store)->nzval);
42 SUPERLU_FREE(A->Store);
45 void Create_Dense_Matrix(
46 SuperMatrix* X,
int m,
int n,
double* x,
int ldx, Stype_t stype, Mtype_t mtype) {
47 dCreate_Dense_Matrix(X, m, n, x, ldx, stype, SLU_D, mtype);
50 void Destroy_Dense_Matrix(SuperMatrix* A) {
51 if (A->Store) { SUPERLU_FREE(((DNformat*)A->Store)->nzval); }
52 SUPERLU_FREE(A->Store);
55 void Destroy_SuperNode_Matrix(SuperMatrix* A) {
57 SUPERLU_FREE(((SCformat*)A->Store)->rowind);
58 SUPERLU_FREE(((SCformat*)A->Store)->rowind_colptr);
59 SUPERLU_FREE(((SCformat*)A->Store)->nzval);
60 SUPERLU_FREE(((SCformat*)A->Store)->nzval_colptr);
61 SUPERLU_FREE(((SCformat*)A->Store)->col_to_sup);
62 SUPERLU_FREE(((SCformat*)A->Store)->sup_to_col);
64 SUPERLU_FREE(A->Store);
68 superlu_options_t* options, SuperMatrix* A,
int* perm_c,
int* perm_r,
int* etree,
69 char* equed,
double* R,
double* C, SuperMatrix* L, SuperMatrix* U,
void* work,
int lwork,
70 SuperMatrix* B, SuperMatrix* X,
double* recip_pivot_growth,
double* rcond,
double* ferr,
71 double* berr, mem_usage_t* mem_usage, SuperLUStat_t* stat,
int* info) {
73 options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X,
74 recip_pivot_growth, rcond, ferr, berr, mem_usage, stat, info);
79class SuperLU_LDLt_sparse_direct_solver :
public LDLt_sparse_solver<T>,
public Generic_SuperLU {
81 SuperLU_LDLt_sparse_direct_solver()
96 Init_SuperMatrix_Store(&L);
97 Init_SuperMatrix_Store(&U);
98 Init_SuperMatrix_Store(&A);
101 ~SuperLU_LDLt_sparse_direct_solver() {
107 Destroy_SuperNode_Matrix(&L);
108 Destroy_CompCol_Matrix(&U);
109 Destroy_CompCol_Matrix(&A);
113 size_t size_,
size_t nnz_,
const size_t* colind_,
const size_t* rowind_,
const T* value_,
114 int connectivity,
const Dictionary& dictionary) {
122 perm_c =
new int[size];
124 perm_r =
new int[size];
126 etree =
new int[size];
133 set_default_options(&options);
134 options.SymmetricMode = YES;
138 options.ConditionNumber = YES;
141 void update_value() { options.Fact = SamePattern; }
144 size_t s,
size_t nrhs,
const T* b,
size_t ldb, T* x,
size_t ldx,
145 char left_or_right =
' ') {
150 mem_usage_t mem_usage;
153 std::vector<T> ferr(s);
154 std::vector<T> berr(s);
157 Create_Dense_Matrix(&B, s, nrhs,
const_cast<double*
>(b), ldb, SLU_DN, SLU_GE);
158 Create_Dense_Matrix(&X, s, nrhs, x, ldx, SLU_DN, SLU_GE);
160 if (options.Fact != FACTORED) {
161 Destroy_SuperNode_Matrix(&L);
162 Destroy_CompCol_Matrix(&U);
163 Destroy_CompCol_Matrix(&A);
164 colptr1 = (
int*)SUPERLU_MALLOC((size + 2) *
sizeof(int));
165 colptr1[0] = colptr1[1] = 0;
167 for (
size_t j = 0; j != size; ++j) { colptr1[j] = colind[j + 1] - colind[j]; }
168 for (
size_t j = 0; j != size; ++j) {
169 const size_t i_end = colind[j + 1];
170 for (
size_t i = colind[j] + 1; i < i_end; ++i) { ++colptr1[rowind[i]]; }
173 for (
size_t j = 0; j != size; ++j) { colptr1[j + 1] += colptr1[j]; }
174 int nnz1 = colptr1[size];
175 int* rowind1 = (
int*)SUPERLU_MALLOC(nnz1 *
sizeof(
int));
176 T* nzval1 = (T*)SUPERLU_MALLOC(nnz1 *
sizeof(T));
177 for (
size_t j = 0; j != size; ++j) {
178 size_t i = colind[j];
179 const size_t i_end = colind[j + 1];
181 colptr1[j] += i_end - i;
182 std::copy(rowind + i, rowind + i_end, rowind1 + ii);
183 std::copy(value + i, value + i_end, nzval1 + ii);
184 for (++i; i < i_end; ++i) {
185 int ii = colptr1[rowind[i]]++;
187 nzval1[ii] = value[i];
201 Create_CompCol_Matrix(&A, size, size, nnz1, nzval1, rowind1, colptr1, SLU_NC, SLU_GE);
204 gssvx(&options, &A, perm_c, perm_r, etree, &equed, R, C, &L, &U, 0, 0, &B, &X, &rpg, &rcond,
205 &ferr[0], &berr[0], &mem_usage, &stat, &info);
207 std::cout <<
"factorisation, rcond = " << rcond << std::endl;
209 Destroy_SuperMatrix_Store(&B);
210 Destroy_SuperMatrix_Store(&X);
213 if (info > 0 && info <=
int(s)) {
214 Exception() <<
"The matrix entrie L(" <<
info <<
"," <<
info
215 <<
") of the factorised matrix is exactly zero. The factorization has been "
216 "completed, but the factor U is exactly singular, so the solution and "
217 "error bounds could not be computed."
220 if (info ==
int(s) + 1) {
221 Exception() <<
"The factorised matrix L is nonsingular, but this condition number is "
222 "less than machine precision, meaning that the matrix is singular to "
226 if (info) { Exception() <<
THROW; }
228 options.Fact = FACTORED;
231 void resolve(
size_t s,
size_t nrhs, T* bx,
size_t ldbx,
char left_or_right =
' ') {
232 size_t ss = s * nrhs;
234 resolve(s, nrhs, bx, ldbx, x, s, left_or_right);
236 std::copy(x, x + ss, bx);
240 while (xx < xx_end) {
241 std::copy(xx, xx + s, bx);
252 const size_t* colind;
253 const size_t* rowind;
267 superlu_options_t options;
271class SuperLU_LDLt_extension_sparse_direct_solver :
public LDLt_extension_sparse_solver<T>,
272 public Generic_SuperLU {
274 SuperLU_LDLt_extension_sparse_direct_solver()
290 Init_SuperMatrix_Store(&L);
291 Init_SuperMatrix_Store(&U);
292 Init_SuperMatrix_Store(&A);
295 ~SuperLU_LDLt_extension_sparse_direct_solver() {
301 Destroy_SuperNode_Matrix(&L);
302 Destroy_CompCol_Matrix(&U);
303 Destroy_CompCol_Matrix(&A);
307 size_t size_,
size_t nnz_,
const size_t* colind_,
const size_t* rowind_,
const T* value_,
308 size_t size_ext_,
int connectivity,
const Dictionary& dictionary) {
314 size_ext = size_ext_;
317 perm_c =
new int[size + size_ext];
319 perm_r =
new int[size + size_ext];
321 etree =
new int[size + size_ext];
324 R =
new T[size + size_ext];
326 C =
new T[size + size_ext];
328 set_default_options(&options);
329 options.SymmetricMode = YES;
331 options.IterRefine = EXTRA;
333 options.ConditionNumber = YES;
336 void update_value() { options.Fact = SamePattern; }
339 size_t s,
size_t nrhs,
const T* b,
size_t ldb, T* x,
size_t ldx,
const T* ma = 0,
340 const T* mb = 0,
const T* mc = 0,
char left_or_right =
' ') {
345 mem_usage_t mem_usage;
348 std::vector<T> ferr(s);
349 std::vector<T> berr(s);
352 Create_Dense_Matrix(&B, s, nrhs,
const_cast<double*
>(b), ldb, SLU_DN, SLU_GE);
353 Create_Dense_Matrix(&X, s, nrhs, x, ldx, SLU_DN, SLU_GE);
355 if (ma != 0 && mb != 0 && mc != 0 && options.Fact == FACTORED) {
356 options.Fact = SamePattern;
359 if (options.Fact != FACTORED) {
360 Destroy_SuperNode_Matrix(&L);
361 Destroy_CompCol_Matrix(&U);
362 Destroy_CompCol_Matrix(&A);
363 colptr1 = (
int*)SUPERLU_MALLOC((size + size_ext + 1) *
sizeof(int));
364 colptr1[0] = colptr1[1] = 0;
366 for (
size_t j = 0; j != size; ++j) {
367 colptr1[j] = colind[j + 1] - colind[j] + size_ext;
369 for (
size_t j = 0; j != size; ++j) {
370 const size_t i_end = colind[j + 1];
371 for (
size_t i = colind[j] + 1; i < i_end; ++i) { ++colptr1[rowind[i]]; }
374 for (
size_t j = 0; j != size; ++j) { colptr1[j + 1] += colptr1[j]; }
375 int nnz1 = colptr1[size] + size + 1;
376 int* rowind1 = (
int*)SUPERLU_MALLOC(nnz1 *
sizeof(
int));
377 T* nzval1 = (T*)SUPERLU_MALLOC(nnz1 *
sizeof(T));
378 for (
size_t j = 0; j != size; ++j) {
379 size_t i = colind[j];
380 const size_t i_end = colind[j + 1];
382 colptr1[j] += i_end - i;
383 std::copy(rowind + i, rowind + i_end, rowind1 + ii);
384 std::copy(value + i, value + i_end, nzval1 + ii);
385 for (++i; i < i_end; ++i) {
386 int ii = colptr1[rowind[i]]++;
388 nzval1[ii] = value[i];
393 if (ma == 0 || mb == 0 || mc == 0) { Exception() <<
THROW; }
394 for (
size_t j = 0; j != size; ++j) {
395 int& ii = colptr1[j];
396 for (
size_t i = 0; i != size_ext; ++i, ++ii) {
397 rowind1[ii] = size + i;
398 nzval1[ii] = mb[j + i * size];
405 for (
size_t i = 0; i != size_ext; ++i) {
406 size_t ii = colptr1[size + i];
407 colptr1[size + i + 1] = ii + size + size_ext;
408 for (
size_t j = 0; j != size; ++j, ++ii) {
410 nzval1[ii] = ma[j + i * size];
412 for (
size_t j = 0; j != size_ext; ++j, ++ii) {
413 rowind1[ii] = j + size;
414 nzval1[ii] = mc[j + i * size_ext];
419 for (
size_t j = 0; j != size + size_ext; ++j) {
420 for (
int i = colptr1[j]; i != colptr1[j + 1]; ++i) {
421 std::cout <<
"(" << rowind1[i] <<
"," << nzval1[i] <<
") ";
423 std::cout << std::endl;
425 std::cout << std::endl;
427 Create_CompCol_Matrix(
428 &A, size + size_ext, size + size_ext, nnz1, nzval1, rowind1, colptr1, SLU_NC,
432 gssvx(&options, &A, perm_c, perm_r, etree, &equed, R, C, &L, &U, 0, 0, &B, &X, &rpg, &rcond,
433 &ferr[0], &berr[0], &mem_usage, &stat, &info);
435 std::cout <<
"factorisation, rcond = " << rcond << std::endl;
437 Destroy_SuperMatrix_Store(&B);
438 Destroy_SuperMatrix_Store(&X);
441 if (info > 0 && info <=
int(s)) {
442 Exception() <<
"The matrix entrie L(" <<
info <<
"," <<
info
443 <<
") of the factorised matrix is exactly zero. The factorization has been "
444 "completed, but the factor U is exactly singular, so the solution and "
445 "error bounds could not be computed."
448 if (info ==
int(s) + 1) {
449 Exception() <<
"The factorised matrix L is nonsingular, but this condition number is "
450 "less than machine precision, meaning that the matrix is singular to "
454 if (info) { Exception() <<
THROW; }
456 options.Fact = FACTORED;
460 size_t s,
size_t nrhs, T* bx,
size_t ldbx,
const T* ma = 0,
const T* mb = 0,
461 const T* mc = 0,
char left_or_right =
' ') {
462 size_t ss = s * nrhs;
464 resolve(s, nrhs, bx, ldbx, x, s, ma, mb, mc, left_or_right);
466 std::copy(x, x + ss, bx);
470 while (xx < xx_end) {
471 std::copy(xx, xx + s, bx);
482 const size_t* colind;
483 const size_t* rowind;
499 superlu_options_t options;
#define THROW
Definition b2exception.H:198
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
GenericException< UnimplementedError_name > UnimplementedError
Definition b2exception.H:314