OpenLB 1.7
Loading...
Searching...
No Matches
projection.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2012-13, 2016, 2023-24 Mathias J. Krause, Lukas Baron,
4 * Benjamin Förster, Julius Jeßberger
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23*/
24
25
26// This file contains projections which can be used to rescale control variables.
27
28#ifndef PROJECTION_H
29#define PROJECTION_H
30
31#include <regex>
32
33#include "core/unitConverter.h"
34
35
36// All OpenLB code is contained in this namespace.
37namespace olb {
38
40namespace opti {
41
43
44namespace projection {
45
46template <typename T>
47struct Base {
48
49 virtual T project(T) const = 0;
50 virtual T derivative(T) const = 0;
51 virtual T inverse(T) const = 0;
52};
53
54template <typename T>
55struct Identity : public Base<T> {
56
57 T project(T x) const override { return x; }
58 T derivative(T x) const override { return 1; }
59 T inverse(T x) const override { return x; }
60};
61
62template <typename T>
63struct Sigmoid : public Base<T> {
64
65 T project(T x) const override { return util::exp(x) / ( util::exp(x) + T(1) ); }
66 T derivative(T x) const override { return util::exp(x) / util::pow( util::exp(x) + T(1), 2 ); }
67 T inverse(T x) const override { return -util::log(T(1)/x - T(1)); }
68};
69
71template <typename T>
72struct ForceFactor : public Base<T> {
73
74 const T scale;
75
76 template <typename DESCRIPTOR>
78 : scale {converter.getConversionFactorMass() / converter.getConversionFactorForce()}
79 { }
80
81 T project(T x) const override { return scale * x; }
82 T derivative(T x) const override { return scale; }
83 T inverse(T x) const override { return x / scale; }
84};
85
86template <typename T>
87struct Rectifier : public Base<T> {
88
89 T project(T x) const override { return T(1) - T(1)/util::max( T(1), x ); }
90 T derivative(T x) const override { return (x >= T(1) ? T(1)/(x*x) : T(0)); }
91 T inverse(T x) const override { return T(1)/(T(1)-x); }
92};
93
94template <typename T>
95struct Softplus : public Base<T> {
96
97 T project(T x) const override { return T(1) - T(1)/(util::log(T(1)+util::exp(x))+T(1)); }
98 T derivative(T x) const override { return util::exp(x)
99 / ((util::exp(x)+T(1))*(util::log(T(1)+util::exp(x))+T(1))*(util::log(T(1)+util::exp(x))+T(1))); }
100 T inverse(T x) const override { return util::log(util::exp(x/(T(1)-x))-T(1)); }
101};
102
103template <typename T>
104struct Baron : public Base<T> {
105
106 const T pi {T(4) * util::atan(T(1))};
107
108 T project(T x) const override {
109 const T y = T(0.5) + T(0.5) * util::sin((x-T(0.5))*pi);
110 return y*y;
111 }
112 T derivative(T x) const override {
113 return (T(1) + util::sin((x-T(0.5))*pi))
114 * util::cos((x-T(0.5))*pi)
115 * pi * T(0.5);
116 }
117 T inverse(T x) const override {
118 return T(0.5) + util::asin(T(2)*x-T(1)) / pi;
119 }
120};
121
122template <typename T>
123struct Krause : public Base<T> {
124
125 T project(T x) const override {
126 return T(1) - T(1) / util::exp(x*x);
127 }
128 T derivative(T x) const override {
129 return T(2)*x / util::exp(x*x);
130 }
131 T inverse(T x) const override {
132 return util::sqrt(util::log(T(1)/(T(1)-x)));
133 }
134};
135
136
137// ------------------------------------------ //
138// helper functions //
139// ------------------------------------------ //
140
141template<typename T, typename DESCRIPTOR>
143 return converter.getPhysDeltaX()
144 * converter.getPhysDeltaX()
145 * converter.getLatticeViscosity()
146 * converter.getLatticeRelaxationTime();
147}
148
150// Inverse projection function to get startValue from porosity
151template<typename T>
152T porosityToControl(T porosity, const Base<T>& projection)
153{
154 return projection.inverse(porosity);
155}
156
158template<typename T, typename DESCRIPTOR>
159T permeabilityToPorosity(T permeability,
160 const UnitConverter<T,DESCRIPTOR>& converter)
161{
162 return (T(1) - gridTerm(converter) / permeability);
163}
164
166template<typename T, typename DESCRIPTOR>
167T permeabilityToControl(T permeability,
168 const Base<T>& projection,
169 const UnitConverter<T,DESCRIPTOR>& converter)
170{
171 const T porosity = permeabilityToPorosity(permeability, converter);
172 return porosityToControl(porosity);
173}
174
176template<typename T, typename DESCRIPTOR>
177T getInitialControl(T startValue,
178 const Base<T>& projection,
179 const UnitConverter<T,DESCRIPTOR>& converter,
180 StartValueType type,
181 bool verbose = true)
182{
183 T control {0};
184 OstreamManager clout(std::cout, "getInitialControl");
185
186 if (type == Porosity) {
187 control = projection::porosityToControl(startValue, projection);
188 if (verbose) {
189 clout << "Transform porosity startValue into control startValue:\n";
190 clout << "Porosity: " << startValue << std::endl;
191 clout << "Control: " << control << std::endl;
192 }
193 }
194 else if (type == Permeability) {
195 const T tmpPorosity = projection::permeabilityToPorosity(startValue, converter);
196 control = projection::porosityToControl(tmpPorosity, projection);
197 if (verbose) {
198 clout << "Transform permeability startValue into control startValue:\n";
199 clout << "Permeability: " << startValue << std::endl;
200 clout << "Porosity: " << tmpPorosity << std::endl;
201 clout << "Control: " << control << std::endl;
202 }
203 }
204 else if (type == ProjectedControl) {
205 control = projection.inverse(startValue);
206 } else if (type == Control) {
207 control = startValue;
208 } else {
209 throw std::invalid_argument(
210 "Error: unknown start value type.");
211 }
212 return control;
213}
214
215template<typename T, typename OptiCaseDual_Type>
216T getInitialControl(T startValue, OptiCaseDual_Type& optiCase)
217{
218 return getInitialControl(startValue,
219 *(optiCase._projection),
220 *(optiCase._converter),
221 optiCase._startValueType,
222 optiCase._verbose);
223}
224
225// ------------------------------------------ //
226// grid-independent projections //
227// ------------------------------------------ //
228
230
234template <typename T, typename DESCRIPTOR>
235struct GiBase : public Base<T> {
236
237 const T _gridTerm;
238
240 : _gridTerm {gridTerm(converter)}
241 { }
242
243 virtual T subprojection(T x) const = 0;
244 virtual T derivSubprojection(T x) const = 0;
245 virtual T inverseSubprojection(T x) const = 0;
246
247 T project(T x) const override {
248 return subprojection(x) / (subprojection(x) + _gridTerm);
249 }
250 T derivative(T x) const override {
251 const T y = subprojection(x) + _gridTerm;
252 return _gridTerm*derivSubprojection(x) / (y*y);
253 }
254 T inverse(T x) const override {
255 return inverseSubprojection(_gridTerm*x/(T(1)-x));
256 }
257};
258
259template <typename T, typename DESCRIPTOR>
260struct Foerster : public GiBase<T,DESCRIPTOR> {
261
263 : GiBase<T,DESCRIPTOR>{converter}
264 { }
265
266 T subprojection(T x) const override { return util::exp(x); }
267 T derivSubprojection(T x) const override { return util::exp(x); }
268 T inverseSubprojection(T x) const override { return util::log(x); }
269};
270
272
275template <typename T, typename DESCRIPTOR>
276struct FoersterN : public GiBase<T,DESCRIPTOR> {
277
278 const unsigned _n;
279
280 FoersterN(const UnitConverter<T,DESCRIPTOR>& converter, unsigned n)
281 : GiBase<T,DESCRIPTOR>(converter), _n(n)
282 {
283 OLB_PRECONDITION(_n >= 1);
284 }
285
286 T subprojection(T x) const override { return util::exp(util::pow(x, 2*_n)) - T(1); }
287 T derivSubprojection(T x) const override {
288 return T(2*_n) * util::pow(x, 2*_n-1) * subprojection(x);
289 }
290 T inverseSubprojection(T x) const override {
291 return util::pow(util::log(x+T(1)), T(1)/T(2*_n));
292 }
293};
294
296
299template <typename T, typename DESCRIPTOR>
300struct StasiusN : public GiBase<T,DESCRIPTOR> {
301
302 const unsigned _n;
303
304 StasiusN(const UnitConverter<T,DESCRIPTOR>& converter, unsigned n)
305 : GiBase<T,DESCRIPTOR>(converter), _n(n)
306 {
307 OLB_PRECONDITION(_n >= 1);
308 }
309
310 T subprojection(T x) const override { return util::pow(x, 2*_n); }
311 T derivSubprojection(T x) const override { return T(2*_n) * util::pow(x, 2*_n-1); }
312 T inverseSubprojection(T x) const override {
313 return util::pow(x, T(1)/T(2*_n));
314 }
315};
316
317
318
319template <typename T, typename DESCRIPTOR>
320std::shared_ptr<projection::Base<T>> construct(
321 const UnitConverter<T,DESCRIPTOR>& converter, std::string& name)
322{
323 std::smatch match;
324 if (name == "Identity") {
325 return std::make_shared<Identity<T>>();
326 } else if (name == "Sigmoid") {
327 return std::make_shared<Sigmoid<T>>();
328 } else if (name == "ForceFactor") {
329 return std::make_shared<ForceFactor<T>>(converter);
330 } else if (name == "Rectifier") {
331 return std::make_shared<Rectifier<T>>();
332 } else if (name == "Softplus") {
333 return std::make_shared<Softplus<T>>();
334 } else if (name == "Baron") {
335 return std::make_shared<Baron<T>>();
336 } else if (name == "Krause") {
337 return std::make_shared<Krause<T>>();
338 } else if (name == "Foerster") {
339 return std::make_shared<Foerster<T,DESCRIPTOR>>(converter);
340 } else if (std::regex_match(name, match, std::regex ("(Foerster)([0-9])"))) {
341 const unsigned n = std::stoi(match[2]);
342 return std::make_shared<FoersterN<T,DESCRIPTOR>>(converter, n);
343 } else if (std::regex_match(name, match, std::regex ("(Stasius)([0-9])"))) {
344 const unsigned n = std::stoi(match[2]);
345 return std::make_shared<StasiusN<T,DESCRIPTOR>>(converter, n);
346 } else {
347 throw std::invalid_argument(
348 "Error: unknown projection name selected.");
349 }
350}
351
352}
353
354
355} // namespace opti
356
357} // namespace olb
358#endif // PROJECTION_H
class for marking output with some text
Conversion between physical and lattice units, as well as discretization.
constexpr T getLatticeViscosity() const
conversion from physical to lattice viscosity
constexpr T getLatticeRelaxationTime() const
return relaxation time in lattice units
constexpr T getPhysDeltaX() const
returns grid spacing (voxel length) in m
std::shared_ptr< projection::Base< T > > construct(const UnitConverter< T, DESCRIPTOR > &converter, std::string &name)
Definition projection.h:320
T porosityToControl(T porosity, const Base< T > &projection)
Get control value for given porosity.
Definition projection.h:152
T permeabilityToControl(T permeability, const Base< T > &projection, const UnitConverter< T, DESCRIPTOR > &converter)
Get control for given permeability.
Definition projection.h:167
T getInitialControl(T startValue, const Base< T > &projection, const UnitConverter< T, DESCRIPTOR > &converter, StartValueType type, bool verbose=true)
Transform porosity/ permeability/ other startValue into control.
Definition projection.h:177
T permeabilityToPorosity(T permeability, const UnitConverter< T, DESCRIPTOR > &converter)
Get porosity for given permeability.
Definition projection.h:159
T gridTerm(const UnitConverter< T, DESCRIPTOR > &converter)
Definition projection.h:142
@ ProjectedControl
Definition projection.h:42
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
ADf< T, DIM > log(const ADf< T, DIM > &a)
Definition aDiff.h:475
cpu::simd::Pack< T > max(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
Definition pack.h:130
ADf< T, DIM > sin(const ADf< T, DIM > &a)
Definition aDiff.h:569
ADf< T, DIM > asin(const ADf< T, DIM > &a)
Definition aDiff.h:596
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
ADf< T, DIM > atan(const ADf< T, DIM > &a)
Definition aDiff.h:614
ADf< T, DIM > exp(const ADf< T, DIM > &a)
Definition aDiff.h:455
ADf< T, DIM > cos(const ADf< T, DIM > &a)
Definition aDiff.h:578
Top level namespace for all of OpenLB.
Optimization Code.
#define OLB_PRECONDITION(COND)
Definition olbDebug.h:46
T derivative(T x) const override
Definition projection.h:112
T project(T x) const override
Definition projection.h:108
T inverse(T x) const override
Definition projection.h:117
virtual T inverse(T) const =0
virtual T derivative(T) const =0
virtual T project(T) const =0
FoersterProjection for arbitrary n.
Definition projection.h:276
T subprojection(T x) const override
Definition projection.h:286
FoersterN(const UnitConverter< T, DESCRIPTOR > &converter, unsigned n)
Definition projection.h:280
T derivSubprojection(T x) const override
Definition projection.h:287
T inverseSubprojection(T x) const override
Definition projection.h:290
Foerster(const UnitConverter< T, DESCRIPTOR > &converter)
Definition projection.h:262
T subprojection(T x) const override
Definition projection.h:266
T derivSubprojection(T x) const override
Definition projection.h:267
T inverseSubprojection(T x) const override
Definition projection.h:268
Convert force to lattice units.
Definition projection.h:72
T project(T x) const override
Definition projection.h:81
ForceFactor(const UnitConverter< T, DESCRIPTOR > &converter)
Definition projection.h:77
T inverse(T x) const override
Definition projection.h:83
T derivative(T x) const override
Definition projection.h:82
Gridterm-dependent projection base class.
Definition projection.h:235
virtual T inverseSubprojection(T x) const =0
T project(T x) const override
Definition projection.h:247
virtual T derivSubprojection(T x) const =0
GiBase(const UnitConverter< T, DESCRIPTOR > &converter)
Definition projection.h:239
T inverse(T x) const override
Definition projection.h:254
virtual T subprojection(T x) const =0
T derivative(T x) const override
Definition projection.h:250
T derivative(T x) const override
Definition projection.h:58
T inverse(T x) const override
Definition projection.h:59
T project(T x) const override
Definition projection.h:57
T project(T x) const override
Definition projection.h:125
T derivative(T x) const override
Definition projection.h:128
T inverse(T x) const override
Definition projection.h:131
T derivative(T x) const override
Definition projection.h:90
T project(T x) const override
Definition projection.h:89
T inverse(T x) const override
Definition projection.h:91
T project(T x) const override
Definition projection.h:65
T inverse(T x) const override
Definition projection.h:67
T derivative(T x) const override
Definition projection.h:66
T derivative(T x) const override
Definition projection.h:98
T project(T x) const override
Definition projection.h:97
T inverse(T x) const override
Definition projection.h:100
StasiusProjection for arbitrary n.
Definition projection.h:300
T inverseSubprojection(T x) const override
Definition projection.h:312
StasiusN(const UnitConverter< T, DESCRIPTOR > &converter, unsigned n)
Definition projection.h:304
T derivSubprojection(T x) const override
Definition projection.h:311
T subprojection(T x) const override
Definition projection.h:310
Unit conversion handling – header file.