NeoN
WIP Prototype of a modern OpenFOAM core
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) {};
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
72 // Pure virtual function for cloning
73 virtual std::unique_ptr<DivOperatorFactory<ValueType>> clone() const = 0;
74
75protected:
76
78
80};
81
82template<typename ValueType>
83class DivOperator : public dsl::OperatorMixin<VolumeField<ValueType>>
84{
85
86public:
87
88 using VectorValueType = ValueType;
89
90 // copy constructor
92 : dsl::OperatorMixin<VolumeField<ValueType>>(
93 divOp.exec_, divOp.coeffs_, divOp.field_, divOp.type_
94 ),
95 faceFlux_(divOp.faceFlux_),
96 divOperatorStrategy_(
97 divOp.divOperatorStrategy_ ? divOp.divOperatorStrategy_->clone() : nullptr
98 ) {};
99
101 dsl::Operator::Type termType,
102 const SurfaceField<scalar>& faceFlux,
104 Input input
105 )
106 : dsl::OperatorMixin<VolumeField<ValueType>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
107 faceFlux_(faceFlux),
108 divOperatorStrategy_(DivOperatorFactory<ValueType>::create(phi.exec(), phi.mesh(), input)
109 ) {};
110
112 dsl::Operator::Type termType,
113 const SurfaceField<scalar>& faceFlux,
115 std::unique_ptr<DivOperatorFactory<ValueType>> divOperatorStrategy
116 )
117 : dsl::OperatorMixin<VolumeField<scalar>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
118 faceFlux_(faceFlux), divOperatorStrategy_(std::move(divOperatorStrategy)) {};
119
121 dsl::Operator::Type termType,
122 const SurfaceField<scalar>& faceFlux,
124 )
125 : dsl::OperatorMixin<VolumeField<ValueType>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
126 faceFlux_(faceFlux), divOperatorStrategy_(nullptr) {};
127
128
130 {
131 NF_ASSERT(divOperatorStrategy_, "DivOperatorStrategy not initialized");
132 NeoN::Vector<NeoN::scalar> tmpsource(source.exec(), source.size(), 0.0);
133 const auto operatorScaling = this->getCoefficient();
134 divOperatorStrategy_->div(tmpsource, faceFlux_, this->getVector(), operatorScaling);
135 source += tmpsource;
136 }
137
139 {
140 NF_ASSERT(divOperatorStrategy_, "DivOperatorStrategy not initialized");
141 return divOperatorStrategy_->createEmptyLinearSystem();
142 }
143
145 {
146 NF_ASSERT(divOperatorStrategy_, "DivOperatorStrategy not initialized");
147 const auto operatorScaling = this->getCoefficient();
148 divOperatorStrategy_->div(ls, faceFlux_, this->getVector(), operatorScaling);
149 }
150
151 void div(Vector<ValueType>& divPhi) const
152 {
153 const auto operatorScaling = this->getCoefficient();
154 divOperatorStrategy_->div(divPhi, faceFlux_, this->getVector(), operatorScaling);
155 }
156
158 {
159 const auto operatorScaling = this->getCoefficient();
160 divOperatorStrategy_->div(ls, faceFlux_, this->getVector(), operatorScaling);
161 };
162
163 void div(VolumeField<ValueType>& divPhi) const
164 {
165 const auto operatorScaling = this->getCoefficient();
166 divOperatorStrategy_->div(divPhi, faceFlux_, this->getVector(), operatorScaling);
167 }
168
169 void build(const Input& input)
170 {
171 const UnstructuredMesh& mesh = this->getVector().mesh();
172 if (std::holds_alternative<NeoN::Dictionary>(input))
173 {
174 auto dict = std::get<NeoN::Dictionary>(input);
175 std::string schemeName = "div(" + faceFlux_.name + "," + this->getVector().name + ")";
176 auto tokens = dict.subDict("divSchemes").get<NeoN::TokenList>(schemeName);
177 divOperatorStrategy_ =
178 DivOperatorFactory<ValueType>::create(this->exec(), mesh, tokens);
179 }
180 else
181 {
182 auto tokens = std::get<NeoN::TokenList>(input);
183 divOperatorStrategy_ =
184 DivOperatorFactory<ValueType>::create(this->exec(), mesh, tokens);
185 }
186 }
187
188 std::string getName() const { return "DivOperator"; }
189
190private:
191
192 const SurfaceField<NeoN::scalar>& faceFlux_;
193
194 std::unique_ptr<DivOperatorFactory<ValueType>> divOperatorStrategy_;
195};
196
197
198} // 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:53
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:34
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
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 implicitOperation(la::LinearSystem< ValueType, localIdx > &ls)
void explicitOperation(Vector< scalar > &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 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