ReducedModelOptimization/src/reducedmodeloptimizer.cpp

1043 lines
51 KiB
C++
Raw Normal View History

#include "reducedmodeloptimizer.hpp"
#include "linearsimulationmodel.hpp"
2020-11-23 10:06:45 +01:00
#include "simulationhistoryplotter.hpp"
#include "trianglepatterngeometry.hpp"
#include "trianglepattterntopology.hpp"
#include <chrono>
#include <dlib/global_optimization.h>
#include <dlib/optimization.h>
2020-11-23 10:06:45 +01:00
2021-03-23 18:20:46 +01:00
using namespace ReducedModelOptimization;
struct GlobalOptimizationVariables {
std::vector<Eigen::MatrixX3d> g_optimalReducedModelDisplacements;
// std::vector<std::vector<Vector6d>> fullPatternDisplacements;
std::vector<SimulationResults> fullPatternResults;
std::vector<double> translationalDisplacementNormalizationValues;
std::vector<double> rotationalDisplacementNormalizationValues;
std::vector<std::shared_ptr<SimulationJob>> fullPatternSimulationJobs;
std::vector<std::shared_ptr<SimulationJob>> reducedPatternSimulationJobs;
std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
reducedToFullInterfaceViMap;
matplot::line_handle gPlotHandle;
2021-03-23 18:20:46 +01:00
std::vector<double> objectiveValueHistory;
Eigen::VectorXd initialParameters;
2021-03-23 18:20:46 +01:00
std::vector<SimulationScenario>
simulationScenarioIndices;
std::vector<VectorType> g_innerHexagonVectors{6, VectorType(0, 0, 0)};
double innerHexagonInitialRotationAngle{30};
double innerHexagonInitialPos{0};
double minY{DBL_MAX};
std::vector<double> minX;
int numOfSimulationCrashes{false};
int numberOfFunctionCalls{0};
int numberOfOptimizationParameters{5};
2021-03-23 18:20:46 +01:00
ReducedModelOptimization::Settings optimizationSettings;
vcg::Triangle3<double> baseTriangle;
} global;
2020-12-09 16:58:48 +01:00
std::vector<SimulationJob> reducedPatternMaximumDisplacementSimulationJobs;
double ReducedModelOptimizer::computeDisplacementError(
2021-02-18 11:12:52 +01:00
const std::vector<Vector6d> &fullPatternDisplacements,
2021-03-30 18:30:49 +02:00
const std::vector<Vector6d> &reducedPatternDisplacements,
const std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
&reducedToFullInterfaceViMap,
const double &normalizationFactor)
{
2021-03-30 18:30:49 +02:00
const double rawError = computeRawDisplacementError(fullPatternDisplacements,
reducedPatternDisplacements,
reducedToFullInterfaceViMap);
if (global.optimizationSettings.normalizationStrategy !=
Settings::NormalizationStrategy::NonNormalized) {
return rawError / normalizationFactor;
}
return rawError;
}
double ReducedModelOptimizer::computeRawDisplacementError(
const std::vector<Vector6d> &fullPatternDisplacements,
2021-03-30 18:30:49 +02:00
const std::vector<Vector6d> &reducedPatternDisplacements,
const std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
&reducedToFullInterfaceViMap)
{
double error = 0;
for (const auto reducedFullViPair : reducedToFullInterfaceViMap) {
const VertexIndex reducedModelVi = reducedFullViPair.first;
Eigen::Vector3d reducedVertexDisplacement(
reducedPatternDisplacements[reducedModelVi][0],
reducedPatternDisplacements[reducedModelVi][1],
reducedPatternDisplacements[reducedModelVi][2]);
const VertexIndex fullModelVi = reducedFullViPair.second;
Eigen::Vector3d fullVertexDisplacement(
fullPatternDisplacements[fullModelVi][0],
fullPatternDisplacements[fullModelVi][1],
fullPatternDisplacements[fullModelVi][2]);
Eigen::Vector3d errorVector =
fullVertexDisplacement - reducedVertexDisplacement;
// error += errorVector.squaredNorm();
error += errorVector.norm();
}
return error;
}
2021-03-30 18:30:49 +02:00
double ReducedModelOptimizer::computeRawRotationalError(
const std::vector<Eigen::Quaternion<double>> &rotatedQuaternion_fullPattern,
const std::vector<Eigen::Quaternion<double>> &rotatedQuaternion_reducedPattern,
const std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
&reducedToFullInterfaceViMap)
{
double rawRotationalError = 0;
for (const auto &reducedToFullInterfaceViPair : reducedToFullInterfaceViMap) {
const double vertexRotationalError
= rotatedQuaternion_fullPattern[reducedToFullInterfaceViPair.second].angularDistance(
rotatedQuaternion_reducedPattern[reducedToFullInterfaceViPair.first]);
rawRotationalError += vertexRotationalError;
}
return rawRotationalError;
}
double ReducedModelOptimizer::computeRotationalError(
const std::vector<Eigen::Quaternion<double>> &rotatedQuaternion_fullPattern,
const std::vector<Eigen::Quaternion<double>> &rotatedQuaternion_reducedPattern,
const std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
&reducedToFullInterfaceViMap,
const double &normalizationFactor)
{
const double rawRotationalError = computeRawRotationalError(rotatedQuaternion_fullPattern,
rotatedQuaternion_reducedPattern,
reducedToFullInterfaceViMap);
return rawRotationalError / normalizationFactor;
}
double ReducedModelOptimizer::computeError(
const SimulationResults &simulationResults_fullPattern,
const SimulationResults &simulationResults_reducedPattern,
const std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
&reducedToFullInterfaceViMap,
const double &normalizationFactor_translationalDisplacement,
const double &normalizationFactor_rotationalDisplacement)
{
const double translationalError
= computeDisplacementError(simulationResults_fullPattern.displacements,
simulationResults_reducedPattern.displacements,
reducedToFullInterfaceViMap,
normalizationFactor_translationalDisplacement);
const double rotationalError
= computeRotationalError(simulationResults_fullPattern.rotationalDisplacementQuaternion,
simulationResults_reducedPattern.rotationalDisplacementQuaternion,
reducedToFullInterfaceViMap,
normalizationFactor_rotationalDisplacement);
return translationalError + rotationalError;
}
double ReducedModelOptimizer::objective(double E,double A,double J,double I2,double I3,
double innerHexagonSize,
double innerHexagonRotationAngle) {
std::vector<double> x{E,A,J,I2,I3, innerHexagonSize, innerHexagonRotationAngle};
return ReducedModelOptimizer::objective(x.size(), x.data());
}
double ReducedModelOptimizer::objective(long n, const double *x) {
// std::cout.precision(17);
// for (int i = 0; i < n; i++) {
// std::cout << x[i] << " ";
// }
// std::cout << std::endl;
// const Element &e =
// global.reducedPatternSimulationJobs[0]->pMesh->elements[0]; std::cout <<
// e.axialConstFactor << " " << e.torsionConstFactor << " "
// << e.firstBendingConstFactor << " " <<
// e.secondBendingConstFactor
// << std::endl;
updateMesh(n, x);
// std::cout << e.axialConstFactor << " " << e.torsionConstFactor << " "
// << e.firstBendingConstFactor << " " <<
// e.secondBendingConstFactor
// << std::endl;
// run simulations
double totalError = 0;
LinearSimulationModel simulator;
// FormFinder simulator;
for (const int simulationScenarioIndex : global.simulationScenarioIndices) {
SimulationResults reducedModelResults = simulator.executeSimulation(
global.reducedPatternSimulationJobs[simulationScenarioIndex]);
// std::string filename;
if (!reducedModelResults.converged) {
totalError += std::numeric_limits<double>::max();
global.numOfSimulationCrashes++;
#ifdef POLYSCOPE_DEFINED
std::cout << "Failed simulation" << std::endl;
#endif
} else {
const bool usePotentialEnergy = false;
double simulationScenarioError;
if (usePotentialEnergy) {
simulationScenarioError = std::abs(
reducedModelResults.internalPotentialEnergy
- global.fullPatternResults[simulationScenarioIndex].internalPotentialEnergy);
} else {
2021-03-30 18:30:49 +02:00
simulationScenarioError += computeError(
global.fullPatternResults[simulationScenarioIndex],
reducedModelResults,
global.reducedToFullInterfaceViMap,
2021-03-30 18:30:49 +02:00
global.translationalDisplacementNormalizationValues[simulationScenarioIndex],
global.rotationalDisplacementNormalizationValues[simulationScenarioIndex]);
}
//#ifdef POLYSCOPE_DEFINED
// std::cout << "sim error:" << simulationScenarioError << std::endl;
// global.reducedPatternSimulationJobs[simulationScenarioIndex]->pMesh->registerForDrawing(
// ReducedModelOptimization::Colors::reducedInitial);
// reducedModelResults.registerForDrawing(
// ReducedModelOptimization::Colors::reducedDeformed);
// polyscope::show();
// reducedModelResults.unregister();
//#endif
// if (global.optimizationSettings.normalizationStrategy !=
// NormalizationStrategy::Epsilon &&
// simulationScenarioError > 1) {
// std::cout << "Simulation scenario "
// <<
// simulationScenarioStrings[simulationScenarioIndex]
// << " results in an error bigger than one." <<
// std::endl;
// for (size_t parameterIndex = 0; parameterIndex < n;
// parameterIndex++) {
// std::cout << "x[" + std::to_string(parameterIndex) + "]="
// << x[parameterIndex] << std::endl;
// }
// }
//#ifdef POLYSCOPE_DEFINED
// ReducedModelOptimizer::visualizeResults(
// global.fullPatternSimulationJobs[simulationScenarioIndex],
// global.reducedPatternSimulationJobs[simulationScenarioIndex],
// global.reducedToFullInterfaceViMap, false);
// ReducedModelOptimizer::visualizeResults(
// global.fullPatternSimulationJobs[simulationScenarioIndex],
// std::make_shared<SimulationJob>(
// reducedPatternMaximumDisplacementSimulationJobs
// [simulationScenarioIndex]),
// global.reducedToFullInterfaceViMap, true);
// polyscope::removeAllStructures();
//#endif // POLYSCOPE_DEFINED
totalError += simulationScenarioError;
}
}
// std::cout << error << std::endl;
if (totalError < global.minY) {
global.minY = totalError;
global.minX.assign(x, x + n);
}
#ifdef POLYSCOPE_DEFINED
// if (++global.numberOfFunctionCalls % 100 == 0) {
// std::cout << "Number of function calls:" << global.numberOfFunctionCalls
// << std::endl;
// }
#endif
2021-03-23 18:20:46 +01:00
// compute error and return it
// global.objectiveValueHistory.push_back(totalError);
// auto xPlot = matplot::linspace(0, global.objectiveValueHistory.size(),
// global.objectiveValueHistory.size());
// std::vector<double> colors(global.gObjectiveValueHistory.size(), 2);
// if (global.g_firstRoundIterationIndex != 0) {
// for_each(colors.begin() + g_firstRoundIterationIndex, colors.end(),
// [](double &c) { c = 0.7; });
// }
// global.gPlotHandle = matplot::scatter(xPlot, global.objectiveValueHistory);
// SimulationResultsReporter::createPlot("Number of Steps", "Objective value",
// global.objectiveValueHistory);
return totalError;
2020-11-23 10:06:45 +01:00
}
void ReducedModelOptimizer::createSimulationMeshes(
PatternGeometry &fullModel, PatternGeometry &reducedModel,
std::shared_ptr<SimulationMesh> &pFullPatternSimulationMesh,
std::shared_ptr<SimulationMesh> &pReducedPatternSimulationMesh) {
if (typeid(CrossSectionType) != typeid(RectangularBeamDimensions)) {
std::cerr << "Error: A rectangular cross section is expected." << std::endl;
terminate();
}
// Full pattern
pFullPatternSimulationMesh = std::make_shared<SimulationMesh>(fullModel);
pFullPatternSimulationMesh->setBeamCrossSection(
CrossSectionType{0.002, 0.002});
pFullPatternSimulationMesh->setBeamMaterial(0.3, 1 * 1e9);
// Reduced pattern
pReducedPatternSimulationMesh =
std::make_shared<SimulationMesh>(reducedModel);
pReducedPatternSimulationMesh->setBeamCrossSection(
CrossSectionType{0.002, 0.002});
pReducedPatternSimulationMesh->setBeamMaterial(0.3, 1 * 1e9);
}
void ReducedModelOptimizer::createSimulationMeshes(
PatternGeometry &fullModel, PatternGeometry &reducedModel) {
ReducedModelOptimizer::createSimulationMeshes(
fullModel, reducedModel, m_pFullPatternSimulationMesh,
m_pReducedPatternSimulationMesh);
}
void ReducedModelOptimizer::computeMaps(
const std::unordered_map<size_t, std::unordered_set<size_t>> &slotToNode,
PatternGeometry &fullPattern, PatternGeometry &reducedPattern,
std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
&reducedToFullInterfaceViMap,
std::unordered_map<FullPatternVertexIndex, ReducedPatternVertexIndex>
&fullToReducedInterfaceViMap,
std::unordered_map<FullPatternVertexIndex, ReducedPatternVertexIndex>
&fullPatternOppositeInterfaceViMap) {
// Compute the offset between the interface nodes
const size_t interfaceSlotIndex = 4; // bottom edge
assert(slotToNode.find(interfaceSlotIndex) != slotToNode.end() &&
slotToNode.find(interfaceSlotIndex)->second.size() == 1);
// Assuming that in the bottom edge there is only one vertex which is also the
// interface
const size_t baseTriangleInterfaceVi =
*(slotToNode.find(interfaceSlotIndex)->second.begin());
vcg::tri::Allocator<VCGEdgeMesh>::PointerUpdater<PatternGeometry::VertexPointer> pu_fullModel;
fullPattern.deleteDanglingVertices(pu_fullModel);
const size_t fullModelBaseTriangleInterfaceVi =
pu_fullModel.remap.empty() ? baseTriangleInterfaceVi
: pu_fullModel.remap[baseTriangleInterfaceVi];
const size_t fullModelBaseTriangleVN = fullPattern.VN();
fullPattern.createFan();
const size_t duplicateVerticesPerFanPair =
fullModelBaseTriangleVN - fullPattern.VN() / 6;
const size_t fullPatternInterfaceVertexOffset =
fullModelBaseTriangleVN - duplicateVerticesPerFanPair;
// std::cout << "Dups in fan pair:" << duplicateVerticesPerFanPair <<
// std::endl;
// Save excluded edges TODO:this changes the global object. Should this be a
// function parameter?
// global.reducedPatternExludedEdges.clear();
// const size_t reducedBaseTriangleNumberOfEdges = reducedPattern.EN();
// for (size_t fanIndex = 0; fanIndex < fanSize; fanIndex++) {
// for (const size_t ei : reducedModelExcludedEdges) {
// global.reducedPatternExludedEdges.insert(
// fanIndex * reducedBaseTriangleNumberOfEdges + ei);
// }
// }
// Construct reduced->full and full->reduced interface vi map
reducedToFullInterfaceViMap.clear();
vcg::tri::Allocator<VCGEdgeMesh>::PointerUpdater<PatternGeometry::VertexPointer> pu_reducedModel;
reducedPattern.deleteDanglingVertices(pu_reducedModel);
const size_t reducedModelBaseTriangleInterfaceVi =
pu_reducedModel.remap[baseTriangleInterfaceVi];
const size_t reducedModelInterfaceVertexOffset
= reducedPattern.VN() /*- 1*/ /*- reducedModelBaseTriangleInterfaceVi*/;
reducedPattern.createFan({1}); //TODO: should be an input parameter from main
for (size_t fanIndex = 0; fanIndex < fanSize; fanIndex++) {
reducedToFullInterfaceViMap[reducedModelInterfaceVertexOffset * fanIndex +
reducedModelBaseTriangleInterfaceVi] =
fullModelBaseTriangleInterfaceVi +
fanIndex * fullPatternInterfaceVertexOffset;
}
fullToReducedInterfaceViMap.clear();
constructInverseMap(reducedToFullInterfaceViMap, fullToReducedInterfaceViMap);
// Create opposite vertex map
fullPatternOppositeInterfaceViMap.clear();
for (int fanIndex = fanSize / 2 - 1; fanIndex >= 0; fanIndex--) {
const size_t vi0 = fullModelBaseTriangleInterfaceVi +
fanIndex * fullPatternInterfaceVertexOffset;
const size_t vi1 = vi0 + (fanSize / 2) * fullPatternInterfaceVertexOffset;
assert(vi0 < fullPattern.VN() && vi1 < fullPattern.VN());
fullPatternOppositeInterfaceViMap[vi0] = vi1;
}
const bool debugMapping = false;
if (debugMapping) {
#if POLYSCOPE_DEFINED
reducedPattern.registerForDrawing();
// std::vector<glm::vec3> 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<glm::vec3> nodeColorsOpposite(fullPattern.VN(),
glm::vec3(0, 0, 0));
for (const std::pair<size_t, size_t> 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<glm::vec3> nodeColorsReducedToFull_reduced(reducedPattern.VN(),
glm::vec3(0, 0, 0));
std::vector<glm::vec3> 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();
#endif
}
}
2020-11-23 10:06:45 +01:00
2021-03-30 18:30:49 +02:00
void ReducedModelOptimizer::computeMaps(PatternGeometry &fullPattern,
PatternGeometry &reducedPattern)
{
ReducedModelOptimizer::computeMaps(slotToNode,
fullPattern,
reducedPattern,
global.reducedToFullInterfaceViMap,
m_fullToReducedInterfaceViMap,
m_fullPatternOppositeInterfaceViMap);
}
ReducedModelOptimizer::ReducedModelOptimizer(
const std::vector<size_t> &numberOfNodesPerSlot) {
FlatPatternTopology::constructNodeToSlotMap(numberOfNodesPerSlot, nodeToSlot);
FlatPatternTopology::constructSlotToNodeMap(nodeToSlot, slotToNode);
}
2021-03-30 18:30:49 +02:00
void ReducedModelOptimizer::initializePatterns(PatternGeometry &fullPattern,
PatternGeometry &reducedPattern,
const int &optimizationParameters)
{
assert(fullPattern.VN() == reducedPattern.VN() &&
fullPattern.EN() >= reducedPattern.EN());
#if POLYSCOPE_DEFINED
polyscope::removeAllStructures();
#endif
// Create copies of the input models
PatternGeometry copyFullPattern;
PatternGeometry copyReducedPattern;
copyFullPattern.copy(fullPattern);
copyReducedPattern.copy(reducedPattern);
global.baseTriangle = copyReducedPattern.getBaseTriangle();
2021-03-30 18:30:49 +02:00
computeMaps(copyFullPattern, copyReducedPattern);
createSimulationMeshes(copyFullPattern, copyReducedPattern);
2021-03-23 18:20:46 +01:00
initializeOptimizationParameters(m_pReducedPatternSimulationMesh,optimizationParameters);
}
2021-03-23 18:20:46 +01:00
void updateMesh(long n, const double *x) {
std::shared_ptr<SimulationMesh> &pReducedPatternSimulationMesh =
global.reducedPatternSimulationJobs[global.simulationScenarioIndices[0]]
->pMesh;
const double E=global.initialParameters(0)*x[0];
const double A=global.initialParameters(1) * x[1];
const double beamWidth=std::sqrt(A);
const double beamHeight=beamWidth;
const double J=global.initialParameters(2) * x[2];
const double I2=global.initialParameters(3) * x[3];
const double I3=global.initialParameters(4) * x[4];
for (EdgeIndex ei = 0; ei < pReducedPatternSimulationMesh->EN(); ei++) {
Element &e = pReducedPatternSimulationMesh->elements[ei];
e.setDimensions(
RectangularBeamDimensions(beamWidth,
beamHeight));
e.setMaterial(ElementMaterial(e.material.poissonsRatio,
E));
e.J = J;
e.I2 = I2;
e.I3 = I3;
}
assert(pReducedPatternSimulationMesh->EN() == 12);
assert(n>=2);
CoordType center_barycentric(1, 0, 0);
CoordType interfaceEdgeMiddle_barycentric(0, 0.5, 0.5);
CoordType movableVertex_barycentric((center_barycentric + interfaceEdgeMiddle_barycentric)
* x[n - 2]);
CoordType baseTriangleMovableVertexPosition = global.baseTriangle.cP(0)
* movableVertex_barycentric[0]
+ global.baseTriangle.cP(1)
* movableVertex_barycentric[1]
+ global.baseTriangle.cP(2)
* movableVertex_barycentric[2];
baseTriangleMovableVertexPosition
= vcg::RotationMatrix(ReducedModelOptimizer::patternPlaneNormal, vcg::math::ToRad(x[n - 1]))
* baseTriangleMovableVertexPosition;
2021-03-23 18:20:46 +01:00
for (int rotationCounter = 0;
rotationCounter < ReducedModelOptimizer::fanSize; rotationCounter++) {
pReducedPatternSimulationMesh->vert[2 * rotationCounter + 1].P()
= vcg::RotationMatrix(ReducedModelOptimizer::patternPlaneNormal,
vcg::math::ToRad(60.0 * rotationCounter))
* baseTriangleMovableVertexPosition;
2021-03-23 18:20:46 +01:00
}
pReducedPatternSimulationMesh->reset();
//#ifdef POLYSCOPE_DEFINED
// pReducedPatternSimulationMesh->updateEigenEdgeAndVertices();
// pReducedPatternSimulationMesh->registerForDrawing();
// std::cout << "Angle:" + std::to_string(x[n - 1]) + " size:" + std::to_string(x[n - 2])
// << std::endl;
// std::cout << "Verts:" << pReducedPatternSimulationMesh->VN() << std::endl;
// polyscope::show();
//#endif
2021-03-23 18:20:46 +01:00
}
void ReducedModelOptimizer::initializeOptimizationParameters(
2021-03-23 18:20:46 +01:00
const std::shared_ptr<SimulationMesh> &mesh,const int& optimizationParamters) {
global.numberOfOptimizationParameters = optimizationParamters;
global.initialParameters.resize(global.numberOfOptimizationParameters);
2021-03-23 18:20:46 +01:00
global.initialParameters(0) = mesh->elements[0].material.youngsModulus;
global.initialParameters(1) = mesh->elements[0].A;
global.initialParameters(2) = mesh->elements[0].J;
global.initialParameters(3) = mesh->elements[0].I2;
global.initialParameters(4) = mesh->elements[0].I3;
2021-03-23 18:20:46 +01:00
global.initialParameters(optimizationParamters-2) = global.innerHexagonInitialPos;
global.innerHexagonInitialRotationAngle = 30;
2021-03-23 18:20:46 +01:00
global.initialParameters(optimizationParamters-1) = global.innerHexagonInitialRotationAngle;
2020-11-23 10:06:45 +01:00
}
void ReducedModelOptimizer::computeReducedModelSimulationJob(
const SimulationJob &simulationJobOfFullModel,
const std::unordered_map<size_t, size_t> &fullToReducedMap,
SimulationJob &simulationJobOfReducedModel)
{
assert(simulationJobOfReducedModel.pMesh->VN() != 0);
std::unordered_map<VertexIndex, std::unordered_set<DoFType>>
reducedModelFixedVertices;
for (auto fullModelFixedVertex :
simulationJobOfFullModel.constrainedVertices) {
reducedModelFixedVertices[fullToReducedMap.at(fullModelFixedVertex.first)]
= fullModelFixedVertex.second;
}
std::unordered_map<VertexIndex, Vector6d> reducedModelNodalForces;
for (auto fullModelNodalForce :
simulationJobOfFullModel.nodalExternalForces) {
reducedModelNodalForces[fullToReducedMap.at(fullModelNodalForce.first)]
= fullModelNodalForce.second;
}
std::unordered_map<VertexIndex, Eigen::Vector3d> reducedNodalForcedDisplacements;
for (auto fullForcedDisplacement : simulationJobOfFullModel.nodalForcedDisplacements) {
reducedNodalForcedDisplacements[fullToReducedMap.at(fullForcedDisplacement.first)]
= fullForcedDisplacement.second;
}
simulationJobOfReducedModel.constrainedVertices = reducedModelFixedVertices;
simulationJobOfReducedModel.nodalExternalForces = reducedModelNodalForces;
simulationJobOfReducedModel.label = simulationJobOfFullModel.getLabel();
simulationJobOfReducedModel.nodalForcedDisplacements = reducedNodalForcedDisplacements;
2020-11-23 10:06:45 +01:00
}
#if POLYSCOPE_DEFINED
void ReducedModelOptimizer::visualizeResults(
const std::vector<std::shared_ptr<SimulationJob>>
&fullPatternSimulationJobs,
const std::vector<std::shared_ptr<SimulationJob>>
&reducedPatternSimulationJobs,
2021-03-23 18:20:46 +01:00
const std::vector<ReducedModelOptimization::SimulationScenario> &simulationScenarios,
const std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
&reducedToFullInterfaceViMap) {
DRMSimulationModel simulator;
std::shared_ptr<SimulationMesh> pFullPatternSimulationMesh =
fullPatternSimulationJobs[0]->pMesh;
pFullPatternSimulationMesh->registerForDrawing();
pFullPatternSimulationMesh->save(pFullPatternSimulationMesh->getLabel() + "_undeformed.ply");
reducedPatternSimulationJobs[0]->pMesh->save(reducedPatternSimulationJobs[0]->pMesh->getLabel()
+ "_undeformed.ply");
double totalError = 0;
for (const int simulationScenarioIndex : simulationScenarios) {
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob =
fullPatternSimulationJobs[simulationScenarioIndex];
pFullPatternSimulationJob->registerForDrawing(
pFullPatternSimulationMesh->getLabel());
SimulationResults fullModelResults =
simulator.executeSimulation(pFullPatternSimulationJob);
fullModelResults.registerForDrawing();
// fullModelResults.saveDeformedModel();
const std::shared_ptr<SimulationJob> &pReducedPatternSimulationJob =
reducedPatternSimulationJobs[simulationScenarioIndex];
SimulationResults reducedModelResults =
simulator.executeSimulation(pReducedPatternSimulationJob);
double normalizationFactor = 1;
if (global.optimizationSettings.normalizationStrategy !=
2021-03-23 18:20:46 +01:00
ReducedModelOptimization::Settings::NormalizationStrategy::NonNormalized) {
normalizationFactor
= global.translationalDisplacementNormalizationValues[simulationScenarioIndex];
}
reducedModelResults.saveDeformedModel();
fullModelResults.saveDeformedModel();
double error = computeDisplacementError(reducedModelResults.displacements,
fullModelResults.displacements,
reducedToFullInterfaceViMap,
normalizationFactor);
std::cout << "Error of simulation scenario "
2021-03-23 18:20:46 +01:00
<< ReducedModelOptimization::simulationScenarioStrings[simulationScenarioIndex] << " is "
<< error << std::endl;
totalError += error;
reducedModelResults.registerForDrawing();
// firstOptimizationRoundResults[simulationScenarioIndex].registerForDrawing();
// registerWorldAxes();
const std::string screenshotFilename =
"/home/iason/Coding/Projects/Approximating shapes with flat "
"patterns/RodModelOptimizationForPatterns/build/OptimizationResults/"
"Images/" +
pFullPatternSimulationMesh->getLabel() + "_" +
2021-03-23 18:20:46 +01:00
ReducedModelOptimization::simulationScenarioStrings[simulationScenarioIndex];
polyscope::show();
polyscope::screenshot(screenshotFilename, false);
fullModelResults.unregister();
reducedModelResults.unregister();
// firstOptimizationRoundResults[simulationScenarioIndex].unregister();
}
std::cout << "Total error:" << totalError << std::endl;
}
void ReducedModelOptimizer::registerResultsForDrawing(
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob,
const std::shared_ptr<SimulationJob> &pReducedPatternSimulationJob,
const std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
&reducedToFullInterfaceViMap) {
DRMSimulationModel simulator;
std::shared_ptr<SimulationMesh> pFullPatternSimulationMesh =
pFullPatternSimulationJob->pMesh;
pFullPatternSimulationMesh->registerForDrawing();
// pFullPatternSimulationMesh->savePly(pFullPatternSimulationMesh->getLabel()
// +
// "_undeformed.ply");
// reducedPatternSimulationJobs[0]->pMesh->savePly(
// reducedPatternSimulationJobs[0]->pMesh->getLabel() +
// "_undeformed.ply");
pFullPatternSimulationJob->registerForDrawing(
pFullPatternSimulationMesh->getLabel());
SimulationResults fullModelResults =
simulator.executeSimulation(pFullPatternSimulationJob);
fullModelResults.registerForDrawing();
// fullModelResults.saveDeformedModel();
SimulationResults reducedModelResults =
simulator.executeSimulation(pReducedPatternSimulationJob);
// reducedModelResults.saveDeformedModel();
// fullModelResults.saveDeformedModel();
double error = computeRawDisplacementError(
reducedModelResults.displacements, fullModelResults.displacements,
reducedToFullInterfaceViMap/*,
global.reducedPatternMaximumDisplacementNormSum[simulationScenarioIndex]*/);
std::cout << "Error is " << error << std::endl;
reducedModelResults.registerForDrawing();
}
#endif // POLYSCOPE_DEFINED
2020-11-23 10:06:45 +01:00
void ReducedModelOptimizer::computeDesiredReducedModelDisplacements(
const SimulationResults &fullModelResults,
const std::unordered_map<size_t, size_t> &displacementsReducedToFullMap,
Eigen::MatrixX3d &optimalDisplacementsOfReducedModel) {
assert(optimalDisplacementsOfReducedModel.rows() != 0 &&
optimalDisplacementsOfReducedModel.cols() == 3);
optimalDisplacementsOfReducedModel.setZero(
optimalDisplacementsOfReducedModel.rows(),
optimalDisplacementsOfReducedModel.cols());
for (auto reducedFullViPair : displacementsReducedToFullMap) {
const VertexIndex fullModelVi = reducedFullViPair.second;
const Vector6d fullModelViDisplacements =
fullModelResults.displacements[fullModelVi];
optimalDisplacementsOfReducedModel.row(reducedFullViPair.first) =
Eigen::Vector3d(fullModelViDisplacements[0],
fullModelViDisplacements[1],
fullModelViDisplacements[2]);
}
2020-11-23 10:06:45 +01:00
}
2021-03-23 18:20:46 +01:00
ReducedModelOptimization::Results
2021-02-18 11:12:52 +01:00
ReducedModelOptimizer::runOptimization(const Settings &settings) {
2021-03-23 18:20:46 +01:00
global.objectiveValueHistory.clear();
dlib::matrix<double, 0, 1> xMin(global.numberOfOptimizationParameters);
dlib::matrix<double, 0, 1> xMax(global.numberOfOptimizationParameters);
for (int i = 0; i < global.numberOfOptimizationParameters; i++) {
xMin(i) = settings.xRanges[i].min;
xMax(i) = settings.xRanges[i].max;
}
auto start = std::chrono::system_clock::now();
dlib::function_evaluation result;
double (*objF)(double, double, double, double, double,double,double) = &objective;
result = dlib::find_min_global(
2021-02-10 12:19:37 +01:00
objF, xMin, xMax,
dlib::max_function_calls(settings.numberOfFunctionCalls),
std::chrono::hours(24 * 365 * 290), settings.solutionAccuracy);
auto end = std::chrono::system_clock::now();
auto elapsed =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
2021-03-23 18:20:46 +01:00
ReducedModelOptimization::Results results;
results.numberOfSimulationCrashes = global.numOfSimulationCrashes;
results.optimalXNameValuePairs.resize(settings.xRanges.size());
2021-03-23 18:20:46 +01:00
for(int xVariableIndex=0;xVariableIndex<settings.xRanges.size();xVariableIndex++){
results.optimalXNameValuePairs[xVariableIndex]
= std::make_pair(settings.xRanges[xVariableIndex].label, global.minX[xVariableIndex]);
2021-03-23 18:20:46 +01:00
}
results.objectiveValue = global.minY;
2021-03-23 18:20:46 +01:00
#ifdef POLYSCOPE_DEFINED
std::cout<<"Total optimal objective value:"<<global.minY<<std::endl;
if (global.minY != result.y) {
std::cerr << "Global min objective is not equal to result objective"
<< std::endl;
}
2021-03-23 18:20:46 +01:00
#endif
2020-11-23 10:06:45 +01:00
// Compute obj value per simulation scenario and the raw objective value
results.rawObjectiveValue=0;
2021-03-23 18:20:46 +01:00
std::vector<double> optimalX(results.optimalXNameValuePairs.size());
for(int xVariableIndex=0;xVariableIndex<global.numberOfOptimizationParameters;xVariableIndex++){
optimalX[xVariableIndex]=
global.minX[xVariableIndex];
}
updateMesh(optimalX.size(), optimalX.data());
results.objectiveValuePerSimulationScenario.resize(
2021-03-23 18:20:46 +01:00
ReducedModelOptimization::NumberOfSimulationScenarios);
LinearSimulationModel simulator;
for (int simulationScenarioIndex:global.simulationScenarioIndices) {
SimulationResults reducedModelResults = simulator.executeSimulation(
2021-03-23 18:20:46 +01:00
global.reducedPatternSimulationJobs[simulationScenarioIndex]);
2021-03-30 18:30:49 +02:00
const double rawTranslationalError = computeRawDisplacementError(
global.fullPatternResults[simulationScenarioIndex].displacements,
reducedModelResults.displacements,
global.reducedToFullInterfaceViMap);
2021-03-30 18:30:49 +02:00
const double rawRotationalError = computeRawRotationalError(
global.fullPatternResults[simulationScenarioIndex].rotationalDisplacementQuaternion,
reducedModelResults.rotationalDisplacementQuaternion,
global.reducedToFullInterfaceViMap);
results.rawObjectiveValue += rawTranslationalError + rawRotationalError;
const double normalizedTranslationalError
= rawTranslationalError
/ global.translationalDisplacementNormalizationValues[simulationScenarioIndex];
const double normalizedRotationalError
= rawRotationalError
/ global.rotationalDisplacementNormalizationValues[simulationScenarioIndex];
std::cout << "Simulation scenario:" << simulationScenarioStrings[simulationScenarioIndex]
<< std::endl;
std::cout << "Translational error:" << normalizedTranslationalError << std::endl;
std::cout << "Rotational error:" << normalizedRotationalError << std::endl;
std::cout << std::endl;
results.objectiveValuePerSimulationScenario[simulationScenarioIndex]
= normalizedTranslationalError + normalizedRotationalError;
}
results.time = elapsed.count() / 1000.0;
const bool printDebugInfo = false;
if (printDebugInfo) {
std::cout << "Finished optimizing." << endl;
// std::cout << "Solution x:" << endl;
// std::cout << result.x << endl;
std::cout << "Objective value:" << global.minY << endl;
}
return results;
2020-12-16 20:31:58 +01:00
}
std::vector<std::shared_ptr<SimulationJob>>
ReducedModelOptimizer::createScenarios(
const std::shared_ptr<SimulationMesh> &pMesh) {
std::vector<std::shared_ptr<SimulationJob>> scenarios;
scenarios.resize(SimulationScenario::NumberOfSimulationScenarios);
std::unordered_map<VertexIndex, std::unordered_set<DoFType>> fixedVertices;
std::unordered_map<VertexIndex, Vector6d> nodalForces;
2021-03-23 18:20:46 +01:00
const double forceMagnitude = 10;
//// Axial
SimulationScenario scenarioName = SimulationScenario::Axial;
// NewMethod
for (auto viPairIt = m_fullPatternOppositeInterfaceViMap.begin();
viPairIt != m_fullPatternOppositeInterfaceViMap.end(); viPairIt++) {
if (viPairIt != m_fullPatternOppositeInterfaceViMap.begin()) {
CoordType forceDirection(1, 0, 0);
const auto viPair = *viPairIt;
nodalForces[viPair.first] =
Vector6d({forceDirection[0], forceDirection[1], forceDirection[2], 0,
0, 0}) *
2021-03-23 18:20:46 +01:00
forceMagnitude * 10;
fixedVertices[viPair.second] =
std::unordered_set<DoFType>{0, 1, 2, 3, 4, 5};
}
}
scenarios[scenarioName] = std::make_shared<SimulationJob>(
SimulationJob(pMesh, simulationScenarioStrings[scenarioName],
fixedVertices, nodalForces, {}));
//// Shear
scenarioName = SimulationScenario::Shear;
fixedVertices.clear();
nodalForces.clear();
// NewMethod
for (auto viPairIt = m_fullPatternOppositeInterfaceViMap.begin();
viPairIt != m_fullPatternOppositeInterfaceViMap.end(); viPairIt++) {
if (viPairIt != m_fullPatternOppositeInterfaceViMap.begin()) {
CoordType forceDirection(0, 1, 0);
const auto viPair = *viPairIt;
nodalForces[viPair.first] =
Vector6d({forceDirection[0], forceDirection[1], forceDirection[2], 0,
0, 0}) *
2021-03-23 18:20:46 +01:00
forceMagnitude * 4;
fixedVertices[viPair.second] =
std::unordered_set<DoFType>{0, 1, 2, 3, 4, 5};
}
}
scenarios[scenarioName] = std::make_shared<SimulationJob>(
SimulationJob(pMesh, simulationScenarioStrings[scenarioName],
fixedVertices, nodalForces, {}));
//// Bending
scenarioName = SimulationScenario::Bending;
fixedVertices.clear();
nodalForces.clear();
for (const auto &viPair : m_fullPatternOppositeInterfaceViMap) {
nodalForces[viPair.first] = Vector6d({0, 0, forceMagnitude, 0, 0, 0}) * 0.0005;
fixedVertices[viPair.second] =
std::unordered_set<DoFType>{0, 1, 2, 3, 4, 5};
2020-12-16 20:31:58 +01:00
}
scenarios[scenarioName] = std::make_shared<SimulationJob>(
SimulationJob(pMesh, simulationScenarioStrings[scenarioName],
fixedVertices, nodalForces, {}));
//// Dome
scenarioName = SimulationScenario::Dome;
fixedVertices.clear();
nodalForces.clear();
std::unordered_map<VertexIndex, Eigen::Vector3d> nodalForcedDisplacements;
for (auto viPairIt = m_fullPatternOppositeInterfaceViMap.begin();
viPairIt != m_fullPatternOppositeInterfaceViMap.end(); viPairIt++) {
const auto viPair = *viPairIt;
if (viPairIt == m_fullPatternOppositeInterfaceViMap.begin()) {
CoordType interfaceV = (pMesh->vert[viPair.first].cP()
- pMesh->vert[viPair.second].cP());
nodalForcedDisplacements[viPair.first] = Eigen::Vector3d(-interfaceV[0],
-interfaceV[1],
0)
* 0.025;
nodalForcedDisplacements[viPair.second] = Eigen::Vector3d(interfaceV[0],
interfaceV[1],
0)
* 0.025;
// CoordType v = (pMesh->vert[viPair.first].cP() - pMesh->vert[viPair.second].cP())
// ^ CoordType(0, 0, -1).Normalize();
// nodalForces[viPair.first] = Vector6d({0, 0, 0, v[0], v[1], 0}) * forceMagnitude
// * 0.0001;
// nodalForces[viPair.second] = Vector6d({0, 0, 0, -v[0], -v[1], 0}) * forceMagnitude
// * 0.0001;
} else {
fixedVertices[viPair.first] = std::unordered_set<DoFType>{2};
fixedVertices[viPair.second] = std::unordered_set<DoFType>{2};
CoordType v = (pMesh->vert[viPair.first].cP() - pMesh->vert[viPair.second].cP())
^ CoordType(0, 0, -1).Normalize();
nodalForces[viPair.first] = Vector6d({0, 0, 0, v[0], v[1], 0}) * forceMagnitude
* 0.0005;
nodalForces[viPair.second] = Vector6d({0, 0, 0, -v[0], -v[1], 0}) * forceMagnitude
* 0.0005;
}
}
scenarios[scenarioName] = std::make_shared<SimulationJob>(
SimulationJob(pMesh,
simulationScenarioStrings[scenarioName],
fixedVertices,
nodalForces,
nodalForcedDisplacements));
//// Saddle
scenarioName = SimulationScenario::Saddle;
fixedVertices.clear();
nodalForces.clear();
for (auto viPairIt = m_fullPatternOppositeInterfaceViMap.begin();
viPairIt != m_fullPatternOppositeInterfaceViMap.end(); viPairIt++) {
const auto &viPair = *viPairIt;
CoordType v =
(pMesh->vert[viPair.first].cP() - pMesh->vert[viPair.second].cP()) ^
CoordType(0, 0, -1).Normalize();
if (viPairIt == m_fullPatternOppositeInterfaceViMap.begin()) {
nodalForces[viPair.first] = Vector6d({0, 0, 0, v[0], v[1], 0}) * 0.0002
* forceMagnitude;
nodalForces[viPair.second] = Vector6d({0, 0, 0, -v[0], -v[1], 0}) * 0.0002
* forceMagnitude;
} else {
fixedVertices[viPair.first] = std::unordered_set<DoFType>{2};
fixedVertices[viPair.second] = std::unordered_set<DoFType>{0, 1, 2};
nodalForces[viPair.first] = Vector6d({0, 0, 0, -v[0], -v[1], 0}) * 0.0001
* forceMagnitude;
nodalForces[viPair.second] = Vector6d({0, 0, 0, v[0], v[1], 0}) * 0.0001
* forceMagnitude;
}
2020-12-09 16:58:48 +01:00
}
scenarios[scenarioName] = std::make_shared<SimulationJob>(
SimulationJob(pMesh, simulationScenarioStrings[scenarioName],
fixedVertices, nodalForces, {}));
2020-11-23 10:06:45 +01:00
return scenarios;
2020-11-23 10:06:45 +01:00
}
void ReducedModelOptimizer::computeObjectiveValueNormalizationFactors() {
// Compute the sum of the displacement norms
std::vector<double> fullPatternTranslationalDisplacementNormSum(NumberOfSimulationScenarios);
std::vector<double> fullPatternAngularDistance(NumberOfSimulationScenarios);
for (int simulationScenarioIndex : global.simulationScenarioIndices) {
double translationalDisplacementNormSum = 0;
double angularDistanceSum = 0;
for (auto interfaceViPair : global.reducedToFullInterfaceViMap) {
const int fullPatternVi = interfaceViPair.second;
//If the full pattern vertex is translationally constrained dont take it into account
if (global.fullPatternSimulationJobs[simulationScenarioIndex]
->constrainedVertices.contains(fullPatternVi)) {
const std::unordered_set<int> constrainedDof
= global.fullPatternSimulationJobs[simulationScenarioIndex]
->constrainedVertices.at(fullPatternVi);
if (constrainedDof.contains(0) && constrainedDof.contains(1)
&& constrainedDof.contains(2)) {
continue;
}
}
const Vector6d &vertexDisplacement = global
.fullPatternResults[simulationScenarioIndex]
.displacements[fullPatternVi];
translationalDisplacementNormSum += vertexDisplacement.getTranslation().norm();
//If the full pattern vertex is rotationally constrained dont take it into account
if (global.fullPatternSimulationJobs[simulationScenarioIndex]
->constrainedVertices.contains(fullPatternVi)) {
const std::unordered_set<int> constrainedDof
= global.fullPatternSimulationJobs[simulationScenarioIndex]
->constrainedVertices.at(fullPatternVi);
if (constrainedDof.contains(3) && constrainedDof.contains(5)
&& constrainedDof.contains(4)) {
continue;
}
}
angularDistanceSum += global.fullPatternResults[simulationScenarioIndex]
.rotationalDisplacementQuaternion[fullPatternVi]
.angularDistance(Eigen::Quaterniond::Identity());
}
fullPatternTranslationalDisplacementNormSum[simulationScenarioIndex]
= translationalDisplacementNormSum;
fullPatternAngularDistance[simulationScenarioIndex] = angularDistanceSum;
}
for (int simulationScenarioIndex : global.simulationScenarioIndices) {
if (global.optimizationSettings.normalizationStrategy ==
Settings::NormalizationStrategy::Epsilon) {
const double epsilon_translationalDisplacement = global.optimizationSettings
.normalizationParameter;
global.translationalDisplacementNormalizationValues[simulationScenarioIndex]
= std::max(fullPatternTranslationalDisplacementNormSum[simulationScenarioIndex],
epsilon_translationalDisplacement);
const double epsilon_rotationalDisplacement = vcg::math::ToRad(2.0);
global.rotationalDisplacementNormalizationValues[simulationScenarioIndex]
= std::max(fullPatternAngularDistance[simulationScenarioIndex],
epsilon_rotationalDisplacement);
2021-03-30 18:30:49 +02:00
} else {
global.translationalDisplacementNormalizationValues[simulationScenarioIndex] = 1;
global.rotationalDisplacementNormalizationValues[simulationScenarioIndex] = 1;
}
}
}
2021-03-23 18:20:46 +01:00
Results ReducedModelOptimizer::optimize(
2021-02-14 13:27:14 +01:00
const Settings &optimizationSettings,
const std::vector<SimulationScenario> &simulationScenarios) {
global.simulationScenarioIndices = simulationScenarios;
if (global.simulationScenarioIndices.empty()) {
global.simulationScenarioIndices = {SimulationScenario::Axial,
SimulationScenario::Shear,
SimulationScenario::Bending,
SimulationScenario::Dome,
SimulationScenario::Saddle};
}
global.g_optimalReducedModelDisplacements.resize(NumberOfSimulationScenarios);
global.reducedPatternSimulationJobs.resize(NumberOfSimulationScenarios);
global.fullPatternResults.resize(NumberOfSimulationScenarios);
global.translationalDisplacementNormalizationValues.resize(NumberOfSimulationScenarios);
global.rotationalDisplacementNormalizationValues.resize(NumberOfSimulationScenarios);
global.minY = std::numeric_limits<double>::max();
global.numOfSimulationCrashes = 0;
global.numberOfFunctionCalls = 0;
global.optimizationSettings = optimizationSettings;
global.fullPatternSimulationJobs =
createScenarios(m_pFullPatternSimulationMesh);
reducedPatternMaximumDisplacementSimulationJobs.resize(
NumberOfSimulationScenarios);
// polyscope::removeAllStructures();
DRMSimulationModel::Settings simulationSettings;
simulationSettings.shouldDraw = false;
// global.fullPatternSimulationJobs[0]->pMesh->registerForDrawing(
// ReducedModelOptimization::Colors::fullInitial);
for (int simulationScenarioIndex : global.simulationScenarioIndices) {
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob =
global.fullPatternSimulationJobs[simulationScenarioIndex];
SimulationResults fullPatternResults = simulator.executeSimulation(pFullPatternSimulationJob,
simulationSettings);
// fullPatternResults.registerForDrawing(ReducedModelOptimization::Colors::fullDeformed);
// polyscope::show();
// fullPatternResults.unregister();
global.fullPatternResults[simulationScenarioIndex] = fullPatternResults;
SimulationJob reducedPatternSimulationJob;
reducedPatternSimulationJob.pMesh = m_pReducedPatternSimulationMesh;
computeReducedModelSimulationJob(*pFullPatternSimulationJob,
m_fullToReducedInterfaceViMap,
reducedPatternSimulationJob);
global.reducedPatternSimulationJobs[simulationScenarioIndex] =
std::make_shared<SimulationJob>(reducedPatternSimulationJob);
}
// global.fullPatternSimulationJobs[0]->pMesh->unregister();
if (global.optimizationSettings.normalizationStrategy !=
Settings::NormalizationStrategy::NonNormalized) {
computeObjectiveValueNormalizationFactors();
}
Results optResults = runOptimization(optimizationSettings);
for (int simulationScenarioIndex : global.simulationScenarioIndices) {
optResults.fullPatternSimulationJobs.push_back(
global.fullPatternSimulationJobs[simulationScenarioIndex]);
optResults.reducedPatternSimulationJobs.push_back(
global.reducedPatternSimulationJobs[simulationScenarioIndex]);
}
return optResults;
2020-11-23 10:06:45 +01:00
}