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 virtual void
49 const SurfaceField<scalar>& faceFlux,
50 const VolumeField<ValueType>& phi,
51 const dsl::Coeff operatorScaling) const = 0;
52
53 virtual void
55 const SurfaceField<scalar>& faceFlux,
56 const VolumeField<ValueType>& phi,
57 const dsl::Coeff operatorScaling) const = 0;
58
59 virtual void
61 const SurfaceField<scalar>& faceFlux,
62 const VolumeField<ValueType>& phi,
63 const dsl::Coeff operatorScaling) const = 0;
64
66 div(const SurfaceField<scalar>& faceFlux,
67 const VolumeField<ValueType>& phi,
68 const dsl::Coeff operatorScaling) const = 0;
69
70 [[deprecated("This function will be removed")]] const la::SparsityPattern&
72 {
73 return sparsityPattern_;
74 }
75
76 // Pure virtual function for cloning
77 virtual std::unique_ptr<DivOperatorFactory<ValueType>> clone() const = 0;
78
79protected:
80
82
84
86};
87
88template<typename ValueType>
89class DivOperator : public dsl::OperatorMixin<VolumeField<ValueType>>
90{
91
92public:
93
94 using VectorValueType = ValueType;
95
96 // copy constructor
98 : dsl::OperatorMixin<VolumeField<ValueType>>(
99 divOp.exec_, divOp.coeffs_, divOp.field_, divOp.type_
100 ),
101 faceFlux_(divOp.faceFlux_),
102 divOperatorStrategy_(
103 divOp.divOperatorStrategy_ ? divOp.divOperatorStrategy_->clone() : nullptr
104 ) {};
105
107 dsl::Operator::Type termType,
108 const SurfaceField<scalar>& faceFlux,
109 const VolumeField<ValueType>& phi,
110 Input input
111 )
112 : dsl::OperatorMixin<VolumeField<ValueType>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
113 faceFlux_(faceFlux),
114 divOperatorStrategy_(DivOperatorFactory<ValueType>::create(phi.exec(), phi.mesh(), input)
115 ) {};
116
118 dsl::Operator::Type termType,
119 const SurfaceField<scalar>& faceFlux,
120 const VolumeField<ValueType>& phi,
121 std::unique_ptr<DivOperatorFactory<ValueType>> divOperatorStrategy
122 )
123 : dsl::OperatorMixin<VolumeField<scalar>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
124 faceFlux_(faceFlux), divOperatorStrategy_(std::move(divOperatorStrategy)) {};
125
127 dsl::Operator::Type termType,
128 const SurfaceField<scalar>& faceFlux,
129 const VolumeField<ValueType>& phi
130 )
131 : dsl::OperatorMixin<VolumeField<ValueType>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
132 faceFlux_(faceFlux), divOperatorStrategy_(nullptr) {};
133
134
136 {
137 NF_ASSERT(divOperatorStrategy_, "DivOperatorStrategy not initialized");
138 auto tmpsource = Vector<ValueType>(source.exec(), source.size(), zero<ValueType>());
139 const auto operatorScaling = this->getCoefficient();
140 divOperatorStrategy_->div(tmpsource, faceFlux_, this->getVector(), operatorScaling);
141 source += tmpsource;
142 }
143
145 {
146 NF_ASSERT(divOperatorStrategy_, "DivOperatorStrategy not initialized");
147 return divOperatorStrategy_->createEmptyLinearSystem();
148 }
149
151 {
152 NF_ASSERT(divOperatorStrategy_, "DivOperatorStrategy not initialized");
153 const auto operatorScaling = this->getCoefficient();
154 divOperatorStrategy_->div(ls, faceFlux_, this->getVector(), operatorScaling);
155 }
156
157 [[deprecated("use explicit or implicit operation")]] void div(auto&&... args) const
158 {
159 const auto operatorScaling = this->getCoefficient();
160 divOperatorStrategy_->div(
161 std::forward<decltype(args)>(args)..., faceFlux_, this->getVector(), operatorScaling
162 );
163 }
164
165 void read(const Input& input)
166 {
167 const UnstructuredMesh& mesh = this->getVector().mesh();
168 if (std::holds_alternative<NeoN::Dictionary>(input))
169 {
170 auto dict = std::get<NeoN::Dictionary>(input);
171 std::string schemeName = "div(" + faceFlux_.name + "," + this->getVector().name + ")";
172 auto tokens = dict.subDict("divSchemes").get<NeoN::TokenList>(schemeName);
173 divOperatorStrategy_ =
174 DivOperatorFactory<ValueType>::create(this->exec(), mesh, tokens);
175 }
176 else
177 {
178 auto tokens = std::get<NeoN::TokenList>(input);
179 divOperatorStrategy_ =
180 DivOperatorFactory<ValueType>::create(this->exec(), mesh, tokens);
181 }
182 }
183
184 std::string getName() const { return "DivOperator"; }
185
186private:
187
188 const SurfaceField<NeoN::scalar>& faceFlux_;
189
190 std::unique_ptr<DivOperatorFactory<ValueType>> divOperatorStrategy_;
191};
192
193
194} // 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 VolumeField< ValueType > & field_
Definition operator.hpp:68
const Executor exec_
Executor associated with the field. (CPU, GPU, openMP, etc.)
Definition operator.hpp:64
OperatorMixin(const Executor exec, const Coeff &coeffs, const VolumeField< ValueType > &field, Operator::Type type)
Definition operator.hpp:41
const VolumeField< ValueType > & getVector() const
Definition operator.hpp:57
virtual const Executor & exec() const final
Definition operator.hpp:51
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, const VolumeField< ValueType > &phi, std::unique_ptr< DivOperatorFactory< ValueType > > divOperatorStrategy)
void explicitOperation(Vector< ValueType > &source) const
DivOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &faceFlux, const VolumeField< ValueType > &phi)
void implicitOperation(la::LinearSystem< ValueType, localIdx > &ls) const
DivOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &faceFlux, const VolumeField< ValueType > &phi, Input input)
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