NeoN
WIP Prototype of a modern OpenFOAM core
Loading...
Searching...
No Matches
petscSolverContext.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2025 NeoN authors
3// inspired by
4// https://develop.openfoam.com/modules/external-solver/-/blob/develop/src/petsc4Foam/utils/petscLinearSolverContext.H
5
6#pragma once
7
8#if NF_WITH_PETSC
9
10#include <Kokkos_Core.hpp>
11#include <petscvec_kokkos.hpp>
12#include <petscmat.h>
13#include <petscksp.h>
14
15#include "NeoN/fields/field.hpp"
19
20// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
21
22namespace NeoN::la::petscSolverContext
23{
24
25template<typename ValueType>
26class petscSolverContext
27{
28 // Private Data
29
30 bool init_, updated_;
31 Executor exec_;
32 Mat Amat_;
33 KSP ksp_;
34
35 Vec sol_, rhs_;
36
37public:
38
39
40 // Constructors
41
42 //- Default construct
43 petscSolverContext(Executor exec)
44 : init_(false), updated_(false), exec_(exec), Amat_(nullptr), sol_(nullptr), rhs_(nullptr),
45 ksp_(nullptr)
46 {}
47
48
49 //- Destructor
50 virtual ~petscSolverContext()
51 {
52 MatDestroy(&Amat_);
53 KSPDestroy(&ksp_);
54 VecDestroy(&sol_);
55 VecDestroy(&rhs_);
56 }
57
58
59 // Member Functions
60
61 //- Return value of initialized
62 bool initialized() const noexcept { return init_; }
63
64
65 //- Return value of initialized
66 bool updated() const noexcept { return updated_; }
67
68 //- Create auxiliary rows for calculation purposes
69 void initialize(const LinearSystem<scalar, localIdx>& sys)
70 {
71 std::size_t size = sys.matrix().values().size();
72 std::size_t nrows = sys.rhs().size();
73 PetscInt colIdx[size];
74 PetscInt rowIdx[size];
75 PetscInt rhsIdx[nrows];
76
77 // colIdx = sys.matrix().colIdxs().data();
78
79 auto hostLS = sys.copyToHost();
80
81 // auto fieldS = field.view();
82
83 auto rowPtrHost = hostLS.matrix().rowPtrs().view();
84 auto colIdxHost = hostLS.matrix().colIdxs().view();
85 auto rhsHost = sys.rhs().copyToHost();
86
87 for (size_t index = 0; index < nrows; ++index)
88 {
89 rhsIdx[index] = static_cast<PetscInt>(index);
90 }
91 // copy colidx
92 // TODO: (this should be done only once when the matrix
93 // topology changes
94 for (size_t index = 0; index < size; ++index)
95 {
96 colIdx[index] = static_cast<PetscInt>(colIdxHost[index]);
97 }
98 // convert rowPtr to rowIdx
99 // TODO: (this should be done only once when the matrix
100 // topology changes
101 size_t rowI = 0;
102 size_t rowOffset = rowPtrHost[rowI + 1];
103 for (size_t index = 0; index < size; ++index)
104 {
105 if (index == rowOffset)
106 {
107 rowI++;
108 rowOffset = rowPtrHost[rowI + 1];
109 }
110 rowIdx[index] = rowI;
111 }
112
113 // move all not necessary staff to outer most scope since matrix has
114 // to be preallocated only once every time the mesh changes
115 PetscInitialize(NULL, NULL, 0, NULL);
116
117 MatCreate(PETSC_COMM_WORLD, &Amat_);
118 MatSetSizes(Amat_, sys.matrix().nRows(), sys.rhs().size(), PETSC_DECIDE, PETSC_DECIDE);
119
120 VecCreate(PETSC_COMM_SELF, &rhs_);
121 VecSetSizes(rhs_, PETSC_DECIDE, nrows);
122
123 std::string execName = std::visit([](const auto& e) { return e.name(); }, exec_);
124
125 if (execName == "GPUExecutor")
126 {
127 VecSetType(rhs_, VECKOKKOS);
128 MatSetType(Amat_, MATAIJKOKKOS);
129 }
130 else
131 {
132 VecSetType(rhs_, VECSEQ);
133 MatSetType(Amat_, MATSEQAIJ);
134 }
135 VecDuplicate(rhs_, &sol_);
136
137 VecSetPreallocationCOO(rhs_, nrows, rhsIdx);
138 MatSetPreallocationCOO(Amat_, size, colIdx, rowIdx);
139
140 KSPCreate(PETSC_COMM_WORLD, &ksp_);
141 KSPSetFromOptions(ksp_);
142 KSPSetOperators(ksp_, Amat_, Amat_);
143
144
145 init_ = true;
146 }
147
148 //- Create auxiliary rows for calculation purposes
149 void update() { NF_ERROR_EXIT("Mesh changes not supported"); }
150
151 [[nodiscard]] Mat& AMat() { return Amat_; }
152
153 [[nodiscard]] Vec& rhs() { return rhs_; }
154
155 [[nodiscard]] Vec& sol() { return sol_; }
156
157 [[nodiscard]] KSP& ksp() { return ksp_; }
158};
159
160
161// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
162
163} // End NeoN::la::petscSolverContext
164
165// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
166
167#endif
#define NF_ERROR_EXIT(message)
Macro for printing an error message and aborting the program.
Definition error.hpp:108
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:16