OpenLB 1.8.1
Loading...
Searching...
No Matches
optiCase.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2012, 2021 Mathias J. Krause, Julius Jeßberger
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
25#ifndef OPTI_CASE_H
26#define OPTI_CASE_H
27
28#include <functional>
29
30#include "io/xmlReader.h"
31
32namespace olb {
33
34namespace opti {
35
36
38// provides function evaluation and gradient computation
39template <typename S, typename C>
40class OptiCase{
41
42protected:
43 std::function<void (void)> _postEvaluation { [](){} };
44
45public:
46 OptiCase() = default;
47
48 explicit OptiCase(std::function<void (void)> postEvaluation)
50 { }
51
52 virtual S evaluateObjective(const C& control, unsigned optiStep=0) = 0;
53 virtual void computeDerivatives (
54 const C& control, C& derivatives, unsigned optiStep=0) = 0;
55
58 }
59};
60
61
63template <typename S, typename C>
64class OptiCaseAnalytical : public OptiCase<S,C> {
65
66protected:
67 std::function<S (const C&)> _function;
68 std::function<void (const C&, C&)> _derivative;
69
70public:
71 OptiCaseAnalytical(std::function<S (const C&)> function,
72 std::function<void (const C&, C&)> derivative,
73 std::function<void (void)> postEvaluation = [](){})
75 { }
76
77 // Empty constructor where objective and derivative computation is set afterwards
79
80 void setObjective(std::function<S (const C&)> f) {
81 _function = f;
82 }
83
84 void setDerivative(std::function<void (const C&, C&)> d) {
85 _derivative = d;
86 }
87
89 const C& control, unsigned optiStep=0) override {
90 return _function(control);
91 }
92
94 const C& control, C& derivatives, unsigned optiStep=0) override {
95 _derivative(control, derivatives);
96 }
97};
98
99template <typename S, typename C>
100OptiCaseAnalytical(std::function<S (const C&)>,
101 std::function<void (const C&, C&)>)
103
104template <typename S, typename C>
105OptiCaseAnalytical(std::function<S (const C&)>,
106 std::function<void (const C&, C&)>,
107 std::function<void (void)>)
109
110
111// Abstract base class for gradient computation with difference quotients
112template <typename S, typename C>
113class OptiCaseDQ : public OptiCase<S,C> {
114
115protected:
116 std::function<S (const C&)> _functionHelp { [](const C&){ return S{}; } };
117 std::function<S (const C&, unsigned)> _function;
118 S _stepWidth {1.e-8};
119
120 bool _objectiveComputed {false};
122
123public:
124 explicit OptiCaseDQ(std::function<S (const C&, unsigned)> function,
125 std::function<void (void)> postEvaluation)
126 : OptiCase<S,C>(postEvaluation), _function(function)
127 { }
128
129 // If function with (only) one argument is passed, use plain wrapper
130 explicit OptiCaseDQ(std::function<S (const C&)> function,
131 std::function<void (void)> postEvaluation)
132 : OptiCase<S,C>(postEvaluation),
133 _functionHelp(function),
134 _function([&](const C& arg, unsigned){ return _functionHelp(arg); })
135 { }
136
137 template <typename F>
138 OptiCaseDQ(F function, S stepWidth,
139 std::function<void (void)> postEvaluation)
140 : OptiCaseDQ(function, postEvaluation) {
141 _stepWidth = stepWidth;
142 }
143
145 const C& control, unsigned optiStep=0) override {
146 _objective = _function(control, optiStep);
147 _objectiveComputed = true;
148 return _objective;
149 }
150};
151
152
154template <typename S, typename C>
155class OptiCaseFDQ : public OptiCaseDQ<S,C> {
156private:
157 OstreamManager clout {std::cout, "OptiCaseFDQ"};
158
159public:
160 template <typename F>
161 explicit OptiCaseFDQ(F function,
162 std::function<void (void)> postEvaluation = [](){})
164 { }
165
166 template <typename F>
167 OptiCaseFDQ(F function, S stepWidth,
168 std::function<void (void)> postEvaluation = [](){})
169 : OptiCaseFDQ::OptiCaseDQ(function, stepWidth, postEvaluation)
170 { }
171
173 C& derivatives, unsigned optiStep=0) override
174 {
175 assert((control.size() == derivatives.size()));
176
177 if (!(this->_objectiveComputed)) {
178 this->evaluateObjective(control, optiStep);
179 }
180 const S objective(this->_objective);
181
182 for (std::size_t it = 0; it < control.size(); ++it)
183 {
184 C shiftedControl(control);
185 shiftedControl[it] += this->_stepWidth;
186 S shiftedObjective = this->evaluateObjective(shiftedControl, optiStep);
187 derivatives[it] = (shiftedObjective - objective) / this->_stepWidth;
188 }
189 this->_objectiveComputed = false;
190 }
191};
192
193template <typename S, typename C>
194OptiCaseFDQ(std::function<S (const C&)>, std::function<void (void)>)
196
197template <typename S, typename C>
198OptiCaseFDQ(std::function<S (const C&)>, S, std::function<void (void)>)
200
201template <typename S, typename C>
202OptiCaseFDQ(std::function<S (const C&, unsigned)>, std::function<void (void)>)
204
205template <typename S, typename C>
206OptiCaseFDQ(std::function<S (const C&, unsigned)>, S, std::function<void (void)>)
208
209template <typename S, typename C>
210OptiCaseFDQ(std::function<S (const C&)>)
212
213template <typename S, typename C>
214OptiCaseFDQ(std::function<S (const C&)>, S)
216
217template <typename S, typename C>
218OptiCaseFDQ(std::function<S (const C&, unsigned)>)
220
221template <typename S, typename C>
222OptiCaseFDQ(std::function<S (const C&, unsigned)>, S)
224
226template <typename S, typename C>
227class OptiCaseCDQ : public OptiCaseDQ<S,C> {
228private:
229 OstreamManager clout {std::cout, "OptiCaseCDQ"};
230
231public:
232 template <typename F>
233 explicit OptiCaseCDQ(F function,
234 std::function<void (void)> postEvaluation = [](){})
236 { }
237
238 template <typename F>
239 OptiCaseCDQ(F function, S stepWidth,
240 std::function<void (void)> postEvaluation = [](){})
241 : OptiCaseCDQ::OptiCaseDQ(function, stepWidth, postEvaluation)
242 { }
243
245 C& derivatives, unsigned optiStep=0) override
246 {
247 assert((control.size() == derivatives.size()));
248
249 for (std::size_t it = 0; it < control.size(); ++it)
250 {
251 C shiftedControl(control);
252 shiftedControl[it] += this->_stepWidth;
253 S shiftedObjective_plus = this->evaluateObjective(shiftedControl, optiStep);
254
255 shiftedControl[it] = control[it] - this->_stepWidth;
256 S shiftedObjective_minus = this->evaluateObjective(shiftedControl, optiStep);
257
258 derivatives[it] = 0.5 * (shiftedObjective_plus - shiftedObjective_minus) / this->_stepWidth;
259 }
260 }
261};
262
263template <typename S, typename C>
264OptiCaseCDQ(std::function<S (const C&)>, std::function<void (void)>)
266
267template <typename S, typename C>
268OptiCaseCDQ(std::function<S (const C&)>, S, std::function<void (void)>)
270
271template <typename S, typename C>
272OptiCaseCDQ(std::function<S (const C&, unsigned)>, std::function<void (void)>)
274
275template <typename S, typename C>
276OptiCaseCDQ(std::function<S (const C&, unsigned)>, S, std::function<void (void)>)
278
279template <typename S, typename C>
280OptiCaseCDQ(std::function<S (const C&)>)
282
283template <typename S, typename C>
284OptiCaseCDQ(std::function<S (const C&)>, S)
286
287template <typename S, typename C>
288OptiCaseCDQ(std::function<S (const C&, unsigned)>)
290
291template <typename S, typename C>
292OptiCaseCDQ(std::function<S (const C&, unsigned)>, S)
294
295} // namespace opti
296
297} // namespace olb
298
299#endif
class for marking output with some text
Gradient is just passed as a function (and not computed by an own routine)
Definition optiCase.h:64
void setDerivative(std::function< void(const C &, C &)> d)
Definition optiCase.h:84
std::function< S(const C &)> _function
Definition optiCase.h:67
OptiCaseAnalytical(std::function< S(const C &)> function, std::function< void(const C &, C &)> derivative, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:71
void computeDerivatives(const C &control, C &derivatives, unsigned optiStep=0) override
Definition optiCase.h:93
void setObjective(std::function< S(const C &)> f)
Definition optiCase.h:80
S evaluateObjective(const C &control, unsigned optiStep=0) override
Definition optiCase.h:88
std::function< void(const C &, C &)> _derivative
Definition optiCase.h:68
Gradient computation with central difference quotients.
Definition optiCase.h:227
void computeDerivatives(const C &control, C &derivatives, unsigned optiStep=0) override
Definition optiCase.h:244
OptiCaseCDQ(F function, S stepWidth, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:239
OptiCaseCDQ(F function, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:233
OptiCaseDQ(std::function< S(const C &)> function, std::function< void(void)> postEvaluation)
Definition optiCase.h:130
S evaluateObjective(const C &control, unsigned optiStep=0) override
Definition optiCase.h:144
std::function< S(const C &, unsigned)> _function
Definition optiCase.h:117
OptiCaseDQ(F function, S stepWidth, std::function< void(void)> postEvaluation)
Definition optiCase.h:138
OptiCaseDQ(std::function< S(const C &, unsigned)> function, std::function< void(void)> postEvaluation)
Definition optiCase.h:124
std::function< S(const C &)> _functionHelp
Definition optiCase.h:116
Gradient computation with forward difference quotients.
Definition optiCase.h:155
void computeDerivatives(const C &control, C &derivatives, unsigned optiStep=0) override
Definition optiCase.h:172
OptiCaseFDQ(F function, S stepWidth, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:167
OptiCaseFDQ(F function, std::function< void(void)> postEvaluation=[](){})
Definition optiCase.h:161
Abstract base class for optimization tasks.
Definition optimizer.hh:37
virtual S evaluateObjective(const C &control, unsigned optiStep=0)=0
void postEvaluation()
Definition optiCase.h:56
std::function< void(void)> _postEvaluation
Definition optiCase.h:43
OptiCase(std::function< void(void)> postEvaluation)
Definition optiCase.h:48
virtual void computeDerivatives(const C &control, C &derivatives, unsigned optiStep=0)=0
OptiCaseCDQ(std::function< S(const C &)>, std::function< void(void)>) -> OptiCaseCDQ< S, C >
OptiCaseFDQ(std::function< S(const C &)>, std::function< void(void)>) -> OptiCaseFDQ< S, C >
OptiCaseAnalytical(std::function< S(const C &)>, std::function< void(const C &, C &)>) -> OptiCaseAnalytical< S, C >
Top level namespace for all of OpenLB.
Optimization Code.
Stores populations of the primal problems for adjoint simulations.
Definition fields.h:550
Input/Output in XML format – header file.