core 1.5.0
Shared MPI block decomposition, asynchronous ghost-layer exchange, SDF geometry, load balancing (header-only C++20)
Loading...
Searching...
No Matches
csr_operator.hpp
Go to the documentation of this file.
1// core — an assembled face-CSR operator on the device (Kokkos): matvec, residual, weighted-Jacobi
2// and symmetric multicolour Gauss–Seidel sweeps.
3//
4// Lifted verbatim from the AMR tree (peclet/core/amr/momentum.hpp, 2026-09-10; QUALITY_PLAN G.2),
5// where it is the cut-cell momentum operator A = (ρ/dt)I − μ∇² (+ implicit-FOU advection + the
6// ξ-polynomial Dirichlet overlay on cut cells) assembled as a per-cell diagonal + general face CSR,
7// uploaded once and applied / smoothed entirely in device kernels. Nothing in it is specific to
8// momentum or to an octree: `MomentumOp` is any diagonal + face-CSR operator (with an optional
9// second CSR), which is why voro's optimal-transport optimiser drives the same code. The names keep
10// their AMR spelling — the AMR package and voro alias them, and a rename is not a structural move.
11//
12// The row arithmetic itself lives in face_csr.hpp, shared with the host serial oracle so the two
13// cannot drift. A is generally NON-symmetric (row scaling, upwind advection), so the smoother is
14// weighted Jacobi (parallel, deterministic: reads only the previous iterate) or the multicolour GS
15// below, and the Krylov accelerator is BiCGStab (csr_bicgstab.hpp) rather than CG.
16#ifndef PECLET_CORE_SOLVER_CSR_OPERATOR_HPP
17#define PECLET_CORE_SOLVER_CSR_OPERATOR_HPP
18
19#include <cstddef>
20
25
26namespace peclet::core::solver {
27
45
52 v.n = op.n;
53 v.diag = op.diag;
54 v.coef = op.faceCoef;
55 v.start = op.faceStart;
56 v.nbr = op.faceNbr;
57 v.hasAdv = op.hasAdv;
58 v.advDiag = op.advDiag;
59 v.advCoef = op.advCoef;
60 v.advStart = op.advStart;
61 v.advNbr = op.advNbr;
62 return v;
63}
64
67 const auto A = momView(op);
68 Kokkos::parallel_for(
69 "amr::mom_apply", op.n, KOKKOS_LAMBDA(const Index i) { Au(i) = faceCsrApplyRow(A, i, u); });
70}
71
74 View<double> res) {
75 const auto A = momView(op);
76 Kokkos::parallel_for(
77 "amr::mom_residual", op.n,
78 KOKKOS_LAMBDA(const Index i) { res(i) = b(i) - faceCsrApplyRow(A, i, u); });
79}
80
84 double omega) {
85 const auto A = momView(op);
86 Kokkos::parallel_for(
87 "amr::mom_jacobi_compute", op.n, KOKKOS_LAMBDA(const Index i) {
88 double off, d;
89 faceCsrOffDiag(A, i, u, off, d);
90 tmp(i) = (d != 0.0) ? (b(i) - off) / d : u(i);
91 });
92 Kokkos::parallel_for(
93 "amr::mom_jacobi_update", op.n,
94 KOKKOS_LAMBDA(const Index i) { u(i) = (1.0 - omega) * u(i) + omega * tmp(i); });
95}
96
108 const Coloring& col, double omega) {
109 const auto A = momView(op);
110 auto idx = col.idx;
111 auto colorPass = [&](int c) {
112 const Index a0 = col.hStart[static_cast<std::size_t>(c)];
113 const Index a1 = col.hStart[static_cast<std::size_t>(c) + 1];
114 Kokkos::parallel_for(
115 "amr::gs_mom", Kokkos::RangePolicy<ExecSpace>(a0, a1), KOKKOS_LAMBDA(const Index k) {
116 const Index i = idx(k);
117 double off, d;
118 faceCsrOffDiag(A, i, u, off, d);
119 u(i) = faceCsrPointUpdate(b(i), off, d, u(i), omega);
120 });
121 };
122 for (int c = 0; c < col.nColors; ++c)
123 colorPass(c); // forward
124 for (int c = col.nColors - 2; c >= 0; --c)
125 colorPass(c); // reverse (last colour not repeated)
126}
127
128} // namespace peclet::core::solver
129
130#endif // PECLET_CORE_SOLVER_CSR_OPERATOR_HPP
PECLET_HD void faceCsrOffDiag(const Op &op, Index i, const U &u, double &off, double &d)
Off-diagonal sum and the (advection-inclusive) diagonal for the point smoothers: out off = Σ coef·u[n...
Definition face_csr.hpp:73
PECLET_HD double faceCsrPointUpdate(double b_i, double off, double d, double uOld, double omega)
The damped point update used by both Jacobi and (multicolour) Gauss–Seidel: returns the new u_i given...
Definition face_csr.hpp:88
void applyMom(const MomentumOp &op, View< const double > u, View< double > Au)
Au = A u (cut-cell operator + optional implicit-FOU advection).
void multicolorGSMom(const MomentumOp &op, View< double > u, View< const double > b, const Coloring &col, double omega)
One symmetric multicolour Gauss–Seidel sweep of A u = b in place (momentum operator: diag + face CSR ...
FaceCsrOpT< View< const double >, View< const Index > > momView(const MomentumOp &op)
View the assembled momentum operator through the shared, backend-agnostic FaceCsrOpT,...
void residualMom(const MomentumOp &op, View< const double > u, View< const double > b, View< double > res)
res = b − A u.
void jacobiMom(const MomentumOp &op, View< double > u, View< const double > b, View< double > tmp, double omega)
One weighted-Jacobi sweep of A u = b (in place).
PECLET_HD double faceCsrApplyRow(const Op &op, Index i, const U &u)
(A u)_i — one assembled-operator row.
Definition face_csr.hpp:57
Kokkos::View< T *, MemSpace > View
1D device array.
Definition view.hpp:26
std::int64_t Index
Signed index type for grids and particles (supersedes block_decomposer's long int IndxT).
Definition types.hpp:15
A graph colouring of a face CSR: cells grouped by colour.
Definition coloring.hpp:22
Assembled momentum operator on the device: (A u)_i = diag_i u_i + Σ coef·u[nbr], with an optional imp...
View< double > advDiag
per-cell outflow (diagonal) advection weight, size n
View< double > faceCoef
off-diagonal coefficient, size nnz
View< Index > faceNbr
neighbour leaf per off-diagonal, size nnz
View< Index > faceStart
CSR row offsets, size n+1.
View< Index > advStart
face-geom CSR row offsets, size n+1
View< double > advCoef
per-face inflow advection coefficient (0 on outflow/solid faces)
View< Index > advNbr
face-geom neighbour per face, size nFaces