529 lines
24 KiB
C++
529 lines
24 KiB
C++
|
#ifndef REDUCEDMODELOPTIMIZER_STRUCTS_HPP
|
||
|
#define REDUCEDMODELOPTIMIZER_STRUCTS_HPP
|
||
|
#include "csvfile.hpp"
|
||
|
#include "drmsimulationmodel.hpp"
|
||
|
#include "linearsimulationmodel.hpp"
|
||
|
#include "simulation_structs.hpp"
|
||
|
#include "unordered_map"
|
||
|
#include <string>
|
||
|
|
||
|
namespace ReducedPatternOptimization {
|
||
|
|
||
|
enum BaseSimulationScenario {
|
||
|
Axial,
|
||
|
Shear,
|
||
|
Bending,
|
||
|
Dome,
|
||
|
Saddle,
|
||
|
NumberOfBaseSimulationScenarios
|
||
|
};
|
||
|
inline static std::vector<std::string> baseSimulationScenarioNames{"Axial",
|
||
|
"Shear",
|
||
|
"Bending",
|
||
|
"Dome",
|
||
|
"Saddle"};
|
||
|
|
||
|
struct Colors
|
||
|
{
|
||
|
inline static std::array<double, 3> fullInitial{0.416666, 0.109804, 0.890196};
|
||
|
inline static std::array<double, 3> fullDeformed{0.583333, 0.890196, 0.109804};
|
||
|
inline static std::array<double, 3> reducedInitial{0.890196, 0.109804, 0.193138};
|
||
|
inline static std::array<double, 3> reducedDeformed{0.109804, 0.890196, 0.806863};
|
||
|
};
|
||
|
|
||
|
struct xRange{
|
||
|
std::string label;
|
||
|
double min;
|
||
|
double max;
|
||
|
std::string toString() const {
|
||
|
return label + "=[" + std::to_string(min) + "," + std::to_string(max) +
|
||
|
"]";
|
||
|
}
|
||
|
};
|
||
|
struct Settings {
|
||
|
enum NormalizationStrategy {
|
||
|
NonNormalized,
|
||
|
Epsilon,
|
||
|
MaxDisplacement,
|
||
|
EqualDisplacements
|
||
|
};
|
||
|
inline static vector<std::string> normalizationStrategyStrings{
|
||
|
"NonNormalized", "Epsilon", "MaxDsiplacement", "EqualDisplacements"};
|
||
|
std::vector<xRange> xRanges;
|
||
|
int numberOfFunctionCalls{100};
|
||
|
double solutionAccuracy{1e-2};
|
||
|
NormalizationStrategy normalizationStrategy{Epsilon};
|
||
|
double normalizationParameter{0.003};
|
||
|
|
||
|
std::string toString() const {
|
||
|
std::string settingsString;
|
||
|
if (!xRanges.empty()) {
|
||
|
std::string xRangesString;
|
||
|
for (const xRange &range : xRanges) {
|
||
|
xRangesString += range.toString() + " ";
|
||
|
}
|
||
|
settingsString += xRangesString;
|
||
|
}
|
||
|
settingsString +=
|
||
|
"FuncCalls=" + std::to_string(numberOfFunctionCalls) +
|
||
|
" Accuracy=" + std::to_string(solutionAccuracy) +
|
||
|
" Norm=" + normalizationStrategyStrings[normalizationStrategy];
|
||
|
|
||
|
return settingsString;
|
||
|
}
|
||
|
|
||
|
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 << "Normalization strategy";
|
||
|
// os << std::endl;
|
||
|
}
|
||
|
|
||
|
void writeSettingsTo(csvFile &os) const {
|
||
|
if (!xRanges.empty()) {
|
||
|
for (const xRange &range : xRanges) {
|
||
|
os << range.max;
|
||
|
os << range.min;
|
||
|
}
|
||
|
}
|
||
|
os << numberOfFunctionCalls;
|
||
|
os << solutionAccuracy;
|
||
|
os << normalizationStrategyStrings[normalizationStrategy] + "_" +
|
||
|
std::to_string(normalizationParameter);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
inline void updateMeshWithOptimalVariables(const std::vector<double> &x, SimulationMesh &m)
|
||
|
{
|
||
|
const double E = x[0];
|
||
|
const double A = x[1];
|
||
|
const double beamWidth = std::sqrt(A);
|
||
|
const double beamHeight = beamWidth;
|
||
|
|
||
|
const double J = x[2];
|
||
|
const double I2 = x[3];
|
||
|
const double I3 = x[4];
|
||
|
for (EdgeIndex ei = 0; ei < m.EN(); ei++) {
|
||
|
Element &e = m.elements[ei];
|
||
|
e.setDimensions(RectangularBeamDimensions(beamWidth, beamHeight));
|
||
|
e.setMaterial(ElementMaterial(e.material.poissonsRatio, E));
|
||
|
e.J = J;
|
||
|
e.I2 = I2;
|
||
|
e.I3 = I3;
|
||
|
}
|
||
|
|
||
|
CoordType center_barycentric(1, 0, 0);
|
||
|
CoordType interfaceEdgeMiddle_barycentric(0, 0.5, 0.5);
|
||
|
CoordType movableVertex_barycentric((center_barycentric + interfaceEdgeMiddle_barycentric)
|
||
|
* x[x.size() - 2]);
|
||
|
|
||
|
CoordType patternCoord0 = CoordType(0, 0, 0);
|
||
|
double bottomEdgeHalfSize = 0.03 / std::tan(M_PI / 3);
|
||
|
CoordType interfaceNodePosition(0, -0.03, 0);
|
||
|
CoordType patternBottomRight = interfaceNodePosition + CoordType(bottomEdgeHalfSize, 0, 0);
|
||
|
CoordType patternBottomLeft = interfaceNodePosition - CoordType(bottomEdgeHalfSize, 0, 0);
|
||
|
vcg::Triangle3<double> baseTriangle(patternCoord0, patternBottomLeft, patternBottomRight);
|
||
|
CoordType baseTriangleMovableVertexPosition = baseTriangle.cP(0)
|
||
|
* movableVertex_barycentric[0]
|
||
|
+ baseTriangle.cP(1)
|
||
|
* movableVertex_barycentric[1]
|
||
|
+ baseTriangle.cP(2)
|
||
|
* movableVertex_barycentric[2];
|
||
|
VectorType patternPlaneNormal(0, 0, 1);
|
||
|
baseTriangleMovableVertexPosition = vcg::RotationMatrix(patternPlaneNormal,
|
||
|
vcg::math::ToRad(x[x.size() - 1]))
|
||
|
* baseTriangleMovableVertexPosition;
|
||
|
|
||
|
const int fanSize = 6;
|
||
|
for (int rotationCounter = 0; rotationCounter < fanSize; rotationCounter++) {
|
||
|
m.vert[2 * rotationCounter + 1].P() = vcg::RotationMatrix(patternPlaneNormal,
|
||
|
vcg::math::ToRad(
|
||
|
60.0 * rotationCounter))
|
||
|
* baseTriangleMovableVertexPosition;
|
||
|
}
|
||
|
|
||
|
m.reset();
|
||
|
}
|
||
|
|
||
|
struct Results
|
||
|
{
|
||
|
double time{-1};
|
||
|
int numberOfSimulationCrashes{0};
|
||
|
|
||
|
struct ObjectiveValues
|
||
|
{
|
||
|
double totalRaw;
|
||
|
double total;
|
||
|
std::vector<double> perSimulationScenario_rawTranslational;
|
||
|
std::vector<double> perSimulationScenario_rawRotational;
|
||
|
std::vector<double> perSimulationScenario_translational;
|
||
|
std::vector<double> perSimulationScenario_rotational;
|
||
|
std::vector<double> perSimulationScenario_total;
|
||
|
} objectiveValue;
|
||
|
|
||
|
// std::vector<std::pair<std::string,double>> optimalXNameValuePairs;
|
||
|
std::vector<std::pair<std::string, double>> optimalXNameValuePairs;
|
||
|
std::vector<std::shared_ptr<SimulationJob>> fullPatternSimulationJobs;
|
||
|
std::vector<std::shared_ptr<SimulationJob>> reducedPatternSimulationJobs;
|
||
|
vcg::Triangle3<double> baseTriangle;
|
||
|
struct JsonKeys
|
||
|
{
|
||
|
inline static std::string filename{"OptimizationResults.json"};
|
||
|
inline static std::string optimizationVariables{"OptimizationVariables"};
|
||
|
inline static std::string baseTriangle{"BaseTriangle"};
|
||
|
};
|
||
|
|
||
|
void save(const string &saveToPath) const
|
||
|
{
|
||
|
assert(std::filesystem::is_directory(saveToPath));
|
||
|
//clear directory
|
||
|
for (const auto &entry : std::filesystem::directory_iterator(saveToPath))
|
||
|
std::filesystem::remove_all(entry.path());
|
||
|
|
||
|
//Save optimal X
|
||
|
nlohmann::json json_optimizationResults;
|
||
|
std::string jsonValue_optimizationVariables;
|
||
|
for (const auto &optimalXNameValuePair : optimalXNameValuePairs) {
|
||
|
jsonValue_optimizationVariables.append(optimalXNameValuePair.first + ",");
|
||
|
}
|
||
|
jsonValue_optimizationVariables.pop_back(); // for deleting the last comma
|
||
|
json_optimizationResults[JsonKeys::optimizationVariables] = jsonValue_optimizationVariables;
|
||
|
|
||
|
for (const auto &optimalXNameValuePair : optimalXNameValuePairs) {
|
||
|
json_optimizationResults[optimalXNameValuePair.first] = optimalXNameValuePair.second;
|
||
|
}
|
||
|
//base triangle
|
||
|
json_optimizationResults[JsonKeys::baseTriangle]
|
||
|
= std::vector<double>{baseTriangle.cP0(0)[0],
|
||
|
baseTriangle.cP0(0)[1],
|
||
|
baseTriangle.cP0(0)[2],
|
||
|
baseTriangle.cP1(0)[0],
|
||
|
baseTriangle.cP1(0)[1],
|
||
|
baseTriangle.cP1(0)[2],
|
||
|
baseTriangle.cP2(0)[0],
|
||
|
baseTriangle.cP2(0)[1],
|
||
|
baseTriangle.cP2(0)[2]};
|
||
|
////Save to json file
|
||
|
std::filesystem::path jsonFilePath(
|
||
|
std::filesystem::path(saveToPath).append(JsonKeys::filename));
|
||
|
std::ofstream jsonFile_optimizationResults(jsonFilePath.string());
|
||
|
jsonFile_optimizationResults << json_optimizationResults;
|
||
|
|
||
|
/*TODO: Refactor since the meshes are saved for each simulation scenario although they do not change*/
|
||
|
//Save jobs and meshes for each simulation scenario
|
||
|
|
||
|
//Save the reduced and full patterns
|
||
|
|
||
|
const int numberOfSimulationJobs = fullPatternSimulationJobs.size();
|
||
|
for (int simulationScenarioIndex = 0; simulationScenarioIndex < numberOfSimulationJobs;
|
||
|
simulationScenarioIndex++) {
|
||
|
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob
|
||
|
= fullPatternSimulationJobs[simulationScenarioIndex];
|
||
|
std::filesystem::path simulationJobFolderPath(
|
||
|
std::filesystem::path(saveToPath).append(pFullPatternSimulationJob->label));
|
||
|
std::filesystem::create_directory(simulationJobFolderPath);
|
||
|
const auto fullPatternDirectoryPath = std::filesystem::path(simulationJobFolderPath)
|
||
|
.append("Full");
|
||
|
std::filesystem::create_directory(fullPatternDirectoryPath);
|
||
|
pFullPatternSimulationJob->save(fullPatternDirectoryPath.string());
|
||
|
const std::shared_ptr<SimulationJob> &pReducedPatternSimulationJob
|
||
|
= reducedPatternSimulationJobs[simulationScenarioIndex];
|
||
|
const auto reducedPatternDirectoryPath
|
||
|
= std::filesystem::path(simulationJobFolderPath).append("Reduced");
|
||
|
if (!std::filesystem::exists(reducedPatternDirectoryPath)) {
|
||
|
std::filesystem::create_directory(reducedPatternDirectoryPath);
|
||
|
}
|
||
|
pReducedPatternSimulationJob->save(reducedPatternDirectoryPath.string());
|
||
|
}
|
||
|
|
||
|
std::cout << "Saved optimization results to:" << saveToPath << std::endl;
|
||
|
}
|
||
|
|
||
|
template<typename MeshType>
|
||
|
static void applyOptimizationResults_innerHexagon(
|
||
|
const ReducedPatternOptimization::Results &reducedPattern_optimizationResults,
|
||
|
const vcg::Triangle3<double> &patternBaseTriangle,
|
||
|
MeshType &reducedPattern)
|
||
|
{
|
||
|
std::unordered_map<std::string, double>
|
||
|
optimalXVariables(reducedPattern_optimizationResults.optimalXNameValuePairs.begin(),
|
||
|
reducedPattern_optimizationResults.optimalXNameValuePairs.end());
|
||
|
assert(optimalXVariables.contains("HexSize") && optimalXVariables.contains("HexAngle"));
|
||
|
|
||
|
//Set optimal geometrical params of the reduced pattern
|
||
|
CoordType center_barycentric(1, 0, 0);
|
||
|
CoordType interfaceEdgeMiddle_barycentric(0, 0.5, 0.5);
|
||
|
CoordType movableVertex_barycentric((center_barycentric + interfaceEdgeMiddle_barycentric)
|
||
|
* optimalXVariables.at("HexSize"));
|
||
|
reducedPattern.vert[1].P() = patternBaseTriangle.cP(0) * movableVertex_barycentric[0]
|
||
|
+ patternBaseTriangle.cP(1) * movableVertex_barycentric[1]
|
||
|
+ patternBaseTriangle.cP(2) * movableVertex_barycentric[2];
|
||
|
reducedPattern.vert[1].P() = vcg::RotationMatrix(CoordType{0, 0, 1},
|
||
|
vcg::math::ToRad(
|
||
|
optimalXVariables.at("HexAngle")))
|
||
|
* reducedPattern.vert[1].cP();
|
||
|
}
|
||
|
|
||
|
static void applyOptimizationResults_elements(
|
||
|
const ReducedPatternOptimization::Results &reducedPattern_optimizationResults,
|
||
|
const shared_ptr<SimulationMesh> &pTiledReducedPattern_simulationMesh)
|
||
|
{
|
||
|
// Set reduced parameters fron the optimization results
|
||
|
std::unordered_map<std::string, double>
|
||
|
optimalXVariables(reducedPattern_optimizationResults.optimalXNameValuePairs.begin(),
|
||
|
reducedPattern_optimizationResults.optimalXNameValuePairs.end());
|
||
|
|
||
|
const std::string ALabel = "A";
|
||
|
assert(optimalXVariables.contains(ALabel));
|
||
|
const double A = optimalXVariables.at(ALabel);
|
||
|
const double beamWidth = std::sqrt(A);
|
||
|
const double beamHeight = beamWidth;
|
||
|
RectangularBeamDimensions elementDimensions(beamWidth, beamHeight);
|
||
|
|
||
|
const double poissonsRatio = 0.3;
|
||
|
const std::string ymLabel = "E";
|
||
|
assert(optimalXVariables.contains(ymLabel));
|
||
|
const double E = optimalXVariables.at(ymLabel);
|
||
|
const ElementMaterial elementMaterial(poissonsRatio, E);
|
||
|
|
||
|
const std::string JLabel = "J";
|
||
|
assert(optimalXVariables.contains(JLabel));
|
||
|
const double J = optimalXVariables.at(JLabel);
|
||
|
|
||
|
const std::string I2Label = "I2";
|
||
|
assert(optimalXVariables.contains(I2Label));
|
||
|
const double I2 = optimalXVariables.at(I2Label);
|
||
|
|
||
|
const std::string I3Label = "I3";
|
||
|
assert(optimalXVariables.contains(I3Label));
|
||
|
const double I3 = optimalXVariables.at(I3Label);
|
||
|
for (int ei = 0; ei < pTiledReducedPattern_simulationMesh->EN(); ei++) {
|
||
|
Element &e = pTiledReducedPattern_simulationMesh->elements[ei];
|
||
|
e.setDimensions(elementDimensions);
|
||
|
e.setMaterial(elementMaterial);
|
||
|
e.J = J;
|
||
|
e.I2 = I2;
|
||
|
e.I3 = I3;
|
||
|
}
|
||
|
pTiledReducedPattern_simulationMesh->reset();
|
||
|
}
|
||
|
|
||
|
void load(const string &loadFromPath)
|
||
|
{
|
||
|
assert(std::filesystem::is_directory(loadFromPath));
|
||
|
//Load optimal X
|
||
|
nlohmann::json json_optimizationResults;
|
||
|
std::ifstream ifs(std::filesystem::path(loadFromPath).append(JsonKeys::filename));
|
||
|
ifs >> json_optimizationResults;
|
||
|
|
||
|
std::string optimizationVariablesString = *json_optimizationResults.find(
|
||
|
JsonKeys::optimizationVariables);
|
||
|
std::string optimizationVariablesDelimeter = ",";
|
||
|
size_t pos = 0;
|
||
|
std::vector<std::string> optimizationVariablesNames;
|
||
|
while ((pos = optimizationVariablesString.find(optimizationVariablesDelimeter))
|
||
|
!= std::string::npos) {
|
||
|
const std::string variableName = optimizationVariablesString.substr(0, pos);
|
||
|
optimizationVariablesNames.push_back(variableName);
|
||
|
optimizationVariablesString.erase(0, pos + optimizationVariablesDelimeter.length());
|
||
|
}
|
||
|
optimizationVariablesNames.push_back(optimizationVariablesString); //add last variable name
|
||
|
|
||
|
optimalXNameValuePairs.resize(optimizationVariablesNames.size());
|
||
|
for (int xVariable_index = 0; xVariable_index < optimizationVariablesNames.size();
|
||
|
xVariable_index++) {
|
||
|
const std::string xVariable_name = optimizationVariablesNames[xVariable_index];
|
||
|
const double xVariable_value = *json_optimizationResults.find(xVariable_name);
|
||
|
optimalXNameValuePairs[xVariable_index] = std::make_pair(xVariable_name,
|
||
|
xVariable_value);
|
||
|
}
|
||
|
|
||
|
std::vector<double> baseTriangleVertices = json_optimizationResults.at(
|
||
|
JsonKeys::baseTriangle);
|
||
|
baseTriangle.P0(0) = CoordType(baseTriangleVertices[0],
|
||
|
baseTriangleVertices[1],
|
||
|
baseTriangleVertices[2]);
|
||
|
baseTriangle.P1(0) = CoordType(baseTriangleVertices[3],
|
||
|
baseTriangleVertices[4],
|
||
|
baseTriangleVertices[5]);
|
||
|
baseTriangle.P2(0) = CoordType(baseTriangleVertices[6],
|
||
|
baseTriangleVertices[7],
|
||
|
baseTriangleVertices[8]);
|
||
|
|
||
|
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"))) {
|
||
|
const auto filepath = fileEntry.path();
|
||
|
if (filepath.extension() == ".json") {
|
||
|
SimulationJob job;
|
||
|
|
||
|
job.load(filepath.string());
|
||
|
fullPatternSimulationJobs.push_back(std::make_shared<SimulationJob>(job));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Load full pattern files
|
||
|
for (const auto &fileEntry : filesystem::directory_iterator(
|
||
|
std::filesystem::path(simulationScenarioPath).append("Reduced"))) {
|
||
|
const auto filepath = fileEntry.path();
|
||
|
if (filepath.extension() == ".json") {
|
||
|
SimulationJob job;
|
||
|
job.load(filepath.string());
|
||
|
applyOptimizationResults_innerHexagon(*this, baseTriangle, *job.pMesh);
|
||
|
applyOptimizationResults_elements(*this, job.pMesh);
|
||
|
reducedPatternSimulationJobs.push_back(std::make_shared<SimulationJob>(job));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#if POLYSCOPE_DEFINED
|
||
|
void draw() const {
|
||
|
initPolyscope();
|
||
|
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());
|
||
|
SimulationResults fullModelResults = drmSimulator.executeSimulation(
|
||
|
pFullPatternSimulationJob);
|
||
|
fullModelResults.registerForDrawing(Colors::fullDeformed, true, 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];
|
||
|
// SimulationResults reducedModelResults = drmSimulator.executeSimulation(
|
||
|
// pReducedPatternSimulationJob);
|
||
|
// reducedModelResults.registerForDrawing(Colors::reducedDeformed, false);
|
||
|
SimulationResults reducedModelLinearResults =
|
||
|
linearSimulator.executeSimulation(pReducedPatternSimulationJob);
|
||
|
reducedModelLinearResults.setLabelPrefix("linear");
|
||
|
reducedModelLinearResults.registerForDrawing(Colors::reducedDeformed, true, 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);
|
||
|
fullModelResults.unregister();
|
||
|
// reducedModelResults.unregister();
|
||
|
reducedModelLinearResults.unregister();
|
||
|
// fullModelLinearResults.unregister();
|
||
|
// double error = computeError(
|
||
|
// reducedModelResults.displacements,fullModelResults.displacements,
|
||
|
// );
|
||
|
// std::cout << "Error of simulation scenario "
|
||
|
// <<
|
||
|
// simula simulationScenarioStrings[simulationScenarioIndex]
|
||
|
// << " is "
|
||
|
// << error << std::endl;
|
||
|
}
|
||
|
}
|
||
|
#endif // POLYSCOPE_DEFINED
|
||
|
void saveMeshFiles() const {
|
||
|
const int numberOfSimulationJobs = fullPatternSimulationJobs.size();
|
||
|
assert(numberOfSimulationJobs != 0 &&
|
||
|
fullPatternSimulationJobs.size() ==
|
||
|
reducedPatternSimulationJobs.size());
|
||
|
|
||
|
fullPatternSimulationJobs[0]->pMesh->save(
|
||
|
"undeformed " + fullPatternSimulationJobs[0]->pMesh->getLabel() + ".ply");
|
||
|
reducedPatternSimulationJobs[0]->pMesh->save(
|
||
|
"undeformed " + reducedPatternSimulationJobs[0]->pMesh->getLabel() + ".ply");
|
||
|
DRMSimulationModel simulator_drm;
|
||
|
LinearSimulationModel simulator_linear;
|
||
|
for (int simulationJobIndex = 0; simulationJobIndex < numberOfSimulationJobs;
|
||
|
simulationJobIndex++) {
|
||
|
// Drawing of full pattern results
|
||
|
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob
|
||
|
= fullPatternSimulationJobs[simulationJobIndex];
|
||
|
SimulationResults fullModelResults = simulator_drm.executeSimulation(
|
||
|
pFullPatternSimulationJob);
|
||
|
fullModelResults.saveDeformedModel();
|
||
|
|
||
|
// Drawing of reduced pattern results
|
||
|
const std::shared_ptr<SimulationJob> &pReducedPatternSimulationJob
|
||
|
= reducedPatternSimulationJobs[simulationJobIndex];
|
||
|
SimulationResults reducedModelResults = simulator_linear.executeSimulation(
|
||
|
pReducedPatternSimulationJob);
|
||
|
reducedModelResults.saveDeformedModel();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void writeHeaderTo(csvFile &os)
|
||
|
{
|
||
|
os << "Total raw Obj value";
|
||
|
os << "Total Obj value";
|
||
|
for (int simulationScenarioIndex = 0;
|
||
|
simulationScenarioIndex < fullPatternSimulationJobs.size();
|
||
|
simulationScenarioIndex++) {
|
||
|
const std::string simulationScenarioName
|
||
|
= fullPatternSimulationJobs[simulationScenarioIndex]->getLabel();
|
||
|
os << "Obj value Trans " + simulationScenarioName;
|
||
|
os << "Obj value Rot " + simulationScenarioName;
|
||
|
os << "Obj value Total " + simulationScenarioName;
|
||
|
}
|
||
|
for (const auto &nameValuePair : optimalXNameValuePairs) {
|
||
|
os << nameValuePair.first;
|
||
|
}
|
||
|
os << "Time(s)";
|
||
|
os << "#Crashes";
|
||
|
}
|
||
|
|
||
|
void writeResultsTo(const Settings &settings_optimization, csvFile &os) const
|
||
|
{
|
||
|
os << objectiveValue.totalRaw;
|
||
|
os << objectiveValue.total;
|
||
|
for (int simulationScenarioIndex = 0;
|
||
|
simulationScenarioIndex < fullPatternSimulationJobs.size();
|
||
|
simulationScenarioIndex++) {
|
||
|
os << objectiveValue.perSimulationScenario_translational[simulationScenarioIndex];
|
||
|
os << objectiveValue.perSimulationScenario_rotational[simulationScenarioIndex];
|
||
|
os << objectiveValue.perSimulationScenario_total[simulationScenarioIndex];
|
||
|
}
|
||
|
for (const auto &optimalXNameValuePair : optimalXNameValuePairs) {
|
||
|
os << optimalXNameValuePair.second;
|
||
|
}
|
||
|
|
||
|
os << time;
|
||
|
if (numberOfSimulationCrashes == 0) {
|
||
|
os << "-";
|
||
|
} else {
|
||
|
os << numberOfSimulationCrashes;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // namespace ReducedPatternOptimization
|
||
|
#endif // REDUCEDMODELOPTIMIZER_STRUCTS_HPP
|