Added the S scenario. Refactoring

This commit is contained in:
iasonmanolas 2022-02-18 17:50:16 +02:00
parent 96807c3b85
commit 3d0de46922
1 changed files with 229 additions and 134 deletions

View File

@ -15,13 +15,15 @@ enum BaseSimulationScenario {
Bending, Bending,
Dome, Dome,
Saddle, Saddle,
S,
NumberOfBaseSimulationScenarios NumberOfBaseSimulationScenarios
}; };
inline static std::vector<std::string> baseSimulationScenarioNames{"Axial", inline static std::vector<std::string> baseSimulationScenarioNames{"Axial",
"Shear", "Shear",
"Bending", "Bending",
"Dome", "Dome",
"Saddle"}; "Saddle",
"S"};
struct Colors struct Colors
{ {
@ -107,24 +109,122 @@ inline int getParameterIndex(const std::string &s)
struct Settings struct Settings
{ {
inline static std::string defaultFilename{"OptimizationSettings.json"}; inline static std::string defaultFilename{"OptimizationSettings.json"};
std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMaxMagnitudes{0,
3,
0.95,
0.087,
1.9,
/*3*/ 0}; //custom
// std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMaxMagnitudes{2.74429,
// 5.9173,
// 0.493706,
// 0.0820769,
// 1.57789};
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMaxMagnitudes{20.85302947095844,
// 1.8073431893126763,
// 0.2864731720436702,
// 0.14982243562639147,
// 0.18514829631059054};//median
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMaxMagnitudes{1.1725844893199244,
// 0.3464275389927846,
// 0.09527915004635197,
// 0.06100757786262501,
// 0.10631914784812076}; //5_1565 0.03axial
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMaxMagnitudes{/*15*/ 0 /*1.711973658196369*/,
// 1.878077115238504,
// 0.8,
// 0.15851675178327318,
// 0.8,
// /*1.711973658196369*/ 0}; //custom
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMaxMagnitudes{0,
// 14.531854387244818,
// 0.38321932238436796,
// 0.21381267870193282,
// 0.28901381608791094,
// 1.711973658196369}; //9_14423
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMaxMagnitudes{1.1725844893199244,
// 0.3464275389927846,
// 0.09527915004635197,
// 0.06100757786262501,
// 0.10631914784812076}; //5_1565 0.03axial
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMagnitudes{9.82679, 0.138652, 0.247242, 0.739443, 0.00675865}; //Hyperparam opt
// std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMaxMagnitudes{
// 30, 8, 0.4421382884449713, 0.22758433903942452, 0.3247935583883217};
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMagnitudes{10 * 6.310485381644259,
// 10 * 1.7100142258819078,
// 10 * 0.18857048204421728,
// 10 * 0.10813697502645818,
// 10 * 0.11982893539207524}; //6_338
// std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMagnitudes{7.72224,
// 7.72224,
// 0.89468,
// 0.445912,
// 0.625905};
// std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMagnitudes{0.407714,
// 22.3524,
// 0.703164,
// 0.0226138,
// 0.161316};
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMagnitudes{2, 1, 0.4, 0.2, 0.2}; //8_15444 magnitudes from randomBending0
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMagnitudes{1.0600375226325425,
// 0.6381040280710403,
// 0.17201755995098306,
// 0.0706601822149856,
// 0.13578373479448072}; //8_15444 magnitudes from displacements
// std::array<double, NumberOfBaseSimulationScenarios>
// baseScenarioMagnitudes{10 * 1.0600375226325425,
// 10 * 0.6381040280710403,
// 10 * 0.17201755995098306,
// 10 * 0.0706601822149856,
// 10 * 0.13578373479448072}; //8_15444 magnitudes from displacements
// std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMaxMagnitudes;
std::vector<std::vector<OptimizationParameterIndex>> optimizationStrategy = { std::vector<std::vector<OptimizationParameterIndex>> optimizationStrategy = {
{E, A, I2, I3, J, R, Theta}}; // {E,A, I2, I3, J, R, Theta}};
// {A, I2, I3, J, R, Theta}}; {A, I2, I3, J, R, Theta}};
std::optional<std::vector<double>> std::optional<std::vector<double>>
optimizationVariablesGroupsWeights; //TODO:should be removed in the future if not a splitting strategy is used for the optimization optimizationVariablesGroupsWeights; //TODO:should be removed in the future if not a splitting strategy is used for the optimization
enum NormalizationStrategy { NonNormalized, Epsilon }; enum NormalizationStrategy { NonNormalized, Epsilon };
inline static std::vector<std::string> normalizationStrategyStrings{"NonNormalized", "Epsilon"}; inline static std::vector<std::string> normalizationStrategyStrings{"NonNormalized", "Epsilon"};
NormalizationStrategy normalizationStrategy{Epsilon}; NormalizationStrategy normalizationStrategy{Epsilon};
std::array<xRange, NumberOfOptimizationVariables> variablesRanges{xRange{"E", 0.001, 1000}, std::array<xRange, NumberOfOptimizationVariables> variablesRanges{xRange{"E", 1e-3, 1e3},
xRange{"A", 0.001, 1000}, xRange{"A", 1e-3, 1e3},
xRange{"I2", 0.001, 1000}, xRange{"I2", 1e-3, 1e3},
xRange{"I3", 0.001, 1000}, xRange{"I3", 1e-3, 1e3},
xRange{"J", 0.001, 1000}, xRange{"J", 1e-3, 1e3},
xRange{"R", 0.05, 0.95}, xRange{"R", 0.05, 0.95},
xRange{"Theta", -30, 30}}; xRange{"Theta", -30, 30}};
struct SettingsPSO
{
int numberOfParticles{200};
#ifdef USE_PSO
inline static std::string optimizerName{"pso"};
#else
inline static std::string optimizerName{"sa"};
#endif
} pso;
struct SettingsDlibGlobal
{
int numberOfFunctionCalls{100000}; int numberOfFunctionCalls{100000};
double solverAccuracy{1e-3}; } dlib;
double translationEpsilon{3e-3};
double solverAccuracy{1e-2};
double translationEpsilon{4e-3};
// double translationEpsilon{0};
// double angularDistanceEpsilon{vcg::math::ToRad(2.0)};
double angularDistanceEpsilon{vcg::math::ToRad(0.0)}; double angularDistanceEpsilon{vcg::math::ToRad(0.0)};
double targetBaseTriangleSize{0.03}; double targetBaseTriangleSize{0.03};
std::filesystem::path intermediateResultsDirectoryPath; std::filesystem::path intermediateResultsDirectoryPath;
@ -132,11 +232,7 @@ struct Settings
{ {
double translational{1.2}; double translational{1.2};
double rotational{0.8}; double rotational{0.8};
bool operator==(const ObjectiveWeights &other) const bool operator==(const ObjectiveWeights &other) const;
{
return this->translational == other.translational
&& this->rotational == other.rotational;
}
}; };
std::array<ObjectiveWeights, NumberOfBaseSimulationScenarios> perBaseScenarioObjectiveWeights; std::array<ObjectiveWeights, NumberOfBaseSimulationScenarios> perBaseScenarioObjectiveWeights;
std::array<std::pair<double, double>, NumberOfBaseSimulationScenarios> std::array<std::pair<double, double>, NumberOfBaseSimulationScenarios>
@ -163,10 +259,8 @@ struct Settings
inline static std::string ObjectiveWeights{"ObjectiveWeight"}; inline static std::string ObjectiveWeights{"ObjectiveWeight"};
}; };
void save(const std::filesystem::path &saveToPath) nlohmann::json toJson() const
{ {
assert(std::filesystem::is_directory(saveToPath));
nlohmann::json json; nlohmann::json json;
json[GET_VARIABLE_NAME(optimizationStrategy)] = optimizationStrategy; json[GET_VARIABLE_NAME(optimizationStrategy)] = optimizationStrategy;
if (optimizationVariablesGroupsWeights.has_value()) { if (optimizationVariablesGroupsWeights.has_value()) {
@ -193,7 +287,6 @@ struct Settings
// = xRange.toString(); // = xRange.toString();
// } // }
json[GET_VARIABLE_NAME(numberOfFunctionCalls)] = numberOfFunctionCalls;
json[GET_VARIABLE_NAME(solverAccuracy)] = solverAccuracy; json[GET_VARIABLE_NAME(solverAccuracy)] = solverAccuracy;
//Objective weights //Objective weights
std::array<std::pair<double, double>, NumberOfBaseSimulationScenarios> objectiveWeightsPairs; std::array<std::pair<double, double>, NumberOfBaseSimulationScenarios> objectiveWeightsPairs;
@ -206,10 +299,24 @@ struct Settings
}); });
json[JsonKeys::ObjectiveWeights] = objectiveWeightsPairs; json[JsonKeys::ObjectiveWeights] = objectiveWeightsPairs;
json[GET_VARIABLE_NAME(translationEpsilon)] = translationEpsilon; json[GET_VARIABLE_NAME(translationEpsilon)] = translationEpsilon;
json[GET_VARIABLE_NAME(angularDistanceEpsilon)] = vcg::math::ToDeg( json[GET_VARIABLE_NAME(angularDistanceEpsilon)] = vcg::math::ToDeg(angularDistanceEpsilon);
angularDistanceEpsilon);
json[GET_VARIABLE_NAME(targetBaseTriangleSize)] = targetBaseTriangleSize; json[GET_VARIABLE_NAME(targetBaseTriangleSize)] = targetBaseTriangleSize;
json[GET_VARIABLE_NAME(baseScenarioMaxMagnitudes)] = baseScenarioMaxMagnitudes;
#ifdef USE_ENSMALLEN
#ifdef USE_PSO
json[GET_VARIABLE_NAME(pso.numberOfParticles)] = pso.numberOfParticles;
#endif
json[GET_VARIABLE_NAME(pso.optimizerName)] = pso.optimizerName;
#else
json[GET_VARIABLE_NAME(dlib.numberOfFunctionCalls)] = dlib.numberOfFunctionCalls;
#endif
return json;
}
void save(const std::filesystem::path &saveToPath)
{
assert(std::filesystem::is_directory(saveToPath));
nlohmann::json json = toJson();
std::filesystem::path jsonFilePath( std::filesystem::path jsonFilePath(
std::filesystem::path(saveToPath).append(defaultFilename)); std::filesystem::path(saveToPath).append(defaultFilename));
std::ofstream jsonFile(jsonFilePath.string()); std::ofstream jsonFile(jsonFilePath.string());
@ -260,8 +367,8 @@ struct Settings
} }
} }
if (json.contains(GET_VARIABLE_NAME(numberOfFunctionCalls))) { if (json.contains(GET_VARIABLE_NAME(dlib.numberOfFunctionCalls))) {
numberOfFunctionCalls = json.at(GET_VARIABLE_NAME(numberOfFunctionCalls)); dlib.numberOfFunctionCalls = json.at(GET_VARIABLE_NAME(dlib.numberOfFunctionCalls));
} }
if (json.contains(GET_VARIABLE_NAME(solverAccuracy))) { if (json.contains(GET_VARIABLE_NAME(solverAccuracy))) {
solverAccuracy = json.at(GET_VARIABLE_NAME(solverAccuracy)); solverAccuracy = json.at(GET_VARIABLE_NAME(solverAccuracy));
@ -293,33 +400,17 @@ struct Settings
json[GET_VARIABLE_NAME(targetBaseTriangleSize)]); json[GET_VARIABLE_NAME(targetBaseTriangleSize)]);
} }
if (json.contains(GET_VARIABLE_NAME(pso.numberOfParticles))) {
pso.numberOfParticles = static_cast<int>(json[GET_VARIABLE_NAME(pso.numberOfParticles)]);
}
// perBaseScenarioObjectiveWeights = json.at(JsonKeys::ObjectiveWeights); // perBaseScenarioObjectiveWeights = json.at(JsonKeys::ObjectiveWeights);
// objectiveWeights.translational = json.at(JsonKeys::ObjectiveWeights); // objectiveWeights.translational = json.at(JsonKeys::ObjectiveWeights);
// objectiveWeights.rotational = 2 - objectiveWeights.translational; // objectiveWeights.rotational = 2 - objectiveWeights.translational;
return true; return true;
} }
std::string toString() const std::string toString() const { return toJson().dump(); }
{
std::string settingsString;
if (!variablesRanges.empty()) {
std::string xRangesString;
for (const xRange &range : variablesRanges) {
xRangesString += range.toString() + " ";
}
settingsString += xRangesString;
}
settingsString += "FuncCalls=" + std::to_string(numberOfFunctionCalls)
+ " Accuracy=" + std::to_string(solverAccuracy);
for (int baseScenario = Axial; baseScenario != NumberOfBaseSimulationScenarios;
baseScenario++) {
+" W_t=" + std::to_string(perBaseScenarioObjectiveWeights[baseScenario].translational)
+ " W_r="
+ std::to_string(perBaseScenarioObjectiveWeights[baseScenario].rotational);
}
return settingsString;
}
void writeHeaderTo(csvFile &os) const void writeHeaderTo(csvFile &os) const
{ {
@ -346,7 +437,7 @@ struct Settings
os << range.min; os << range.min;
} }
} }
os << numberOfFunctionCalls; os << dlib.numberOfFunctionCalls;
os << solverAccuracy; os << solverAccuracy;
os << std::to_string(translationEpsilon); os << std::to_string(translationEpsilon);
os << std::to_string(vcg::math::ToDeg(angularDistanceEpsilon)); os << std::to_string(vcg::math::ToDeg(angularDistanceEpsilon));
@ -384,11 +475,10 @@ struct Settings
settings2.perBaseScenarioObjectiveWeights.begin()) settings2.perBaseScenarioObjectiveWeights.begin())
.first .first
== settings1.perBaseScenarioObjectiveWeights.end(); == settings1.perBaseScenarioObjectiveWeights.end();
return settings1.numberOfFunctionCalls == settings2.numberOfFunctionCalls return settings1.dlib.numberOfFunctionCalls == settings2.dlib.numberOfFunctionCalls
&& settings1.variablesRanges == settings2.variablesRanges && settings1.variablesRanges == settings2.variablesRanges
&& settings1.solverAccuracy == settings2.solverAccuracy && haveTheSameObjectiveWeights && settings1.solverAccuracy == settings2.solverAccuracy && haveTheSameObjectiveWeights
&& settings1.translationEpsilon && settings1.translationEpsilon == settings2.translationEpsilon;
== settings2.translationEpsilon;
} }
inline void updateMeshWithOptimalVariables(const std::vector<double> &x, SimulationMesh &m) inline void updateMeshWithOptimalVariables(const std::vector<double> &x, SimulationMesh &m)
@ -477,6 +567,8 @@ struct Settings
std::vector<double> objectiveValueHistory; std::vector<double> objectiveValueHistory;
std::vector<size_t> objectiveValueHistory_iteration; std::vector<size_t> objectiveValueHistory_iteration;
inline static std::string DefaultFileName{"OptimizationResults.json"};
struct CSVExportingSettings struct CSVExportingSettings
{ {
bool exportPE{false}; bool exportPE{false};
@ -488,7 +580,6 @@ struct Settings
const CSVExportingSettings exportSettings; const CSVExportingSettings exportSettings;
struct JsonKeys struct JsonKeys
{ {
inline static std::string filename{"OptimizationResults.json"};
inline static std::string optimizationVariables{"OptimizationVariables"}; inline static std::string optimizationVariables{"OptimizationVariables"};
inline static std::string baseTriangle{"BaseTriangle"}; inline static std::string baseTriangle{"BaseTriangle"};
inline static std::string Label{"Label"}; inline static std::string Label{"Label"};
@ -552,7 +643,7 @@ struct Settings
json_optimizationResults[JsonKeys::fullPatternYoungsModulus] = fullPatternYoungsModulus; json_optimizationResults[JsonKeys::fullPatternYoungsModulus] = fullPatternYoungsModulus;
////Save to json file ////Save to json file
std::filesystem::path jsonFilePath( std::filesystem::path jsonFilePath(
std::filesystem::path(saveToPath).append(JsonKeys::filename)); std::filesystem::path(saveToPath).append(DefaultFileName));
std::ofstream jsonFile_optimizationResults(jsonFilePath.string()); std::ofstream jsonFile_optimizationResults(jsonFilePath.string());
jsonFile_optimizationResults << json_optimizationResults; jsonFile_optimizationResults << json_optimizationResults;
@ -602,18 +693,18 @@ struct Settings
#endif #endif
} }
bool load(const std::string &loadFromPath, const bool &shouldLoadDebugFiles = false) bool load(const std::filesystem::path &loadFromPath, const bool &shouldLoadDebugFiles = false)
{ {
assert(std::filesystem::is_directory(loadFromPath)); assert(std::filesystem::is_directory(loadFromPath));
std::filesystem::path jsonFilepath( std::filesystem::path jsonFilepath(
std::filesystem::path(loadFromPath).append(JsonKeys::filename)); std::filesystem::path(loadFromPath).append(DefaultFileName));
if (!std::filesystem::exists(jsonFilepath)) { if (!std::filesystem::exists(jsonFilepath)) {
std::cerr << "Input path does not exist:" << loadFromPath << std::endl; std::cerr << "Input path does not exist:" << loadFromPath << std::endl;
return false; return false;
} }
//Load optimal X //Load optimal X
nlohmann::json json_optimizationResults; nlohmann::json json_optimizationResults;
std::ifstream ifs(std::filesystem::path(loadFromPath).append(JsonKeys::filename)); std::ifstream ifs(std::filesystem::path(loadFromPath).append(DefaultFileName));
ifs >> json_optimizationResults; ifs >> json_optimizationResults;
label = json_optimizationResults.at(JsonKeys::Label); label = json_optimizationResults.at(JsonKeys::Label);
@ -665,40 +756,30 @@ struct Settings
const std::filesystem::path simulationJobsFolderPath( const std::filesystem::path simulationJobsFolderPath(
std::filesystem::path(loadFromPath).append("SimulationJobs")); std::filesystem::path(loadFromPath).append("SimulationJobs"));
const std::vector<std::filesystem::path> scenariosSortedByName = [&]() {
std::vector<std::filesystem::path> sortedByName; std::vector<std::filesystem::path> sortedByName;
for (auto &entry : std::filesystem::directory_iterator(simulationJobsFolderPath)) for (auto &entry : std::filesystem::directory_iterator(simulationJobsFolderPath))
sortedByName.push_back(entry.path()); sortedByName.push_back(entry.path());
std::sort(sortedByName.begin(), sortedByName.end(), &Utilities::compareNat); std::sort(sortedByName.begin(), sortedByName.end(), &Utilities::compareNat);
return sortedByName;
for (const auto &simulationScenarioPath : sortedByName) { }();
for (const auto &simulationScenarioPath : scenariosSortedByName) {
if (!std::filesystem::is_directory(simulationScenarioPath)) { if (!std::filesystem::is_directory(simulationScenarioPath)) {
continue; continue;
} }
// Load full pattern files // Load full job
for (const auto &fileEntry : std::filesystem::directory_iterator(
std::filesystem::path(simulationScenarioPath).append("Full"))) {
const auto filepath = fileEntry.path();
if (filepath.extension() == ".json") {
SimulationJob job;
job.load(filepath.string());
job.pMesh->setBeamMaterial(0.3, fullPatternYoungsModulus);
fullPatternSimulationJobs.push_back(std::make_shared<SimulationJob>(job));
}
}
const auto fullJobFilepath = Utilities::getFilepathWithExtension( const auto fullJobFilepath = Utilities::getFilepathWithExtension(
std::filesystem::path(simulationScenarioPath).append("Full"), ".json"); std::filesystem::path(simulationScenarioPath).append("Full"), ".json");
SimulationJob fullJob; SimulationJob fullJob;
fullJob.load(fullJobFilepath.string()); fullJob.load(fullJobFilepath.string());
fullJob.pMesh->setBeamMaterial(0.3, fullPatternYoungsModulus); fullJob.pMesh->setBeamMaterial(0.3, fullPatternYoungsModulus);
fullPatternSimulationJobs.push_back(std::make_shared<SimulationJob>(fullJob)); fullPatternSimulationJobs.push_back(std::make_shared<SimulationJob>(fullJob));
// Load reduced job
const auto reducedJobFilepath = Utilities::getFilepathWithExtension( const auto reducedJobFilepath = Utilities::getFilepathWithExtension(
std::filesystem::path(simulationScenarioPath).append("Reduced"), ".json"); std::filesystem::path(simulationScenarioPath).append("Reduced"), ".json");
SimulationJob reducedJob; SimulationJob reducedJob;
reducedJob.load(reducedJobFilepath.string()); reducedJob.load(reducedJobFilepath.string());
// applyOptimizationResults_innerHexagon(*this, baseTriangle, *job.pMesh);
applyOptimizationResults_elements(*this, reducedJob.pMesh); applyOptimizationResults_elements(*this, reducedJob.pMesh);
reducedPatternSimulationJobs.push_back( reducedPatternSimulationJobs.push_back(
std::make_shared<SimulationJob>(reducedJob)); std::make_shared<SimulationJob>(reducedJob));
@ -834,7 +915,8 @@ struct Settings
} }
#if POLYSCOPE_DEFINED #if POLYSCOPE_DEFINED
void draw() const { void draw(const std::vector<int> &desiredSimulationScenariosIndices = std::vector<int>()) const
{
PolyscopeInterface::init(); PolyscopeInterface::init();
DRMSimulationModel drmSimulator; DRMSimulationModel drmSimulator;
LinearSimulationModel linearSimulator; LinearSimulationModel linearSimulator;
@ -843,8 +925,17 @@ struct Settings
reducedPatternSimulationJobs[0]->pMesh->registerForDrawing(Colors::reducedInitial, false); reducedPatternSimulationJobs[0]->pMesh->registerForDrawing(Colors::reducedInitial, false);
const int numberOfSimulationJobs = fullPatternSimulationJobs.size(); const int numberOfSimulationJobs = fullPatternSimulationJobs.size();
for (int simulationJobIndex = 0; simulationJobIndex < numberOfSimulationJobs; const std::vector<int> scenariosToDraw = [&]() {
simulationJobIndex++) { if (desiredSimulationScenariosIndices.empty()) {
std::vector<int> v(numberOfSimulationJobs);
std::iota(v.begin(), v.end(), 0); //draw all
return v;
} else {
return desiredSimulationScenariosIndices;
}
}();
for (const int &simulationJobIndex : scenariosToDraw) {
// Drawing of full pattern results // Drawing of full pattern results
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob
= fullPatternSimulationJobs[simulationJobIndex]; = fullPatternSimulationJobs[simulationJobIndex];
@ -1027,5 +1118,9 @@ struct Settings
}; };
enum SimulationModelTag { DRM, Linear }; enum SimulationModelTag { DRM, Linear };
} // namespace ReducedPatternOptimization inline bool Settings::ObjectiveWeights::operator==(const ObjectiveWeights &other) const
{
return this->translational == other.translational && this->rotational == other.rotational;
}
} // namespace ReducedModelOptimization
#endif // REDUCEDMODELOPTIMIZER_STRUCTS_HPP #endif // REDUCEDMODELOPTIMIZER_STRUCTS_HPP