2022-01-14 14:02:27 +01:00
|
|
|
#include "reducedmodelevaluator.hpp"
|
|
|
|
#include "hexagonremesher.hpp"
|
2022-02-18 16:46:28 +01:00
|
|
|
#include "reducedmodel.hpp"
|
2022-05-06 15:40:05 +02:00
|
|
|
#include "reducedmodeloptimizer.hpp"
|
2022-01-14 14:02:27 +01:00
|
|
|
#include "trianglepatterngeometry.hpp"
|
2022-05-06 15:40:05 +02:00
|
|
|
#include <execution>
|
2022-01-14 14:02:27 +01:00
|
|
|
#include <filesystem>
|
|
|
|
|
|
|
|
using FullPatternVertexIndex = VertexIndex;
|
|
|
|
using ReducedPatternVertexIndex = VertexIndex;
|
|
|
|
|
|
|
|
ReducedModelEvaluator::ReducedModelEvaluator()
|
|
|
|
{
|
2022-05-06 15:40:05 +02:00
|
|
|
pTileIntoSurface = [&]() {
|
|
|
|
std::istringstream inputStream_tileIntoTriSurface(tileIntoSurfaceFileContent);
|
|
|
|
VCGTriMesh tileInto_triMesh;
|
|
|
|
const bool surfaceLoadSuccessfull = tileInto_triMesh.load(inputStream_tileIntoTriSurface);
|
|
|
|
tileInto_triMesh.setLabel("instantMeshes_plane_34");
|
|
|
|
assert(surfaceLoadSuccessfull);
|
|
|
|
return PolygonalRemeshing::remeshWithPolygons(tileInto_triMesh);
|
|
|
|
}();
|
2022-01-14 14:02:27 +01:00
|
|
|
}
|
2022-05-06 15:40:05 +02:00
|
|
|
|
|
|
|
//double ReducedModelEvaluator::evaluateOptimizationSettings(
|
|
|
|
// const ReducedModelOptimization::Settings &optimizationSettings,
|
|
|
|
// const std::vector<std::shared_ptr<PatternGeometry>> &pPatterns,
|
|
|
|
// std::vector<ReducedModelEvaluator::Results> &patternEvaluationResults)
|
|
|
|
//{
|
|
|
|
// assert(!pPatterns.empty());
|
|
|
|
// double optimizationError = 0;
|
|
|
|
// auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
// std::vector<double> averageNormalizedError(pPatterns.size(), 0);
|
|
|
|
// patternEvaluationResults.clear();
|
|
|
|
// patternEvaluationResults.resize(pPatterns.size());
|
|
|
|
// std::for_each(
|
|
|
|
// // std::execution::par_unseq,
|
|
|
|
// pPatterns.begin(),
|
|
|
|
// pPatterns.end(),
|
|
|
|
// [&](const std::shared_ptr<ConstPatternGeometry> &pPattern) {
|
|
|
|
// // std::cout << "Optimizing " << pPattern->getLabel() << std::endl;
|
|
|
|
// ReducedModelOptimization::Results optimizationResults;
|
|
|
|
// ReducedModelOptimizer optimizer;
|
|
|
|
// optimizer.optimize(*pPattern, optimizationSettings, optimizationResults);
|
|
|
|
// const auto evaluationResults
|
|
|
|
// = ReducedModelEvaluator::evaluateReducedModel(optimizationResults,
|
|
|
|
// tileIntoSurfaceFilePath,
|
|
|
|
// scenariosDirPath,
|
|
|
|
// fullPatternTessellatedResultsDirPath);
|
|
|
|
// const double averageNormalizedErrorOfPattern
|
|
|
|
// = std::reduce(evaluationResults.distances_normalizedDrm2reduced.begin(),
|
|
|
|
// evaluationResults.distances_normalizedDrm2reduced.end())
|
|
|
|
// / evaluationResults.distances_normalizedDrm2reduced.size();
|
|
|
|
// const int patternIndex = &pPattern - &patterns[0];
|
|
|
|
// averageNormalizedError[patternIndex] = averageNormalizedErrorOfPattern;
|
|
|
|
// patternsEvaluationResults[patternIndex] = evaluationResults;
|
|
|
|
// });
|
|
|
|
// const double strategyAverageNormalizedError = std::reduce(std::execution::par_unseq,
|
|
|
|
// averageNormalizedError.begin(),
|
|
|
|
// averageNormalizedError.end())
|
|
|
|
// / pPointers.size();
|
|
|
|
// const auto totalDuration_min = std::chrono::duration_cast<std::chrono::seconds>(
|
|
|
|
// std::chrono::high_resolution_clock::now() - start)
|
|
|
|
// .count()
|
|
|
|
// / 60.0;
|
|
|
|
// std::cout << "Optimized pattern(s) in:" << totalDuration_min << " minutes." << std::endl;
|
|
|
|
// std::cout << "Average time per pattern:" << totalDuration_min / patternsPointers.size()
|
|
|
|
// << " minutes." << std::endl;
|
|
|
|
// std::cout << "Objective value:" << strategyAverageNormalizedError << std::endl;
|
|
|
|
// return strategyAverageNormalizedError;
|
|
|
|
// // std::cout << "After:" << ++numberOfOptimizationRoundsExecuted << " iterations." << std::endl;
|
|
|
|
//}
|
|
|
|
|
2022-01-28 19:01:44 +01:00
|
|
|
ReducedModelEvaluator::Results ReducedModelEvaluator::evaluateReducedModel(
|
|
|
|
ReducedModelOptimization::Results &optimizationResult)
|
|
|
|
{
|
|
|
|
const std::filesystem::path scenariosDirectoryPath
|
|
|
|
= "/home/iason/Coding/Projects/Approximating shapes with flat "
|
|
|
|
"patterns/ReducedModelEvaluator/Scenarios";
|
|
|
|
const std::filesystem::path fullPatternTessellatedResultsDirectoryPath
|
2022-02-01 12:06:53 +01:00
|
|
|
= "/home/iason/Coding/Projects/Approximating shapes with flat "
|
|
|
|
"patterns/ReducedModelEvaluator/TessellatedResults";
|
2022-01-14 14:02:27 +01:00
|
|
|
|
2022-01-28 19:01:44 +01:00
|
|
|
return evaluateReducedModel(optimizationResult,
|
|
|
|
scenariosDirectoryPath,
|
|
|
|
fullPatternTessellatedResultsDirectoryPath);
|
|
|
|
}
|
2022-02-18 16:46:28 +01:00
|
|
|
//void ReducedModelEvaluator::printResults(const Results &evaluationResults,
|
|
|
|
// const std::string &resultsLabel,
|
|
|
|
// const std::filesystem::path &resultsOutputPath)
|
|
|
|
//{
|
|
|
|
// const bool outputPathIsDirectory = !resultsOutputPath.empty()
|
|
|
|
// && !resultsOutputPath.has_extension();
|
|
|
|
// const bool outputPathIsFile = !resultsOutputPath.empty() && resultsOutputPath.has_extension();
|
|
|
|
// assert(outputPathIsDirectory && outputPathIsFile);
|
|
|
|
// if (outputPathIsDirectory) {
|
|
|
|
// std::filesystem::create_directories(resultsOutputPath);
|
|
|
|
// }
|
|
|
|
|
|
|
|
//#else
|
|
|
|
// std::filesystem::path csvOutputFilePath;
|
|
|
|
// bool shouldOverwrite = false;
|
|
|
|
// if (outputPathIsDirectory) {
|
|
|
|
// csvOutputFilePath = std::filesystem::path(resultsOutputPath)
|
|
|
|
// .append("distances_" + resultsLabel + ".csv")
|
|
|
|
// .string();
|
|
|
|
// shouldOverwrite = true;
|
|
|
|
// } else if (outputPathIsFile) {
|
|
|
|
// csvOutputFilePath = resultsOutputPath;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// csvFile csvOutput(csvOutputFilePath, shouldOverwrite);
|
|
|
|
// printResults(evaluationResults, resultsLabel, csvOutput);
|
|
|
|
//}
|
|
|
|
|
|
|
|
void ReducedModelEvaluator::printResults(const Results &evaluationResults,
|
|
|
|
const std::string &resultsLabel)
|
|
|
|
{
|
|
|
|
csvFile csvOutputToCout({}, true);
|
|
|
|
Settings exportSettings;
|
|
|
|
exportSettings.exportingDirection = Vertical;
|
|
|
|
exportSettings.shouldWriteHeader = false;
|
|
|
|
exportSettings.resultsLabel = resultsLabel;
|
|
|
|
printResults(evaluationResults, exportSettings, csvOutputToCout);
|
|
|
|
}
|
2022-01-28 19:01:44 +01:00
|
|
|
|
|
|
|
void ReducedModelEvaluator::printResults(const Results &evaluationResults,
|
2022-02-18 16:46:28 +01:00
|
|
|
const Settings &settings,
|
|
|
|
csvFile &csvOutput)
|
2022-01-28 19:01:44 +01:00
|
|
|
{
|
2022-02-18 16:46:28 +01:00
|
|
|
if (settings.shouldWriteHeader) {
|
2022-05-06 15:40:05 +02:00
|
|
|
csvOutput << csvExportingDataStrings[settings.exportingData];
|
2022-02-18 16:46:28 +01:00
|
|
|
printHeader(settings, csvOutput);
|
|
|
|
// csvOutput << "Average error";
|
|
|
|
// csvOutput<<"Cumulative error";
|
|
|
|
csvOutput << endrow;
|
2022-01-28 19:01:44 +01:00
|
|
|
}
|
2022-02-18 16:46:28 +01:00
|
|
|
if (!settings.resultsLabel.empty()) {
|
|
|
|
csvOutput << settings.resultsLabel;
|
|
|
|
}
|
|
|
|
if (settings.exportingDirection == Vertical) {
|
|
|
|
printResultsVertically(evaluationResults, csvOutput);
|
|
|
|
} else {
|
|
|
|
printResultsHorizontally(evaluationResults, csvOutput);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReducedModelEvaluator::printHeader(const Settings &settings, csvFile &csvOutput)
|
|
|
|
{
|
|
|
|
if (settings.exportingDirection == Horizontal) {
|
|
|
|
// csvOutput << "Job label";
|
|
|
|
for (int jobIndex = 0; jobIndex < ReducedModelEvaluator::scenariosTestSetLabels.size();
|
|
|
|
jobIndex++) {
|
|
|
|
const std::string &jobLabel = ReducedModelEvaluator::scenariosTestSetLabels[jobIndex];
|
|
|
|
csvOutput << jobLabel;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
std::cout << "Vertical header not defined" << std::endl;
|
|
|
|
assert(false);
|
|
|
|
std::terminate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReducedModelEvaluator::printResultsHorizontally(const Results &evaluationResults,
|
|
|
|
csvFile &csvOutput)
|
|
|
|
{
|
|
|
|
//print header
|
|
|
|
//print raw error
|
|
|
|
constexpr bool shouldPrintRawError = false;
|
|
|
|
if (shouldPrintRawError) {
|
|
|
|
// csvOutput << "drm2Reduced";
|
|
|
|
double sumOfFull2Reduced = 0;
|
|
|
|
int numOfNonEvaluatedScenarios = 0;
|
|
|
|
for (int jobIndex = 0; jobIndex < ReducedModelEvaluator::scenariosTestSetLabels.size();
|
|
|
|
jobIndex++) {
|
|
|
|
const double &distance_fullDrmToReduced = evaluationResults
|
|
|
|
.distances_drm2reduced[jobIndex];
|
|
|
|
if (distance_fullDrmToReduced == -1) {
|
|
|
|
csvOutput << "notEvaluated";
|
|
|
|
numOfNonEvaluatedScenarios++;
|
|
|
|
} else {
|
|
|
|
csvOutput << distance_fullDrmToReduced;
|
|
|
|
sumOfFull2Reduced += distance_fullDrmToReduced;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// const int numOfEvaluatedScenarios = ReducedModelEvaluator::scenariosTestSetLabels.size()
|
|
|
|
// - numOfNonEvaluatedScenarios;
|
|
|
|
// const double averageDistance_full2Reduced = sumOfFull2Reduced / numOfEvaluatedScenarios;
|
|
|
|
// csvOutput << averageDistance_full2Reduced;
|
|
|
|
// csvOutput << endrow;
|
|
|
|
}
|
|
|
|
//print normalized error
|
|
|
|
// csvOutput << "norm_drm2Reduced";
|
|
|
|
double sumOfNormalizedFull2Reduced = 0;
|
|
|
|
for (int jobIndex = 0; jobIndex < ReducedModelEvaluator::scenariosTestSetLabels.size();
|
|
|
|
jobIndex++) {
|
|
|
|
const double &distance_normalizedFullDrmToReduced
|
|
|
|
= evaluationResults.distances_normalizedDrm2reduced[jobIndex];
|
|
|
|
if (distance_normalizedFullDrmToReduced == -1) {
|
|
|
|
csvOutput << "notEvaluated";
|
|
|
|
} else {
|
|
|
|
csvOutput << distance_normalizedFullDrmToReduced;
|
|
|
|
sumOfNormalizedFull2Reduced += distance_normalizedFullDrmToReduced;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// const double averageDistance_normalizedFull2Reduced = sumOfNormalizedFull2Reduced
|
|
|
|
// / numOfEvaluatedScenarios;
|
|
|
|
// csvOutput << averageDistance_normalizedFull2Reduced;
|
|
|
|
// csvOutput << endrow;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReducedModelEvaluator::printResultsVertically(const Results &evaluationResults,
|
|
|
|
csvFile &csvOutput)
|
|
|
|
{
|
2022-01-28 19:01:44 +01:00
|
|
|
#ifdef POLYSCOPE_DEFINED
|
2022-02-18 16:46:28 +01:00
|
|
|
csvOutput << "drm2Reduced"
|
|
|
|
<< "norm_drm2Reduced";
|
2022-01-28 19:01:44 +01:00
|
|
|
#else
|
2022-02-18 16:46:28 +01:00
|
|
|
csvOutput << "Job Label"
|
|
|
|
<< "drm2Reduced"
|
|
|
|
<< "norm_drm2Reduced";
|
2022-01-28 19:01:44 +01:00
|
|
|
|
|
|
|
#endif
|
2022-02-18 16:46:28 +01:00
|
|
|
csvOutput << endrow;
|
|
|
|
double sumOfFull2Reduced = 0;
|
|
|
|
double sumOfNormalizedFull2Reduced = 0;
|
|
|
|
int numOfNonEvaluatedScenarios = 0;
|
2022-01-28 19:01:44 +01:00
|
|
|
for (int jobIndex = 0; jobIndex < ReducedModelEvaluator::scenariosTestSetLabels.size();
|
|
|
|
jobIndex++) {
|
|
|
|
const double &distance_fullDrmToReduced = evaluationResults.distances_drm2reduced[jobIndex];
|
|
|
|
const double &distance_normalizedFullDrmToReduced
|
|
|
|
= evaluationResults.distances_normalizedDrm2reduced[jobIndex];
|
2022-02-18 16:46:28 +01:00
|
|
|
#ifndef POLYSCOPE_DEFINED
|
|
|
|
const std::string &jobLabel = ReducedModelEvaluator::scenariosTestSetLabels[jobIndex];
|
|
|
|
csvOutput << jobLabel;
|
2022-01-28 19:01:44 +01:00
|
|
|
#endif
|
2022-02-18 16:46:28 +01:00
|
|
|
if (distance_fullDrmToReduced == -1) {
|
|
|
|
csvOutput << "notEvaluated"
|
|
|
|
<< "notEvaluated";
|
|
|
|
numOfNonEvaluatedScenarios++;
|
|
|
|
} else {
|
|
|
|
csvOutput << distance_fullDrmToReduced << distance_normalizedFullDrmToReduced;
|
|
|
|
sumOfFull2Reduced += distance_fullDrmToReduced;
|
|
|
|
sumOfNormalizedFull2Reduced += distance_normalizedFullDrmToReduced;
|
|
|
|
}
|
|
|
|
csvOutput << endrow;
|
2022-01-28 19:01:44 +01:00
|
|
|
// sumOfNormalizedFull2Reduced += distance_normalizedFullDrmToReduced;
|
|
|
|
}
|
2022-02-18 16:46:28 +01:00
|
|
|
const int numOfEvaluatedScenarios = ReducedModelEvaluator::scenariosTestSetLabels.size()
|
|
|
|
- numOfNonEvaluatedScenarios;
|
|
|
|
const double averageDistance_full2Reduced = sumOfFull2Reduced / numOfEvaluatedScenarios;
|
|
|
|
const double averageDistance_normalizedFull2Reduced = sumOfNormalizedFull2Reduced
|
|
|
|
/ numOfEvaluatedScenarios;
|
|
|
|
#ifndef POLYSCOPE_DEFINED
|
|
|
|
csvOutput << "Average error";
|
|
|
|
#endif
|
|
|
|
csvOutput << averageDistance_full2Reduced << averageDistance_normalizedFull2Reduced;
|
|
|
|
csvOutput << endrow;
|
|
|
|
#ifndef POLYSCOPE_DEFINED
|
|
|
|
csvOutput << "Cumulative error";
|
|
|
|
#endif
|
|
|
|
csvOutput << sumOfFull2Reduced << sumOfNormalizedFull2Reduced;
|
|
|
|
csvOutput << endrow;
|
|
|
|
csvOutput << endrow;
|
2022-01-28 19:01:44 +01:00
|
|
|
}
|
|
|
|
|
2022-05-06 15:40:05 +02:00
|
|
|
//void ReducedModelEvaluator::createFullAndReducedPatternTessellations(){
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
//ReducedModelEvaluator::Results ReducedModelEvaluator::evaluateReducedModel(
|
|
|
|
// std::vector<ReducedModelOptimization::Results> &optimizationResults,
|
|
|
|
// const std::filesystem::path &tileInto_triMesh_filePath,
|
|
|
|
// const std::filesystem::path &scenariosDirectoryPath,
|
|
|
|
// // const std::filesystem::path &reducedPatternFilePath,
|
|
|
|
// const std::filesystem::path &fullPatternTessellatedResultsDirectoryPath)
|
|
|
|
//{
|
|
|
|
// //Load surface
|
|
|
|
// std::shared_ptr<VCGPolyMesh> pTileIntoSurface = [&]() {
|
|
|
|
// VCGTriMesh tileInto_triMesh;
|
|
|
|
// const bool surfaceLoadSuccessfull = tileInto_triMesh.load(tileInto_triMesh_filePath);
|
|
|
|
// assert(surfaceLoadSuccessfull);
|
|
|
|
// return PolygonalRemeshing::remeshWithPolygons(tileInto_triMesh);
|
|
|
|
// }();
|
|
|
|
// const double optimizedBaseTriangleHeight = vcg::Distance(optimizationResult.baseTriangle.cP(0),
|
|
|
|
// (optimizationResult.baseTriangle.cP(1)
|
|
|
|
// + optimizationResult.baseTriangle.cP(
|
|
|
|
// 2))
|
|
|
|
// / 2);
|
|
|
|
// pTileIntoSurface->moveToCenter();
|
|
|
|
// const double scaleFactor = optimizedBaseTriangleHeight
|
|
|
|
// / pTileIntoSurface->getAverageFaceRadius();
|
|
|
|
// vcg::tri::UpdatePosition<VCGPolyMesh>::Scale(*pTileIntoSurface, scaleFactor);
|
|
|
|
// //Tile full pattern into surface
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
2022-01-28 19:01:44 +01:00
|
|
|
ReducedModelEvaluator::Results ReducedModelEvaluator::evaluateReducedModel(
|
|
|
|
ReducedModelOptimization::Results &optimizationResult,
|
|
|
|
const std::filesystem::path &scenariosDirectoryPath,
|
|
|
|
const std::filesystem::path &fullPatternTessellatedResultsDirectoryPath)
|
2022-01-14 14:02:27 +01:00
|
|
|
{
|
2022-05-06 15:40:05 +02:00
|
|
|
// const double optimizedBaseTriangleHeight = vcg::Distance(optimizationResult.baseTriangle.cP(0),
|
|
|
|
// (optimizationResult.baseTriangle.cP(1)
|
|
|
|
// + optimizationResult.baseTriangle.cP(
|
|
|
|
// 2))
|
|
|
|
// / 2);
|
2022-01-14 14:02:27 +01:00
|
|
|
pTileIntoSurface->moveToCenter();
|
2022-05-06 15:40:05 +02:00
|
|
|
const double scaleFactor = optimizationResult.settings.targetBaseTriangleSize
|
2022-01-14 14:02:27 +01:00
|
|
|
/ pTileIntoSurface->getAverageFaceRadius();
|
|
|
|
vcg::tri::UpdatePosition<VCGPolyMesh>::Scale(*pTileIntoSurface, scaleFactor);
|
|
|
|
// tileIntoSurface.registerForDrawing();
|
|
|
|
// polyscope::show();
|
|
|
|
|
|
|
|
//Tile full pattern into surface
|
|
|
|
std::vector<PatternGeometry> fullPatterns(1);
|
2022-01-28 19:01:44 +01:00
|
|
|
fullPatterns[0].copy(optimizationResult.baseTriangleFullPattern);
|
2022-01-14 14:02:27 +01:00
|
|
|
//// Base triangle pattern might contain dangling vertices.Remove those
|
|
|
|
fullPatterns[0].interfaceNodeIndex = 3;
|
|
|
|
fullPatterns[0].deleteDanglingVertices();
|
|
|
|
std::vector<int> perSurfaceFacePatternIndices(pTileIntoSurface->FN(), 0);
|
|
|
|
std::vector<std::vector<size_t>> perPatternIndexTiledFullPatternEdgeIndices;
|
|
|
|
std::vector<size_t> tileIntoEdgeToTiledFullVi;
|
|
|
|
std::shared_ptr<PatternGeometry> pTiledFullPattern
|
|
|
|
= PatternGeometry::tilePattern(fullPatterns,
|
|
|
|
{},
|
|
|
|
*pTileIntoSurface,
|
|
|
|
perSurfaceFacePatternIndices,
|
|
|
|
tileIntoEdgeToTiledFullVi,
|
|
|
|
perPatternIndexTiledFullPatternEdgeIndices);
|
|
|
|
pTiledFullPattern->setLabel("Tiled_full_patterns");
|
|
|
|
// pTiledFullPattern->registerForDrawing();
|
|
|
|
//Tile reduced pattern into surface
|
2022-02-18 16:46:28 +01:00
|
|
|
// PatternGeometry reducedPattern;
|
|
|
|
ReducedModel reducedModel;
|
|
|
|
// reducedModel.registerForDrawing();
|
|
|
|
// polyscope::show();
|
|
|
|
reducedModel.deleteDanglingVertices();
|
|
|
|
// reducedPattern.interfaceNodeIndex = 1;
|
|
|
|
// assert(reducedPattern.interfaceNodeIndex == 1);
|
2022-01-14 14:02:27 +01:00
|
|
|
std::vector<PatternGeometry> reducedPatterns(1);
|
2022-02-18 16:46:28 +01:00
|
|
|
reducedPatterns[0].copy(reducedModel);
|
|
|
|
const auto reducedPatternBaseTriangle = reducedModel.computeBaseTriangle();
|
2022-05-06 15:40:05 +02:00
|
|
|
ReducedModelOptimization::Results::applyOptimizationResults_reducedModel_nonFanned(
|
2022-01-28 19:01:44 +01:00
|
|
|
optimizationResult, reducedPatternBaseTriangle, reducedPatterns[0]);
|
2022-01-14 14:02:27 +01:00
|
|
|
|
|
|
|
std::vector<std::vector<size_t>> perPatternIndexTiledReducedPatternEdgeIndices;
|
|
|
|
std::vector<size_t> tileIntoEdgeToTiledReducedVi;
|
|
|
|
std::shared_ptr<PatternGeometry> pTiledReducedPattern
|
|
|
|
= PatternGeometry::tilePattern(reducedPatterns,
|
|
|
|
{0},
|
|
|
|
*pTileIntoSurface,
|
|
|
|
perSurfaceFacePatternIndices,
|
|
|
|
tileIntoEdgeToTiledReducedVi,
|
|
|
|
perPatternIndexTiledReducedPatternEdgeIndices);
|
|
|
|
pTiledReducedPattern->setLabel("Tiled_reduced_patterns");
|
2022-02-18 16:46:28 +01:00
|
|
|
// pTiledReducedPattern->registerForDrawing();
|
|
|
|
// polyscope::show();
|
2022-01-14 14:02:27 +01:00
|
|
|
|
|
|
|
std::unordered_map<FullPatternVertexIndex, ReducedPatternVertexIndex>
|
|
|
|
fullToReducedViMap; //of only the common vertices
|
|
|
|
std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
|
|
|
|
reducedToFullViMap; //of only the common vertices
|
|
|
|
for (int ei = 0; ei < pTileIntoSurface->EN(); ei++) {
|
|
|
|
fullToReducedViMap[tileIntoEdgeToTiledFullVi[ei]] = tileIntoEdgeToTiledReducedVi[ei];
|
|
|
|
}
|
|
|
|
constructInverseMap(fullToReducedViMap, reducedToFullViMap);
|
|
|
|
|
|
|
|
std::vector<size_t> tilledFullPatternInterfaceVi;
|
|
|
|
tilledFullPatternInterfaceVi.clear();
|
|
|
|
tilledFullPatternInterfaceVi.resize(fullToReducedViMap.size());
|
|
|
|
size_t viIndex = 0;
|
|
|
|
for (std::pair<size_t, size_t> fullToReducedPair : fullToReducedViMap) {
|
|
|
|
tilledFullPatternInterfaceVi[viIndex++] = fullToReducedPair.first;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Create simulation meshes
|
|
|
|
////Tessellated full pattern simulation mesh
|
|
|
|
std::shared_ptr<SimulationMesh> pTiledFullPattern_simulationMesh;
|
|
|
|
pTiledFullPattern_simulationMesh = std::make_shared<SimulationMesh>(*pTiledFullPattern);
|
|
|
|
//NOTE: Those should be derived from the optimization results instead of hardcoding them
|
|
|
|
pTiledFullPattern_simulationMesh->setBeamCrossSection(CrossSectionType{0.002, 0.002});
|
2022-01-28 19:01:44 +01:00
|
|
|
if (optimizationResult.fullPatternYoungsModulus == 0) {
|
2022-01-14 14:02:27 +01:00
|
|
|
std::cerr << "Full pattern's young modulus not found." << std::endl;
|
|
|
|
std::terminate();
|
|
|
|
}
|
|
|
|
pTiledFullPattern_simulationMesh->setBeamMaterial(0.3,
|
2022-01-28 19:01:44 +01:00
|
|
|
optimizationResult.fullPatternYoungsModulus);
|
2022-01-14 14:02:27 +01:00
|
|
|
pTiledFullPattern_simulationMesh->reset();
|
|
|
|
|
|
|
|
////Tessellated reduced pattern simulation mesh
|
|
|
|
std::shared_ptr<SimulationMesh> pTiledReducedPattern_simulationMesh;
|
|
|
|
pTiledReducedPattern_simulationMesh = std::make_shared<SimulationMesh>(*pTiledReducedPattern);
|
|
|
|
const std::vector<size_t> &tiledPatternElementIndicesForReducedPattern
|
|
|
|
= perPatternIndexTiledReducedPatternEdgeIndices[0];
|
|
|
|
ReducedModelOptimization::Results::applyOptimizationResults_elements(
|
2022-01-28 19:01:44 +01:00
|
|
|
optimizationResult, pTiledReducedPattern_simulationMesh);
|
2022-05-06 15:40:05 +02:00
|
|
|
// pTiledReducedPattern_simulationMesh->reset();
|
2022-01-28 19:01:44 +01:00
|
|
|
Results evaluationResults;
|
2022-02-18 16:46:28 +01:00
|
|
|
evaluationResults.distances_drm2reduced.fill(-1);
|
|
|
|
evaluationResults.distances_normalizedDrm2reduced.fill(-1);
|
2022-05-06 15:40:05 +02:00
|
|
|
DRMSimulationModel::Settings drmSimulationSettings;
|
|
|
|
drmSimulationSettings.totalExternalForcesNormPercentageTermination = 1e-3;
|
|
|
|
// drmSimulationSettings.load(drmSettingsFilePath);
|
|
|
|
drmSimulationSettings.beVerbose = true;
|
|
|
|
drmSimulationSettings.maxDRMIterations = 5e6;
|
|
|
|
drmSimulationSettings.debugModeStep = 100000;
|
|
|
|
drmSimulationSettings.translationalKineticEnergyThreshold = 1e-15;
|
|
|
|
drmSimulationSettings.linearGuessForceScaleFactor = 0.8;
|
|
|
|
drmSimulationSettings.viscousDampingFactor = 7e-3;
|
|
|
|
drmSimulationSettings.xi = 0.9999;
|
|
|
|
// drmSimulationSettings.Dtini = 5.86;
|
|
|
|
drmSimulationSettings.gamma = 0.25;
|
|
|
|
#ifdef POLYSCOPE_DEFINED
|
|
|
|
// drmSimulationSettings.shouldDraw = true;
|
|
|
|
drmSimulationSettings.shouldCreatePlots = true;
|
|
|
|
#endif
|
|
|
|
constexpr bool shouldRerunFullPatternSimulation = false;
|
|
|
|
// for (int jobIndex = 0; jobIndex < scenariosTestSetLabels.size(); jobIndex++) {
|
|
|
|
std::for_each(
|
|
|
|
//#ifndef POLYSCOPE_DEFINED
|
|
|
|
// std::execution::par_unseq,
|
|
|
|
//#endif
|
|
|
|
scenariosTestSetLabels.begin(),
|
|
|
|
scenariosTestSetLabels.end(),
|
|
|
|
[&](const std::string &jobLabel) {
|
|
|
|
//check if reduced model scenario exists
|
|
|
|
// const std::string &jobLabel = scenariosTestSetLabels[jobIndex];
|
|
|
|
const std::filesystem::path tiledReducedPatternJobFilePath
|
|
|
|
= std::filesystem::path(scenariosDirectoryPath)
|
|
|
|
.append(pTileIntoSurface->getLabel())
|
|
|
|
.append(jobLabel)
|
|
|
|
.append("ReducedJob")
|
|
|
|
.append(SimulationJob::jsonDefaultFileName);
|
|
|
|
if (!std::filesystem::exists(tiledReducedPatternJobFilePath)) {
|
|
|
|
std::cerr << "Scenario " << jobLabel
|
|
|
|
<< " not found in:" << tiledReducedPatternJobFilePath << std::endl;
|
|
|
|
// continue; //if not move on to the next scenario
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//Map the reduced job to the job on the pattern tessellation
|
|
|
|
//set jobs
|
|
|
|
std::shared_ptr<SimulationJob> pJob_tiledReducedPattern;
|
|
|
|
pJob_tiledReducedPattern = std::make_shared<SimulationJob>(SimulationJob());
|
|
|
|
pJob_tiledReducedPattern->load(tiledReducedPatternJobFilePath, false);
|
|
|
|
pJob_tiledReducedPattern->pMesh = pTiledReducedPattern_simulationMesh;
|
|
|
|
std::shared_ptr<SimulationJob> pJob_tiledFullPattern;
|
|
|
|
pJob_tiledFullPattern = std::make_shared<SimulationJob>(SimulationJob());
|
|
|
|
pJob_tiledFullPattern->pMesh = pTiledFullPattern_simulationMesh;
|
|
|
|
pJob_tiledReducedPattern->remap(reducedToFullViMap, *pJob_tiledFullPattern);
|
|
|
|
// pJob_tiledReducedPattern->registerForDrawing(pTiledReducedPattern->getLabel());
|
|
|
|
// pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern->getLabel());
|
|
|
|
// polyscope::show();
|
|
|
|
const std::filesystem::path surfaceFolderPath
|
|
|
|
= std::filesystem::path(fullPatternTessellatedResultsDirectoryPath)
|
|
|
|
.append(pTileIntoSurface->getLabel());
|
|
|
|
const std::string scenarioLabel = pJob_tiledFullPattern->getLabel();
|
|
|
|
const std::filesystem::path scenarioDirectoryPath
|
|
|
|
= std::filesystem::path(surfaceFolderPath).append(scenarioLabel);
|
|
|
|
//Save reduced job
|
|
|
|
constexpr bool exportReducedJob = false;
|
|
|
|
if (exportReducedJob) {
|
|
|
|
const std::filesystem::path reducedJobDirectoryPath
|
|
|
|
= std::filesystem::path(scenarioDirectoryPath).append("ReducedJob");
|
|
|
|
std::filesystem::create_directories(reducedJobDirectoryPath);
|
|
|
|
pJob_tiledReducedPattern->save(reducedJobDirectoryPath);
|
|
|
|
}
|
|
|
|
//Check if the drm simulation of the full pattern has already been computed
|
|
|
|
////Full
|
|
|
|
const std::string &patternLabel = [&]() {
|
|
|
|
const std::string patternLabel = optimizationResult.baseTriangleFullPattern
|
|
|
|
.getLabel();
|
|
|
|
if (patternLabel.find("_") == std::string::npos) {
|
|
|
|
return std::to_string(optimizationResult.baseTriangleFullPattern.EN()) + "_"
|
|
|
|
+ patternLabel;
|
|
|
|
} else {
|
|
|
|
return patternLabel;
|
|
|
|
}
|
|
|
|
}();
|
|
|
|
const auto fullResultsFolderPath = std::filesystem::path(scenarioDirectoryPath)
|
|
|
|
.append(patternLabel)
|
|
|
|
.append("Results");
|
|
|
|
if (shouldRerunFullPatternSimulation && std::filesystem::exists(fullResultsFolderPath)) {
|
|
|
|
std::filesystem::remove_all(fullResultsFolderPath);
|
|
|
|
}
|
2022-01-28 19:01:44 +01:00
|
|
|
|
2022-05-06 15:40:05 +02:00
|
|
|
const std::filesystem::path fullPatternJobFolderPath = std::filesystem::path(
|
|
|
|
scenarioDirectoryPath)
|
|
|
|
.append(patternLabel)
|
|
|
|
.append("SimulationJob");
|
|
|
|
SimulationResults simulationResults_tiledFullPattern_drm;
|
|
|
|
if (std::filesystem::exists(fullResultsFolderPath)) {
|
|
|
|
//Load full pattern results
|
|
|
|
assert(std::filesystem::exists(fullPatternJobFolderPath));
|
|
|
|
simulationResults_tiledFullPattern_drm.load(fullResultsFolderPath,
|
|
|
|
fullPatternJobFolderPath);
|
|
|
|
//#ifdef POLYSCOPE_DEFINED
|
|
|
|
// std::array<double, 3> resultsColor({28.0, 99.0, 227.0});
|
|
|
|
// simulationResults_tiledFullPattern_drm.registerForDrawing(resultsColor);
|
|
|
|
// std::ifstream ifs("CameraSettings.json");
|
|
|
|
// nlohmann::json json;
|
|
|
|
// ifs >> json;
|
|
|
|
// polyscope::view::setCameraFromJson(json.dump(), false);
|
|
|
|
// // polyscope::show();
|
|
|
|
// const std::string cameraJson = polyscope::view::getCameraJson();
|
|
|
|
// std::filesystem::path jsonFilePath("CameraSettings.json");
|
|
|
|
// std::ofstream jsonFile_cameraSettings(jsonFilePath.string());
|
|
|
|
// jsonFile_cameraSettings << cameraJson;
|
|
|
|
// jsonFile_cameraSettings.close();
|
|
|
|
// std::filesystem::create_directories("screenshots");
|
|
|
|
// const std::string screenshotOutputFilePath
|
|
|
|
// = (std::filesystem::current_path()
|
|
|
|
// .append("screenshots")
|
|
|
|
// .append(optimizationResult.label + "_" + pJob_tiledFullPattern->getLabel()))
|
|
|
|
// .string()
|
|
|
|
// + ".png";
|
|
|
|
// // std::cout << "Saving image to:" << screenshotOutputFilePath << std::endl;
|
|
|
|
// polyscope::screenshot(screenshotOutputFilePath, false);
|
|
|
|
// simulationResults_tiledFullPattern_drm.unregister();
|
|
|
|
//#endif
|
2022-01-14 14:02:27 +01:00
|
|
|
|
2022-05-06 15:40:05 +02:00
|
|
|
simulationResults_tiledFullPattern_drm.converged = true;
|
|
|
|
} else {
|
|
|
|
std::cout << "Drm results not found in:" << fullResultsFolderPath << std::endl;
|
|
|
|
//Full
|
|
|
|
std::cout << "Executing:" << jobLabel << std::endl;
|
|
|
|
DRMSimulationModel drmSimulationModel;
|
|
|
|
simulationResults_tiledFullPattern_drm
|
|
|
|
= drmSimulationModel.executeSimulation(pJob_tiledFullPattern,
|
|
|
|
drmSimulationSettings);
|
|
|
|
simulationResults_tiledFullPattern_drm.setLabelPrefix("DRM");
|
|
|
|
}
|
|
|
|
if (!simulationResults_tiledFullPattern_drm.converged) {
|
|
|
|
std::cerr << "Full pattern simulation failed." << std::endl;
|
|
|
|
std::cerr << "Not saving results" << std::endl;
|
|
|
|
// continue;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
std::filesystem::create_directories(fullResultsFolderPath);
|
|
|
|
const std::filesystem::path drmResultsOutputPath
|
|
|
|
= std::filesystem::path(scenarioDirectoryPath).append(patternLabel);
|
|
|
|
simulationResults_tiledFullPattern_drm.save(drmResultsOutputPath);
|
2022-02-18 16:46:28 +01:00
|
|
|
|
2022-05-06 15:40:05 +02:00
|
|
|
LinearSimulationModel linearSimulationModel;
|
|
|
|
SimulationResults simulationResults_tiledReducedPattern
|
|
|
|
= linearSimulationModel.executeSimulation(pJob_tiledReducedPattern);
|
2022-01-14 14:02:27 +01:00
|
|
|
|
2022-05-06 15:40:05 +02:00
|
|
|
// simulationResults_tiledReducedPattern.registerForDrawing();
|
|
|
|
// simulationResults_tiledFullPattern_drm.registerForDrawing();
|
|
|
|
// polyscope::show();
|
2022-01-14 14:02:27 +01:00
|
|
|
|
2022-05-06 15:40:05 +02:00
|
|
|
//compute the full2reduced distance
|
|
|
|
const double distance_fullDrmToReduced
|
|
|
|
= simulationResults_tiledFullPattern_drm
|
|
|
|
.computeDistance(simulationResults_tiledReducedPattern, fullToReducedViMap);
|
|
|
|
double distance_fullSumOfAllVerts = 0;
|
|
|
|
for (std::pair<size_t, size_t> fullToReducedPair : fullToReducedViMap) {
|
|
|
|
distance_fullSumOfAllVerts += simulationResults_tiledFullPattern_drm
|
|
|
|
.displacements[fullToReducedPair.first]
|
|
|
|
.getTranslation()
|
|
|
|
.norm();
|
|
|
|
}
|
|
|
|
const double distance_normalizedFullDrmToReduced = distance_fullDrmToReduced
|
|
|
|
/ distance_fullSumOfAllVerts;
|
|
|
|
const int jobIndex = &jobLabel - &scenariosTestSetLabels[0];
|
|
|
|
evaluationResults.distances_drm2reduced[jobIndex] = distance_fullDrmToReduced;
|
|
|
|
evaluationResults.distances_normalizedDrm2reduced[jobIndex]
|
|
|
|
= distance_normalizedFullDrmToReduced;
|
|
|
|
});
|
2022-01-14 14:02:27 +01:00
|
|
|
|
2022-01-28 19:01:44 +01:00
|
|
|
return evaluationResults;
|
2022-01-14 14:02:27 +01:00
|
|
|
}
|