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