NeoN
WIP Prototype of a modern OpenFOAM core
Loading...
Searching...
No Matches
temporalOperator.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2023-2025 NeoN authors
3#pragma once
4
5#include <memory>
6#include <concepts>
7
11#include "NeoN/core/input.hpp"
12#include "NeoN/dsl/coeff.hpp"
13#include "NeoN/dsl/operator.hpp"
14
15namespace NeoN::dsl
16{
17
18template<typename T>
19concept HasTemporalExplicitOperator = requires(T t) {
20 {
21 t.explicitOperation(
22 std::declval<Vector<typename T::VectorValueType>&>(),
23 std::declval<NeoN::scalar>(),
24 std::declval<NeoN::scalar>()
25 )
26 } -> std::same_as<void>; // Adjust return type and arguments as needed
27};
28
29template<typename T>
30concept HasTemporalImplicitOperator = requires(T t) {
31 {
32 t.implicitOperation(
33 std::declval<la::LinearSystem<typename T::VectorValueType, localIdx>&>(),
34 std::declval<NeoN::scalar>(),
35 std::declval<NeoN::scalar>()
36 )
37 } -> std::same_as<void>; // Adjust return type and arguments as needed
38};
39
40template<typename T>
42
43/* @class TemporalOperator
44 * @brief A class to represent a TemporalOperator in NeoNs DSL
45 *
46 * The design here is based on the type erasure design pattern
47 * see https://www.youtube.com/watch?v=4eeESJQk-mw
48 *
49 * Motivation for using type erasure is that concrete implementation
50 * of TemporalOperator e.g Divergence, Laplacian, etc can be stored in a vector of
51 * TemporalOperator
52 *
53 * @ingroup dsl
54 */
55template<typename ValueType>
57{
58public:
59
60 using VectorValueType = ValueType;
61
62 template<HasTemporalOperator T>
63 TemporalOperator(T cls) : model_(std::make_unique<TemporalOperatorModel<T>>(std::move(cls)))
64 {}
65
66 TemporalOperator(const TemporalOperator& eqnOperator) : model_ {eqnOperator.model_->clone()} {}
67
68 TemporalOperator(TemporalOperator&& eqnOperator) : model_ {std::move(eqnOperator.model_)} {}
69
71 {
72 model_->explicitOperation(source, t, dt);
73 }
74
76 {
77 model_->implicitOperation(ls, t, dt);
78 }
79
80 /* returns the fundamental type of an operator, ie explicit, implicit */
81 Operator::Type getType() const { return model_->getType(); }
82
83 std::string getName() const { return model_->getName(); }
84
85 Coeff& getCoefficient() { return model_->getCoefficient(); }
86
87 Coeff getCoefficient() const { return model_->getCoefficient(); }
88
89 /* @brief Given an input this function reads required coeffs */
90 void build(const Input& input) { model_->build(input); }
91
92 /* @brief Get the executor */
93 const Executor& exec() const { return model_->exec(); }
94
95
96private:
97
98 /* @brief Base class defining the concept of a term. This effectively
99 * defines what functions need to be implemented by a concrete Operator implementation
100 * */
101 struct TemporalOperatorConcept
102 {
103 virtual ~TemporalOperatorConcept() = default;
104
105 virtual void explicitOperation(Vector<ValueType>& source, scalar t, scalar dt) = 0;
106
107 virtual void
108 implicitOperation(la::LinearSystem<ValueType, localIdx>& ls, scalar t, scalar dt) = 0;
109
110 /* @brief Given an input this function reads required coeffs */
111 virtual void build(const Input& input) = 0;
112
113 /* returns the name of the operator */
114 virtual std::string getName() const = 0;
115
116 /* returns the fundamental type of an operator, ie explicit, implicit, temporal */
117 virtual Operator::Type getType() const = 0;
118
119 /* @brief get the associated coefficient for this term */
120 virtual Coeff& getCoefficient() = 0;
121
122 /* @brief get the associated coefficient for this term */
123 virtual Coeff getCoefficient() const = 0;
124
125 /* @brief Get the executor */
126 virtual const Executor& exec() const = 0;
127
128 // The Prototype Design Pattern
129 virtual std::unique_ptr<TemporalOperatorConcept> clone() const = 0;
130 };
131
132 // Templated derived class to implement the type-specific behavior
133 template<typename ConcreteTemporalOperatorType>
134 struct TemporalOperatorModel : TemporalOperatorConcept
135 {
136 /* @brief build with concrete TemporalOperator */
137 TemporalOperatorModel(ConcreteTemporalOperatorType concreteOp)
138 : concreteOp_(std::move(concreteOp))
139 {}
140
141 /* returns the name of the operator */
142 std::string getName() const override { return concreteOp_.getName(); }
143
144 virtual void explicitOperation(Vector<ValueType>& source, scalar t, scalar dt) override
145 {
146 if constexpr (HasTemporalExplicitOperator<ConcreteTemporalOperatorType>)
147 {
148 concreteOp_.explicitOperation(source, t, dt);
149 }
150 }
151
152 virtual void
153 implicitOperation(la::LinearSystem<ValueType, localIdx>& ls, scalar t, scalar dt) override
154 {
155 if constexpr (HasTemporalImplicitOperator<ConcreteTemporalOperatorType>)
156 {
157 concreteOp_.implicitOperation(ls, t, dt);
158 }
159 }
160
161 /* @brief Given an input this function reads required coeffs */
162 virtual void build(const Input& input) override { concreteOp_.build(input); }
163
164 /* returns the fundamental type of an operator, ie explicit, implicit, temporal */
165 Operator::Type getType() const override { return concreteOp_.getType(); }
166
167 /* @brief Get the executor */
168 const Executor& exec() const override { return concreteOp_.exec(); }
169
170 /* @brief get the associated coefficient for this term */
171 virtual Coeff& getCoefficient() override { return concreteOp_.getCoefficient(); }
172
173 /* @brief get the associated coefficient for this term */
174 virtual Coeff getCoefficient() const override { return concreteOp_.getCoefficient(); }
175
176 // The Prototype Design Pattern
177 std::unique_ptr<TemporalOperatorConcept> clone() const override
178 {
179 return std::make_unique<TemporalOperatorModel>(*this);
180 }
181
182 ConcreteTemporalOperatorType concreteOp_;
183 };
184
185 std::unique_ptr<TemporalOperatorConcept> model_;
186};
187
188
189template<typename ValueType>
191{
192 TemporalOperator<ValueType> result = rhs;
193 result.getCoefficient() *= scalarCoeff;
194 return result;
195}
196
197template<typename ValueType>
198TemporalOperator<ValueType>
200{
201 TemporalOperator<ValueType> result = rhs;
202 result.getCoefficient() *= Coeff {coeffVector};
203 return result;
204}
205
206template<typename ValueType>
208{
209 TemporalOperator<ValueType> result = rhs;
210 result.getCoefficient() *= coeff;
211 return result;
212}
213
214
215} // namespace NeoN::dsl
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
TemporalOperator(const TemporalOperator &eqnOperator)
Operator::Type getType() const
const Executor & exec() const
void implicitOperation(la::LinearSystem< ValueType, localIdx > &ls, scalar t, scalar dt)
TemporalOperator(TemporalOperator &&eqnOperator)
void build(const Input &input)
void explicitOperation(Vector< ValueType > &source, scalar t, scalar dt) const
A class representing a linear system of equations.
Coeff operator*(const Coeff &lhs, const Coeff &rhs)
Definition coeff.hpp:57
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