OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
OpalSimulation.cpp
Go to the documentation of this file.
1//
2// Class OpalSimulation
3// Concrete implementation of an Opal simulation wrapper.
4//
5// Copyright (c) 2017, Paul Scherrer Institute, Villigen PSI, Switzerland
6// All rights reserved
7//
8// This file is part of OPAL.
9//
10// OPAL is free software: you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// You should have received a copy of the GNU General Public License
16// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17//
19
20#include "opal.h"
21
24#include "Utilities/Options.h"
25#include "Utilities/Util.h"
26
27#include "Util/SDDSReader.h"
28#include "Util/SDDSParser.h"
32
33#include <cstdlib>
34#include <cstring>
35#include <ctime>
36#include <exception>
37#include <iostream>
38#include <sstream>
39#include <vector>
40
41#include <dirent.h>
42#include <sys/types.h>
43#include <sys/wait.h>
44#include <sys/stat.h>
45#include <unistd.h>
46
48 Expressions::Named_t constraints,
49 Param_t params, std::string name,
50 MPI_Comm comm, CmdArguments_t args,
51 std::map<std::string, std::string> uvars)
52 : Simulation(args)
53 , objectives_(objectives)
54 , constraints_(constraints)
55 , comm_(comm)
56 , id_m(-1)
57{
58 namespace fs = std::filesystem;
59
60 simTmpDir_ = args->getArg<std::string>("simtmpdir");
61 if (simTmpDir_.empty()) {
62 if (getenv("SIMTMPDIR") == nullptr) {
63 std::cout << "Environment variable SIMTMPDIR not defined!"
64 << std::endl;
65 simTmpDir_ = getenv("PWD");
66 } else
67 simTmpDir_ = getenv("SIMTMPDIR");
68 }
70
71 // prepare design variables given by the optimizer for generating the
72 // input file
73 std::vector<std::string> dict;
74 for (auto parameter : params) {
75 std::ostringstream tmp;
76 tmp.precision(15);
77 tmp << parameter.first << "=" << parameter.second;
78 dvarNames_.insert(parameter.first);
79 dict.push_back(tmp.str());
80
81 std::ostringstream value;
82 value.precision(15);
83 value << parameter.second;
84 userVariables_.insert(
85 std::pair<std::string, std::string>(parameter.first, value.str()));
86 }
87
88 /*
89 This is a copy from Comm/Splitter/ManyMasterSplit.h
90 in order to calculate the leader which is the unique ID in case
91 of more than one core per worker.
92 */
93
94 int my_rank=0;
95 MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
96 int world_size=0;
97 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
98
99 unsigned num_coworkers_worker_ = 0;
100 num_coworkers_worker_ = args->getArg<size_t>("num-coworkers");
101
102 unsigned group_start = 0;
103
104 unsigned worker_group = ((my_rank % world_size) - 2) / num_coworkers_worker_;
105
106 unsigned leader_ = group_start + 2 + worker_group * num_coworkers_worker_;
107 leader_ = leader_ % world_size;
108
109 // hash the dictionary to get a short unique directory name for temporary
110 // simulation data
111 std::string hash = NativeHashGenerator::generate(dict);
112
113 std::ostringstream tmp;
114 tmp.precision(15);
115
116 tmp << simTmpDir_ << "/" << hash << "_" << leader_;
117
118 simulationDirName_ = tmp.str();
119
120 std::string tmplDir = args->getArg<std::string>("templates");
121 if (tmplDir.empty()) {
122 if (getenv("TEMPLATES") == nullptr) {
123 throw OptPilotException("OpalSimulation::OpalSimulation",
124 "Environment variable TEMPLATES not defined!");
125 }
126 tmplDir = getenv("TEMPLATES");
127 }
128 std::string tmplFile = tmplDir + "/" + simulationName_ + ".tmpl";
129 // data file is assumed to be located in the root directory
130 std::string dataFile = simulationName_ + ".data";
131
132 if (!fs::exists(tmplFile)) {
133 throw OptPilotException("OpalSimulation::OpalSimulation",
134 "The template file '" + tmplFile + "' doesn't exit");
135 }
136
137 for (const auto& uvar : userVariables_) {
138 uvars[uvar.first] = uvar.second;
139 }
140
141 gs_.reset(new GenerateOpalSimulation(tmplFile, dataFile, uvars));
142}
143
144
149
151
152 std::string infile = simulationDirName_ + "/" + simulationName_ + ".in";
153 struct stat fileInfo;
154
155 if (stat(infile.c_str(), &fileInfo) == 0) {
156 std::cout << "-> Simulation input file (" << infile
157 << ") already exist from previous run.." << std::endl;
158 return true;
159 }
160
161 return false;
162}
163
164
165void OpalSimulation::createSymlink_m(const std::string& path) {
166 namespace fs = std::filesystem;
167
168 for (auto &p: fs::directory_iterator(path)) {
169 fs::path source = p.path();
170 fs::path target(simulationDirName_ + "/");
171 target +=source.filename();
172
173 try {
174 fs::create_symlink(source, target);
175 } catch (fs::filesystem_error &e) {
176 std::cerr << e.what() << "\n"
177 << "in OpalSimulation::createSymlink()" << std::endl;
178 }
179 }
180}
181
182
184 CmdArguments_t args = getArgs();
185 std::string restartfile = args->getArg<std::string>("restartfile", "", false);
186
187 if (restartfile.empty()) return;
188
189 namespace fs = std::filesystem;
190 if ( !fs::exists(restartfile) ) {
191 std::cerr << "H5 file '" + restartfile + "' doesn't exist." << "\n"
192 << "in OpalSimulation::copyH5_m()" << std::endl;
193
194 return;
195 }
196
197 try {
198 fs::path srcfile(restartfile);
199 fs::path targetfile(simulationDirName_ + "/" + simulationName_ + ".h5");
200 fs::copy_file(srcfile, targetfile);
201 } catch (fs::filesystem_error &ex) {
202 std::cerr << ex.what() << "\n"
203 << "in OpalSimulation::copyH5_m()" << std::endl;
204 }
205}
206
207
209 namespace fs = std::filesystem;
210
211 CmdArguments_t args = getArgs();
212 std::string restartfile = args->getArg<std::string>("restartfile", "", false);
213
214 if ( id_m > -1 ) {
215 std::ostringstream tmp;
216 tmp << simTmpDir_ << "/" << id_m;
217 simulationDirName_ = tmp.str();
218 }
219 std::string dataDir = simulationDirName_ + "/data";
220
222 opal->setOptimizerFlag();
223
224 // linking fieldmaps + distributions
225 if (getenv("FIELDMAPS") == nullptr) {
226 throw OptPilotException("OpalSimulation::setupSimulation",
227 "Environment variable FIELDMAPS not defined!");
228 }
229
231
232 MPI_Barrier(comm_);
233
234 if (!fs::exists(simulationDirName_)) {
235 throw OptPilotException("OpalSimulation::setupSimulation",
236 "Directory '" + simulationDirName_ + "' doesn't exist");
237 }
238
239 if (!fs::exists(dataDir)) {
240 throw OptPilotException("OpalSimulation::setupSimulation",
241 "Directory '" + dataDir + "' doesn't exist");
242 }
243
244 if (!restartfile.empty() &&
245 !fs::exists(simulationDirName_ + "/" + simulationName_ + ".h5")) {
246 throw OptPilotException("OpalSimulation::setupSimulation",
247 "H5 file '" + simulationDirName_ + "/" + simulationName_ + ".h5' doesn't exist");
248 }
249}
250
252 namespace fs = std::filesystem;
253
254 int rank = 0;
255 MPI_Comm_rank(comm_, &rank);
256 if (rank != 0) return; // only one processor in comm group has to setup files
257
258 if (fs::exists(simulationDirName_)) {
259 fs::remove_all(simulationDirName_);
260 }
261
262 try {
263 fs::create_directory(simulationDirName_);
264 fs::permissions(simulationDirName_,
265 fs::perms::owner_all |
266 fs::perms::group_read |
267 fs::perms::group_exec |
268 fs::perms::others_read |
269 fs::perms::others_exec);
270
271 } catch (fs::filesystem_error &e) {
272 std::cerr << e.what() << "\n"
273 << "in OpalSimulation::setupSimulation" << std::endl;
274 return;
275 }
276
277 try {
278 std::string dataDir = simulationDirName_ + "/data";
279
280 fs::create_directory(dataDir);
281 fs::permissions(dataDir,
282 fs::perms::owner_all |
283 fs::perms::group_read |
284 fs::perms::group_exec |
285 fs::perms::others_read |
286 fs::perms::others_exec);
287
288 } catch (fs::filesystem_error &e) {
289 std::cerr << e.what() << "\n"
290 << "in OpalSimulation::setupSimulation" << std::endl;
291 return;
292 }
293
294 std::string infile = simulationDirName_ + "/" +
295 simulationName_ + ".in";
296 gs_->writeInputFile(infile);
297
298 std::string fieldmapPath = getenv("FIELDMAPS");
299 this->createSymlink_m(fieldmapPath);
300
301 if (getenv("DISTRIBUTIONS") != nullptr) {
302 std::string distPath = getenv("DISTRIBUTIONS");
303 this->createSymlink_m(distPath);
304 }
305
306 this->copyH5_m();
307}
308
310
311 // backup stdout and err file handles
312 strm_buffer_ = std::cout.rdbuf();
313 strm_err_ = std::cerr.rdbuf();
314
315 int world_pid = 0;
316 MPI_Comm_rank(MPI_COMM_WORLD, &world_pid);
317
318 std::ostringstream fname;
319 fname << "sim.out." << world_pid;
320 std::ofstream file(fname.str().c_str());
321 fname << ".err";
322 std::ofstream err(fname.str().c_str());
323
324 // and redirect stdout and err to new files
325 std::cout.rdbuf(file.rdbuf());
326 std::cerr.rdbuf(err.rdbuf());
327}
328
329
331 std::cout.rdbuf(strm_buffer_);
332 std::cerr.rdbuf(strm_err_);
333}
334
335
337 namespace fs = std::filesystem;
338
339 // make sure input file is not already existing
340 MPI_Barrier(comm_);
341 if ( hasResultsAvailable() ) return;
342 MPI_Barrier(comm_);
343
345
346 pwd_ = fs::current_path().native();
347 pwd_ += "/";
348 int err = chdir(simulationDirName_.c_str());
349
350 if (err != 0) {
351 std::cout << "Cannot chdir to "
352 << simulationDirName_.c_str() << std::endl;
353 std::cout << "Continuing 1, disregarding this simulation.."
354 << std::endl;
355 return;
356 }
357
358 // setup OPAL command line options
359 std::ostringstream inputFileName;
360 inputFileName << simulationName_ << ".in";
361 char *inputfile = new char[inputFileName.str().size()+1] ;
362 strcpy(inputfile, inputFileName.str().c_str());
363 int seed = Options::seed;
364
365 CmdArguments_t args = getArgs();
366 int restartStep= args->getArg<int>("restartstep",
367 std::numeric_limits<int>::min(), false);
368 std::string restartfile = args->getArg<std::string>("restartfile", "", false);
369
370 try {
371 if ( restartStep > -2 && restartfile.empty() ) {
372 throw OpalException("OpalSimulation::run()",
373 "Restart specified but no restart H5 file available.");
374 }
375
376 char exe_name[] = "opal";
377 char nocomm[] = "--nocomminit";
378 char info[] = "--info";
379 char info0[] = "0";
380 char warn[] = "--warn";
381 char warn0[] = "0";
382 char *arg[] = { exe_name, inputfile, nocomm, info, info0, warn, warn0 };
383
384 //FIXME: this seems to crash OPAL in some cases
385 //redirectOutToFile();
386#ifdef SUPRESS_OUTPUT
387 //XXX: hack to disable output to stdout
388 std::cout.setstate(std::ios::failbit);
389#endif
390 // now we can run the simulation
391 run_opal(arg, inputFileName.str(), restartStep, Options::infoLevel, Options::warnLevel, comm_);
392
393 //restoreOut();
394#ifdef SUPRESS_OUTPUT
395 std::cout.clear();
396#endif
397
398 } catch(OpalException *ex) {
399
400 //restoreOut();
401#ifdef SUPRESS_OUTPUT
402 std::cout.clear();
403#endif
404
405 std::cerr << "Opal exception during simulation run: \n"
406 << ex->where() << "\n"
407 << ex->what() << std::endl;
408 std::cerr << "Continuing, disregarding this simulation.."
409 << std::endl;
410
411 } catch(ClassicException *ex) {
412
413 //restoreOut();
414#ifdef SUPRESS_OUTPUT
415 std::cout.clear();
416#endif
417
418 std::cerr << "Classic exception during simulation run: \n"
419 << ex->where() << "\n"
420 << ex->what() << std::endl;
421 std::cerr << "Continuing, disregarding this simulation.."
422 << std::endl;
423 } catch(std::exception &ex) {
424#ifdef SUPRESS_OUTPUT
425 std::cout.clear();
426#endif
427 std::cerr << "Exception occured during simulation run: \n"
428 << ex.what() << std::endl
429 << "Continuing, disregarding this simulation.." << std::endl;
430 } catch(...) {
431#ifdef SUPRESS_OUTPUT
432 std::cout.clear();
433#endif
434 std::cerr << "Unknown exception occured during simulation run.\n"
435 << "Continuing, disregarding this simulation.." << std::endl;
436
437 }
438
439 Options::seed = seed;
440
441 delete[] inputfile;
442 err = chdir(pwd_.c_str());
443 if (err != 0) {
444 std::cerr << "Cannot chdir to "
445 << pwd_ << std::endl;
446 }
447}
448
449
450std::map<std::string, std::vector<double> > OpalSimulation::getData(const std::vector<std::string>& statVariables) {
451 std::map<std::string, std::vector<double> > ret;
452 SDDS::SDDSParser parser(simulationDirName_ + "/" + simulationName_ + ".stat");
453 parser.run();
454 for (const std::string &var : statVariables) {
456 try {
457 column = parser.getColumnData(var);
458 } catch (SDDSParserException &e) {
459 std::cout << "failed to read data: " << e.what() << " in " << e.where() << std::endl;
460 continue;
461 }
462
463 std::vector<double> values;
464 values.reserve(column.size());
465 auto type = parser.getColumnType(var);
466 for (const auto& val: column) {
467 values.push_back(parser.getVariantValue<double>(val, type));
468 }
469 ret.insert(std::make_pair(var, values));
470 }
471
472 return ret;
473}
474
476
477 // std::cout << "collectResults" << std::endl;
478
479 // clear old solutions
480 requestedVars_.clear();
481
482 int err = chdir(simulationDirName_.c_str());
483 if (err != 0) {
484 std::cout << "Cannot chdir to "
485 << simulationDirName_.c_str() << std::endl;
486 std::cout << "Continuing, with cleanup.."
487 << std::endl;
488 cleanUp();
489 return;
490 }
491
492 std::string fn = simulationName_ + ".stat";
493 struct stat fileInfo;
494
495 // if no stat file, simulation parameters produced invalid bunch
496 if (stat(fn.c_str(), &fileInfo) != 0) {
497 invalidBunch();
498 } else {
499 Expressions::Named_t::iterator namedIt;
500 try {
501 for (namedIt=objectives_.begin(); namedIt!=objectives_.end(); ++namedIt) {
502 if (namedIt->first == "dummy") continue; // FIXME SamplePilot has default objective named dummy
503 Expressions::Expr_t *objective = namedIt->second;
504
505 // find out which variables we need in order to evaluate the objective
506 variableDictionary_t variable_dictionary;
507 getVariableDictionary(variable_dictionary,fn,objective);
508
509 // and evaluate the expression using the built dictionary of
510 // variable values
511 Expressions::Result_t result =
512 objective->evaluate(variable_dictionary);
513
514 std::vector<double> values;
515 values.push_back(std::get<0>(result));
516 bool is_valid = std::get<1>(result);
517
518 reqVarInfo_t tmps = {EVALUATE, values, is_valid};
519 requestedVars_.insert(
520 std::pair<std::string, reqVarInfo_t>(namedIt->first, tmps));
521
522 }
523
524 // .. and constraints
525 for (namedIt=constraints_.begin(); namedIt!=constraints_.end(); ++namedIt) {
526
527 Expressions::Expr_t *constraint = namedIt->second;
528
529 // find out which variables we need in order to evaluate the constraint
530 variableDictionary_t variable_dictionary;
531 getVariableDictionary(variable_dictionary,fn,constraint);
532
533 Expressions::Result_t result =
534 constraint->evaluate(variable_dictionary);
535
536 std::vector<double> values;
537 values.push_back(std::get<0>(result));
538 bool is_valid = std::get<1>(result);
539
540 //FIXME: hack to give feedback about values of LHS and RHS
541 std::string constr_str = constraint->toString();
542 std::vector<std::string> split = Util::split_any_of(constr_str, "<>!=", true);
543 std::string lhs_constr_str = (split.size() > 0) ? split[0] : std::string();
544 std::string rhs_constr_str = (split.size() > 1) ? split[1] : std::string();
545 rhs_constr_str = Util::trim_chars(rhs_constr_str, "=");
546
547 functionDictionary_t funcs = constraint->getRegFuncs();
548 const std::unique_ptr<Expressions::Expr_t> lhs(
549 new Expressions::Expr_t(lhs_constr_str, funcs));
550 const std::unique_ptr<Expressions::Expr_t> rhs(
551 new Expressions::Expr_t(rhs_constr_str, funcs));
552
553 Expressions::Result_t lhs_res = lhs->evaluate(variable_dictionary);
554 Expressions::Result_t rhs_res = rhs->evaluate(variable_dictionary);
555
556 values.push_back(std::get<0>(lhs_res));
557 values.push_back(std::get<0>(rhs_res));
558
559 reqVarInfo_t tmps = {EVALUATE, values, is_valid};
560 requestedVars_.insert(
561 std::pair<std::string, reqVarInfo_t>(namedIt->first, tmps));
562
563 }
564 } catch(SDDSParserException &e) {
565 std::cout << "Evaluation of objective or constraint " << namedIt->first << " threw an exception ('" << e.what() << "' in " << e.where() << ")!" << std::endl;
566 invalidBunch();
567 } catch(OptPilotException &e) {
568 std::cout << "Evaluation of objective or constraint " << namedIt->first << " threw an exception ('" << e.what() << "' in " << e.where() << ")!" << std::endl;
569 invalidBunch();
570 } catch(std::exception &e) {
571 std::cout << "Evaluation of objective or constraint " << namedIt->first << " threw an exception ('" << e.what() << "')!" << std::endl;
572 invalidBunch();
573 } catch(...) {
574 std::cout << "Evaluation of objective or constraint " << namedIt->first << " threw an exception!" << std::endl;
575 invalidBunch();
576 }
577
578 }
579
580 err = chdir(pwd_.c_str());
581 if (err != 0) {
582 std::cout << "Cannot chdir to "
583 << simulationDirName_.c_str() << std::endl;
584 }
585}
586
588 const std::string& filename,
589 const Expressions::Expr_t* const expression) {
590
591 std::set<std::string> req_vars = expression->getReqVars();
592
593 // first check if required variables are design variables
594 for (auto req_it = req_vars.begin(); req_it!=req_vars.end();) {
595 auto it = userVariables_.find(*req_it);
596 if (it==userVariables_.end()) { // not a design var
597 ++req_it;
598 continue;
599 }
600 double value = std::stod((*it).second);
601 dictionary.insert(std::pair<std::string, double>(*req_it, value));
602 req_it = req_vars.erase(req_it); // remove and update iterator to next
603 }
604
605 if (req_vars.empty()) return;
606
607 // get remaining required variable values from the stat file
608 const std::unique_ptr<SDDSReader> sddsr(new SDDSReader(filename));
609 sddsr->parseFile();
610
611 for (std::string req_var : req_vars) {
612 if (dictionary.count(req_var) != 0) continue;
613
614 double value = 0.0;
615 sddsr->getValue(-1 /*atTime*/, req_var, value);
616 dictionary.insert(std::pair<std::string, double>(req_var, value));
617 }
618}
619
621
622 for (auto namedObjective : objectives_) {
623 std::vector<double> tmp_values;
624 tmp_values.push_back(0.0);
625 reqVarInfo_t tmps = {EVALUATE, tmp_values, false};
626 requestedVars_.insert(
627 std::pair<std::string, reqVarInfo_t>(namedObjective.first, tmps));
628 }
629}
630
632 namespace fs = std::filesystem;
633 try {
634 int my_rank = 0;
635 MPI_Comm_rank(comm_, &my_rank);
636 if (my_rank == 0) {
637 fs::path p(simulationDirName_.c_str());
638 fs::remove_all(p);
639 }
640 } catch(fs::filesystem_error &ex) {
641 std::cout << "Can't remove directory '" << simulationDirName_ << "', (" << ex.what() << ")" << std::endl;
642 } catch(...) {
643 std::cout << "Can't remove directory '" << simulationDirName_ << "'" << std::endl;
644 }
645}
646
647void OpalSimulation::cleanUp(const std::vector<std::string>& keep) {
648 namespace fs = std::filesystem;
649
650 if ( keep.empty() ) {
651 // if empty we keep all files
652 return;
653 }
654
655 try {
656 int my_rank = 0;
657 MPI_Comm_rank(comm_, &my_rank);
658 if (my_rank != 0) {
659 return;
660 }
661 fs::path p(simulationDirName_.c_str());
662 {
663 fs::directory_iterator it{p};
664 while (it != fs::directory_iterator{}) {
665 std::string extension = Util::toUpper(it->path().extension().string());
666
667 // remove .
668 extension.erase(0, 1);
669
670 auto result = std::find(keep.begin(), keep.end(), extension);
671
672 if ( result == keep.end() && ! fs::is_directory(it->path())) {
673 fs::remove(it->path());
674 }
675 ++it;
676 }
677 }
678 {
679 fs::directory_iterator it{p};
680 while (it != fs::directory_iterator{}) {
681 if (fs::is_directory(it->path()) && fs::is_empty(it->path())) {
682 fs::remove(it->path());
683 }
684 ++it;
685 }
686 }
687 } catch(fs::filesystem_error &ex) {
688 std::cout << "Can't remove file in directory '" << simulationDirName_
689 << "', (" << ex.what() << ")" << std::endl;
690 } catch(...) {
691 std::cout << "Can't remove file in directory '" << simulationDirName_
692 << "'" << std::endl;
693 }
694}
int run_opal(char *[], std::string inputfile, int restartStep, int infoLevel, int warnLevel, MPI_Comm comm)
Definition opal.cpp:32
arg(a))
const std::string name
std::map< std::string, client::function::type > functionDictionary_t
Definition Expression.h:51
std::map< std::string, double > variableDictionary_t
Definition Expression.h:50
@ EVALUATE
Definition Types.h:46
namedVariableCollection_t Param_t
Definition Types.h:52
std::shared_ptr< CmdArguments > CmdArguments_t
std::map< std::string, Expressions::Expr_t * > Named_t
type of an expressions with a name
Definition Expression.h:68
std::tuple< double, bool > Result_t
Definition Expression.h:60
int warnLevel
Definition Options.cpp:32
int infoLevel
Definition Options.cpp:27
int seed
The current random seed.
Definition Options.cpp:35
std::string toUpper(const std::string &str)
Definition Util.cpp:152
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
std::vector< variant_t > columnData_t
Definition ast.hpp:51
The global OPAL structure.
Definition OpalData.h:49
void setOptimizerFlag()
Definition OpalData.cpp:292
static OpalData * getInstance()
Definition OpalData.cpp:196
The abstract base class for all exceptions in CLASSIC.
std::string pwd_
holds current directory (for restoring)
void invalidBunch()
mark a solution as invalid
virtual ~OpalSimulation()
std::map< std::string, std::vector< double > > getData(const std::vector< std::string > &statVariables)
void getVariableDictionary(variableDictionary_t &dictionary, const std::string &filename, const Expressions::Expr_t *const expression)
get variables for expression evaluation from SDDS file. Can throw SDDSParserException
reqVarContainer_t requestedVars_
holds solutions returned to the optimizer
void setupSimulation()
create directories, input files, fieldmaps...
void copyH5_m()
copy H5 file
void redirectOutToFile()
redirect stdout and stderr to file
std::unique_ptr< GenerateOpalSimulation > gs_
object to generate simulation input files
Expressions::Named_t objectives_
std::streambuf * strm_err_
stream buffer to redirect stderr
std::string simulationDirName_
full path of simulation directory (where simulation will be run)
std::set< std::string > dvarNames_
Expressions::Named_t constraints_
std::map< std::string, std::string > userVariables_
variable dictionary holding requested optimizer values
std::string simTmpDir_
temporary directory for simulation data (environment var SIMTMPDIR)
std::streambuf * strm_buffer_
stream buffer to redirect output
void createSymlink_m(const std::string &path)
create symbolic links
std::string simulationName_
identification of the simulation (corresponding to output filename)
bool hasResultsAvailable()
check if we already have simulated the current set of design vars
void setupFSStructure()
create directories, input files, symlinks...
void collectResults()
Parse SDDS stat file and build up requested variable dictionary.
void restoreOut()
restore stdout and stderr to default
int id_m
job id (SAMPLE command)
OpalSimulation(Expressions::Named_t objectives, Expressions::Named_t constraints, Param_t params, std::string name, MPI_Comm comm, CmdArguments_t args, std::map< std::string, std::string > uvars)
The base class for all OPAL exceptions.
virtual const std::string & what() const
Return the message string for the exception.
virtual const std::string & where() const
Return the name of the method or function which detected the exception.
functionDictionary_t getRegFuncs() const
Definition Expression.h:119
const std::string & toString() const
Definition Expression.h:117
Expressions::Result_t evaluate(const variableDictionary_t &vars)
evaluate an expression given a value dictionary of free variables
Definition Expression.h:125
const std::set< std::string > & getReqVars() const
Definition Expression.h:115
CmdArguments_t getArgs()
Definition Simulation.h:47
static std::string generate(std::vector< std::string > arguments, size_t world_pid=0)
T getVariantValue(const ast::variant_t &val, ast::dataType type) const
Convert value from variant (only numeric types) to a value of type T.
Definition SDDSParser.h:193
const ast::columnData_t & getColumnData(const std::string &columnName) const
ast::dataType getColumnType(const std::string &col_name) const
Definition SDDSParser.h:57