Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 31 additions & 13 deletions Common/include/geometry/CGeometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ using namespace std;
* \author F. Palacios
*/
class CGeometry {
public:
/*!
* \brief Aggregates the full symmetric CSR and its LDU split (L strictly-lower, U strictly-upper).
* Built together lazily via GetSparsePattern; all three are always valid once non-empty.
*/
struct LDUSparsePattern {
CCompressedSparsePatternUL csr; /*!< Full symmetric pattern (with diagonal pointer). */
CCompressedSparsePatternUL l; /*!< Strictly-lower part. */
CCompressedSparsePatternUL u; /*!< Strictly-upper part. */

bool empty() const { return csr.empty(); }
};

protected:
enum : size_t { OMP_MIN_SIZE = 32 }; /*!< \brief Chunk size for small loops. */
enum : size_t { MAXNDIM = 3 };
Expand Down Expand Up @@ -187,12 +200,15 @@ class CGeometry {

/*--- Sparsity patterns associated with the geometry. ---*/

CCompressedSparsePatternUL finiteVolumeCSRFill0, /*!< \brief 0-fill FVM sparsity. */
finiteVolumeCSRFillN, /*!< \brief N-fill FVM sparsity (e.g. for ILUn preconditioner). */
finiteElementCSRFill0, /*!< \brief 0-fill FEM sparsity. */
finiteElementCSRFillN; /*!< \brief N-fill FEM sparsity (e.g. for ILUn preconditioner). */
LDUSparsePattern finiteVolumePatternFill0; /*!< \brief FVM sparsity with 0-fill (structural pattern). */
LDUSparsePattern finiteVolumePatternFillN; /*!< \brief FVM sparsity with N-fill (e.g. for ILU-N). */
LDUSparsePattern finiteElementPatternFill0; /*!< \brief FEM sparsity with 0-fill (structural pattern). */
LDUSparsePattern finiteElementPatternFillN; /*!< \brief FEM sparsity with N-fill (e.g. for ILU-N). */

CEdgeToNonZeroMapUL edgeToCSRMap; /*!< \brief Map edges to CSR entries referenced by them (i,j) and (j,i). */
su2vector<unsigned long> finiteVolumeLToUTranspMap; /*!< \brief FVM L-entry -> U-entry of its transpose. */
su2vector<unsigned long> finiteVolumeUToLTranspMap; /*!< \brief FVM U-entry -> L-entry of its transpose. */
su2vector<unsigned long> finiteElementLToUTranspMap; /*!< \brief FEM L-entry -> U-entry of its transpose. */
su2vector<unsigned long> finiteElementUToLTranspMap; /*!< \brief FEM U-entry -> L-entry of its transpose. */

/*--- Edge and element colorings. ---*/

Expand Down Expand Up @@ -1868,21 +1884,23 @@ class CGeometry {
* \param[in] fillLvl - Level of fill of the pattern.
* \return Reference to the sparse pattern.
*/
const CCompressedSparsePatternUL& GetSparsePattern(ConnectivityType type, unsigned long fillLvl = 0);
const LDUSparsePattern& GetSparsePattern(ConnectivityType type, unsigned long fillLvl = 0);

/*!
* \brief Get the edge to sparse pattern map.
* \note This method builds the map and required pattern (0-fill FVM) if that has not been done yet.
* \return Reference to the map.
* \brief Get the bijective map from L-entry indices to U-entry indices of their transposes.
* \note Requires symmetric pattern. Builds both LU transpose maps if not already built.
* \param[in] type - Finite volume or finite element.
* \return Reference to the l_to_u map.
*/
const CEdgeToNonZeroMapUL& GetEdgeToSparsePatternMap();
const su2vector<unsigned long>& GetLToUTransposeSparsePatternMap(ConnectivityType type);

/*!
* \brief Get the transpose of the (main, i.e 0 fill) sparse pattern (e.g. CSR becomes CSC).
* \brief Get the bijective map from U-entry indices to L-entry indices of their transposes.
* \note Requires symmetric pattern. Builds both LU transpose maps if not already built.
* \param[in] type - Finite volume or finite element.
* \return Reference to the map.
* \return Reference to the u_to_l map.
*/
const su2vector<unsigned long>& GetTransposeSparsePatternMap(ConnectivityType type);
const su2vector<unsigned long>& GetUToLTransposeSparsePatternMap(ConnectivityType type);

/*!
* \brief Get the edge coloring.
Expand Down
64 changes: 48 additions & 16 deletions Common/include/linear_algebra/CPastixWrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,28 @@ class CPastixWrapper {
vector<pastix_int_t> perm; /*!< \brief Ordering computed by PaStiX. */
vector<su2mixedfloat> workvec; /*!< \brief RHS vector which then becomes the solution. */

vector<unsigned long> csr_row_ptr; /*!< \brief Owned CSR row pointers (built from LDU). */
vector<unsigned long> csr_col_ind; /*!< \brief Owned CSR column indices (built from LDU). */

pastix_int_t iparm[IPARM_SIZE]; /*!< \brief Integer parameters for PaStiX. */
double dparm[DPARM_SIZE]; /*!< \brief Floating point parameters for PaStiX. */

struct {
unsigned long nVar = 0;
unsigned long nPoint = 0;
unsigned long nPointDomain = 0;
const unsigned long* rowptr = nullptr;
const unsigned long* colidx = nullptr;
const ScalarType* values = nullptr;
unsigned long blkSz = 0; /*!< \brief Block size (nVar * nVar) for value assembly. */

const unsigned long* row_ptr_l = nullptr; /*!< \brief LDU lower row pointers (geometry-owned). */
const unsigned long* row_ptr_u = nullptr; /*!< \brief LDU upper row pointers (geometry-owned). */
const ScalarType* d = nullptr; /*!< \brief Diagonal blocks (matrix-owned). */
const ScalarType* l = nullptr; /*!< \brief Lower blocks (matrix-owned). */
const ScalarType* u = nullptr; /*!< \brief Upper blocks (matrix-owned). */

unsigned long size_rhs() const { return nPointDomain * nVar; }
} matrix; /*!< \brief Pointers and sizes of the input matrix. */
} matrix; /*!< \brief Dimensions and LDU pointers captured from the owning CSysMatrix. */

bool issetup{}; /*!< \brief Signals that the matrix data has been provided. */
bool issetup{}; /*!< \brief Signals that the structure has been provided. */
bool isinitialized{}; /*!< \brief Signals that the sparsity pattern has been set. */
bool isfactorized{}; /*!< \brief Signals that a factorization has been computed. */
bool transpose{}; /*!< \brief Solve A^T x = b instead of A x = b. */
Expand Down Expand Up @@ -110,6 +117,11 @@ class CPastixWrapper {
*/
void Initialize(CGeometry* geometry, const CConfig* config);

/*!
* \brief Assemble CSR values from the stored LDU pointers directly into the values buffer.
*/
void AssembleValues();

public:
CPastixWrapper() = default;

Expand All @@ -125,23 +137,43 @@ class CPastixWrapper {
~CPastixWrapper() { Clean(); }

/*!
* \brief Set matrix data, only once.
* \param[in] nVar - DOF per point.
* \brief Returns true once SetLDU has been called.
*/
bool IsSetup() const { return issetup; }

/*!
* \brief Set LDU structure and value pointers; builds and owns assembled CSR (called once).
* \param[in] nVar - DOF per point (square blocks: nVar x nVar).
* \param[in] nPoint - Total number of points including halos.
* \param[in] nPointDomain - Number of internal points.
* \param[in] rowptr - Array, where column index data starts for each matrix row.
* \param[in] colidx - Non zeros column indices.
* \param[in] values - Matrix coefficients.
* \param[in] nPointDomain - Number of internal points (domain rows).
* \param[in] row_ptr_l/u - LDU lower/upper row pointers (geometry-owned, must outlive wrapper).
* \param[in] col_ind_l/u - LDU lower/upper column indices (geometry-owned).
* \param[in] d/l/u - LDU value blocks (matrix-owned, must outlive wrapper).
*/
void SetMatrix(unsigned long nVar, unsigned long nPoint, unsigned long nPointDomain, const unsigned long* rowptr,
const unsigned long* colidx, const ScalarType* values) {
void SetLDU(unsigned long nVar, unsigned long nPoint, unsigned long nPointDomain, const unsigned long* row_ptr_l,
const unsigned long* col_ind_l, const unsigned long* row_ptr_u, const unsigned long* col_ind_u,
const ScalarType* d, const ScalarType* l, const ScalarType* u) {
if (issetup) return;
matrix.nVar = nVar;
matrix.nPoint = nPoint;
matrix.nPointDomain = nPointDomain;
matrix.rowptr = rowptr;
matrix.colidx = colidx;
matrix.values = values;
matrix.row_ptr_l = row_ptr_l;
matrix.row_ptr_u = row_ptr_u;
matrix.d = d;
matrix.l = l;
matrix.u = u;
matrix.blkSz = nVar * nVar;

const unsigned long nnz_domain = row_ptr_l[nPointDomain] + nPointDomain + row_ptr_u[nPointDomain];
csr_row_ptr.resize(nPointDomain + 1);
csr_col_ind.reserve(nnz_domain);
for (auto i = 0ul; i < nPointDomain; ++i) {
csr_row_ptr[i] = static_cast<unsigned long>(csr_col_ind.size());
for (auto k = row_ptr_l[i]; k < row_ptr_l[i + 1]; ++k) csr_col_ind.push_back(col_ind_l[k]);
csr_col_ind.push_back(i);
for (auto k = row_ptr_u[i]; k < row_ptr_u[i + 1]; ++k) csr_col_ind.push_back(col_ind_u[k]);
}
csr_row_ptr[nPointDomain] = static_cast<unsigned long>(csr_col_ind.size());
issetup = true;
}

Expand Down
Loading
Loading