NeoN
A framework for CFD software
Loading...
Searching...
No Matches
diagonalSolver.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 - 2026 NeoN authors
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <chrono>
8
9#include "NeoN/core/error.hpp"
12
13namespace NeoN::la
14{
15
16class DiagonalSolver : public SolverFactory::template Register<DiagonalSolver>
17{
18 using Base = SolverFactory::template Register<DiagonalSolver>;
19
20public:
21
22 DiagonalSolver(const Executor& exec, const Dictionary&) : Base(exec) {}
23
24 static std::string name() { return "diagonal"; }
25 static std::string doc() { return "Direct diagonal solver (CSR scan)"; }
26 static std::string schema() { return "none"; }
27
28 // -------- scalar --------
30 {
31 auto start = std::chrono::steady_clock::now();
32
33 const auto rhs = sys.rhs();
34 const auto mtx = sys.matrix();
35 const auto mtxV = mtx.view();
36 auto [colIdx, rowOffs] = sys.matrix().sparsity()->view();
37 auto [xV, bV] = views(x, rhs);
38
39 NF_ASSERT(bV.size() + 1 == rowOffs.size(), "Inconsistent rowOffs.size()");
41 x.exec(),
42 {0, bV.size()},
43 NEON_LAMBDA(const localIdx i) {
44 const auto rowBegin = rowOffs[i];
45 const auto rowEnd = rowOffs[i + 1];
46
47 localIdx diagIdx = -1;
48 for (localIdx k = rowBegin; k < rowEnd; ++k)
49 {
50 if (colIdx[k] == i)
51 {
52 diagIdx = k;
53 break;
54 }
55 }
56
57 if (diagIdx < 0)
58 {
59 Kokkos::abort("DiagonalSolver: diagonal entry not found");
60 }
61
62 xV[i] = bV[i] / mtxV.values[diagIdx];
63 },
64 "DiagonalSolver::solve<scalar>"
65 );
66
67 fence(x.exec());
68
69 auto end = std::chrono::steady_clock::now();
70 auto ms = static_cast<scalar>(
71 std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
72 )
73 / 1000.0;
74
75 return {1, 0.0, 0.0, ms};
76 }
77
78 // -------- Vec3 --------
80 {
81 const auto rhs = sys.rhs();
82 const auto mtx = sys.matrix();
83 const auto mtxV = mtx.view();
84 auto [colIdx, rowOffs] = sys.matrix().sparsity()->view();
85
86 auto [xV, bV] = views(x, rhs);
87
89 x.exec(),
90 {0, bV.size()},
91 NEON_LAMBDA(const localIdx i) {
92 const auto rowBegin = rowOffs[i];
93 const auto rowEnd = rowOffs[i + 1];
94
95 localIdx diagIdx = -1;
96 for (localIdx k = rowBegin; k < rowEnd; ++k)
97 {
98 if (colIdx[k] == i)
99 {
100 diagIdx = k;
101 break;
102 }
103 }
104
105 if (diagIdx < 0)
106 {
107 Kokkos::abort("DiagonalSolver<Vec3>: diagonal entry not found");
108 }
109
110 const Vec3& a = mtxV.values[diagIdx];
111 const Vec3& b = bV[i];
112
113 Vec3 xi;
114 xi[0] = b[0] / a[0];
115 xi[1] = b[1] / a[1];
116 xi[2] = b[2] / a[2];
117
118 xV[i] = xi;
119 },
120 "DiagonalSolver::solve<Vec3>"
121 );
122
123 fence(x.exec());
124 return {{1, 0.0, 0.0, 0.0}};
125 }
126
127 std::unique_ptr<SolverFactory> clone() const override
128 {
129 return std::make_unique<DiagonalSolver>(*this);
130 }
131};
132
133} // namespace NeoN::la
A class representing a dictionary that stores key-value pairs.
A class for the representation of a 3D Vec3.
Definition vec3.hpp:24
A class to contain the data and executors for a field and define some basic operations.
Definition vector.hpp:27
const Executor & exec() const
Gets the executor associated with the field.
Definition vector.hpp:262
SolverStats solve(const la::LinearSystem< Vec3 > &sys, Vector< Vec3 > &x) const override
DiagonalSolver(const Executor &exec, const Dictionary &)
std::unique_ptr< SolverFactory > clone() const override
static std::string schema()
SolverStats solve(const la::LinearSystem< scalar > &sys, Vector< scalar > &x) const override
static std::string doc()
static std::string name()
A class representing a linear system of equations.
Vector< RHSValueType > & rhs()
SystemMatrixType & matrix()
A template class for registering derived classes with a base class.
#define NF_ASSERT(condition, message)
Macro for asserting a condition and printing an error message if the condition is false.
Definition error.hpp:118
void fence(const Executor &exec)
Definition executor.hpp:23
int32_t localIdx
Definition label.hpp:50
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:20
float scalar
Definition scalar.hpp:17
void parallelFor(const ExecutorType &, std::pair< localIdx, localIdx > range, const Kernel &kernel, std::string name)
auto views(Types &... args)
Unpacks all views of the passed classes.
Definition view.hpp:107
#define NEON_LAMBDA