OpenLB 1.7
Loading...
Searching...
No Matches
optimizer.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2012-2016 Mathias J. Krause, Benjamin Förster
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 OPTIMIZER_HH
25#define OPTIMIZER_HH
26
27#include "optimizer.h"
28#include "utilities/norm.h"
29#include <iterator>
30
31namespace olb {
32
34namespace opti {
35
36
37template<typename, typename> class OptiCase;
38
39
40template<typename S, typename C>
41Optimizer<S,C>::Optimizer(int dimCtrl, S eps, int maxIt,
42 bool verboseOn, const std::string fname,
43 const std::string logFileName,
44 bool withUpperBound, S upperBound,
45 bool withLowerBound, S lowerBound,
46 bool vectorBounds,
47 S controlEps,
48 bool failOnMaxIter,
49 std::vector<OptimizerLogType> gplotAnalysis)
50: clout(std::cout,"Optimizer"), _dimCtrl(dimCtrl),
51 _it(0), _maxIt(maxIt), _failOnMaxIter(failOnMaxIter), _eps(eps),
52 _verboseOn(verboseOn),
53 _withUpperBound(withUpperBound), _withLowerBound(withLowerBound),
54 _vectorBounds(vectorBounds), _controlEps(controlEps),
55 gplot(logFileName, Gnuplot<S>::LINEAR, Gnuplot<S>::OFF),
56 _gplotAnalysis(gplotAnalysis)
57{
58 _controlsConverged = false;
59
62
65 if (_withLowerBound) {
67 if (! _vectorBounds) {
68 _lowerBound[0] = lowerBound; // only first component is used...
69 }
70 }
71 if (_withUpperBound) {
73 if (! _vectorBounds) {
74 _upperBound[0] = upperBound; // only first component is used...
75 }
76 }
77 }
78
80}
81
82template<typename S, typename C>
84{
85 if (_failOnMaxIter) {
86 clout << "Warning: Optimization problem failed to converge within specified iteration limit of "
87 << _maxIt << " iterations with tolerance of " << _eps << ".\nProgram terminated" << std::endl;
88 exit(1);
89 }
90 else {
91 clout << "Maximum iteration reached." << std::endl;
92 }
93}
94
95template<typename S, typename C>
97{
98 // Evaluate objective function
99 evaluateObjective(_control, _value);
100 _optiCase->postEvaluation();
101
102 // Optimization step (update of _control, _value, _derivatives and _it)
103 do {
104 if (_it >= _maxIt) {
105 maxIterationReached();
106 return;
107 }
108
109 // Call optimisation algorithm: evaluate objective function and compute derivatives
110 optimizationStep();
111
112 // Print info
113 _optiCase->postEvaluation();
114 if (_verboseOn) {
115 print(_it);
116 }
117 if (_gplotAnalysis.size() > 0) {
118 setGnuplotData();
119 }
120
121 // Optimize as long as |derivative| > eps or a maximum of iterations is reached
122 }
123 while (util::euklidN2(_derivative) > (_eps*_eps) && !_controlsConverged);
124
125 if(_gplotAnalysis.size() > 0){
126 gplot.writePNG();
127 }
128}
129
130template<typename S, typename C>
132{
133 clout << "=======================================" << std::endl;
134 clout << ">>>>>>>>>> Optimizer: step " << it << " <<<<<<<<<<" << std::endl;
135 clout << " Value objective = " << std::setprecision(12) << _value << std::endl;
136 clout << " Norm derivative = " << std::setprecision(12) << util::euklidN(&_derivative[0], _dimCtrl) << std::endl;
137 clout << "=======================================" << std::endl;
138}
139
140template<typename S, typename C>
141void Optimizer<S,C>::writeControlToFile(const std::string fname)
142{
143 if (singleton::mpi().isMainProcessor() ) {
144 std::stringstream stream;
145 stream << _dimCtrl << std::endl;
146 std::for_each(_control.begin(), _control.end(), [&stream](auto c){ stream << c << '\n'; });
147 std::ofstream file;
148 file.open(singleton::directories().getLogOutDir() + fname.c_str());
149 file << stream.str();
150 file.close();
151 }
152}
153
154template<typename S, typename C>
155void Optimizer<S,C>::readControlFromFile(const std::string fname)
156{
157 std::ifstream file(fname.c_str());
158 if ( file.is_open() ) {
159 int dimCtrl;
160 file >> dimCtrl;
161 if (dimCtrl!=_dimCtrl) {
162 clout << "Error: dimensions do not match! dim_controller=" << _dimCtrl << "; dim_file=" << dimCtrl << std::endl;
163 assert(false);
164 }
165 else {
166 for (int i=0; i<_dimCtrl; i++) {
167 double tmpVal;
168 file >> tmpVal;
169 _control[i] = tmpVal;
170 }
171 if (_withLowerBound && _vectorBounds) {
172 for (int i=0; i<_dimCtrl; i++) {
173 double tmpVal;
174 file >> tmpVal;
175 _lowerBound[i] = tmpVal;
176 }
177 }
178 if (_withUpperBound && _vectorBounds) {
179 for (int i=0; i<_dimCtrl; i++) {
180 double tmpVal;
181 file >> tmpVal;
182 _upperBound[i] = tmpVal;
183 }
184 }
185 }
186 file.close();
187 }
188}
189
190template<typename S, typename C>
192{
193 // update control variables
194 std::fill(_control.begin(), _control.end(), startValue);
195}
196
197template<typename S, typename C>
199{
200 std::vector<S> yValues;
201 std::vector<std::string> labels;
202 std::vector<char> plotTypes;
203
204 for(unsigned i = 0; i < _gplotAnalysis.size(); i++){
205 if(_gplotAnalysis[i] == value){
206 yValues.push_back(_value);
207 labels.push_back("value");
208 plotTypes.push_back('p');
209 } else if(_gplotAnalysis[i] == control){
210 // get all entries of control
211 for(unsigned j = 0; j< _control.size(); j++){
212 yValues.push_back(_control[j]);
213 labels.push_back("control[" + std::to_string(j) + "]");
214 plotTypes.push_back('p');
215 }
216 } else if(_gplotAnalysis[i] == derivative){
217
218 for(unsigned j = 0; j< _derivative.size(); j++){
219 yValues.push_back(_derivative[j]);
220 labels.push_back("derivative[" + std::to_string(j) + "]");
221 plotTypes.push_back('p');
222 }
223 } else if(_gplotAnalysis[i] == error){
224 yValues.push_back(util::euklidDistance(_control, _referenceControl));
225 labels.push_back("control_error");
226 plotTypes.push_back('p');
227 } else if(_gplotAnalysis[i] == norm_derivative){
228 yValues.push_back(util::euklidN(&_derivative[0], _dimCtrl));
229 labels.push_back("derivative_norm");
230 plotTypes.push_back('p');
231 }
232 }
233 gplot.setData(S(_it), yValues, labels, "top right", plotTypes); // _it is the iterationstep
234}
235
236void getGnuplotTagsFromString(std::string gplotAnalysisString,
237 std::vector<OptimizerLogType>& gplotAnalysis ){
238 // part the string to get the enum vector
239 std::vector<std::string> gplotAnalysisStringVector;
240 std::istringstream iss(gplotAnalysisString);
241 std::copy(std::istream_iterator<std::string>(iss),
242 std::istream_iterator<std::string>(),
243 std::back_inserter(gplotAnalysisStringVector));
244
245 for(unsigned i = 0; i < gplotAnalysisStringVector.size(); i++){
246 if(gplotAnalysisStringVector[i] == "VALUE"){
247 gplotAnalysis.push_back(OptimizerLogType::value);
248 } else if(gplotAnalysisStringVector[i] == "CONTROL"){
249 gplotAnalysis.push_back(OptimizerLogType::control);
250 } else if(gplotAnalysisStringVector[i] == "DERIVATIVE"){
251 gplotAnalysis.push_back(OptimizerLogType::derivative);
252 } else if(gplotAnalysisStringVector[i] == "ERROR"){
253 gplotAnalysis.push_back(OptimizerLogType::error);
254 } else if(gplotAnalysisStringVector[i] == "NORM_DERIVATIVE"){
255 gplotAnalysis.push_back(OptimizerLogType::norm_derivative);
256 }
257 }
258}
259
260} // namespace opti
261
262} // namespace olb
263
264#endif
void print(int it)
Prints information of the current optimization step it.
Definition optimizer.hh:131
bool _withUpperBound
Bounded versions.
Definition optimizer.h:84
C _derivative
Vector of derivatives of the object functional with respect to the controlled variables.
Definition optimizer.h:71
int _dimCtrl
Number of controlled variables.
Definition optimizer.h:63
C _control
Vector of controlled variables (size _dimCtrl)
Definition optimizer.h:65
void setStartValue(S startValue)
Definition optimizer.hh:191
void readControlFromFile(const std::string fname="control.dat")
Reads the latest control variables from file fname.
Definition optimizer.hh:155
Optimizer(int dimCtrl, S eps, int maxIt, bool verboseOn=true, const std::string fname="", const std::string logFileName="", bool withUpperBound=false, S upperBound=S(), bool withLowerBound=false, S lowerBound=S(), bool vectorBounds=false, S controlEps=S(std::numeric_limits< double >::epsilon()), bool failOnMaxIter=true, std::vector< OptimizerLogType > gplotAnalysis={})
Definition optimizer.hh:41
bool _controlsConverged
For setting tolerance of controls.
Definition optimizer.h:92
void writeControlToFile(const std::string fname="control.dat")
Writes the current control variables linewise into file fname.
Definition optimizer.hh:141
virtual void optimize()
Definition optimizer.hh:96
@ norm_derivative
Definition optimizer.h:46
void getGnuplotTagsFromString(std::string gplotAnalysisString, std::vector< OptimizerLogType > &gplotAnalysis)
the gplotAnalysisString is gained from the xml file and the function than separates and prepares it t...
Definition optimizer.hh:236
MpiManager & mpi()
Directories & directories()
Definition singleton.h:150
T euklidN(const T x[], int dim)
Euclidean norm of an array.
Definition norm.h:60
T euklidDistance(const T x[], const T y[], int dim)
Euclidean distance between two arrays.
Definition norm.h:67
T euklidN2(const T x[], int dim)
Squared Euclidean norm of an array.
Definition norm.h:37
Top level namespace for all of OpenLB.
Optimization Code.
Implements Euclidean norm for arrays.
The description of optimization algorithms – header file.
Creates a container of type C.