MFEM  v4.6.0
Finite element discretization library
pardiso.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include "pardiso.hpp"
13 
14 #ifdef MFEM_USE_MKL_PARDISO
15 
16 #include "sparsemat.hpp"
17 
18 namespace mfem
19 {
20 
22 {
23  // Indicate that default parameters are changed
24  iparm[0] = 1;
25  // Use METIS for fill-in reordering
26  iparm[1] = 2;
27  // Write the solution into the x vector data
28  iparm[5] = 0;
29  // Maximum number of iterative refinement steps
30  iparm[7] = 2;
31  // Perturb the pivot elements with 1E-13
32  iparm[9] = 13;
33  // Use nonsymmetric permutation
34  iparm[10] = 1;
35  // Perform a check on the input data
36  iparm[26] = 1;
37  // 0-based indexing in CSR data structure
38  iparm[34] = 1;
39  // Maximum number of numerical factorizations
40  maxfct = 1;
41  // Which factorization to use. This parameter is ignored and always assumed
42  // to be equal to 1. See MKL documentation.
43  mnum = 1;
44  // Print statistical information in file
45  msglvl = 0;
46  // Initialize error flag
47  error = 0;
48  // Real nonsymmetric matrix
49  mtype = MatType::REAL_NONSYMMETRIC;
50  // Number of right hand sides
51  nrhs = 1;
52 }
53 
55 {
56  auto mat = const_cast<SparseMatrix *>(dynamic_cast<const SparseMatrix *>(&op));
57 
58  MFEM_ASSERT(mat, "Must pass SparseMatrix as Operator");
59 
60  height = op.Height();
61 
62  width = op.Width();
63 
64  m = mat->Size();
65 
66  nnz = mat->NumNonZeroElems();
67 
68  const int *Ap = mat->HostReadI();
69  const int *Ai = mat->HostReadJ();
70  const double *Ax = mat->HostReadData();
71 
72  csr_rowptr = new int[m + 1];
73  reordered_csr_colind = new int[nnz];
74  reordered_csr_nzval = new double[nnz];
75 
76  for (int i = 0; i <= m; i++)
77  {
78  csr_rowptr[i] = Ap[i];
79  }
80 
81  // Pardiso expects the column indices to be sorted for each row
82  mat->SortColumnIndices();
83 
84  for (int i = 0; i < nnz; i++)
85  {
86  reordered_csr_colind[i] = Ai[i];
87  reordered_csr_nzval[i] = Ax[i];
88  }
89 
90  // Analyze inputs
91  phase = 11;
92  PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &m, reordered_csr_nzval, csr_rowptr,
93  reordered_csr_colind, &idum, &nrhs,
94  iparm, &msglvl, &ddum, &ddum, &error);
95 
96  MFEM_ASSERT(error == 0, "Pardiso symbolic factorization error");
97 
98  // Numerical factorization
99  phase = 22;
100  PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &m, reordered_csr_nzval, csr_rowptr,
101  reordered_csr_colind, &idum, &nrhs,
102  iparm, &msglvl, &ddum, &ddum, &error);
103 
104  MFEM_ASSERT(error == 0, "Pardiso numerical factorization error");
105 }
106 
107 void PardisoSolver::Mult(const Vector &b, Vector &x) const
108 {
109  // Solve
110  phase = 33;
111  PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &m, reordered_csr_nzval, csr_rowptr,
112  reordered_csr_colind, &idum, &nrhs,
113  iparm, &msglvl, b.GetData(), x.GetData(), &error);
114 
115  MFEM_ASSERT(error == 0, "Pardiso solve error");
116 }
117 
118 void PardisoSolver::SetPrintLevel(int print_level)
119 {
120  msglvl = print_level;
121 }
122 
124 {
125  mtype = mat_type;
126 }
127 
129 {
130  // Release all internal memory
131  phase = -1;
132  PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &m, reordered_csr_nzval, csr_rowptr,
133  reordered_csr_colind, &idum, &nrhs,
134  iparm, &msglvl, &ddum, &ddum, &error);
135 
136  MFEM_ASSERT(error == 0, "Pardiso free error");
137 
138  delete[] csr_rowptr;
139  delete[] reordered_csr_colind;
140  delete[] reordered_csr_nzval;
141 }
142 
143 } // namespace mfem
144 
145 #endif // MFEM_USE_MKL_PARDISO
void Mult(const Vector &b, Vector &x) const override
Solve.
Definition: pardiso.cpp:107
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:72
void SetMatrixType(MatType mat_type)
Set the matrix type.
Definition: pardiso.cpp:123
PardisoSolver()
Construct a new PardisoSolver object.
Definition: pardiso.cpp:21
void SetPrintLevel(int print_lvl)
Set the print level for MKL Pardiso.
Definition: pardiso.cpp:118
Data type sparse matrix.
Definition: sparsemat.hpp:50
double b
Definition: lissajous.cpp:42
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:206
void SetOperator(const Operator &op) override
Set the Operator object and perform factorization.
Definition: pardiso.cpp:54
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:66
int height
Dimension of the output / number of rows in the matrix.
Definition: operator.hpp:27
Vector data type.
Definition: vector.hpp:58
Abstract operator.
Definition: operator.hpp:24
int width
Dimension of the input / number of columns in the matrix.
Definition: operator.hpp:28