12 #include "../config/config.hpp"
14 #ifdef MFEM_USE_SUPERLU
20 #include "superlu_defs.h"
21 #include "superlu_ddefs.h"
31 unsigned int root = 0;
32 unsigned short len =
sizeof(int); len <<= 2;
33 unsigned short shift = (
unsigned short)((len<<1) - 2);
35 for (
int i=0; i<len; i++)
38 rem = ((rem << 2) + (a_ >> shift));
54 SuperLURowLocMatrix::SuperLURowLocMatrix(MPI_Comm comm,
55 int num_loc_rows,
int first_loc_row,
56 int glob_nrows,
int glob_ncols,
57 int *I,
int *J,
double *data)
66 rowLocPtr_ =
new SuperMatrix;
67 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
73 int nnz_loc = I[num_loc_rows];
74 int m_loc = num_loc_rows;
75 int fst_row = first_loc_row;
77 double * nzval = NULL;
81 if ( !(nzval = doubleMalloc_dist(nnz_loc)) )
83 ABORT(
"Malloc fails for nzval[].");
85 for (
int i=0; i<nnz_loc; i++)
90 if ( !(colind = intMalloc_dist(nnz_loc)) )
92 ABORT(
"Malloc fails for colind[].");
94 for (
int i=0; i<nnz_loc; i++)
99 if ( !(rowptr = intMalloc_dist(m_loc+1)) )
101 ABORT(
"Malloc fails for rowptr[].");
103 for (
int i=0; i<=m_loc; i++)
109 dCreate_CompRowLoc_Matrix_dist(A, m, n, nnz_loc, m_loc, fst_row,
110 nzval, colind, rowptr,
111 SLU_NR_loc, SLU_D, SLU_GE);
115 : comm_(hypParMat.GetComm()),
118 rowLocPtr_ =
new SuperMatrix;
119 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
124 hypre_ParCSRMatrix * parcsr_op =
125 (hypre_ParCSRMatrix *)const_cast<HypreParMatrix&>(hypParMat);
127 MFEM_ASSERT(parcsr_op != NULL,
"SuperLU: const_cast failed in SetOperator");
131 hypre_CSRMatrix * csr_op = hypre_MergeDiagAndOffd(parcsr_op);
132 hypre_CSRMatrixSetDataOwner(csr_op,0);
134 int m = parcsr_op->global_num_rows;
135 int n = parcsr_op->global_num_cols;
136 int fst_row = parcsr_op->first_row_index;
137 int nnz_loc = csr_op->num_nonzeros;
138 int m_loc = csr_op->num_rows;
143 double * nzval = csr_op->data;
144 int * colind = csr_op->j;
148 if ( !(rowptr = intMalloc_dist(m_loc+1)) )
150 ABORT(
"Malloc fails for rowptr[].");
152 for (
int i=0; i<=m_loc; i++)
154 rowptr[i] = (csr_op->i)[i];
158 hypre_CSRMatrixDestroy(csr_op);
161 dCreate_CompRowLoc_Matrix_dist(A, m, n, nnz_loc, m_loc, fst_row,
162 nzval, colind, rowptr,
163 SLU_NR_loc, SLU_D, SLU_GE);
168 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
171 Destroy_CompRowLoc_Matrix_dist(A);
174 if ( A != NULL ) {
delete A; }
182 ScalePermstructPtr_(NULL),
184 SOLVEstructPtr_(NULL),
191 firstSolveWithThisA_(false),
192 gridInitialized_(false),
193 LUStructInitialized_(false)
199 : comm_(A.GetComm()),
203 ScalePermstructPtr_(NULL),
205 SOLVEstructPtr_(NULL),
212 firstSolveWithThisA_(true),
213 gridInitialized_(false),
214 LUStructInitialized_(false)
224 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
225 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
229 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
236 ScalePermstructFree(SPstruct);
237 Destroy_LU(
width, grid, LUstruct);
238 LUstructFree(LUstruct);
241 if ( options->SolveInitialized )
243 dSolveFinalize(options, SOLVEstruct);
246 if ( options != NULL ) {
delete options; }
247 if ( stat != NULL ) {
delete stat; }
248 if ( SPstruct != NULL ) {
delete SPstruct; }
249 if ( LUstruct != NULL ) {
delete LUstruct; }
250 if ( SOLVEstruct != NULL ) {
delete SOLVEstruct; }
251 if ( grid != NULL ) {
delete grid; }
255 void SuperLUSolver::Init()
267 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
268 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
272 ABORT(
"Malloc fails for berr[].");
276 set_default_options_dist(options);
278 options->ParSymbFact = YES;
299 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
301 yes_no_t opt = print_stat?YES:NO;
303 options->PrintStat = opt;
308 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
310 yes_no_t opt = equil?YES:NO;
312 options->Equil = opt;
317 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
319 colperm_t opt = (colperm_t)col_perm;
321 options->ColPerm = opt;
327 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
329 rowperm_t opt = (rowperm_t)row_perm;
331 options->RowPerm = opt;
337 mfem_error(
"SuperLUSolver::SetRowPermutation :"
338 " permutation vector not set!");
343 ABORT(
"Malloc fails for perm_r[].");
345 for (
int i=0; i<perm->
Size(); i++)
354 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
356 trans_t opt = (trans_t)trans;
358 options->Trans = opt;
363 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
365 IterRefine_t opt = (IterRefine_t)iter_ref;
367 options->IterRefine = opt;
372 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
374 yes_no_t opt = rtp?YES:NO;
376 options->ReplaceTinyPivot = opt;
381 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
383 options->num_lookaheads = num_lookaheads;
388 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
390 yes_no_t opt = etree?YES:NO;
392 options->lookahead_etree = opt;
397 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
399 yes_no_t opt = sym?YES:NO;
401 options->SymPattern = opt;
406 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
413 mfem:
err <<
"Warning: User specified nprow and npcol are such that "
414 <<
"(nprow * npcol) > numProcs or (nprow * npcol) < 1. "
415 <<
"Using default values for nprow and npcol instead." << endl;
437 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
439 superlu_gridexit(grid);
447 MFEM_ASSERT(
APtr_ != NULL,
448 "SuperLU Error: The operator must be set before"
449 " the system can be solved.");
451 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
452 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
458 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
462 options->Fact = FACTORED;
473 SPstruct->DiagScale = NOEQUIL;
483 if ( !(SPstruct->perm_r = intMalloc_dist(A->nrow)) )
485 ABORT(
"Malloc fails for perm_r[].");
488 if ( !(SPstruct->perm_c = intMalloc_dist(A->ncol)) )
490 ABORT(
"Malloc fails for perm_c[].");
493 LUstructInit(A->ncol, LUstruct);
502 double* yPtr = (
double*)y;
503 int info = -1, locSize = y.
Size();
506 pdgssvx(options, A, SPstruct, yPtr, locSize,
nrhs_, grid,
507 LUstruct, SOLVEstruct,
berr_, stat, &info);
511 if ( info <= A->ncol )
513 MFEM_ABORT(
"SuperLU: Found a singular matrix, U("
514 << info <<
"," << info <<
") is exactly zero.");
516 else if ( info > A->ncol )
518 MFEM_ABORT(
"SuperLU: Memory allocation error with "
519 << info - A->ncol <<
" bytes already allocated,");
523 MFEM_ABORT(
"Unknown SuperLU Error");
534 mfem_error(
"SuperLUSolver::SetOperator : not SuperLURowLocMatrix!");
553 #endif // MFEM_USE_MPI
554 #endif // MFEM_USE_SUPERLU
int Size() const
Logical size of the array.
void * InternalData() const
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
bool LUStructInitialized_
void * ScalePermstructPtr_
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void SetRowPermutation(superlu::RowPerm row_perm, Array< int > *perm=NULL)
int Size() const
Returns the size of the vector.
void SetSymmetricPattern(bool sym)
void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetIterativeRefine(superlu::IterRefine iter_ref)
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void SetColumnPermutation(superlu::ColPerm col_perm)
void SetNumLookAheads(int num_lookaheads)
void SetPrintStatistics(bool print_stat)
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
void mfem_error(const char *msg)
int height
Dimension of the output / number of rows in the matrix.
void SetLookAheadElimTree(bool etree)
unsigned int sqrti(const unsigned int &a)
void SetReplaceTinyPivot(bool rtp)
void SetTranspose(superlu::Trans trans)
const SuperLURowLocMatrix * APtr_
bool firstSolveWithThisA_
SuperLURowLocMatrix(MPI_Comm comm, int num_loc_rows, int first_loc_row, int glob_nrows, int glob_ncols, int *I, int *J, double *data)
Wrapper for hypre's ParCSR matrix class.
SuperLUSolver(MPI_Comm comm)
int width
Dimension of the input / number of columns in the matrix.
void SetEquilibriate(bool equil)