90 GENEMUTATIONPROBABILITY,
92 RECOMBINATIONPROBABILITY,
110 "The \"OPTIMIZE\" command initiates optimization.") {
112 (
"INPUT",
"Path to input file");
114 (
"OUTPUT",
"Name used in output file generation");
116 (
"OUTDIR",
"Name of directory used to store generation output files");
118 (
"OBJECTIVES",
"List of objectives to be used");
120 (
"DVARS",
"List of optimization variables to be used");
122 (
"CONSTRAINTS",
"List of constraints to be used");
124 (
"INITIALPOPULATION",
"Size of the initial population");
126 (
"STARTPOPULATION",
"Generation file (JSON format) to be started from (optional)",
"");
128 (
"NUM_MASTERS",
"Number of master nodes");
130 (
"NUM_COWORKERS",
"Number processors per worker");
132 (
"DUMP_DAT",
"Dump old generation data format with frequency (PISA only)");
134 (
"DUMP_FREQ",
"Dump generation data with frequency (PISA only)");
136 (
"DUMP_OFFSPRING",
"Dump offspring (instead of parent population), default: true");
138 (
"NUM_IND_GEN",
"Number of individuals in a generation (PISA only)");
140 (
"MAXGENERATIONS",
"Number of generations to run");
142 (
"EPSILON",
"Tolerance of hypervolume criteria, default 0.001");
144 (
"EXPECTED_HYPERVOL",
"The reference hypervolume, default 0");
146 (
"HYPERVOLREFERENCE",
"The reference point (real array) for the hypervolume, default empty (origin)");
148 (
"CONV_HVOL_PROG",
"Converge if change in hypervolume is smaller, default 0");
150 (
"ONE_PILOT_CONVERGE",
"default false");
152 (
"SOL_SYNCH",
"Solution exchange frequency, default 0");
154 (
"GENE_MUTATION_PROBABILITY",
"Mutation probability of individual gene, default: 0.5");
156 (
"MUTATION_PROBABILITY",
"Mutation probability of genome, default: 0.5");
158 (
"RECOMBINATION_PROBABILITY",
"Probability for genes to recombine, default: 0.5");
160 (
"SIMBIN_CROSSOVER_NU",
"Simulated binary crossover, default: 2.0");
162 (
"INITIAL_OPTIMIZATION",
"Optimize speed of initial generation, default: false");
164 (
"BIRTH_CONTROL",
"Enforce strict population sizes (or flexible to keep workers busy), default: false");
166 (
"SIMTMPDIR",
"Directory where simulations are run");
168 (
"TEMPLATEDIR",
"Directory where templates are stored");
170 (
"FIELDMAPDIR",
"Directory where field maps are stored");
172 (
"DISTDIR",
"Directory where distributions are stored",
"");
174 (
"CROSSOVER",
"Type of cross over.", {
"BLEND",
"NAIVEONEPOINT",
"NAIVEUNIFORM",
"SIMULATEDBINARY"},
"BLEND");
176 (
"MUTATION",
"Type of bit mutation.", {
"ONEBIT",
"INDEPENDENTBIT"},
"INDEPENDENTBIT");
178 (
"RESTART_FILE",
"H5 file to restart the OPAL simulations from (optional)",
"");
180 (
"RESTART_STEP",
"Restart from given H5 step (optional)",
197 namespace fs = std::filesystem;
200 opal->setOptimizerFlag();
219 funcs.insert(std::pair<std::string, client::function::type>
223 funcs.insert(std::pair<std::string, client::function::type>
227 funcs.insert(std::pair<std::string, client::function::type>
228 (
"sddsVariableAt", ff));
231 funcs.insert(std::pair<std::string, client::function::type>
235 funcs.insert(std::pair<std::string, client::function::type>
236 (
"maxNormRadialPeak", ff));
239 funcs.insert(std::pair<std::string, client::function::type>
240 (
"numberOfPeaks", ff));
243 funcs.insert(std::pair<std::string, client::function::type>
244 (
"sumErrSqRadialPeak", ff));
247 funcs.insert(std::pair<std::string, client::function::type>
248 (
"probVariableWithID", ff));
250 std::string fname = inputfile.stem().native();
252 funcs.insert(std::pair<std::string, client::function::type>
253 (
"statVariableAt", ff));
256 funcs.insert(std::pair<std::string, client::function::type>
261 std::vector<std::string> arguments(opal->getArguments());
262 std::vector<char*> argv;
263 std::map<unsigned int, std::string> argumentMapper({
264 {INPUT,
"inputfile"},
267 {INITIALPOPULATION,
"initialPopulation"},
268 {STARTPOPULATION,
"start-population"},
269 {NUMMASTERS,
"num-masters"},
270 {NUMCOWORKERS,
"num-coworkers"},
271 {DUMPDAT,
"dump-dat"},
272 {DUMPFREQ,
"dump-freq"},
273 {DUMPOFFSPRING,
"dump-offspring"},
274 {NUMINDGEN,
"num-ind-gen"},
275 {MAXGENERATIONS,
"maxGenerations"},
276 {EPSILON,
"epsilon"},
277 {EXPECTEDHYPERVOL,
"expected-hypervol"},
278 {CONVHVOLPROG,
"conv-hvol-prog"},
279 {ONEPILOTCONVERGE,
"one-pilot-converge"},
280 {SOLSYNCH,
"sol-synch"},
281 {GENEMUTATIONPROBABILITY,
"gene-mutation-probability"},
282 {MUTATIONPROBABILITY,
"mutation-probability"},
283 {RECOMBINATIONPROBABILITY,
"recombination-probability"},
284 {SIMBINCROSSOVERNU,
"simbin-crossover-nu"},
285 {INITIALOPTIMIZATION,
"initial-optimization"},
286 {BIRTHCONTROL,
"birth-control"},
287 {RESTART_FILE,
"restartfile"},
288 {RESTART_STEP,
"restartstep"}
291 auto it = argumentMapper.end();
292 for (
unsigned int i = 0; i <
SIZE; ++ i) {
293 if ((it = argumentMapper.find(i)) != argumentMapper.end()) {
295 if (
type ==
"string") {
298 arguments.push_back(argument);
300 }
else if (
type ==
"real") {
303 size_t last = val.find_last_not_of(
'0');
304 if (val[last] !=
'.') ++ last;
305 val.erase (last, std::string::npos );
306 std::string argument =
"--" + (*it).second +
"=" + val;
307 arguments.push_back(argument);
309 }
else if (
type ==
"logical") {
312 arguments.push_back(argument);
320 "The argument INPUT has to be provided");
324 "The argument INITIALPOPULATION has to be provided");
328 "The argument MAXGENERATIONS has to be provided");
333 "The hypervolume reference point should have the same dimension as the objectives");
338 "No INITIAL_OPTIMIZATION possible when reading initial population from file (STARTPOPULATION)");
343 "No INITIAL_OPTIMIZATION possible with BIRTH_CONTROL");
348 if (dir.is_relative()) {
349 fs::path path = fs::path(std::string(getenv(
"PWD")));
354 if (!fs::exists(dir)) {
355 fs::create_directory(dir);
357 std::string argument =
"--simtmpdir=" + dir.native();
358 arguments.push_back(argument);
363 if (dir.is_relative()) {
364 fs::path path = fs::path(std::string(getenv(
"PWD")));
369 std::string argument =
"--templates=" + dir.native();
370 arguments.push_back(argument);
375 if (dir.is_relative()) {
376 fs::path path = fs::path(std::string(getenv(
"PWD")));
381 setenv(
"FIELDMAPS", dir.c_str(), 1);
386 if (dir.is_relative()) {
387 fs::path path = fs::path(std::string(getenv(
"PWD")));
392 setenv(
"DISTRIBUTIONS", dir.c_str(), 1);
397 for (
size_t i = 0; i < arguments.size(); ++ i) {
398 argv.push_back(
const_cast<char*
>(arguments[i].c_str()));
399 *
gmsg << arguments[i] <<
" ";
403 std::set<std::string> vars;
404 for (
const std::string &
name: dvarsstr) {
406 DVar* dvar =
dynamic_cast<DVar*
>(obj);
407 if (dvar ==
nullptr) {
409 "The design variable " +
name +
" is not known");
416 DVar_t tmp = boost::make_tuple(var, lowerbound, upperbound);
418 auto ret = vars.insert(var);
419 if (ret.second ==
false) {
421 "There is already a design variable with the variable " + var +
" defined");
424 std::set<std::string> objExpressions;
425 for (
const std::string &
name: objectivesstr) {
428 if (objective ==
nullptr) {
430 "The objective " +
name +
" is not known");
436 auto ret = objExpressions.insert(expr);
437 if (ret.second ==
false) {
439 "There is already a objective with the expression " + expr +
" defined");
442 std::set<std::string> constraintExpressions;
443 for (
const std::string &
name: constraintsstr) {
446 if (constraint ==
nullptr) {
448 "The constraint " +
name +
" is not known");
454 auto ret = constraintExpressions.insert(expr);
455 if (ret.second ==
false) {
457 "There is already a constraint with the expression " + expr +
" defined");
463 size_t pos = tmplFile.find_last_of(
"/");
464 if(pos != std::string::npos)
465 tmplFile = tmplFile.substr(pos+1);
466 pos = tmplFile.find(
".");
467 tmplFile = tmplFile.substr(0,pos);
470 std::ifstream infile(tmplFile.c_str());
472 std::map<std::string, short> dvarCheck;
473 for (
auto itr = dvars.begin(); itr != dvars.end(); ++ itr) {
474 dvarCheck.insert(std::make_pair(boost::get<0>(itr->second), 0));
477 while(infile.good()) {
479 std::getline(infile, line,
'\n');
482 for(
auto &check: dvarCheck) {
483 pos = line.find(
"_" + check.first +
"_");
484 if (pos != std::string::npos &&
485 dvarCheck.find(check.first) != dvarCheck.end()) {
486 dvarCheck.at(check.first) = 1;
492 for (
auto itr = dvarCheck.begin(); itr != dvarCheck.end(); ++ itr) {
493 if (itr->second == 0) {
495 "Couldn't find the design variable '" + itr->first +
"' in '" + tmplFile +
"'!");
505 this->
run(args, funcs, dvars, objectives, constraints);
508 std::cout <<
"Exception caught: " <<
e.what() <<
std::endl;
509 MPI_Abort(MPI_COMM_WORLD, -100);
529 std::map<std::string, CrossOver> map;
530 map[
"BLEND"] = CrossOver::Blend;
531 map[
"NAIVEONEPOINT"] = CrossOver::NaiveOnePoint;
532 map[
"NAIVEUNIFORM"] = CrossOver::NaiveUniform;
533 map[
"SIMULATEDBINARY"] = CrossOver::SimulatedBinary;
537 switch ( map[crossover] ) {
538 case CrossOver::Blend:
540 case CrossOver::NaiveOnePoint:
541 co = CrossOver::NaiveOnePoint;
543 case CrossOver::NaiveUniform:
544 co = CrossOver::NaiveUniform;
546 case CrossOver::SimulatedBinary:
547 co = CrossOver::SimulatedBinary;
551 "No cross over '" + crossover +
"' supported.");
558 std::map<std::string, Mutation> map;
559 map[
"INDEPENDENTBIT"] = Mutation::IndependentBit;
560 map[
"ONEBIT"] = Mutation::OneBit;
562 Mutation mut = Mutation::IndependentBit;
564 switch ( map[mutation] ) {
565 case Mutation::IndependentBit:
567 case Mutation::OneBit:
568 mut = Mutation::OneBit;
572 "No mutation '" + mutation +
"' supported.");
589 std::shared_ptr<Comm_t> comm(
new Comm_t(args, MPI_COMM_WORLD));
590 if (comm->isWorker())
599 switch ( crossover + mutation ) {
600 case CrossOver::Blend + Mutation::IndependentBit:
605 const std::unique_ptr<pilot_t>
pi(
new pilot_t(args, comm,
607 objectives, constraints,
609 true, userVariables));
612 case CrossOver::Blend + Mutation::OneBit:
617 const std::unique_ptr<pilot_t>
pi(
new pilot_t(args, comm,
619 objectives, constraints,
621 true, userVariables));
624 case CrossOver::NaiveOnePoint + Mutation::IndependentBit:
629 const std::unique_ptr<pilot_t>
pi(
new pilot_t(args, comm,
631 objectives, constraints,
633 true, userVariables));
636 case CrossOver::NaiveOnePoint + Mutation::OneBit:
641 const std::unique_ptr<pilot_t>
pi(
new pilot_t(args, comm,
643 objectives, constraints,
645 true, userVariables));
648 case CrossOver::NaiveUniform + Mutation::IndependentBit:
653 const std::unique_ptr<pilot_t>
pi(
new pilot_t(args, comm,
655 objectives, constraints,
657 true, userVariables));
660 case CrossOver::NaiveUniform + Mutation::OneBit:
665 const std::unique_ptr<pilot_t>
pi(
new pilot_t(args, comm,
667 objectives, constraints,
669 true, userVariables));
672 case CrossOver::SimulatedBinary + Mutation::IndependentBit:
677 const std::unique_ptr<pilot_t>
pi(
new pilot_t(args, comm,
679 objectives, constraints,
681 true, userVariables));
684 case CrossOver::SimulatedBinary + Mutation::OneBit:
689 const std::unique_ptr<pilot_t>
pi(
new pilot_t(args, comm,
691 objectives, constraints,
693 true, userVariables));
698 "No such cross over and mutation combination supported.");
701 if (comm->isWorker())
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Inform & endl(Inform &inf)
boost::tuple< std::string, double, double > DVar_t
type of design variables
std::map< std::string, DVar_t > DVarContainer_t
std::pair< std::string, DVar_t > namedDVar_t
std::shared_ptr< CmdArguments > CmdArguments_t
std::map< std::string, client::function::type > functionDictionary_t
std::map< std::string, Expressions::Expr_t * > Named_t
type of an expressions with a name
std::pair< std::string, Expressions::Expr_t * > SingleNamed_t
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
double getReal(const Attribute &attr)
Return real value.
Attribute makeStringArray(const std::string &name, const std::string &help)
Create a string array attribute.
Attribute makePredefinedString(const std::string &name, const std::string &help, const std::initializer_list< std::string > &predefinedStrings)
Make predefined string attribute.
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
bool getBool(const Attribute &attr)
Return logical value.
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
std::vector< std::string > getStringArray(const Attribute &attr)
Get string array value.
std::string getString(const Attribute &attr)
Get string value.
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
constexpr double e
The value of.
boost::function< boost::tuple< double, bool >(arguments_t)> type
double FromFile(std::string file, const std::vector< double > &referencePoint)
The base class for all OPAL actions.
The base class for all OPAL objects.
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
std::vector< Attribute > itsAttr
The object attributes.
std::map< std::string, std::string > getVariableData()
static void stashInstance()
static OpalData * getInstance()
static OpalData * popInstance()
std::string getExpression() const
std::string getVariable() const
double getUpperBound() const
double getLowerBound() const
std::string getExpression() const
Concrete implementation of an Opal simulation wrapper.
virtual OptimizeCmd * clone(const std::string &name)
Make clone.
CrossOver crossoverSelection(std::string crossover)
Mutation mutationSelection(std::string mutation)
void run(const CmdArguments_t &args, const functionDictionary_t &funcs, const DVarContainer_t &dvars, const Expressions::Named_t &objectives, const Expressions::Named_t &constraints)
virtual void execute()
Execute the command.
OptimizeCmd()
Exemplar constructor.
The base class for all OPAL exceptions.
A simple expression to get the n-th peak of a radial probe.
A simple expression to get value from stat file near a specific position (ref_val,...