OpenLB 1.7
Loading...
Searching...
No Matches
expr.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 Adrian Kummerlaender
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef UTILITIES_EXPR_H
25#define UTILITIES_EXPR_H
26
27#include <string>
28#include <sstream>
29#include <memory>
30#include <variant>
31
32#include "core/meta.h"
33#include "core/cellD.h"
34
35namespace olb {
36
38class Expr : public ExprBase {
39public:
40 enum struct Op {
41 Add, Mul, Sub, Div, Sqrt, Abs, Pow, Exp
42 };
43
44private:
45 struct Symbol {
46 std::string name;
47 std::string describe() const {
48 return name;
49 }
50 };
51
52 struct Constant {
53 double value;
54 std::string describe() const {
55 return std::to_string(value);
56 }
57 };
58
59 class Binary {
60 private:
61 std::shared_ptr<Expr> lhs;
62 Op op;
63 std::shared_ptr<Expr> rhs;
64
65 public:
66 Binary(Expr lhs, Op op, Expr rhs):
67 lhs{std::make_shared<Expr>(lhs)},
68 op{op},
69 rhs{std::make_shared<Expr>(rhs)} { }
70
71 std::string describe() const {
72 switch (op) {
73 case Op::Add: return "(" + lhs->describe() + ") + (" + rhs->describe() + ")";
74 case Op::Sub: return "(" + lhs->describe() + ") - (" + rhs->describe() + ")";
75 case Op::Mul: return "(" + lhs->describe() + ") * (" + rhs->describe() + ")";
76 case Op::Div: return "(" + lhs->describe() + ") / (" + rhs->describe() + ")";
77 case Op::Pow: return "Pow(" + lhs->describe() + "," + rhs->describe() + ")";
78 default: throw std::invalid_argument("Unsupported binary operation");
79 }
80 }
81 };
82
83 class Unary {
84 private:
85 Op op;
86 std::shared_ptr<Expr> arg;
87
88 public:
89 Unary(Op op, Expr arg):
90 op{op},
91 arg{std::make_shared<Expr>(arg)} { }
92
93 std::string describe() const {
94 switch (op) {
95 case Op::Sqrt: return "sqrt(" + arg->describe() + ")";
96 case Op::Abs: return "Abs(" + arg->describe() + ")";
97 case Op::Exp: return "exp(" + arg->describe() + ")";
98 default: throw std::invalid_argument("Unsupported unary operation");
99 }
100 }
101 };
102
103 std::variant<Symbol,Constant,Binary,Unary> _payload;
104
105public:
106 Expr(const Expr& rhs):
107 _payload(rhs._payload) { }
108
109 Expr(double v):
110 _payload(Constant{v}) { }
111
113 Expr(double{}) { }
114
115 Expr(std::string name):
116 _payload(Symbol{name}) { }
117
118 Expr(Expr lhs, Op op, Expr rhs):
119 _payload(Binary(lhs, op, rhs)) { }
120
121 Expr(Op op, Expr rhs):
122 _payload(Unary(op, rhs)) { }
123
124 std::string describe() const {
125 std::string out;
126 std::visit([&out](auto& x) {
127 out = x.describe();
128 }, _payload);
129 return out;
130 };
131
132 Expr& operator+=(Expr rhs);
133 Expr& operator-=(Expr rhs);
134 Expr& operator*=(Expr rhs);
135 Expr& operator/=(Expr rhs);
136};
137
139 _payload = Binary(*this, Op::Add, rhs);
140 return *this;
141}
142
144 _payload = Binary(*this, Op::Sub, rhs);
145 return *this;
146}
147
149 _payload = Binary(*this, Op::Mul, rhs);
150 return *this;
151}
152
154 _payload = Binary(*this, Op::Div, rhs);
155 return *this;
156}
157
159 return Expr(lhs, Expr::Op::Add, rhs);
160}
161
163 return Expr(lhs, Expr::Op::Sub, rhs);
164}
165
167 return Expr(lhs, Expr::Op::Mul, rhs);
168}
169
171 return Expr(lhs, Expr::Op::Div, rhs);
172}
173
175 return Expr(-1.) * rhs;
176}
177
178namespace util {
179
181 return Expr(Expr::Op::Sqrt, x);
182}
183
185 return Expr(Expr::Op::Abs, x);
186}
187
189 return Expr(base, Expr::Op::Pow, exp);
190}
191
193 return Expr(Expr::Op::Exp, x);
194}
195
196}
197
198}
199
200#endif
Basic value-substitute enabling extraction of expression trees for code generation.
Definition expr.h:38
std::string describe() const
Definition expr.h:124
Expr & operator*=(Expr rhs)
Definition expr.h:148
Expr(const Expr &rhs)
Definition expr.h:106
Expr(double v)
Definition expr.h:109
Expr(std::string name)
Definition expr.h:115
Expr(Expr lhs, Op op, Expr rhs)
Definition expr.h:118
Expr & operator-=(Expr rhs)
Definition expr.h:143
Expr & operator/=(Expr rhs)
Definition expr.h:153
Expr(Op op, Expr rhs)
Definition expr.h:121
Expr()
Definition expr.h:112
Expr & operator+=(Expr rhs)
Definition expr.h:138
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
cpu::simd::Pack< T > fabs(cpu::simd::Pack< T > value)
Definition pack.h:106
ADf< T, DIM > exp(const ADf< T, DIM > &a)
Definition aDiff.h:455
Top level namespace for all of OpenLB.
constexpr meta::enable_if_arithmetic_t< U, Vector< T, D > > operator-(U a, const ScalarVector< T, D, IMPL > &b) any_platform
Definition vector.h:297
constexpr meta::enable_if_arithmetic_t< U, Vector< T, D > > operator+(U a, const ScalarVector< T, D, IMPL > &b) any_platform
Definition vector.h:265
constexpr meta::enable_if_arithmetic_t< U, Vector< decltype(T{} *U{}), D > > operator*(U a, const ScalarVector< T, D, IMPL > &b) any_platform
Definition vector.h:329
constexpr meta::enable_if_arithmetic_t< U, Vector< T, D > > operator/(const ScalarVector< T, D, IMPL > &a, U b) any_platform
Definition vector.h:357