Loading...
Searching...
No Matches
GenericExpression.H
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2025 M. Janssens
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26Namespace
27 Foam::Expression
28
29Description
30 A namespace for expression templates
31
32\*---------------------------------------------------------------------------*/
33
34#ifndef Foam_GenericExpression_H
35#define Foam_GenericExpression_H
36
37#include <cassert>
38
39// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40
41namespace Foam
42{
43namespace Expression
44{
46/*---------------------------------------------------------------------------*\
47 Class GenericExpression Declaration
48\*---------------------------------------------------------------------------*/
49
50template<typename E>
52{
53public:
54 static constexpr bool is_leaf = false;
55
56 auto evaluate() const
57 {
58 // Delegation to the actual expression type. This avoids dynamic
59 // polymorphism (a.k.a. virtual functions in C++)
60 return static_cast<E const&>(*this).evaluate();
61 }
62};
64
65// Macros
66// ~~~~~~
67
68#undef EXPRESSION_FUNCTION1
69#define EXPRESSION_FUNCTION1(BaseClass, Func, BaseFunc, OpFunc) \
70template<typename E1> \
71class OpFunc \
72: \
73 public BaseClass<OpFunc<E1>> \
74{ \
75 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
76 \
77public: \
78 static constexpr bool is_leaf = false; \
79 \
80 OpFunc(const E1& u) \
81 : \
82 u_(u) \
83 {} \
84 \
85 auto evaluate() const \
86 { \
87 return BaseFunc(u_.evaluate()); \
88 } \
89}; \
90template<typename E1> \
91OpFunc<E1> Func \
92( \
93 const BaseClass<E1>& u \
94) \
95{ \
96 return OpFunc<E1>(static_cast<const E1&>(u)); \
97}
98
99
100#undef EXPRESSION_FUNCTION2
101#define EXPRESSION_FUNCTION2(BaseClass, Func, BaseFunc, OpFunc) \
102template<typename E1, typename E2> \
103class OpFunc \
104: \
105 public BaseClass<OpFunc<E1, E2>> \
106{ \
107 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
108 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_; \
109 \
110public: \
111 static constexpr bool is_leaf = false; \
112 \
113 OpFunc(const E1& u, const E2& v) \
114 : \
115 u_(u), v_(v) \
116 {} \
117 auto evaluate() const \
118 { \
119 return BaseFunc(u_.evaluate(), v_.evaluate()); \
120 } \
121}; \
122template<typename E1, typename E2> \
123OpFunc<E1, E2> Func \
124( \
125 const BaseClass<E1>& u, \
126 const BaseClass<E2>& v \
127) \
128{ \
129 return OpFunc<E1, E2> \
130 ( \
131 static_cast<const E1&>(u), \
132 static_cast<const E2&>(v) \
133 ); \
134}
135
136
137#undef EXPRESSION_OPERATOR
138#define EXPRESSION_OPERATOR(BaseClass, Op, BaseOp, OpFunc) \
139template<typename E1, typename E2> \
140class OpFunc \
141: \
142 public BaseClass \
143 < \
144 OpFunc<E1, E2> \
145 > \
146{ \
147 /* cref if leaf, copy otherwise */ \
148 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
149 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_; \
150 \
151public: \
152 static constexpr bool is_leaf = false; \
153 \
154 OpFunc(const E1& u, const E2& v) \
155 : \
156 u_(u), v_(v) \
157 {} \
158 auto evaluate() const \
159 { \
160 return u_.evaluate() BaseOp v_.evaluate(); \
161 } \
162}; \
163template<typename E1, typename E2> \
164OpFunc<E1, E2> \
165operator Op \
166( \
167 BaseClass<E1> const& u, \
168 BaseClass<E2> const& v \
169) \
170{ \
171 return OpFunc<E1, E2> \
172 ( \
173 static_cast<const E1&>(u), \
174 static_cast<const E2&>(v) \
175 ); \
176}
177
178
179// Do '-' separately until we work out macro expansion...
180template<typename E1>
181class g_negate
182:
183 public GenericExpression
184 <
185 g_negate<E1>
186 >
188 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_;
189
190public:
191 static constexpr bool is_leaf = false;
193 g_negate(const E1& u)
194 :
195 u_(u)
196 {}
197
198 auto evaluate() const
199 {
200 return -u_.evaluate();
201 }
202};
203template<typename E1>
204g_negate<E1> operator-
205(
206 const GenericExpression<E1>& u
209 return g_negate<E1>(static_cast<const E1&>(u));
220EXPRESSION_FUNCTION1(GenericExpression, operator~, Foam::operator~, g_compl)
222//TBD. Parse problem
223//EXPRESSION_FUNCTION1(GenericExpression, operator!, Foam::operator!, g_not)
225#undef EXPRESSION_FUNCTION1
226
227EXPRESSION_FUNCTION2(GenericExpression, operator+, Foam::operator+, g_add);
230EXPRESSION_FUNCTION2(GenericExpression, operator/, Foam::operator/, g_divide);
232#undef EXPRESSION_FUNCTION2
233
239
240#undef EXPRESSION_OPERATOR
241
242// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
243
244} // End namespace Expression
245} // End namespace Foam
246
247// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
248
249#endif
250
251// ************************************************************************* //
#define EXPRESSION_OPERATOR(BaseClass, Op, BaseOp, OpFunc)
#define EXPRESSION_FUNCTION2(BaseClass, Func, BaseFunc, OpFunc)
#define EXPRESSION_FUNCTION1(BaseClass, Func, BaseFunc, OpFunc)
g_add(const E1 &u, const E2 &v)
g_and(const E1 &u, const E2 &v)
g_bitand(const E1 &u, const E2 &v)
g_bitor(const E1 &u, const E2 &v)
g_divide(const E1 &u, const E2 &v)
g_multiply(const E1 &u, const E2 &v)
static constexpr bool is_leaf
g_or(const E1 &u, const E2 &v)
g_subtract(const E1 &u, const E2 &v)
g_xor(const E1 &u, const E2 &v)
A namespace for expression templates.
g_pow2< E1 > pow2(const GenericExpression< E1 > &u)
g_sqrt< E1 > sqrt(const GenericExpression< E1 > &u)
g_sqr< E1 > sqr(const GenericExpression< E1 > &u)
g_pow4< E1 > pow4(const GenericExpression< E1 > &u)
g_symm< E1 > symm(const GenericExpression< E1 > &u)
g_pow3< E1 > pow3(const GenericExpression< E1 > &u)
g_magSqr< E1 > magSqr(const GenericExpression< E1 > &u)
Namespace for OpenFOAM.
dimensionedSymmTensor sqr(const dimensionedVector &dv)