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