Documentation 6b54b78464
Loading...
Searching...
No Matches
CPastixWrapper.hpp
Go to the documentation of this file.
1/*!
2 * \file CPastixWrapper.hpp
3 * \brief An interface to the INRIA solver PaStiX
4 * (http://pastix.gforge.inria.fr/files/README-txt.html)
5 * \author P. Gomes
6 * \version 8.5.0 "Harrier"
7 *
8 * SU2 Project Website: https://su2code.github.io
9 *
10 * The SU2 Project is maintained by the SU2 Foundation
11 * (http://su2foundation.org)
12 *
13 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
14 *
15 * SU2 is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * SU2 is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
27 */
28
29#pragma once
30
31#include "../code_config.hpp"
32
33#ifdef HAVE_PASTIX
34
35#ifdef CODI_FORWARD_TYPE
36#error Cannot use PaStiX with forward mode AD
37#endif
38
39#include <pastix.h>
40#include <spm.h>
41#include <vector>
42
43using namespace std;
44
45class CConfig;
46class CGeometry;
47
48/*!
49 * \class CPastixWrapper
50 * \ingroup SpLinSys
51 * \brief Wrapper class that converts between SU2 sparse format and PaStiX
52 * format and simplifies calls to the external solver.
53 */
54template <class ScalarType>
56 private:
57 pastix_data_t* state{}; /*!< \brief Internal state of the solver. */
58 spmatrix_t spm; /*!< \brief Matrix format used by the solver. */
59 pastix_int_t nCols; /*!< \brief Local number of columns. */
60 vector<pastix_int_t> colptr; /*!< \brief Equiv. to our "row_ptr". */
61 vector<pastix_int_t> rowidx; /*!< \brief Equiv. to our "col_ind". */
62 vector<su2mixedfloat> values; /*!< \brief Equiv. to our "matrix". */
63 vector<pastix_int_t> loc2glb; /*!< \brief Global index of the columns held by this rank. */
64 vector<pastix_int_t> perm; /*!< \brief Ordering computed by PaStiX. */
65 vector<su2mixedfloat> workvec; /*!< \brief RHS vector which then becomes the solution. */
66
67 vector<unsigned long> csr_row_ptr; /*!< \brief Owned CSR row pointers (built from LDU). */
68 vector<unsigned long> csr_col_ind; /*!< \brief Owned CSR column indices (built from LDU). */
69
70 pastix_int_t iparm[IPARM_SIZE]; /*!< \brief Integer parameters for PaStiX. */
71 double dparm[DPARM_SIZE]; /*!< \brief Floating point parameters for PaStiX. */
72
73 struct {
74 unsigned long nVar = 0;
75 unsigned long nPoint = 0;
76 unsigned long nPointDomain = 0;
77 unsigned long blkSz = 0; /*!< \brief Block size (nVar * nVar) for value assembly. */
78
79 const su2uint* row_ptr_l = nullptr; /*!< \brief LDU lower row pointers (geometry-owned). */
80 const su2uint* row_ptr_u = nullptr; /*!< \brief LDU upper row pointers (geometry-owned). */
81 const ScalarType* d = nullptr; /*!< \brief Diagonal blocks (matrix-owned). */
82 const ScalarType* l = nullptr; /*!< \brief Lower blocks (matrix-owned). */
83 const ScalarType* u = nullptr; /*!< \brief Upper blocks (matrix-owned). */
84
85 unsigned long size_rhs() const { return nPointDomain * nVar; }
86 } matrix; /*!< \brief Dimensions and LDU pointers captured from the owning CSysMatrix. */
87
88 bool issetup{}; /*!< \brief Signals that the structure has been provided. */
89 bool isinitialized{}; /*!< \brief Signals that the sparsity pattern has been set. */
90 bool isfactorized{}; /*!< \brief Signals that a factorization has been computed. */
91 bool transpose{}; /*!< \brief Solve A^T x = b instead of A x = b. */
92 unsigned long iter{}; /*!< \brief Number of times a factorization has been requested. */
93 unsigned short verb{}; /*!< \brief Verbosity level. */
94 const int mpi_size = SU2_MPI::GetSize();
95 const int mpi_rank = SU2_MPI::GetRank();
96
97 vector<unsigned long> sort_rows; /*!< \brief List of rows with halo points. */
98 vector<vector<unsigned long>> sort_order; /*!< \brief How each of those rows needs to be sorted. */
99
100 /*!
101 * \brief Run the "clean" task, releases all memory, leaves object in unusable state.
102 */
103 void Clean() {
104 if (isinitialized) {
105 iparm[IPARM_VERBOSE] = (verb > 0) ? PastixVerboseNo : PastixVerboseNot;
106 pastixFinalize(&state);
107 spm.colptr = nullptr;
108 spm.rowptr = nullptr;
109 spm.values = nullptr;
110 if (mpi_size > 1) spm.loc2glob = nullptr;
111 spmExit(&spm);
112 isfactorized = false;
113 isinitialized = false;
114 }
115 }
116
117 /*!
118 * \brief Initialize the matrix format that PaStiX requires.
119 */
120 void Initialize(CGeometry* geometry, const CConfig* config);
121
122 /*!
123 * \brief Assemble CSR values from the stored LDU pointers directly into the values buffer.
124 */
125 void AssembleValues();
126
127 public:
128 CPastixWrapper() = default;
129
130 /*--- Move or copy is not allowed. ---*/
135
136 /*!
137 * \brief Class destructor.
138 */
139 ~CPastixWrapper() { Clean(); }
140
141 /*!
142 * \brief Returns true once SetLDU has been called.
143 */
144 bool IsSetup() const { return issetup; }
145
146 /*!
147 * \brief Set LDU structure and value pointers; builds and owns assembled CSR (called once).
148 * \param[in] nVar - DOF per point (square blocks: nVar x nVar).
149 * \param[in] nPoint - Total number of points including halos.
150 * \param[in] nPointDomain - Number of internal points (domain rows).
151 * \param[in] row_ptr_l/u - LDU lower/upper row pointers (geometry-owned, must outlive wrapper).
152 * \param[in] col_ind_l/u - LDU lower/upper column indices (geometry-owned).
153 * \param[in] d/l/u - LDU value blocks (matrix-owned, must outlive wrapper).
154 */
155 void SetLDU(unsigned long nVar, unsigned long nPoint, unsigned long nPointDomain, const su2uint* row_ptr_l,
156 const su2uint* col_ind_l, const su2uint* row_ptr_u, const su2uint* col_ind_u, const ScalarType* d,
157 const ScalarType* l, const ScalarType* u) {
158 if (issetup) return;
159 matrix.nVar = nVar;
160 matrix.nPoint = nPoint;
161 matrix.nPointDomain = nPointDomain;
162 matrix.row_ptr_l = row_ptr_l;
163 matrix.row_ptr_u = row_ptr_u;
164 matrix.d = d;
165 matrix.l = l;
166 matrix.u = u;
167 matrix.blkSz = nVar * nVar;
168
169 const unsigned long nnz_domain = row_ptr_l[nPointDomain] + nPointDomain + row_ptr_u[nPointDomain];
170 csr_row_ptr.resize(nPointDomain + 1);
171 csr_col_ind.reserve(nnz_domain);
172 for (auto i = 0ul; i < nPointDomain; ++i) {
173 csr_row_ptr[i] = static_cast<unsigned long>(csr_col_ind.size());
174 for (auto k = row_ptr_l[i]; k < row_ptr_l[i + 1]; ++k) csr_col_ind.push_back(col_ind_l[k]);
175 csr_col_ind.push_back(i);
176 for (auto k = row_ptr_u[i]; k < row_ptr_u[i + 1]; ++k) csr_col_ind.push_back(col_ind_u[k]);
177 }
178 csr_row_ptr[nPointDomain] = static_cast<unsigned long>(csr_col_ind.size());
179 issetup = true;
180 }
181
182 /*!
183 * \brief Factorize matrix.
184 * \param[in] geometry - Geometrical definition of the problem.
185 * \param[in] config - Definition of the particular problem.
186 * \param[in] kind_fact - Type of factorization.
187 */
188 void Factorize(CGeometry* geometry, const CConfig* config, unsigned short kind_fact);
189
190 /*!
191 * \brief Request solves with the transposed matrix.
192 * \param[in] transposed - Yes or no.
193 */
194 void SetTransposedSolve(bool transposed = true) { transpose = transposed; }
195
196 /*!
197 * \brief Runs the "solve" task for any rhs/sol with operator []
198 * \param[in] rhs - Right hand side of the linear system.
199 * \param[out] sol - Solution of the system.
200 */
201 template <class T>
202 void Solve(const T& rhs, T& sol) {
203 if (!isfactorized) SU2_MPI::Error("The factorization has not been computed yet.", CURRENT_FUNCTION);
204
205 /*--- Inverted logic due to CSR to CSC direct copy (PaStiX's A is our A^T). ---*/
206 if (iparm[IPARM_FACTORIZATION] == PastixFactLDLT || transpose) {
207 iparm[IPARM_TRANSPOSE_SOLVE] = PastixNoTrans;
208 } else {
209 iparm[IPARM_TRANSPOSE_SOLVE] = PastixTrans;
210 }
211 iparm[IPARM_VERBOSE] = PastixVerboseNot;
212
213 for (auto i = 0ul; i < matrix.size_rhs(); ++i) workvec[i] = rhs[i];
214 if (pastix_task_solve(state, matrix.size_rhs(), 1, workvec.data(), matrix.size_rhs()) != PASTIX_SUCCESS) {
215 SU2_MPI::Error("Error solving linear system.", CURRENT_FUNCTION);
216 }
217 for (auto i = 0ul; i < matrix.size_rhs(); ++i) sol[i] = workvec[i];
218 }
219};
220#endif
static int GetRank()
Definition mpi_structure.hpp:524
static void Error(const std::string &ErrorMsg, const std::string &FunctionName)
Definition mpi_structure.cpp:131
static int GetSize()
Definition mpi_structure.hpp:526
Main class for defining the problem; basically this class reads the configuration file,...
Definition CConfig.hpp:64
Parent class for defining the geometry of the problem (complete geometry, multigrid agglomerated geom...
Definition CGeometry.hpp:75
Wrapper class that converts between SU2 sparse format and PaStiX format and simplifies calls to the e...
Definition CPastixWrapper.hpp:55
const ScalarType * l
Lower blocks (matrix-owned).
Definition CPastixWrapper.hpp:82
CPastixWrapper(CPastixWrapper &&)=delete
~CPastixWrapper()
Class destructor.
Definition CPastixWrapper.hpp:139
const su2uint * row_ptr_l
LDU lower row pointers (geometry-owned).
Definition CPastixWrapper.hpp:79
void Factorize(CGeometry *geometry, const CConfig *config, unsigned short kind_fact)
Factorize matrix.
Definition CPastixWrapper.cpp:229
bool IsSetup() const
Returns true once SetLDU has been called.
Definition CPastixWrapper.hpp:144
void SetLDU(unsigned long nVar, unsigned long nPoint, unsigned long nPointDomain, const su2uint *row_ptr_l, const su2uint *col_ind_l, const su2uint *row_ptr_u, const su2uint *col_ind_u, const ScalarType *d, const ScalarType *l, const ScalarType *u)
Set LDU structure and value pointers; builds and owns assembled CSR (called once).
Definition CPastixWrapper.hpp:155
void Solve(const T &rhs, T &sol)
Runs the "solve" task for any rhs/sol with operator [].
Definition CPastixWrapper.hpp:202
unsigned long blkSz
Block size (nVar * nVar) for value assembly.
Definition CPastixWrapper.hpp:77
CPastixWrapper(const CPastixWrapper &)=delete
const su2uint * row_ptr_u
LDU upper row pointers (geometry-owned).
Definition CPastixWrapper.hpp:80
unsigned long nVar
Definition CPastixWrapper.hpp:74
unsigned long nPointDomain
Definition CPastixWrapper.hpp:76
unsigned long nPoint
Definition CPastixWrapper.hpp:75
CPastixWrapper & operator=(const CPastixWrapper &)=delete
const ScalarType * d
Diagonal blocks (matrix-owned).
Definition CPastixWrapper.hpp:81
const ScalarType * u
Upper blocks (matrix-owned).
Definition CPastixWrapper.hpp:83
void SetTransposedSolve(bool transposed=true)
Request solves with the transposed matrix.
Definition CPastixWrapper.hpp:194
CPastixWrapper & operator=(CPastixWrapper &&)=delete
CPastixWrapper()=default
uint32_t su2uint
Definition code_config.hpp:121
#define CURRENT_FUNCTION
Definition mpi_structure.hpp:59