NeoN
A framework for CFD software
Loading...
Searching...
No Matches
faceToMatrixAddress.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 NeoN authors
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include "NeoN/core/array.hpp"
12
13namespace NeoN::la
14{
15
17{
19 View<const uint8_t> ownerOffsetView,
20 View<const uint8_t> neighbourOffsetView,
21 View<const uint8_t> diagOffsetView,
22 View<const localIdx> rowOffsView
23 )
24 : ownerOffset(ownerOffsetView), neighbourOffset(neighbourOffsetView),
25 diagOffset(diagOffsetView), rowOffs(rowOffsView) {};
26
27 // TODO check performance
28 /* @brief Returns the flat values-array index of the diagonal entry for cell celli.
29 * diagIdx(celli) = rowOffs[celli] + diagOffset[celli]
30 */
31 KOKKOS_INLINE_FUNCTION localIdx diagIdx(localIdx celli) const
32 {
33 return rowOffs[celli] + diagOffset[celli];
34 }
35
36 /* @brief Returns the flat values-array index of the upper-triangular entry A[own, nei].
37 *
38 * By construction own < nei for every internal face, so the column index nei is greater
39 * than the row index own — this entry lies in the upper triangle.
40 *
41 * upperIdx(own, f) = rowOffs[own] + ownerOffset[f]
42 */
43 KOKKOS_INLINE_FUNCTION localIdx upperIdx(localIdx own, localIdx faceIdx) const
44 {
45 return rowOffs[own] + ownerOffset[faceIdx];
46 }
47
48 /* @brief Returns the flat values-array index of the lower-triangular entry A[nei, own].
49 *
50 * By construction nei > own for every internal face, so the column index own is less
51 * than the row index nei — this entry lies in the lower triangle.
52 *
53 * lowerIdx(nei, f) = rowOffs[nei] + neighbourOffset[f]
54 */
55 KOKKOS_INLINE_FUNCTION localIdx lowerIdx(localIdx nei, localIdx faceIdx) const
56 {
57 return rowOffs[nei] + neighbourOffset[faceIdx];
58 }
59
60 // corresponding views
62
64
66
67 // row offsets borrowed from the owning Matrix's sparsity pattern
69};
70
71/* @class FaceToMatrixAddress
72 * @brief Stores the mapping between mesh faces and matrix row offsets.
73 *
74 * Based on a given computational mesh this class stores a mapping for a consistent iteration
75 * procedure for matrices which share the same sparsity pattern.
76 *
77 * This class implements the finite volume 3/5/7 pt stencil specific generation
78 * of face-to-matrix offset mappings. The sparsity pattern itself is owned by
79 * the Matrix, not by this class; this class only borrows a view of the row offsets.
80 *
81 */
82class FaceToMatrixAddress : public NeoN::SupportsCopyTo<FaceToMatrixAddress>
83{
84 void validate() const;
85
86 // clang-format off
87 // NOTE The following data members store a simple mapping from face ids to offsets within
88 // the corresponding row of the CSR values array.
89 //
90 // For an internal face f with owner P and neighbour N (P < N by construction):
91 // ownerOffset[f] = offset within row P for column N → A[P, N] (upper triangular)
92 // neighbourOffset[f] = offset within row N for column P → A[N, P] (lower triangular)
93 //
94 // Example row layout for a cell with two lower entries and one upper entry:
95 // Row P: [ A[P,j0] A[P,j1] | A[P,P] | A[P,N] ]
96 // lower (j<P) diag upper (N>P)
97 // ownerOffset[f] = 3 (position of A[P,N] within row P)
98 // neighbourOffset[f] = 0 (position of A[N,P] within row N)
99 // clang-format on
101 ownerOffset_;
102
103 Array<uint8_t> neighbourOffset_;
105
106 Array<uint8_t> diagOffset_;
107
108public:
109
110 /* @brief constructor
111 *
112 * @param ownerOffset face-to-upper-offset mapping for the owner row
113 * @param neighbourOffset face-to-lower-offset mapping for the neighbour row
114 * @param diagOffset cell-to-diagonal-offset mapping
115 */
118 );
119
120 /* @brief copy constructor */
122
123
125
130 [[nodiscard]] FaceToMatrixView view(View<const localIdx> rowOffsView) const;
131
132 /*@brief getter for ownerOffset */
134
135 /*@brief getter for neighbourOffset */
137
138 /*@brief getter for diagOffset */
140
141 /*@brief getter for ownerOffset */
143
144 /*@brief getter for neighbourOffset */
146
147 /*@brief getter for diagOffset */
149};
150
151/* @brief Creates the sparsity pattern and corresponding FaceToMatrixAddress from a mesh.
152 *
153 * The two are returned together because FaceToMatrixAddress borrows the row-offsets
154 * view from the sparsity pattern. The boundary sparsity is created separately
155 * via createBoundarySparsityPattern.
156 *
157 * @tparam SparsityType - The full sparsity pattern type to create, e.g.
158 * CsrSparsityPattern<localIdx> or CooSparsityPattern<localIdx>
159 */
160template<typename SparsityType>
161std::pair<std::shared_ptr<const SparsityType>, std::shared_ptr<const FaceToMatrixAddress>>
163
164/* @brief Creates the boundary sparsity pattern from a mesh and an existing
165 * FaceToMatrixAddress (which provides the diagonal offsets needed to compute it).
166 *
167 * @tparam SparsityType - The full sparsity pattern type to create, e.g.
168 * CooSparsityPattern<localIdx> or CsrSparsityPattern<localIdx>
169 */
170template<typename SparsityType>
171std::shared_ptr<const SparsityType> createBoundarySparsityPattern(
172 const UnstructuredMesh& mesh, const FaceToMatrixAddress& faceToMatrixAddress
173);
174
175template<typename SparsityType>
176std::shared_ptr<const SparsityType> createOffDiagonalSparsityPattern(
177 const UnstructuredMesh& mesh, const FaceToMatrixAddress& faceToMatrixAddress
178);
179
180/* @brief Immutable, topology-only bundle shared across every LinearSystem built on a mesh.
181 *
182 * The CSR system sparsity (colIdxs/rowOffs), its FaceToMatrixAddress (diag/owner/neighbour
183 * offsets), and the boundary COO sparsity depend ONLY on mesh topology — they are byte-identical
184 * for every equation (U, p, nuTilda, ...) on the same mesh. Only the per-system value/RHS vectors
185 * legitimately differ. Caching this bundle once per mesh removes the per-equation duplication of
186 * these identical arrays.
187 *
188 * All three members are stored as shared_ptr<const ...> so the cached objects stay immutable and
189 * are safe to share between systems; consumers write only their own per-system value/RHS vectors.
190 *
191 * @tparam SystemSparsityType - the system sparsity type, e.g. CsrSparsityPattern<localIdx>
192 * @tparam BoundarySparsityType - the boundary sparsity type, e.g. CooSparsityPattern<localIdx>
193 */
194template<typename SystemSparsityType, typename BoundarySparsityType>
196{
197 std::shared_ptr<const SystemSparsityType> systemSparsity;
198 std::shared_ptr<const FaceToMatrixAddress> faceToMatrixAddress;
199 std::shared_ptr<const BoundarySparsityType> boundarySparsity;
200
201 // Explicit constructor: CUDA-12.4 nvcc rejects parenthesized aggregate init, so give the
202 // bundle a real constructor for portability (brace-init would otherwise suffice).
204 std::shared_ptr<const SystemSparsityType> systemSparsity,
205 std::shared_ptr<const FaceToMatrixAddress> faceToMatrixAddress,
206 std::shared_ptr<const BoundarySparsityType> boundarySparsity
207 )
208 : systemSparsity(std::move(systemSparsity)),
211 {}
212};
213
214/* @brief Returns the SHARED, immutable topology bundle for a mesh, caching it in
215 * mesh.stencilDB(). Mirrors the GeometryScheme::readOrCreate precedent exactly
216 * (contains/insert/get of a std::shared_ptr keyed by a type-specific string).
217 *
218 * The cache key encodes both sparsity types so the CSR system pattern and the COO boundary pattern
219 * (and the index type) never collide. Returns a cheap copy of the bundle (three shared_ptrs).
220 *
221 * @note mesh.stencilDB() is mutable and not thread-safe; this matches the GeometryScheme cache and
222 * is acceptable for CPU-serial v1. No locking is added here.
223 */
224template<typename SystemSparsityType, typename BoundarySparsityType>
225[[nodiscard]] SharedSparsityBundle<SystemSparsityType, BoundarySparsityType>
227
228}
A class to contain the data and executors for a field and define some basic operations.
Definition array.hpp:28
MixinClass signaling copyTo is supported.
Definition copyTo.hpp:20
Represents an unstructured mesh in NeoN.
FaceToMatrixView view(View< const localIdx > rowOffsView) const
Get a view representation of the matrix's data.
Array< uint8_t > & neighbourOffset()
const Array< uint8_t > & neighbourOffset() const
FaceToMatrixAddress(Array< uint8_t > ownerOffset, Array< uint8_t > neighbourOffset, Array< uint8_t > diagOffset)
mapping from celli to diagonal element offset
const Array< uint8_t > & diagOffset() const
const Array< uint8_t > & ownerOffset() const
FaceToMatrixAddress copyToExecutor(Executor dstExec) const
Array< uint8_t > & diagOffset()
Array< uint8_t > & ownerOffset()
FaceToMatrixAddress(const FaceToMatrixAddress &mi)
std::shared_ptr< const SparsityType > createBoundarySparsityPattern(const UnstructuredMesh &mesh, const FaceToMatrixAddress &faceToMatrixAddress)
std::pair< std::shared_ptr< const SparsityType >, std::shared_ptr< const FaceToMatrixAddress > > createSparsityPatternFaceToMatrixAddress(const UnstructuredMesh &mesh)
std::shared_ptr< const SparsityType > createOffDiagonalSparsityPattern(const UnstructuredMesh &mesh, const FaceToMatrixAddress &faceToMatrixAddress)
SharedSparsityBundle< SystemSparsityType, BoundarySparsityType > readOrCreateSparsityBundle(const UnstructuredMesh &mesh)
int32_t localIdx
Definition label.hpp:50
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:20
KOKKOS_INLINE_FUNCTION localIdx upperIdx(localIdx own, localIdx faceIdx) const
KOKKOS_INLINE_FUNCTION localIdx lowerIdx(localIdx nei, localIdx faceIdx) const
KOKKOS_INLINE_FUNCTION localIdx diagIdx(localIdx celli) const
View< const localIdx > rowOffs
View< const uint8_t > ownerOffset
FaceToMatrixView(View< const uint8_t > ownerOffsetView, View< const uint8_t > neighbourOffsetView, View< const uint8_t > diagOffsetView, View< const localIdx > rowOffsView)
View< const uint8_t > diagOffset
View< const uint8_t > neighbourOffset
SharedSparsityBundle(std::shared_ptr< const SystemSparsityType > systemSparsity, std::shared_ptr< const FaceToMatrixAddress > faceToMatrixAddress, std::shared_ptr< const BoundarySparsityType > boundarySparsity)
std::shared_ptr< const FaceToMatrixAddress > faceToMatrixAddress
std::shared_ptr< const SystemSparsityType > systemSparsity
std::shared_ptr< const BoundarySparsityType > boundarySparsity