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,
Dome,
Saddle,
S,
NumberOfBaseSimulationScenarios
};
inline static std::vector<std::string> baseSimulationScenarioNames{"Axial",
"Shear",
"Bending",
"Dome",
"Saddle"};
"Saddle",
"S"};
struct Colors
{
@ -107,24 +109,122 @@ inline int getParameterIndex(const std::string &s)
struct Settings
{
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 = {
{E, A, I2, I3, J, R, Theta}};
// {A, I2, I3, J, R, Theta}};
// {E,A, I2, I3, J, R, Theta}};
{A, I2, I3, J, R, Theta}};
std::optional<std::vector<double>>
optimizationVariablesGroupsWeights; //TODO:should be removed in the future if not a splitting strategy is used for the optimization
enum NormalizationStrategy { NonNormalized, Epsilon };
inline static std::vector<std::string> normalizationStrategyStrings{"NonNormalized", "Epsilon"};
NormalizationStrategy normalizationStrategy{Epsilon};
std::array<xRange, NumberOfOptimizationVariables> variablesRanges{xRange{"E", 0.001, 1000},
xRange{"A", 0.001, 1000},
xRange{"I2", 0.001, 1000},
xRange{"I3", 0.001, 1000},
xRange{"J", 0.001, 1000},
std::array<xRange, NumberOfOptimizationVariables> variablesRanges{xRange{"E", 1e-3, 1e3},
xRange{"A", 1e-3, 1e3},
xRange{"I2", 1e-3, 1e3},
xRange{"I3", 1e-3, 1e3},
xRange{"J", 1e-3, 1e3},
xRange{"R", 0.05, 0.95},
xRange{"Theta", -30, 30}};
int numberOfFunctionCalls{100000};
double solverAccuracy{1e-3};
double translationEpsilon{3e-3};
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};
} dlib;
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 targetBaseTriangleSize{0.03};
std::filesystem::path intermediateResultsDirectoryPath;
@ -132,11 +232,7 @@ struct Settings
{
double translational{1.2};
double rotational{0.8};
bool operator==(const ObjectiveWeights &other) const
{
return this->translational == other.translational
&& this->rotational == other.rotational;
}
bool operator==(const ObjectiveWeights &other) const;
};
std::array<ObjectiveWeights, NumberOfBaseSimulationScenarios> perBaseScenarioObjectiveWeights;
std::array<std::pair<double, double>, NumberOfBaseSimulationScenarios>
@ -163,10 +259,8 @@ struct Settings
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;
json[GET_VARIABLE_NAME(optimizationStrategy)] = optimizationStrategy;
if (optimizationVariablesGroupsWeights.has_value()) {
@ -193,7 +287,6 @@ struct Settings
// = xRange.toString();
// }
json[GET_VARIABLE_NAME(numberOfFunctionCalls)] = numberOfFunctionCalls;
json[GET_VARIABLE_NAME(solverAccuracy)] = solverAccuracy;
//Objective weights
std::array<std::pair<double, double>, NumberOfBaseSimulationScenarios> objectiveWeightsPairs;
@ -206,10 +299,24 @@ struct Settings
});
json[JsonKeys::ObjectiveWeights] = objectiveWeightsPairs;
json[GET_VARIABLE_NAME(translationEpsilon)] = translationEpsilon;
json[GET_VARIABLE_NAME(angularDistanceEpsilon)] = vcg::math::ToDeg(
angularDistanceEpsilon);
json[GET_VARIABLE_NAME(angularDistanceEpsilon)] = vcg::math::ToDeg(angularDistanceEpsilon);
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(saveToPath).append(defaultFilename));
std::ofstream jsonFile(jsonFilePath.string());
@ -260,8 +367,8 @@ struct Settings
}
}
if (json.contains(GET_VARIABLE_NAME(numberOfFunctionCalls))) {
numberOfFunctionCalls = json.at(GET_VARIABLE_NAME(numberOfFunctionCalls));
if (json.contains(GET_VARIABLE_NAME(dlib.numberOfFunctionCalls))) {
dlib.numberOfFunctionCalls = json.at(GET_VARIABLE_NAME(dlib.numberOfFunctionCalls));
}
if (json.contains(GET_VARIABLE_NAME(solverAccuracy))) {
solverAccuracy = json.at(GET_VARIABLE_NAME(solverAccuracy));
@ -293,33 +400,17 @@ struct Settings
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);
// objectiveWeights.translational = json.at(JsonKeys::ObjectiveWeights);
// objectiveWeights.rotational = 2 - objectiveWeights.translational;
return true;
}
std::string toString() const
{
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;
}
std::string toString() const { return toJson().dump(); }
void writeHeaderTo(csvFile &os) const
{
@ -346,7 +437,7 @@ struct Settings
os << range.min;
}
}
os << numberOfFunctionCalls;
os << dlib.numberOfFunctionCalls;
os << solverAccuracy;
os << std::to_string(translationEpsilon);
os << std::to_string(vcg::math::ToDeg(angularDistanceEpsilon));
@ -384,11 +475,10 @@ struct Settings
settings2.perBaseScenarioObjectiveWeights.begin())
.first
== settings1.perBaseScenarioObjectiveWeights.end();
return settings1.numberOfFunctionCalls == settings2.numberOfFunctionCalls
return settings1.dlib.numberOfFunctionCalls == settings2.dlib.numberOfFunctionCalls
&& settings1.variablesRanges == settings2.variablesRanges
&& settings1.solverAccuracy == settings2.solverAccuracy && haveTheSameObjectiveWeights
&& settings1.translationEpsilon
== settings2.translationEpsilon;
&& settings1.translationEpsilon == settings2.translationEpsilon;
}
inline void updateMeshWithOptimalVariables(const std::vector<double> &x, SimulationMesh &m)
@ -477,6 +567,8 @@ struct Settings
std::vector<double> objectiveValueHistory;
std::vector<size_t> objectiveValueHistory_iteration;
inline static std::string DefaultFileName{"OptimizationResults.json"};
struct CSVExportingSettings
{
bool exportPE{false};
@ -488,7 +580,6 @@ struct Settings
const CSVExportingSettings exportSettings;
struct JsonKeys
{
inline static std::string filename{"OptimizationResults.json"};
inline static std::string optimizationVariables{"OptimizationVariables"};
inline static std::string baseTriangle{"BaseTriangle"};
inline static std::string Label{"Label"};
@ -552,7 +643,7 @@ struct Settings
json_optimizationResults[JsonKeys::fullPatternYoungsModulus] = fullPatternYoungsModulus;
////Save to json file
std::filesystem::path jsonFilePath(
std::filesystem::path(saveToPath).append(JsonKeys::filename));
std::filesystem::path(saveToPath).append(DefaultFileName));
std::ofstream jsonFile_optimizationResults(jsonFilePath.string());
jsonFile_optimizationResults << json_optimizationResults;
@ -602,18 +693,18 @@ struct Settings
#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));
std::filesystem::path jsonFilepath(
std::filesystem::path(loadFromPath).append(JsonKeys::filename));
std::filesystem::path(loadFromPath).append(DefaultFileName));
if (!std::filesystem::exists(jsonFilepath)) {
std::cerr << "Input path does not exist:" << loadFromPath << std::endl;
return false;
}
//Load optimal X
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;
label = json_optimizationResults.at(JsonKeys::Label);
@ -665,40 +756,30 @@ struct Settings
const std::filesystem::path simulationJobsFolderPath(
std::filesystem::path(loadFromPath).append("SimulationJobs"));
std::vector<std::filesystem::path> sortedByName;
for (auto &entry : std::filesystem::directory_iterator(simulationJobsFolderPath))
sortedByName.push_back(entry.path());
const std::vector<std::filesystem::path> scenariosSortedByName = [&]() {
std::vector<std::filesystem::path> sortedByName;
for (auto &entry : std::filesystem::directory_iterator(simulationJobsFolderPath))
sortedByName.push_back(entry.path());
std::sort(sortedByName.begin(), sortedByName.end(), &Utilities::compareNat);
for (const auto &simulationScenarioPath : sortedByName) {
std::sort(sortedByName.begin(), sortedByName.end(), &Utilities::compareNat);
return sortedByName;
}();
for (const auto &simulationScenarioPath : scenariosSortedByName) {
if (!std::filesystem::is_directory(simulationScenarioPath)) {
continue;
}
// Load full pattern files
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));
}
}
// Load full job
const auto fullJobFilepath = Utilities::getFilepathWithExtension(
std::filesystem::path(simulationScenarioPath).append("Full"), ".json");
SimulationJob fullJob;
fullJob.load(fullJobFilepath.string());
fullJob.pMesh->setBeamMaterial(0.3, fullPatternYoungsModulus);
fullPatternSimulationJobs.push_back(std::make_shared<SimulationJob>(fullJob));
// Load reduced job
const auto reducedJobFilepath = Utilities::getFilepathWithExtension(
std::filesystem::path(simulationScenarioPath).append("Reduced"), ".json");
SimulationJob reducedJob;
reducedJob.load(reducedJobFilepath.string());
// applyOptimizationResults_innerHexagon(*this, baseTriangle, *job.pMesh);
applyOptimizationResults_elements(*this, reducedJob.pMesh);
reducedPatternSimulationJobs.push_back(
std::make_shared<SimulationJob>(reducedJob));
@ -834,67 +915,77 @@ struct Settings
}
#if POLYSCOPE_DEFINED
void draw() const {
PolyscopeInterface::init();
DRMSimulationModel drmSimulator;
LinearSimulationModel linearSimulator;
assert(fullPatternSimulationJobs.size() == reducedPatternSimulationJobs.size());
fullPatternSimulationJobs[0]->pMesh->registerForDrawing(Colors::fullInitial);
reducedPatternSimulationJobs[0]->pMesh->registerForDrawing(Colors::reducedInitial, false);
void draw(const std::vector<int> &desiredSimulationScenariosIndices = std::vector<int>()) const
{
PolyscopeInterface::init();
DRMSimulationModel drmSimulator;
LinearSimulationModel linearSimulator;
assert(fullPatternSimulationJobs.size() == reducedPatternSimulationJobs.size());
fullPatternSimulationJobs[0]->pMesh->registerForDrawing(Colors::fullInitial);
reducedPatternSimulationJobs[0]->pMesh->registerForDrawing(Colors::reducedInitial, false);
const int numberOfSimulationJobs = fullPatternSimulationJobs.size();
for (int simulationJobIndex = 0; simulationJobIndex < numberOfSimulationJobs;
simulationJobIndex++) {
// Drawing of full pattern results
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob
= fullPatternSimulationJobs[simulationJobIndex];
pFullPatternSimulationJob->registerForDrawing(
fullPatternSimulationJobs[0]->pMesh->getLabel());
DRMSimulationModel::Settings drmSettings;
SimulationResults fullModelResults
= drmSimulator.executeSimulation(pFullPatternSimulationJob, drmSettings);
fullModelResults.registerForDrawing(Colors::fullDeformed, true);
// SimulationResults fullModelLinearResults =
// linearSimulator.executeSimulation(pFullPatternSimulationJob);
// fullModelLinearResults.setLabelPrefix("linear");
// fullModelLinearResults.registerForDrawing(Colors::fullDeformed,false);
// Drawing of reduced pattern results
const std::shared_ptr<SimulationJob> &pReducedPatternSimulationJob
= reducedPatternSimulationJobs[simulationJobIndex];
// pReducedPatternSimulationJob->pMesh->registerForDrawing();
// polyscope::show();
// SimulationResults reducedModelResults = drmSimulator.executeSimulation(
// pReducedPatternSimulationJob);
// reducedModelResults.registerForDrawing(Colors::reducedDeformed, false);
// SimulationResults reducedModelResults
// = drmSimulator.executeSimulation(pReducedPatternSimulationJob,
// DRMSimulationModel::Settings());
SimulationResults reducedModelResults = linearSimulator.executeSimulation(
pReducedPatternSimulationJob);
reducedModelResults.setLabelPrefix("linear");
reducedModelResults.registerForDrawing(Colors::reducedDeformed, true);
polyscope::options::programName = fullPatternSimulationJobs[0]->pMesh->getLabel();
// polyscope::view::resetCameraToHomeView();
polyscope::show();
// Save a screensh
const std::string screenshotFilename
= "/home/iason/Coding/Projects/Approximating shapes with flat "
"patterns/RodModelOptimizationForPatterns/Results/Images/"
+ fullPatternSimulationJobs[0]->pMesh->getLabel() + "_"
+ pFullPatternSimulationJob->getLabel();
polyscope::screenshot(screenshotFilename, false);
pFullPatternSimulationJob->unregister(fullPatternSimulationJobs[0]->pMesh->getLabel());
fullModelResults.unregister();
// reducedModelResults.unregister();
reducedModelResults.unregister();
// fullModelLinearResults.unregister();
// double error = computeError(reducedModelLinearResults.displacements,
// fullModelResults.displacements);
// std::cout << "Error of simulation scenario "
// << simulationScenarioStrings[simulationScenarioIndex] << " is " << error
// << std::endl;
const int numberOfSimulationJobs = fullPatternSimulationJobs.size();
const std::vector<int> scenariosToDraw = [&]() {
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
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob
= fullPatternSimulationJobs[simulationJobIndex];
pFullPatternSimulationJob->registerForDrawing(
fullPatternSimulationJobs[0]->pMesh->getLabel());
DRMSimulationModel::Settings drmSettings;
SimulationResults fullModelResults
= drmSimulator.executeSimulation(pFullPatternSimulationJob, drmSettings);
fullModelResults.registerForDrawing(Colors::fullDeformed, true);
// SimulationResults fullModelLinearResults =
// linearSimulator.executeSimulation(pFullPatternSimulationJob);
// fullModelLinearResults.setLabelPrefix("linear");
// fullModelLinearResults.registerForDrawing(Colors::fullDeformed,false);
// Drawing of reduced pattern results
const std::shared_ptr<SimulationJob> &pReducedPatternSimulationJob
= reducedPatternSimulationJobs[simulationJobIndex];
// pReducedPatternSimulationJob->pMesh->registerForDrawing();
// polyscope::show();
// SimulationResults reducedModelResults = drmSimulator.executeSimulation(
// pReducedPatternSimulationJob);
// reducedModelResults.registerForDrawing(Colors::reducedDeformed, false);
// SimulationResults reducedModelResults
// = drmSimulator.executeSimulation(pReducedPatternSimulationJob,
// DRMSimulationModel::Settings());
SimulationResults reducedModelResults = linearSimulator.executeSimulation(
pReducedPatternSimulationJob);
reducedModelResults.setLabelPrefix("linear");
reducedModelResults.registerForDrawing(Colors::reducedDeformed, true);
polyscope::options::programName = fullPatternSimulationJobs[0]->pMesh->getLabel();
// polyscope::view::resetCameraToHomeView();
polyscope::show();
// Save a screensh
const std::string screenshotFilename
= "/home/iason/Coding/Projects/Approximating shapes with flat "
"patterns/RodModelOptimizationForPatterns/Results/Images/"
+ fullPatternSimulationJobs[0]->pMesh->getLabel() + "_"
+ pFullPatternSimulationJob->getLabel();
polyscope::screenshot(screenshotFilename, false);
pFullPatternSimulationJob->unregister(fullPatternSimulationJobs[0]->pMesh->getLabel());
fullModelResults.unregister();
// reducedModelResults.unregister();
reducedModelResults.unregister();
// fullModelLinearResults.unregister();
// double error = computeError(reducedModelLinearResults.displacements,
// fullModelResults.displacements);
// std::cout << "Error of simulation scenario "
// << simulationScenarioStrings[simulationScenarioIndex] << " is " << error
// << std::endl;
}
}
}
#endif // POLYSCOPE_DEFINED
void saveMeshFiles() const {
const int numberOfSimulationJobs = fullPatternSimulationJobs.size();
@ -1027,5 +1118,9 @@ struct Settings
};
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