OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
GenerateOpalSimulation.h
Go to the documentation of this file.
1//
2// Class GenerateOpalSimulation
3// Generates an OPAL input file from data and template file.
4//
5// When running the optimizer with the OPAL forward solvers this utility
6// class helps generating OPAL input files corresponding to the design
7// variable values of the requested evaluation.
8// Using the data file we start by generating the dictionary of known
9// templates.
10// When the input file is requested, all template variables in the template
11// input file are replaced with values found in the dictionary.
12//
13// TODO:
14// - pass stream directly to opal (detour over file not necessary)
15//
16// Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
17// All rights reserved
18//
19// Implemented as part of the PhD thesis
20// "Toward massively parallel multi-objective optimization with application to
21// particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
22//
23// This file is part of OPAL.
24//
25// OPAL is free software: you can redistribute it and/or modify
26// it under the terms of the GNU General Public License as published by
27// the Free Software Foundation, either version 3 of the License, or
28// (at your option) any later version.
29//
30// You should have received a copy of the GNU General Public License
31// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
32//
33#ifndef __GENERATE_SIMULATION_H__
34#define __GENERATE_SIMULATION_H__
35
36#include <iostream>
37#include <fstream>
38#include <sstream>
39#include <string>
40#include <map>
41#include <cstdlib>
42
43#include <vector>
44#include <boost/algorithm/string.hpp>
45#include "boost/filesystem.hpp"
46
48
50
51public:
52
61 GenerateOpalSimulation(std::string tmplFile, std::string varDictionary,
62 std::map<std::string,std::string> userValues) {
63 varDictionary_ = varDictionary;
64 tmplFile_ = tmplFile;
65
66 // some variables need to be scaled
67 scaleVars_.insert(std::pair<std::string, double>("GUNSOLB", 1.));
68
69 // add user values and then fill using the data file without
70 // overwriting user values..
71 dictionary_.insert(userValues.begin(),userValues.end());
73 }
74
76 dictionary_.clear();
77 scaleVars_.clear();
78 }
79
86 void writeInputFile(std::string outputFile) {
87
88 std::ifstream infile(tmplFile_.c_str());
89 std::ostringstream outdata;
90 outdata.precision(15);
91
92 while(infile.good()) {
93 std::string line;
94 std::getline(infile, line, '\n');
95
96 //XXX doing the inverse would be better
98 for(;itr != dictionary_.end(); itr++) {
99 size_t pos = line.find("_" + itr->first + "_");
100 while(pos != std::string::npos) {
101 line.replace(pos, itr->first.length() + 2, itr->second);
102 pos = line.find("_" + itr->first + "_");
103 }
104 }
105
106 outdata << line << std::endl;
107 }
108 infile.close();
109
110 // ensure the contents are written to disk
111 std::ofstream outfile(outputFile.c_str());
112 outfile.precision(15);
113 outfile << outdata.str();
114 outfile.flush();
115 outfile.rdbuf()->pubsync();
116
117 outfile.close();
118 }
119
120
121private:
122
124 std::string tmplFile_;
126 std::string varDictionary_;
128 std::map<std::string, std::string> dictionary_;
130 std::map<std::string, double> scaleVars_;
131
146
147 namespace fs = boost::filesystem;
148
149 fs::path pwd = fs::current_path();
150 if (!fs::exists(varDictionary_) || fs::is_empty(varDictionary_))
151 return;
152
153 std::ifstream infile;
154 infile.open(varDictionary_.c_str(), std::ifstream::in);
155
156 char tmp[1024];
157 unsigned int line_nr = 0;
158 while(infile.good()) {
159 std::fill_n(tmp, 1024, '\0');
160 infile.getline(tmp, 1024);
161 line_nr++;
162 if(tmp[0] != '#') {
163 std::string stmp(tmp);
164 boost::trim(stmp);
165 if(stmp.size() == 0)
166 continue;
167
168 std::vector<std::string> all_strings;
169 boost::split(all_strings, stmp,
170 boost::is_any_of("\r\n\v\f\t "),
171 boost::token_compress_on);
172
173 if(all_strings.size() < 2) {
174 std::cout << "PROBLEM with the following line "
175 << "(at least name and value required)!"
176 << std::endl;
177 std::cout << stmp << std::endl;
178 std::ostringstream ex;
179 ex << "Invalid data file on line " << line_nr;
180 throw OptPilotException(
181 "GenerateOpalSimulation::fillDictionary()",
182 ex.str());
183 }
184
185 std::string varname = all_strings[0];
186 std::string value = all_strings[1];
187 scale(varname, &value);
188 dictionary_.insert(std::pair<std::string, std::string>(
189 varname, value));
190 }
191 }
192
193 infile.close();
194 }
195
196
198 void scale(std::string name, std::string *value) {
199 if(scaleVars_.count(name) > 0) {
200 std::istringstream instr(*value);
201 double val;
202 instr >> val;
203 val *= scaleVars_[name];
204
205 // we keep values as strings, since we have to write them to
206 // output streams anyways..
207 std::ostringstream of;
208 of << val;
209 *value = of.str();
210 }
211 }
212
213};
214
215#endif
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
const std::string name
std::string::iterator iterator
Definition: MSLang.h:16
FRONT * fs
Definition: hypervolume.cpp:59
void scale(std::string name, std::string *value)
Helper method to scale variable if necessary.
std::string tmplFile_
template filename
std::map< std::string, double > scaleVars_
holds all variables that need scaling
void writeInputFile(std::string outputFile)
GenerateOpalSimulation(std::string tmplFile, std::string varDictionary, std::map< std::string, std::string > userValues)
std::map< std::string, std::string > dictionary_
holds parsed template data
std::string varDictionary_
data filename