NeoFOAM
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 NeoFOAM authors
3#pragma once
4
5#include <memory>
6#include <concepts>
7
12#include "NeoFOAM/dsl/coeff.hpp"
14
15namespace la = NeoFOAM::la;
16
17namespace NeoFOAM::dsl
18{
19
20
21template<typename T>
22concept HasTemporalExplicitOperator = requires(T t) {
23 {
24 t.explicitOperation(
25 std::declval<Field<typename T::FieldValueType>&>(),
26 std::declval<NeoFOAM::scalar>(),
27 std::declval<NeoFOAM::scalar>()
28 )
29 } -> std::same_as<void>; // Adjust return type and arguments as needed
30};
31
32template<typename T>
33concept HasTemporalImplicitOperator = requires(T t) {
34 {
35 t.implicitOperation(
37 std::declval<NeoFOAM::scalar>(),
38 std::declval<NeoFOAM::scalar>()
39 )
40 } -> std::same_as<void>; // Adjust return type and arguments as needed
41};
42
43template<typename T>
45
46/* @class TemporalOperator
47 * @brief A class to represent an TemporalOperator in NeoFOAMs dsl
48 *
49 * The design here is based on the type erasure design pattern
50 * see https://www.youtube.com/watch?v=4eeESJQk-mw
51 *
52 * Motivation for using type erasure is that concrete implementation
53 * of TemporalOperator e.g Divergence, Laplacian, etc can be stored in a vector of
54 * TemporalOperator
55 *
56 * @ingroup dsl
57 */
58template<typename ValueType>
60{
61public:
62
63 using FieldValueType = ValueType;
64
65 template<HasTemporalOperator T>
66 TemporalOperator(T cls) : model_(std::make_unique<TemporalOperatorModel<T>>(std::move(cls)))
67 {}
68
69 TemporalOperator(const TemporalOperator& eqnOperator) : model_ {eqnOperator.model_->clone()} {}
70
71 TemporalOperator(TemporalOperator&& eqnOperator) : model_ {std::move(eqnOperator.model_)} {}
72
74 {
75 model_->explicitOperation(source, t, dt);
76 }
77
79 {
80 model_->implicitOperation(ls, t, dt);
81 }
82
84 {
85 return model_->createEmptyLinearSystem();
86 }
87
88 /* returns the fundamental type of an operator, ie explicit, implicit */
89 Operator::Type getType() const { return model_->getType(); }
90
91 std::string getName() const { return model_->getName(); }
92
93 Coeff& getCoefficient() { return model_->getCoefficient(); }
94
95 Coeff getCoefficient() const { return model_->getCoefficient(); }
96
97 /* @brief Given an input this function reads required coeffs */
98 void build(const Input& input) { model_->build(input); }
99
100 /* @brief Get the executor */
101 const Executor& exec() const { return model_->exec(); }
102
103
104private:
105
106 /* @brief Base class defining the concept of a term. This effectively
107 * defines what functions need to be implemented by a concrete Operator implementation
108 * */
109 struct TemporalOperatorConcept
110 {
111 virtual ~TemporalOperatorConcept() = default;
112
113 virtual void explicitOperation(Field<ValueType>& source, scalar t, scalar dt) = 0;
114
115 virtual void
116 implicitOperation(la::LinearSystem<ValueType, localIdx>& ls, scalar t, scalar dt) = 0;
117
118 virtual la::LinearSystem<ValueType, localIdx> createEmptyLinearSystem() const = 0;
119
120 /* @brief Given an input this function reads required coeffs */
121 virtual void build(const Input& input) = 0;
122
123 /* returns the name of the operator */
124 virtual std::string getName() const = 0;
125
126 /* returns the fundamental type of an operator, ie explicit, implicit, temporal */
127 virtual Operator::Type getType() const = 0;
128
129 /* @brief get the associated coefficient for this term */
130 virtual Coeff& getCoefficient() = 0;
131
132 /* @brief get the associated coefficient for this term */
133 virtual Coeff getCoefficient() const = 0;
134
135 /* @brief Get the executor */
136 virtual const Executor& exec() const = 0;
137
138 // The Prototype Design Pattern
139 virtual std::unique_ptr<TemporalOperatorConcept> clone() const = 0;
140 };
141
142 // Templated derived class to implement the type-specific behavior
143 template<typename ConcreteTemporalOperatorType>
144 struct TemporalOperatorModel : TemporalOperatorConcept
145 {
146 /* @brief build with concrete TemporalOperator */
147 TemporalOperatorModel(ConcreteTemporalOperatorType concreteOp)
148 : concreteOp_(std::move(concreteOp))
149 {}
150
151 /* returns the name of the operator */
152 std::string getName() const override { return concreteOp_.getName(); }
153
154 virtual void explicitOperation(Field<ValueType>& source, scalar t, scalar dt) override
155 {
156 if constexpr (HasTemporalExplicitOperator<ConcreteTemporalOperatorType>)
157 {
158 concreteOp_.explicitOperation(source, t, dt);
159 }
160 }
161
162 virtual void
163 implicitOperation(la::LinearSystem<ValueType, localIdx>& ls, scalar t, scalar dt) override
164 {
165 if constexpr (HasTemporalImplicitOperator<ConcreteTemporalOperatorType>)
166 {
167 concreteOp_.implicitOperation(ls, t, dt);
168 }
169 }
170
171 virtual la::LinearSystem<ValueType, localIdx> createEmptyLinearSystem() const override
172 {
173 // if constexpr (HasTemporalImplicitOperator<ConcreteTemporalOperatorType>)
174 // {
175 return concreteOp_.createEmptyLinearSystem();
176 // }
177 throw std::runtime_error("Implicit operation not implemented");
178 // only need to avoid compiler warning about missing return statement
179 // this code path should never be reached as we call implicitOperation on an explicit
180 // operator
181 NeoFOAM::Field<ValueType> values(exec(), 1, zero<ValueType>());
182 NeoFOAM::Field<NeoFOAM::localIdx> colIdx(exec(), 1, 0);
183 NeoFOAM::Field<NeoFOAM::localIdx> rowPtrs(exec(), 2, 0);
184 NeoFOAM::la::CSRMatrix<ValueType, NeoFOAM::localIdx> csrMatrix(values, colIdx, rowPtrs);
185
186 NeoFOAM::Field<ValueType> rhs(exec(), 1, zero<ValueType>());
187 return la::LinearSystem<ValueType, localIdx>(csrMatrix, rhs, "custom");
188 }
189
190 /* @brief Given an input this function reads required coeffs */
191 virtual void build(const Input& input) override { concreteOp_.build(input); }
192
193 /* returns the fundamental type of an operator, ie explicit, implicit, temporal */
194 Operator::Type getType() const override { return concreteOp_.getType(); }
195
196 /* @brief Get the executor */
197 const Executor& exec() const override { return concreteOp_.exec(); }
198
199 /* @brief get the associated coefficient for this term */
200 virtual Coeff& getCoefficient() override { return concreteOp_.getCoefficient(); }
201
202 /* @brief get the associated coefficient for this term */
203 virtual Coeff getCoefficient() const override { return concreteOp_.getCoefficient(); }
204
205 // The Prototype Design Pattern
206 std::unique_ptr<TemporalOperatorConcept> clone() const override
207 {
208 return std::make_unique<TemporalOperatorModel>(*this);
209 }
210
211 ConcreteTemporalOperatorType concreteOp_;
212 };
213
214 std::unique_ptr<TemporalOperatorConcept> model_;
215};
216
217
218template<typename ValueType>
220{
221 TemporalOperator<ValueType> result = rhs;
222 result.getCoefficient() *= scalarCoeff;
223 return result;
224}
225
226template<typename ValueType>
227TemporalOperator<ValueType>
229{
230 TemporalOperator<ValueType> result = rhs;
231 result.getCoefficient() *= Coeff(coeffField);
232 return result;
233}
234
235template<typename ValueType>
237{
238 TemporalOperator<ValueType> result = rhs;
239 result.getCoefficient() *= coeff;
240 return result;
241}
242
243// template<typename CoeffFunction>
244// requires std::invocable<CoeffFunction&, size_t>
245// TemporalOperator<ValueType> operator*([[maybe_unused]] CoeffFunction coeffFunc, const
246// TemporalOperator<ValueType>& lhs)
247// {
248// // TODO implement
249// NF_ERROR_EXIT("Not implemented");
250// TemporalOperator result = lhs;
251// // if (!result.getCoefficient().useSpan)
252// // {
253// // result.setField(std::make_shared<Field<scalar>>(result.exec(), result.nCells(), 1.0));
254// // }
255// // map(result.exec(), result.getCoefficient().values, scaleFunc);
256// return result;
257// }
258
259
260} // namespace NeoFOAM::dsl
A class to contain the data and executors for a field and define some basic operations.
Definition field.hpp:49
A class that represents a coefficient for the NeoFOAM dsl.
Definition coeff.hpp:22
la::LinearSystem< ValueType, localIdx > createEmptyLinearSystem() const
void explicitOperation(Field< ValueType > &source, scalar t, scalar dt)
TemporalOperator(TemporalOperator &&eqnOperator)
void implicitOperation(la::LinearSystem< ValueType, localIdx > &ls, scalar t, scalar dt)
TemporalOperator(const TemporalOperator &eqnOperator)
const Executor & exec() const
void build(const Input &input)
A class representing a linear system of equations.
Coeff operator*(const Coeff &lhs, const Coeff &rhs)
Definition coeff.hpp:57
float scalar
Definition scalar.hpp:14
std::variant< Dictionary, TokenList > Input
Definition input.hpp:13
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:16