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