NeoN
A framework for CFD software
Loading...
Searching...
No Matches
divOperator.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2023-2025 NeoN authors
3
4#pragma once
5
9#include "NeoN/core/input.hpp"
13
15{
16
17/* @class Factory class to create divergence operators by a given name using
18 * using NeoNs runTimeFactory mechanism
19 */
20template<typename ValueType>
23 DivOperatorFactory<ValueType>,
24 Parameters<const Executor&, const UnstructuredMesh&, const Input&>>
25{
26
27public:
28
29 static std::unique_ptr<DivOperatorFactory<ValueType>>
30 create(const Executor& exec, const UnstructuredMesh& uMesh, const Input& inputs)
31 {
32 std::string key = (std::holds_alternative<Dictionary>(inputs))
33 ? std::get<Dictionary>(inputs).get<std::string>("DivOperator")
34 : std::get<TokenList>(inputs).next<std::string>();
36 return DivOperatorFactory<ValueType>::table().at(key)(exec, uMesh, inputs);
37 }
38
39 static std::string name() { return "DivOperatorFactory"; }
40
42 : exec_(exec), mesh_(mesh), sparsityPattern_(la::SparsityPattern::readOrCreate(mesh)) {};
43
44 virtual ~DivOperatorFactory() {} // Virtual destructor
45
46 // NOTE currently simple overloading is used here, because templating the virtual function
47 // does not work and we cant template the entire class because the static create function
48 // cannot access keyExistsOrError and table anymore.
49 virtual void
51 const SurfaceField<scalar>& faceFlux,
52 const VolumeField<ValueType>& phi,
53 const dsl::Coeff operatorScaling) const = 0;
54
55 virtual void
57 const SurfaceField<scalar>& faceFlux,
58 const VolumeField<ValueType>& phi,
59 const dsl::Coeff operatorScaling) const = 0;
60
61 virtual void
63 const SurfaceField<scalar>& faceFlux,
64 const VolumeField<ValueType>& phi,
65 const dsl::Coeff operatorScaling) const = 0;
66
68 div(const SurfaceField<scalar>& faceFlux,
69 const VolumeField<ValueType>& phi,
70 const dsl::Coeff operatorScaling) const = 0;
71
73
74 // Pure virtual function for cloning
75 virtual std::unique_ptr<DivOperatorFactory<ValueType>> clone() const = 0;
76
77protected:
78
80
82
84};
85
86template<typename ValueType>
87class DivOperator : public dsl::OperatorMixin<VolumeField<ValueType>>
88{
89
90public:
91
92 using VectorValueType = ValueType;
93
94 // copy constructor
96 : dsl::OperatorMixin<VolumeField<ValueType>>(
97 divOp.exec_, divOp.coeffs_, divOp.field_, divOp.type_
98 ),
99 faceFlux_(divOp.faceFlux_),
100 divOperatorStrategy_(
101 divOp.divOperatorStrategy_ ? divOp.divOperatorStrategy_->clone() : nullptr
102 ) {};
103
105 dsl::Operator::Type termType,
106 const SurfaceField<scalar>& faceFlux,
108 Input input
109 )
110 : dsl::OperatorMixin<VolumeField<ValueType>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
111 faceFlux_(faceFlux),
112 divOperatorStrategy_(DivOperatorFactory<ValueType>::create(phi.exec(), phi.mesh(), input)
113 ) {};
114
116 dsl::Operator::Type termType,
117 const SurfaceField<scalar>& faceFlux,
119 std::unique_ptr<DivOperatorFactory<ValueType>> divOperatorStrategy
120 )
121 : dsl::OperatorMixin<VolumeField<scalar>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
122 faceFlux_(faceFlux), divOperatorStrategy_(std::move(divOperatorStrategy)) {};
123
125 dsl::Operator::Type termType,
126 const SurfaceField<scalar>& faceFlux,
128 )
129 : dsl::OperatorMixin<VolumeField<ValueType>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
130 faceFlux_(faceFlux), divOperatorStrategy_(nullptr) {};
131
132
134 {
135 NF_ASSERT(divOperatorStrategy_, "DivOperatorStrategy not initialized");
136 auto tmpsource = Vector<ValueType>(source.exec(), source.size(), zero<ValueType>());
137 const auto operatorScaling = this->getCoefficient();
138 divOperatorStrategy_->div(tmpsource, faceFlux_, this->getVector(), operatorScaling);
139 source += tmpsource;
140 }
141
143 {
144 NF_ASSERT(divOperatorStrategy_, "DivOperatorStrategy not initialized");
145 return divOperatorStrategy_->createEmptyLinearSystem();
146 }
147
149 {
150 NF_ASSERT(divOperatorStrategy_, "DivOperatorStrategy not initialized");
151 const auto operatorScaling = this->getCoefficient();
152 divOperatorStrategy_->div(ls, faceFlux_, this->getVector(), operatorScaling);
153 }
154
155 void div(Vector<ValueType>& divPhi) const
156 {
157 const auto operatorScaling = this->getCoefficient();
158 divOperatorStrategy_->div(divPhi, faceFlux_, this->getVector(), operatorScaling);
159 }
160
162 {
163 const auto operatorScaling = this->getCoefficient();
164 divOperatorStrategy_->div(ls, faceFlux_, this->getVector(), operatorScaling);
165 };
166
167 void div(VolumeField<ValueType>& divPhi) const
168 {
169 const auto operatorScaling = this->getCoefficient();
170 divOperatorStrategy_->div(divPhi, faceFlux_, this->getVector(), operatorScaling);
171 }
172
173 void read(const Input& input)
174 {
175 const UnstructuredMesh& mesh = this->getVector().mesh();
176 if (std::holds_alternative<NeoN::Dictionary>(input))
177 {
178 auto dict = std::get<NeoN::Dictionary>(input);
179 std::string schemeName = "div(" + faceFlux_.name + "," + this->getVector().name + ")";
180 auto tokens = dict.subDict("divSchemes").get<NeoN::TokenList>(schemeName);
181 divOperatorStrategy_ =
182 DivOperatorFactory<ValueType>::create(this->exec(), mesh, tokens);
183 }
184 else
185 {
186 auto tokens = std::get<NeoN::TokenList>(input);
187 divOperatorStrategy_ =
188 DivOperatorFactory<ValueType>::create(this->exec(), mesh, tokens);
189 }
190 }
191
192 std::string getName() const { return "DivOperator"; }
193
194private:
195
196 const SurfaceField<NeoN::scalar>& faceFlux_;
197
198 std::unique_ptr<DivOperatorFactory<ValueType>> divOperatorStrategy_;
199};
200
201
202} // namespace NeoN
A factory class for runtime selection of derived classes.
A class representing a list of tokens.
Definition tokenList.hpp:27
Represents an unstructured mesh in NeoN.
A class to contain the data and executors for a field and define some basic operations.
Definition vector.hpp:28
A class that represents a coefficient for the NeoN dsl.
Definition coeff.hpp:22
const Executor exec_
Executor associated with the field. (CPU, GPU, openMP, etc.)
Definition operator.hpp:57
OperatorMixin(const Executor exec, const Coeff &coeffs, VolumeField< ValueType > &field, Operator::Type type)
Definition operator.hpp:35
virtual const Executor & exec() const final
Definition operator.hpp:42
virtual void div(la::LinearSystem< ValueType, localIdx > &ls, const SurfaceField< scalar > &faceFlux, const VolumeField< ValueType > &phi, const dsl::Coeff operatorScaling) const =0
const la::SparsityPattern & getSparsityPattern() const
static std::unique_ptr< DivOperatorFactory< ValueType > > create(const Executor &exec, const UnstructuredMesh &uMesh, const Input &inputs)
virtual void div(Vector< ValueType > &divPhi, const SurfaceField< scalar > &faceFlux, const VolumeField< ValueType > &phi, const dsl::Coeff operatorScaling) const =0
virtual void div(VolumeField< ValueType > &divPhi, const SurfaceField< scalar > &faceFlux, const VolumeField< ValueType > &phi, const dsl::Coeff operatorScaling) const =0
DivOperatorFactory(const Executor &exec, const UnstructuredMesh &mesh)
virtual std::unique_ptr< DivOperatorFactory< ValueType > > clone() const =0
virtual VolumeField< ValueType > div(const SurfaceField< scalar > &faceFlux, const VolumeField< ValueType > &phi, const dsl::Coeff operatorScaling) const =0
la::LinearSystem< ValueType, localIdx > createEmptyLinearSystem() const
DivOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &faceFlux, VolumeField< ValueType > &phi, Input input)
void explicitOperation(Vector< ValueType > &source) const
void div(la::LinearSystem< ValueType, localIdx > &ls) const
DivOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &faceFlux, VolumeField< ValueType > &phi, std::unique_ptr< DivOperatorFactory< ValueType > > divOperatorStrategy)
void implicitOperation(la::LinearSystem< ValueType, localIdx > &ls) const
void div(Vector< ValueType > &divPhi) const
void div(VolumeField< ValueType > &divPhi) const
DivOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &faceFlux, VolumeField< ValueType > &phi)
Represents a surface field in a finite volume method.
Represents a volume field in a finite volume method.
A class representing a linear system of equations.
#define NF_ASSERT(condition, message)
Macro for asserting a condition and printing an error message if the condition is false.
Definition error.hpp:142
std::variant< Dictionary, TokenList > Input
Definition input.hpp:13
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:16
float scalar
Definition scalar.hpp:14