OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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 <filesystem>
38#include <fstream>
39#include <sstream>
40#include <string>
41#include <map>
42#include <cstdlib>
43
44#include <vector>
45
47#include "Utilities/Util.h"
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
97 std::map<std::string, std::string>::iterator itr = dictionary_.begin();
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 = std::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 stmp = Util::trim_chars(stmp, "\r\n\v\f\t ");
165 if (stmp.size() == 0)
166 continue;
167
168 std::vector<std::string> all_strings = Util::split_any_of(
169 stmp, "\r\n\v\f\t ", true);
170
171 if (all_strings.size() < 2) {
172 std::cout << "PROBLEM with the following line "
173 << "(at least name and value required)!"
174 << std::endl;
175 std::cout << stmp << std::endl;
176 std::ostringstream ex;
177 ex << "Invalid data file on line " << line_nr;
178 throw OptPilotException(
179 "GenerateOpalSimulation::fillDictionary()",
180 ex.str());
181 }
182
183 std::string varname = all_strings[0];
184 std::string value = all_strings[1];
185 scale(varname, &value);
186 dictionary_.insert(std::pair<std::string, std::string>(
187 varname, value));
188 }
189 }
190
191 infile.close();
192 }
193
194
196 void scale(std::string name, std::string *value) {
197 if (scaleVars_.count(name) > 0) {
198 std::istringstream instr(*value);
199 double val;
200 instr >> val;
201 val *= scaleVars_[name];
202
203 // we keep values as strings, since we have to write them to
204 // output streams anyways..
205 std::ostringstream of;
206 of << val;
207 *value = of.str();
208 }
209 }
210
211};
212
213#endif
const std::string name
std::vector< std::string > split_any_of(const std::string &s, const std::string &delims, bool compress)
Definition Util.cpp:250
std::string trim_chars(const std::string &s, const std::string &chars)
Definition Util.h:245
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