diff --git a/src/main.cpp b/src/main.cpp index b4cad26..fbbc4ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,245 +16,61 @@ #include #include -void exportOptimizationResults( - const ReducedModelOptimizer::Results &optimizationResults, - const std::filesystem::path &optimizationDirectory, - const ReducedModelOptimizer::Settings &settings_optimization, - csvFile &statistics, - const std::pair patternPair) { - std::filesystem::path saveToPath(std::filesystem::path(optimizationDirectory) - .append(patternPair.first->getLabel() + - "@" + - patternPair.second->getLabel())); - std::filesystem::create_directories(std::filesystem::path(saveToPath)); - - optimizationResults.save(saveToPath.string()); - statistics << patternPair.first->getLabel() + "@" + - patternPair.second->getLabel(); - statistics << optimizationResults.objectiveValue; - for (const double &optimalX : optimizationResults.x) { - statistics << optimalX; - } - - for (int unusedXVarCounter = 0; - unusedXVarCounter < - settings_optimization.xRanges.size() - optimizationResults.x.size(); - unusedXVarCounter++) { - statistics << "-"; - } - - statistics << optimizationResults.time; - if (optimizationResults.numberOfSimulationCrashes == 0) { - statistics << "No crashes"; - } else { - statistics << optimizationResults.numberOfSimulationCrashes; - } - statistics << endrow; -} - -void optimizeTestSet( - const std::vector> patternPairs, - const ReducedModelOptimizer::Settings &settings_optimization, - const std::string &saveTo) { - const std::string optimizationSettingsString = - settings_optimization.toString(); - std::filesystem::path thisOptimizationDirectory( - std::filesystem::path(saveTo).append(optimizationSettingsString)); - //.append("Results")); - std::filesystem::create_directories(thisOptimizationDirectory); - std::cout << optimizationSettingsString << std::endl; - csvFile csv_settings(std::filesystem::path(thisOptimizationDirectory) - .append("settings.csv") - .string(), - true); - settings_optimization.writeTo(csv_settings); - csvFile statistics(std::filesystem::path(thisOptimizationDirectory) - .append("statistics.csv") - .string(), - false); - - // Write header to csv - statistics << "FullPattern@ReducedPattern" - << "Obj value"; - for (const ReducedModelOptimizer::xRange &range : - settings_optimization.xRanges) { - statistics << range.label; - } - statistics << "Time(s)"; - statistics << "#Crashes"; - statistics << endrow; - - double totalError = 0; - int totalNumberOfSimulationCrashes = 0; - std::vector optimizationResults_testSet( - patternPairs.size()); - auto start = std::chrono::high_resolution_clock::now(); - int pairsOptimized = 0; -#pragma omp parallel for - for (int patternPairIndex = 0; patternPairIndex < patternPairs.size(); - patternPairIndex++) { - const std::pair &patternPair = - patternPairs[patternPairIndex]; - std::cout << "Optimizing " << patternPair.first->getLabel() << "@" - << patternPair.second->getLabel() << std::endl; - const std::vector numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1}; - ReducedModelOptimizer optimizer(numberOfNodesPerSlot); - optimizer.initializePatterns(*patternPair.first, *patternPair.second, {}); - ReducedModelOptimizer::Results optimizationResults = - optimizer.optimize(settings_optimization); - - totalError += optimizationResults.objectiveValue; - optimizationResults_testSet[patternPairIndex] = optimizationResults; - totalNumberOfSimulationCrashes += - optimizationResults.numberOfSimulationCrashes; - - std::cout << "Optimized " << ++pairsOptimized << "/" << patternPairs.size() - << std::endl; -#pragma omp critical - { - exportOptimizationResults(optimizationResults, thisOptimizationDirectory, - settings_optimization, statistics, patternPair); - optimizationResults.draw(); - } - } - - // for (int patternPairIndex = 0; patternPairIndex < patternPairs.size(); - // patternPairIndex++) { - // const std::pair &patternPair = - // patternPairs[patternPairIndex]; - // const ReducedModelOptimizer::Results optimizationResults = - // optimizationResults_testSet[patternPairIndex]; - // // Save results - // std::filesystem::path saveToPath( - // std::filesystem::path(thisOptimizationDirectory) - // .append(patternPair.first->getLabel() + "@" + - // patternPair.second->getLabel())); - // std::filesystem::create_directories(std::filesystem::path(saveToPath)); - // optimizationResults.save(saveToPath.string()); - - // // Save statistics - // statistics << patternPair.first->getLabel() + "@" + - // patternPair.second->getLabel(); - // statistics << optimizationResults.objectiveValue; - // for (const double &optimalX : optimizationResults.x) { - // statistics << optimalX; - // } - - // for (int unusedXVarCounter = 0; - // unusedXVarCounter < - // settings_optimization.xRanges.size() - - // optimizationResults.x.size(); unusedXVarCounter++) { - // statistics << "-"; - // } - - // statistics << optimizationResults.time; - // if (optimizationResults.numberOfSimulationCrashes == 0) { - // statistics << "No crashes"; - // } else { - // statistics << optimizationResults.numberOfSimulationCrashes; - // } - // statistics << endrow; - // } -} - int main(int argc, char *argv[]) { - // Create reduced models - // FormFinder::runUnitTests(); - const std::vector numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1}; - std::vector singleBarReducedModelEdges{vcg::Point2i(0, 3)}; - FlatPattern singleBarReducedModel(numberOfNodesPerSlot, - singleBarReducedModelEdges); - singleBarReducedModel.setLabel("SingleBar_reduced"); - singleBarReducedModel.savePly(singleBarReducedModel.getLabel()); - singleBarReducedModel.scale(0.03); + if (argc < 4) { + std::cerr << "Specify the pattern pair to be optimized." << std::endl; + std::terminate(); + } + // Populate the pattern pair to be optimized + ////Full pattern + const std::string filepath_fullPattern = argv[1]; + FlatPattern fullPattern(filepath_fullPattern); + fullPattern.setLabel( + std::filesystem::path(filepath_fullPattern).stem().string()); + fullPattern.scale(0.03); + ////Reduced pattern + const std::string filepath_reducedPattern = argv[2]; + FlatPattern reducedPattern(filepath_reducedPattern); + reducedPattern.setLabel( + std::filesystem::path(filepath_reducedPattern).stem().string()); + reducedPattern.scale(0.03); - std::vector CWreducedModelEdges{vcg::Point2i(1, 5), - vcg::Point2i(3, 5)}; - FlatPattern CWReducedModel(numberOfNodesPerSlot, CWreducedModelEdges); - CWReducedModel.setLabel("CW_reduced"); - CWReducedModel.scale(0.03); - - std::vector CCWreducedModelEdges{vcg::Point2i(1, 5), - vcg::Point2i(3, 1)}; - FlatPattern CCWReducedModel(numberOfNodesPerSlot, CCWreducedModelEdges); - CCWReducedModel.setLabel("CCW_reduced"); - CCWReducedModel.savePly(CWReducedModel.getLabel()); - CCWReducedModel.scale(0.03); - - std::vector reducedModels{&singleBarReducedModel, - &CWReducedModel, &CCWReducedModel}; - - // Define the ranges that the optimizer will use + // Set the optization settings ReducedModelOptimizer::xRange beamWidth{"B", 0.5, 1.5}; ReducedModelOptimizer::xRange beamDimensionsRatio{"bOverh", 0.7, 1.3}; ReducedModelOptimizer::xRange beamE{"E", 0.1, 1.9}; ReducedModelOptimizer::xRange innerHexagonSize{"HS", 0.1, 0.9}; - // Test set of full patterns - std::string fullPatternsTestSetDirectory = "../TestSet"; - if (!std::filesystem::exists( - std::filesystem::path(fullPatternsTestSetDirectory))) { - std::cerr << "Full pattern directory does not exist: " - << fullPatternsTestSetDirectory << std::endl; - return 1; - } - // "/home/iason/Documents/PhD/Research/Approximating shapes with flat " - // "patterns/Pattern_enumerator/Results/1v_0v_2e_1e_1c_6fan/3/Valid"; - std::vector> patternPairs; - for (const auto &entry : - filesystem::directory_iterator(fullPatternsTestSetDirectory)) { - const auto filepath = - // std::filesystem::path(fullPatternsTestSetDirectory).append("305.ply"); - entry.path(); - const std::string filepathString = filepath.string(); - const std::string tiledSuffix = "_tiled.ply"; - if (filepathString.compare(filepathString.size() - tiledSuffix.size(), - tiledSuffix.size(), tiledSuffix) == 0) { - continue; - } - - FlatPattern fullPattern(filepathString); - fullPattern.setLabel(filepath.stem().string()); - fullPattern.scale(0.03); - // for (int reducedPatternIndex = 0; - // reducedPatternIndex < reducedModels.size(); - // reducedPatternIndex++) { - FlatPattern *pFullPattern = new FlatPattern(); - pFullPattern->copy(fullPattern); - FlatPattern *pReducedPattern = new FlatPattern(); - // pReducedPattern->copy(*reducedModels[reducedPatternIndex]); - pReducedPattern->copy(*reducedModels[0]); - patternPairs.push_back(std::make_pair(pFullPattern, pReducedPattern)); - // } - } - - // for (double rangeOffset = 0.15; rangeOffset <= 0.95; rangeOffset += 0.05) - // { ReducedModelOptimizer::Settings settings_optimization; settings_optimization.xRanges = {beamWidth, beamDimensionsRatio, beamE, innerHexagonSize}; + const bool input_numberOfFunctionCallsDefined = argc >= 4; + settings_optimization.numberOfFunctionCalls = + input_numberOfFunctionCallsDefined ? std::atoi(argv[3]) : 100; + // Optimize pair + const std::string pairName = + fullPattern.getLabel() + "@" + reducedPattern.getLabel(); + 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 >= 5; + std::string optimiziationResultsDirectory = + input_resultDirectoryDefined ? argv[4] : "OptimizationResults"; + std::filesystem::path dirPath_thisOptimization( + std::filesystem::path(optimiziationResultsDirectory).append(pairName)); + std::filesystem::create_directories(dirPath_thisOptimization); + 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()); - // for (settings_optimization.numberOfFunctionCalls = 100; - // settings_optimization.numberOfFunctionCalls < 5000; - // settings_optimization.numberOfFunctionCalls += 100) { - std::string optimiziationResultsDirectory = "OptimizationResults"; - if (argc < 2) { - settings_optimization.numberOfFunctionCalls = 100; - } else if (argc == 2) { - settings_optimization.numberOfFunctionCalls = std::atoi(argv[1]); - } else if (argc == 3) { - settings_optimization.numberOfFunctionCalls = std::atoi(argv[1]); - optimiziationResultsDirectory = argv[2]; - } - // settings_optimization.normalizeObjectiveValue = false; - // optimizeTestSet(patternPairs, settings_optimization, - // optimiziationResultsDirectory); - settings_optimization.normalizeObjectiveValue = true; - optimizeTestSet(patternPairs, settings_optimization, - optimiziationResultsDirectory); + // optimizationResults.draw(); - for (auto &patternPair : patternPairs) { - delete patternPair.first; - delete patternPair.second; - } return 0; } diff --git a/src/reducedmodeloptimizer.hpp b/src/reducedmodeloptimizer.hpp index 0cd4ce1..5bdf3f6 100644 --- a/src/reducedmodeloptimizer.hpp +++ b/src/reducedmodeloptimizer.hpp @@ -47,7 +47,7 @@ public: std::vector xRanges; int numberOfFunctionCalls{100}; double solutionAccuracy{1e-2}; - bool normalizeObjectiveValue{ true }; + bool normalizeObjectiveValue{true}; std::string toString() const { std::string settingsString; @@ -59,23 +59,25 @@ public: settingsString += xRangesString; } settingsString += "FuncCalls=" + std::to_string(numberOfFunctionCalls) + - " Accuracy=" + std::to_string(solutionAccuracy)+" Norm="+(normalizeObjectiveValue ? "yes" : "no"); + " Accuracy=" + std::to_string(solutionAccuracy) + + " Norm=" + (normalizeObjectiveValue ? "yes" : "no"); return settingsString; } - void writeTo(csvFile &csv) const { + void writeTo(csvFile &csv, const bool writeHeader = true) const { // Create settings csv header - if (!xRanges.empty()) { - for (const xRange &range : xRanges) { - csv << range.label + " max"; - csv << range.label + " min"; + if (writeHeader) { + if (!xRanges.empty()) { + for (const xRange &range : xRanges) { + csv << range.label + " max"; + csv << range.label + " min"; + } } + csv << "Function Calls"; + csv << "Solution Accuracy"; + csv << endrow; } - csv << "Function Calls"; - csv << "Solution Accuracy"; - csv << "Normalize obj value"; - csv << endrow; if (!xRanges.empty()) { for (const xRange &range : xRanges) { @@ -85,7 +87,6 @@ public: } csv << numberOfFunctionCalls; csv << solutionAccuracy; - csv <<(normalizeObjectiveValue ? "yes" : "no"); csv << endrow; } }; @@ -149,7 +150,8 @@ public: &reducedToFullInterfaceViMap); static double computeError(const std::vector &reducedPatternResults, - const std::vector &fullPatternResults,const double& interfaceDisplacementNormSum, + const std::vector &fullPatternResults, + const double &interfaceDisplacementNormSum, const std::unordered_map &reducedToFullInterfaceViMap); @@ -250,10 +252,9 @@ struct ReducedModelOptimizer::Results { const std::shared_ptr &pReducedPatternSimulationJob = reducedPatternSimulationJobs[simulationJobIndex]; const auto reducedPatternDirectoryPath = - std::filesystem::path(simulationJobFolderPath) - .append("Reduced"); + std::filesystem::path(simulationJobFolderPath).append("Reduced"); if (!std::filesystem::exists(reducedPatternDirectoryPath)) { - std::filesystem::create_directory(reducedPatternDirectoryPath); + std::filesystem::create_directory(reducedPatternDirectoryPath); } pReducedPatternSimulationJob->save(reducedPatternDirectoryPath.string()); } @@ -264,10 +265,12 @@ struct ReducedModelOptimizer::Results { for (const auto &directoryEntry : filesystem::directory_iterator(loadFromPath)) { const auto simulationScenarioPath = directoryEntry.path(); + if (!std::filesystem::is_directory(simulationScenarioPath)) { + continue; + } // Load reduced pattern files for (const auto &fileEntry : filesystem::directory_iterator( - std::filesystem::path(simulationScenarioPath) - .append("Full"))) { + std::filesystem::path(simulationScenarioPath).append("Full"))) { const auto filepath = fileEntry.path(); if (filepath.extension() == ".json") { SimulationJob job; @@ -291,6 +294,39 @@ struct ReducedModelOptimizer::Results { } } } + + void writeTo(const ReducedModelOptimizer::Settings &settings_optimization, + csvFile &csv, const bool writeHeader = true) const { + if (writeHeader) { + //// Write header to csv + csv << "Obj value"; + for (const ReducedModelOptimizer::xRange &range : + settings_optimization.xRanges) { + csv << range.label; + } + csv << "Time(s)"; + csv << "#Crashes"; + csv << endrow; + } + csv << objectiveValue; + for (const double &optimalX : x) { + csv << optimalX; + } + + for (int unusedXVarCounter = 0; + unusedXVarCounter < settings_optimization.xRanges.size() - x.size(); + unusedXVarCounter++) { + csv << "-"; + } + + csv << time; + if (numberOfSimulationCrashes == 0) { + csv << "No crashes"; + } else { + csv << numberOfSimulationCrashes; + } + csv << endrow; + } }; #endif // REDUCEDMODELOPTIMIZER_HPP