diff --git a/src/main.cpp b/src/main.cpp index 985be38..7831655 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,9 +3,6 @@ #include "edgemesh.hpp" #include "externvariables.hpp" #include "flatpattern.hpp" -#include "polyscope/curve_network.h" -#include "polyscope/point_cloud.h" -#include "polyscope/polyscope.h" #include "reducedmodeloptimizer.hpp" #include "simulationhistoryplotter.hpp" #include "trianglepattterntopology.hpp" @@ -57,33 +54,60 @@ int main(int argc, char *argv[]) { const bool input_numberOfFunctionCallsDefined = argc >= 5; settings_optimization.numberOfFunctionCalls = input_numberOfFunctionCallsDefined ? std::atoi(argv[4]) : 100; + settings_optimization.normalizeObjectiveValue = true; + // Optimize pair const std::string pairName = fullPattern.getLabel() + "@" + reducedPattern.getLabel(); if (printDebugInfo) { std::cout << "Optimizing " << pairName << std::endl; } - const std::vector numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1}; ReducedModelOptimizer optimizer(numberOfNodesPerSlot); optimizer.initializePatterns(fullPattern, reducedPattern, {}); ReducedModelOptimizer::Results optimizationResults = optimizer.optimize(settings_optimization); + // Export results const bool input_resultDirectoryDefined = argc >= 6; - std::string optimiziationResultsDirectory = + std::string optimizationResultsDirectory = input_resultDirectoryDefined ? argv[5] : "OptimizationResults"; - std::filesystem::path dirPath_thisOptimization( - std::filesystem::path(optimiziationResultsDirectory).append(pairName)); - std::filesystem::create_directories(dirPath_thisOptimization); + //// Get current date for creating the results folder + std::time_t now = time(0); + std::tm *ltm = std::localtime(&now); + std::string currentDate = std::to_string(ltm->tm_mday) + "_" + + std::to_string(1 + ltm->tm_mon) + "_" + + std::to_string(1900 + ltm->tm_year); + std::filesystem::path optimizationResultsDirectoryDatePath( + std::filesystem::path(optimizationResultsDirectory).append(currentDate)); + if (optimizationResults.numberOfSimulationCrashes != 0) { + const auto crashedJobsDirPath = + std::filesystem::path(optimizationResultsDirectoryDatePath) + .append("CrashedJobs") + .append(pairName); + std::filesystem::create_directories(crashedJobsDirPath); + optimizationResults.save(crashedJobsDirPath.string()); + } else { + std::filesystem::path dirPath_thisOptimization( + std::filesystem::path(optimizationResultsDirectoryDatePath) + .append("ConvergedJobs") + .append(pairName)); + std::filesystem::create_directories(dirPath_thisOptimization); + optimizationResults.save(dirPath_thisOptimization.string()); + } csvFile csv_results({}, false); // csvFile csv_results(std::filesystem::path(dirPath_thisOptimization) // .append("results.csv") // .string(), // false); - settings_optimization.writeTo(csv_results); - optimizationResults.writeTo(settings_optimization, csv_results); - optimizationResults.save(dirPath_thisOptimization.string()); + csv_results << "Name"; + optimizationResults.writeHeaderTo(settings_optimization, csv_results); + settings_optimization.writeHeaderTo(csv_results); + csv_results << endrow; + csv_results << pairName; + optimizationResults.writeResultsTo(settings_optimization, csv_results); + settings_optimization.writeSettingsTo(csv_results); + csv_results << endrow; // optimizationResults.draw(); diff --git a/src/reducedmodeloptimizer.cpp b/src/reducedmodeloptimizer.cpp index 7703db0..852696e 100644 --- a/src/reducedmodeloptimizer.cpp +++ b/src/reducedmodeloptimizer.cpp @@ -33,16 +33,7 @@ struct GlobalOptimizationVariables { int numberOfFunctionCalls{0}; int numberOfOptimizationParameters{3}; ReducedModelOptimizer::Settings optimizationSettings; -}; - -// static GlobalOptimizationVariables global; - -const static int MAX_THREAD = 64; -#if defined(_MSC_VER) -__declspec(align(64)) GlobalOptimizationVariables tls[MAX_THREAD]; -#elif defined(__GNUC__) -GlobalOptimizationVariables tls[MAX_THREAD] __attribute__((aligned(64))); -#endif +} global; //#pragma omp threadprivate(global) // struct OptimizationCallback { @@ -128,7 +119,6 @@ double ReducedModelOptimizer::computeError( const double &interfaceDisplacementsNormSum, const std::unordered_map &reducedToFullInterfaceViMap) { - auto &global = tls[omp_get_thread_num()]; double error = 0; for (const auto reducedFullViPair : reducedToFullInterfaceViMap) { VertexIndex reducedModelVi = reducedFullViPair.first; @@ -162,7 +152,6 @@ double ReducedModelOptimizer::computeError( } void updateMesh(long n, const double *x) { - auto &global = tls[omp_get_thread_num()]; std::shared_ptr &pReducedPatternSimulationMesh = global.reducedPatternSimulationJobs[global.simulationScenarioIndices[0]] ->pMesh; @@ -235,7 +224,6 @@ double ReducedModelOptimizer::objective(double b, double h, double E, } double ReducedModelOptimizer::objective(long n, const double *x) { - auto &global = tls[omp_get_thread_num()]; // std::cout.precision(17); // for (size_t parameterIndex = 0; parameterIndex < n; parameterIndex++) { @@ -263,34 +251,8 @@ double ReducedModelOptimizer::objective(long n, const double *x) { global.reducedPatternSimulationJobs[simulationScenarioIndex], simulationSettings); std::string filename; - if (!reducedModelResults.converged /*&& - g_reducedPatternSimulationJob[g_simulationScenarioIndices[0]] - ->pMesh->elements[0] - .A > 1e-8 & - x[0] / x[1] < 60*/) { - std::cout << "Failed simulation" << std::endl; + if (!reducedModelResults.converged) { error += std::numeric_limits::max(); - filename = "/home/iason/Coding/Projects/Approximating shapes with flat " - "patterns/RodModelOptimizationForPatterns/build/" - "ProblematicSimulationJobs/nonConv_dimensions.txt"; - // if (failedSimulationsXRatio.empty()) { - // failedSimulationsXRatio.resize(2); - // } - // failedSimulationsXRatio[0].push_back(std::log(x[0] / x[1])); - // failedSimulationsXRatio[1].push_back( - // std::log(g_reducedPatternSimulationJob[g_simulationScenarioIndices[0]] - // ->pMesh->elements[0] - // .A)); - - // SimulationResultsReporter::createPlot( - // "log(b/h)", "log(A)", failedSimulationsXRatio[0], - // failedSimulationsXRatio[1], "ratioToAPlot.png"); - // std::cout << "Failed simulation" << std::endl; - // simulationSettings.shouldDraw = true; - // simulationSettings.debugMessages = true; - // simulator.executeSimulation( - // g_reducedPatternSimulationJob[simulationScenarioIndex], - // simulationSettings); global.numOfSimulationCrashes++; } else { error += computeError( @@ -298,9 +260,6 @@ double ReducedModelOptimizer::objective(long n, const double *x) { global.fullPatternDisplacements[simulationScenarioIndex], global.fullPatternDisplacementNormSum[simulationScenarioIndex], global.reducedToFullInterfaceViMap); - filename = "/home/iason/Coding/Projects/Approximating shapes with flat " - "patterns/RodModelOptimizationForPatterns/build/" - "ProblematicSimulationJobs/conv_dimensions.txt"; } std::ofstream out(filename, std::ios_base::app); auto pMesh = @@ -391,7 +350,6 @@ void ReducedModelOptimizer::computeMaps( std::unordered_map &fullPatternOppositeInterfaceViMap) { - auto &global = tls[omp_get_thread_num()]; // Compute the offset between the interface nodes const size_t interfaceSlotIndex = 4; // bottom edge assert(slotToNode.find(interfaceSlotIndex) != slotToNode.end() && @@ -456,65 +414,11 @@ void ReducedModelOptimizer::computeMaps( assert(vi0 < fullPattern.VN() && vi1 < fullPattern.VN()); fullPatternOppositeInterfaceViMap[vi0] = vi1; } - - const bool debugMapping = false; - if (debugMapping) { - reducedPattern.registerForDrawing(); - std::vector colors_reducedPatternExcludedEdges( - reducedPattern.EN(), glm::vec3(0, 0, 0)); - for (const size_t ei : global.reducedPatternExludedEdges) { - colors_reducedPatternExcludedEdges[ei] = glm::vec3(1, 0, 0); - } - const std::string label = reducedPattern.getLabel(); - polyscope::getCurveNetwork(label) - ->addEdgeColorQuantity("Excluded edges", - colors_reducedPatternExcludedEdges) - ->setEnabled(true); - polyscope::show(); - - std::vector nodeColorsOpposite(fullPattern.VN(), - glm::vec3(0, 0, 0)); - for (const std::pair oppositeVerts : - fullPatternOppositeInterfaceViMap) { - auto color = polyscope::getNextUniqueColor(); - nodeColorsOpposite[oppositeVerts.first] = color; - nodeColorsOpposite[oppositeVerts.second] = color; - } - fullPattern.registerForDrawing(); - polyscope::getCurveNetwork(fullPattern.getLabel()) - ->addNodeColorQuantity("oppositeMap", nodeColorsOpposite) - ->setEnabled(true); - polyscope::show(); - - std::vector nodeColorsReducedToFull_reduced(reducedPattern.VN(), - glm::vec3(0, 0, 0)); - std::vector nodeColorsReducedToFull_full(fullPattern.VN(), - glm::vec3(0, 0, 0)); - for (size_t vi = 0; vi < reducedPattern.VN(); vi++) { - if (global.reducedToFullInterfaceViMap.contains(vi)) { - - auto color = polyscope::getNextUniqueColor(); - nodeColorsReducedToFull_reduced[vi] = color; - nodeColorsReducedToFull_full[global.reducedToFullInterfaceViMap[vi]] = - color; - } - } - polyscope::getCurveNetwork(reducedPattern.getLabel()) - ->addNodeColorQuantity("reducedToFull_reduced", - nodeColorsReducedToFull_reduced) - ->setEnabled(true); - polyscope::getCurveNetwork(fullPattern.getLabel()) - ->addNodeColorQuantity("reducedToFull_full", - nodeColorsReducedToFull_full) - ->setEnabled(true); - polyscope::show(); - } } void ReducedModelOptimizer::computeMaps( FlatPattern &fullPattern, FlatPattern &reducedPattern, const std::unordered_set &reducedModelExcludedEdges) { - auto &global = tls[omp_get_thread_num()]; ReducedModelOptimizer::computeMaps( reducedModelExcludedEdges, slotToNode, fullPattern, reducedPattern, global.reducedToFullInterfaceViMap, m_fullToReducedInterfaceViMap, @@ -534,13 +438,11 @@ void ReducedModelOptimizer::initializePatterns( // reducedPattern.setLabel("reduced_pattern_" + reducedPattern.getLabel()); assert(fullPattern.VN() == reducedPattern.VN() && fullPattern.EN() >= reducedPattern.EN()); - polyscope::removeAllStructures(); // Create copies of the input models FlatPattern copyFullPattern; FlatPattern copyReducedPattern; copyFullPattern.copy(fullPattern); copyReducedPattern.copy(reducedPattern); - auto &global = tls[omp_get_thread_num()]; global.optimizeInnerHexagonSize = copyReducedPattern.EN() == 2; if (global.optimizeInnerHexagonSize) { const double h = copyReducedPattern.getBaseTriangleHeight(); @@ -571,7 +473,6 @@ void ReducedModelOptimizer::initializePatterns( void ReducedModelOptimizer::initializeOptimizationParameters( const std::shared_ptr &mesh) { - auto &global = tls[omp_get_thread_num()]; global.numberOfOptimizationParameters = 3; global.g_initialParameters.resize( global.optimizeInnerHexagonSize ? ++global.numberOfOptimizationParameters @@ -666,7 +567,6 @@ void ReducedModelOptimizer::computeDesiredReducedModelDisplacements( ReducedModelOptimizer::Results ReducedModelOptimizer::runOptimization(const Settings &settings) { - auto &global = tls[omp_get_thread_num()]; global.gObjectiveValueHistory.clear(); @@ -1035,71 +935,9 @@ ReducedModelOptimizer::createScenarios( // reducedModelResults.unregister(); //} -void ReducedModelOptimizer::visualizeResults( - const std::vector> - &fullPatternSimulationJobs, - const std::vector> - &reducedPatternSimulationJobs, - const std::vector &simulationScenarios, - const std::unordered_map - &reducedToFullInterfaceViMap) { - FormFinder simulator; - std::shared_ptr pFullPatternSimulationMesh = - fullPatternSimulationJobs[0]->pMesh; - pFullPatternSimulationMesh->registerForDrawing(); - double totalError = 0; - for (const int simulationScenarioIndex : simulationScenarios) { - const std::shared_ptr &pFullPatternSimulationJob = - fullPatternSimulationJobs[simulationScenarioIndex]; - pFullPatternSimulationJob->registerForDrawing( - pFullPatternSimulationMesh->getLabel()); - SimulationResults fullModelResults = - simulator.executeSimulation(pFullPatternSimulationJob); - fullModelResults.registerForDrawing(); - // fullModelResults.saveDeformedModel(); - const std::shared_ptr &pReducedPatternSimulationJob = - reducedPatternSimulationJobs[simulationScenarioIndex]; - SimulationResults reducedModelResults = - simulator.executeSimulation(pReducedPatternSimulationJob); - double interfaceDisplacementNormSum = 0; - for (const auto &interfaceViPair : reducedToFullInterfaceViMap) { - const int fullPatternInterfaceIndex = interfaceViPair.second; - Eigen::Vector3d fullPatternDisplacementVector( - fullModelResults.displacements[fullPatternInterfaceIndex][0], - fullModelResults.displacements[fullPatternInterfaceIndex][1], - fullModelResults.displacements[fullPatternInterfaceIndex][2]); - interfaceDisplacementNormSum += fullPatternDisplacementVector.norm(); - } - double error = computeError( - reducedModelResults.displacements, fullModelResults.displacements, - interfaceDisplacementNormSum, reducedToFullInterfaceViMap); - std::cout << "Error of simulation scenario " - << simulationScenarioStrings[simulationScenarioIndex] << " is " - << error << std::endl; - totalError += error; - reducedModelResults.registerForDrawing(); - // firstOptimizationRoundResults[simulationScenarioIndex].registerForDrawing(); - // reducedModelResults.saveDeformedModel(); - // registerWorldAxes(); - const std::string screenshotFilename = - "/home/iason/Coding/Projects/Approximating shapes with flat " - "patterns/RodModelOptimizationForPatterns/build/OptimizationResults/" - "Images/" + - pFullPatternSimulationMesh->getLabel() + "_" + - simulationScenarioStrings[simulationScenarioIndex]; - polyscope::show(); - polyscope::screenshot(screenshotFilename, false); - fullModelResults.unregister(); - reducedModelResults.unregister(); - // firstOptimizationRoundResults[simulationScenarioIndex].unregister(); - } - std::cout << "Total error:" << totalError << std::endl; -} - ReducedModelOptimizer::Results ReducedModelOptimizer::optimize( const Settings &optimizationSettings, const std::vector &simulationScenarios) { - auto &global = tls[omp_get_thread_num()]; global.simulationScenarioIndices = simulationScenarios; if (global.simulationScenarioIndices.empty()) { diff --git a/src/reducedmodeloptimizer.hpp b/src/reducedmodeloptimizer.hpp index 71620c1..b4dc7c6 100644 --- a/src/reducedmodeloptimizer.hpp +++ b/src/reducedmodeloptimizer.hpp @@ -65,21 +65,19 @@ public: return settingsString; } - void writeTo(csvFile &os, const bool writeHeader = true) const { - // Create settings csv header - if (writeHeader) { - if (!xRanges.empty()) { - for (const xRange &range : xRanges) { - os << range.label + " max"; - os << range.label + " min"; - } + void writeHeaderTo(csvFile &os) const { + if (!xRanges.empty()) { + for (const xRange &range : xRanges) { + os << range.label + " max"; + os << range.label + " min"; } - os << "Function Calls"; - os << "Solution Accuracy"; - // os << std::endl; - os << endrow; } + os << "Function Calls"; + os << "Solution Accuracy"; + // os << std::endl; + } + void writeSettingsTo(csvFile &os) const { if (!xRanges.empty()) { for (const xRange &range : xRanges) { os << range.max; @@ -88,8 +86,6 @@ public: } os << numberOfFunctionCalls; os << solutionAccuracy; - // os << std::endl; - os << endrow; } }; @@ -191,50 +187,6 @@ struct ReducedModelOptimizer::Results { std::vector> fullPatternSimulationJobs; std::vector> reducedPatternSimulationJobs; - void draw() const { - initPolyscope(); - FormFinder simulator; - assert(fullPatternSimulationJobs.size() == - reducedPatternSimulationJobs.size()); - fullPatternSimulationJobs[0]->pMesh->registerForDrawing(); - reducedPatternSimulationJobs[0]->pMesh->registerForDrawing(); - - const int numberOfSimulationJobs = fullPatternSimulationJobs.size(); - for (int simulationJobIndex = 0; - simulationJobIndex < numberOfSimulationJobs; simulationJobIndex++) { - // Drawing of full pattern results - const std::shared_ptr &pFullPatternSimulationJob = - fullPatternSimulationJobs[simulationJobIndex]; - pFullPatternSimulationJob->registerForDrawing( - fullPatternSimulationJobs[0]->pMesh->getLabel()); - SimulationResults fullModelResults = - simulator.executeSimulation(pFullPatternSimulationJob); - fullModelResults.registerForDrawing(); - // Drawing of reduced pattern results - const std::shared_ptr &pReducedPatternSimulationJob = - reducedPatternSimulationJobs[simulationJobIndex]; - SimulationResults reducedModelResults = - simulator.executeSimulation(pReducedPatternSimulationJob); - reducedModelResults.registerForDrawing(); - polyscope::show(); - // Save a screensh - // const std::string screenshotFilename = - // "/home/iason/Coding/Projects/Approximating shapes with flat " - // "patterns/RodModelOptimizationForPatterns/build/OptimizationResults/" - // + m_pFullPatternSimulationMesh->getLabel() + "_" + - // simulationScenarioStrings[simulationScenarioIndex]; - // polyscope::screenshot(screenshotFilename, false); - fullModelResults.unregister(); - reducedModelResults.unregister(); - // double error = computeError( - // reducedModelResults, - // global.g_optimalReducedModelDisplacements[simulationScenarioIndex]); - // std::cout << "Error of simulation scenario " - // << simulationScenarioStrings[simulationScenarioIndex] << " - // is " - // << error << std::endl; - } - } void save(const string &saveToPath) const { assert(std::filesystem::is_directory(saveToPath)); @@ -325,20 +277,21 @@ struct ReducedModelOptimizer::Results { } } - void writeTo(const ReducedModelOptimizer::Settings &settings_optimization, - csvFile &os, const bool writeHeader = true) const { - if (writeHeader) { - //// Write header to csv - os << "Obj value"; - for (const ReducedModelOptimizer::xRange &range : - settings_optimization.xRanges) { - os << range.label; - } - os << "Time(s)"; - os << "#Crashes"; - // os << std::endl; - os << endrow; + void + writeHeaderTo(const ReducedModelOptimizer::Settings &settings_optimization, + csvFile &os) { + os << "Obj value"; + for (const ReducedModelOptimizer::xRange &range : + settings_optimization.xRanges) { + os << range.label; } + os << "Time(s)"; + os << "#Crashes"; + } + + void + writeResultsTo(const ReducedModelOptimizer::Settings &settings_optimization, + csvFile &os) const { os << objectiveValue; for (const double &optimalX : x) { os << optimalX; @@ -356,8 +309,6 @@ struct ReducedModelOptimizer::Results { } else { os << numberOfSimulationCrashes; } - // os << std::endl; - os << endrow; } };