Exporting simulation scenario when number of simulations is greater than some treshold.
This commit is contained in:
parent
804a634062
commit
42ccaba01e
37
src/main.cpp
37
src/main.cpp
|
|
@ -38,10 +38,19 @@
|
||||||
//}
|
//}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
// ReducedModelOptimizer::runBeamOptimization();
|
||||||
// FlatPattern pattern("/home/iason/Models/valid_6777.ply");
|
// FlatPattern pattern("/home/iason/Models/valid_6777.ply");
|
||||||
// FlatPattern pattern("/home/iason/Models/simple_beam_paper_example.ply");
|
// FlatPattern pattern("/home/iason/Models/simple_beam_paper_example.ply");
|
||||||
// pattern.savePly("fannedValid.ply");
|
// pattern.savePly("fannedValid.ply");
|
||||||
|
|
||||||
|
SimulationJob job;
|
||||||
|
job.load("../"
|
||||||
|
"ProblematicSimulationJobs/12:24_4_1_2021/"
|
||||||
|
"reduced_pattern_Single bar reduced model_simScenario.json");
|
||||||
|
FormFinder ff;
|
||||||
|
ff.executeSimulation(std::make_shared<SimulationJob>(job), false, false,
|
||||||
|
true);
|
||||||
|
|
||||||
// Create reduced models
|
// Create reduced models
|
||||||
// FormFinder::runUnitTests();
|
// FormFinder::runUnitTests();
|
||||||
const std::vector<size_t> numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1};
|
const std::vector<size_t> numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1};
|
||||||
|
|
@ -86,15 +95,18 @@ int main(int argc, char *argv[]) {
|
||||||
// std::filesystem::path(
|
// std::filesystem::path(
|
||||||
// "/home/iason/Documents/PhD/Research/Pattern_enumerator/Results/"
|
// "/home/iason/Documents/PhD/Research/Pattern_enumerator/Results/"
|
||||||
// "1v_0v_2e_1e_1c_6fan/3/Valid/222.ply");
|
// "1v_0v_2e_1e_1c_6fan/3/Valid/222.ply");
|
||||||
// std::filesystem::path(
|
std::filesystem::path(
|
||||||
// "/home/iason/Documents/PhD/Research/Pattern_enumerator/Results/"
|
"/home/iason/Documents/PhD/Research/Pattern_enumerator/Results/"
|
||||||
// "1v_0v_2e_1e_1c_6fan/2/Valid/33.ply");
|
"1v_0v_2e_1e_1c_6fan/3/Valid/624.ply");
|
||||||
// std::filesystem::path(
|
// std::filesystem::path(
|
||||||
// "/home/iason/Documents/PhD/Research/Pattern_enumerator/Results/"
|
// "/home/iason/Documents/PhD/Research/Pattern_enumerator/Results/"
|
||||||
// "1v_0v_2e_1e_1c_6fan/3/Valid/431.ply");
|
// "1v_0v_2e_1e_1c_6fan/2/Valid/33.ply");
|
||||||
// std::filesystem::path(
|
// std::filesystem::path(
|
||||||
// "/home/iason/Models/TestSet_validPatterns/59.ply");
|
// "/home/iason/Documents/PhD/Research/Pattern_enumerator/Results/"
|
||||||
entry.path();
|
// "1v_0v_2e_1e_1c_6fan/3/Valid/431.ply");
|
||||||
|
// std::filesystem::path(
|
||||||
|
// "/home/iason/Models/TestSet_validPatterns/59.ply");
|
||||||
|
// entry.path();
|
||||||
const auto filepathString = filepath.string();
|
const auto filepathString = filepath.string();
|
||||||
// Use only the base triangle version
|
// Use only the base triangle version
|
||||||
const std::string tiledSuffix = "_tiled.ply";
|
const std::string tiledSuffix = "_tiled.ply";
|
||||||
|
|
@ -119,9 +131,10 @@ int main(int argc, char *argv[]) {
|
||||||
// optimizationExcludedEi.insert(0);
|
// optimizationExcludedEi.insert(0);
|
||||||
// }
|
// }
|
||||||
std::cout << "Full pattern:" << filepathString << std::endl;
|
std::cout << "Full pattern:" << filepathString << std::endl;
|
||||||
optimizer.initializePatterns(pattern, *reducedModels[1],
|
FlatPattern cp;
|
||||||
optimizationExcludedEi);
|
cp.copy(*reducedModels[0]);
|
||||||
optimizer.optimize();
|
optimizer.initializePatterns(cp, *reducedModels[0], optimizationExcludedEi);
|
||||||
|
optimizer.optimize({ReducedModelOptimizer::SimulationScenario::Bending});
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,25 @@ const bool gShouldDraw = true;
|
||||||
|
|
||||||
FormFinder simulator;
|
FormFinder simulator;
|
||||||
std::vector<Eigen::MatrixX3d> g_optimalReducedModelDisplacements;
|
std::vector<Eigen::MatrixX3d> g_optimalReducedModelDisplacements;
|
||||||
std::vector<SimulationJob> g_reducedPatternSimulationJob;
|
std::vector<SimulationJob> g_fullPatternSimulationJob;
|
||||||
|
std::vector<std::shared_ptr<SimulationJob>> g_reducedPatternSimulationJob;
|
||||||
std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
|
std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
|
||||||
g_reducedToFullInterfaceViMap;
|
reducedToFullInterfaceViMap;
|
||||||
|
std::unordered_map<ReducedPatternVertexIndex, FullPatternVertexIndex>
|
||||||
|
g_reducedToFullViMap;
|
||||||
matplot::line_handle gPlotHandle;
|
matplot::line_handle gPlotHandle;
|
||||||
std::vector<double> gObjectiveValueHistory;
|
std::vector<double> gObjectiveValueHistory;
|
||||||
Eigen::Vector4d g_initialX;
|
Eigen::Vector4d g_initialX;
|
||||||
std::unordered_set<size_t> g_reducedPatternExludedEdges;
|
std::unordered_set<size_t> g_reducedPatternExludedEdges;
|
||||||
// double g_initialParameters;
|
// double g_initialParameters;
|
||||||
Eigen::VectorXd g_initialParameters;
|
Eigen::VectorXd g_initialParameters;
|
||||||
ReducedModelOptimizer::SimulationScenario g_chosenSimulationScenarioName;
|
std::vector<ReducedModelOptimizer::SimulationScenario>
|
||||||
|
g_simulationScenarioIndices;
|
||||||
std::vector<VectorType> g_innerHexagonVectors{6, VectorType(0, 0, 0)};
|
std::vector<VectorType> g_innerHexagonVectors{6, VectorType(0, 0, 0)};
|
||||||
double g_innerHexagonInitialPos = 0;
|
double g_innerHexagonInitialPos = 0;
|
||||||
|
bool g_optimizeInnerHexagonSize{false};
|
||||||
|
std::vector<SimulationResults> firstOptimizationRoundResults;
|
||||||
|
int g_firstRoundIterationIndex{0};
|
||||||
|
|
||||||
// struct OptimizationCallback {
|
// struct OptimizationCallback {
|
||||||
// double operator()(const size_t &iterations, const Eigen::VectorXd &x,
|
// double operator()(const size_t &iterations, const Eigen::VectorXd &x,
|
||||||
|
|
@ -103,7 +110,7 @@ double ReducedModelOptimizer::computeError(
|
||||||
const SimulationResults &reducedPatternResults,
|
const SimulationResults &reducedPatternResults,
|
||||||
const Eigen::MatrixX3d &optimalReducedPatternDisplacements) {
|
const Eigen::MatrixX3d &optimalReducedPatternDisplacements) {
|
||||||
double error = 0;
|
double error = 0;
|
||||||
for (const auto reducedFullViPair : g_reducedToFullInterfaceViMap) {
|
for (const auto reducedFullViPair : g_reducedToFullViMap) {
|
||||||
VertexIndex reducedModelVi = reducedFullViPair.first;
|
VertexIndex reducedModelVi = reducedFullViPair.first;
|
||||||
// const auto pos =
|
// const auto pos =
|
||||||
// g_reducedPatternSimulationJob.mesh->vert[reducedModelVi].cP();
|
// g_reducedPatternSimulationJob.mesh->vert[reducedModelVi].cP();
|
||||||
|
|
@ -124,16 +131,21 @@ double ReducedModelOptimizer::computeError(
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateMesh(long n, const double *x) {
|
void updateMesh(long n, const double *x) {
|
||||||
std::shared_ptr<SimulationMesh> pReducedPatternSimulationMesh =
|
std::shared_ptr<SimulationMesh> &pReducedPatternSimulationMesh =
|
||||||
g_reducedPatternSimulationJob[0].mesh;
|
g_reducedPatternSimulationJob[0]->pMesh;
|
||||||
|
// const Element &elem = g_reducedPatternSimulationJob[0]->mesh->elements[0];
|
||||||
|
// std::cout << elem.axialConstFactor << " " << elem.torsionConstFactor << "
|
||||||
|
// "
|
||||||
|
// << elem.firstBendingConstFactor << " "
|
||||||
|
// << elem.secondBendingConstFactor << std::endl;
|
||||||
for (EdgeIndex ei = 0; ei < pReducedPatternSimulationMesh->EN(); ei++) {
|
for (EdgeIndex ei = 0; ei < pReducedPatternSimulationMesh->EN(); ei++) {
|
||||||
Element &e = pReducedPatternSimulationMesh->elements[ei];
|
Element &e = pReducedPatternSimulationMesh->elements[ei];
|
||||||
// if (g_reducedPatternExludedEdges.contains(ei)) {
|
// if (g_reducedPatternExludedEdges.contains(ei)) {
|
||||||
// continue;
|
// continue;
|
||||||
// }
|
// }
|
||||||
// e.properties.E = g_initialParameters * x[ei];
|
// e.properties.E = g_initialParameters * x[ei];
|
||||||
// e.properties.E = g_initialParameters(ei, 0) * x[ei];
|
// e.properties.E = g_initialParameters(0) * x[0];
|
||||||
// e.properties.G = g_initialParameters(1) * x[1];
|
// e.properties.G = g_initialParameters(1) * x[1];
|
||||||
e.properties.A = g_initialParameters(0) * x[0];
|
e.properties.A = g_initialParameters(0) * x[0];
|
||||||
e.properties.J = g_initialParameters(1) * x[1];
|
e.properties.J = g_initialParameters(1) * x[1];
|
||||||
e.properties.I2 = g_initialParameters(2) * x[2];
|
e.properties.I2 = g_initialParameters(2) * x[2];
|
||||||
|
|
@ -147,36 +159,51 @@ void updateMesh(long n, const double *x) {
|
||||||
2 * e.properties.E * e.properties.I3 / e.initialLength;
|
2 * e.properties.E * e.properties.I3 / e.initialLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 5) {
|
// std::cout << elem.axialConstFactor << " " << elem.torsionConstFactor << "
|
||||||
|
// "
|
||||||
|
// << elem.firstBendingConstFactor << " "
|
||||||
|
// << elem.secondBendingConstFactor << std::endl;
|
||||||
|
// const Element &e = pReducedPatternSimulationMesh->elements[0];
|
||||||
|
// std::cout << e.axialConstFactor << " " << e.torsionConstFactor << " "
|
||||||
|
// << e.firstBendingConstFactor << " " <<
|
||||||
|
// e.secondBendingConstFactor
|
||||||
|
// << std::endl;
|
||||||
|
|
||||||
|
if (g_optimizeInnerHexagonSize) {
|
||||||
assert(pReducedPatternSimulationMesh->EN() == 12);
|
assert(pReducedPatternSimulationMesh->EN() == 12);
|
||||||
for (VertexIndex vi = 0; vi < pReducedPatternSimulationMesh->VN();
|
for (VertexIndex vi = 0; vi < pReducedPatternSimulationMesh->VN();
|
||||||
vi += 2) {
|
vi += 2) {
|
||||||
pReducedPatternSimulationMesh->vert[vi].P() =
|
pReducedPatternSimulationMesh->vert[vi].P() =
|
||||||
g_innerHexagonVectors[vi / 2] * x[4];
|
g_innerHexagonVectors[vi / 2] * x[n - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
pReducedPatternSimulationMesh->updateEigenEdgeAndVertices();
|
|
||||||
pReducedPatternSimulationMesh->reset();
|
pReducedPatternSimulationMesh->reset();
|
||||||
|
pReducedPatternSimulationMesh->updateEigenEdgeAndVertices();
|
||||||
// pReducedPatternSimulationMesh->registerForDrawing("Optimized
|
// pReducedPatternSimulationMesh->registerForDrawing("Optimized
|
||||||
// hexagon"); polyscope::show();
|
// hexagon"); polyscope::show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double ReducedModelOptimizer::objectiveAllScenarios(long n, const double *x) {
|
double ReducedModelOptimizer::objective(long n, const double *x) {
|
||||||
std::cout.precision(17);
|
std::cout.precision(17);
|
||||||
|
|
||||||
for (size_t parameterIndex = 0; parameterIndex < n; parameterIndex++) {
|
for (size_t parameterIndex = 0; parameterIndex < n; parameterIndex++) {
|
||||||
std::cout << "x[" + std::to_string(parameterIndex) + "]="
|
std::cout << "x[" + std::to_string(parameterIndex) + "]="
|
||||||
<< x[parameterIndex] << std::endl;
|
<< x[parameterIndex] << std::endl;
|
||||||
}
|
}
|
||||||
|
const Element &e = g_reducedPatternSimulationJob[0]->pMesh->elements[0];
|
||||||
|
// std::cout << e.axialConstFactor << " " << e.torsionConstFactor << " "
|
||||||
|
// << e.firstBendingConstFactor << " " <<
|
||||||
|
// e.secondBendingConstFactor
|
||||||
|
// << std::endl;
|
||||||
updateMesh(n, x);
|
updateMesh(n, x);
|
||||||
|
std::cout << e.axialConstFactor << " " << e.torsionConstFactor << " "
|
||||||
|
<< e.firstBendingConstFactor << " " << e.secondBendingConstFactor
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
// run simulations
|
// run simulations
|
||||||
double error = 0;
|
double error = 0;
|
||||||
for (int simulationScenarioIndex = SimulationScenario::Axial;
|
for (const int simulationScenarioIndex : g_simulationScenarioIndices) {
|
||||||
simulationScenarioIndex !=
|
|
||||||
SimulationScenario::NumberOfSimulationScenarios;
|
|
||||||
simulationScenarioIndex++) {
|
|
||||||
SimulationResults reducedModelResults = simulator.executeSimulation(
|
SimulationResults reducedModelResults = simulator.executeSimulation(
|
||||||
g_reducedPatternSimulationJob[simulationScenarioIndex], false, false);
|
g_reducedPatternSimulationJob[simulationScenarioIndex], false, false);
|
||||||
error += computeError(
|
error += computeError(
|
||||||
|
|
@ -188,32 +215,13 @@ double ReducedModelOptimizer::objectiveAllScenarios(long n, const double *x) {
|
||||||
gObjectiveValueHistory.push_back(error);
|
gObjectiveValueHistory.push_back(error);
|
||||||
auto xPlot = matplot::linspace(0, gObjectiveValueHistory.size(),
|
auto xPlot = matplot::linspace(0, gObjectiveValueHistory.size(),
|
||||||
gObjectiveValueHistory.size());
|
gObjectiveValueHistory.size());
|
||||||
gPlotHandle = matplot::scatter(xPlot, gObjectiveValueHistory);
|
std::vector<double> colors(gObjectiveValueHistory.size(), 2);
|
||||||
|
if (g_firstRoundIterationIndex != 0) {
|
||||||
return error;
|
for_each(colors.begin() + g_firstRoundIterationIndex, colors.end(),
|
||||||
}
|
[](double &c) { c = 0.7; });
|
||||||
|
|
||||||
double ReducedModelOptimizer::objectiveSingleScenario(long n, const double *x) {
|
|
||||||
std::cout.precision(17);
|
|
||||||
|
|
||||||
for (size_t parameterIndex = 0; parameterIndex < n; parameterIndex++) {
|
|
||||||
std::cout << "x[" + std::to_string(parameterIndex) + "]="
|
|
||||||
<< x[parameterIndex] << std::endl;
|
|
||||||
}
|
}
|
||||||
|
gPlotHandle = matplot::scatter(xPlot, gObjectiveValueHistory, 6, colors);
|
||||||
updateMesh(n, x);
|
std::cout << std::endl;
|
||||||
|
|
||||||
SimulationResults reducedModelResults = simulator.executeSimulation(
|
|
||||||
g_reducedPatternSimulationJob[g_chosenSimulationScenarioName], false,
|
|
||||||
false);
|
|
||||||
const double error = computeError(
|
|
||||||
reducedModelResults,
|
|
||||||
g_optimalReducedModelDisplacements[g_chosenSimulationScenarioName]);
|
|
||||||
|
|
||||||
gObjectiveValueHistory.push_back(error);
|
|
||||||
auto xPlot = matplot::linspace(0, gObjectiveValueHistory.size(),
|
|
||||||
gObjectiveValueHistory.size());
|
|
||||||
gPlotHandle = matplot::scatter(xPlot, gObjectiveValueHistory);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
@ -257,7 +265,7 @@ void ReducedModelOptimizer::computeMaps(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct reduced->full and full->reduced interface vi map
|
// Construct reduced->full and full->reduced interface vi map
|
||||||
g_reducedToFullInterfaceViMap.clear();
|
reducedToFullInterfaceViMap.clear();
|
||||||
vcg::tri::Allocator<FlatPattern>::PointerUpdater<FlatPattern::VertexPointer>
|
vcg::tri::Allocator<FlatPattern>::PointerUpdater<FlatPattern::VertexPointer>
|
||||||
pu_reducedModel;
|
pu_reducedModel;
|
||||||
reducedPattern.deleteDanglingVertices(pu_reducedModel);
|
reducedPattern.deleteDanglingVertices(pu_reducedModel);
|
||||||
|
|
@ -267,13 +275,13 @@ void ReducedModelOptimizer::computeMaps(
|
||||||
reducedPattern.VN() - 1 /*- reducedModelBaseTriangleInterfaceVi*/;
|
reducedPattern.VN() - 1 /*- reducedModelBaseTriangleInterfaceVi*/;
|
||||||
reducedPattern.createFan();
|
reducedPattern.createFan();
|
||||||
for (size_t fanIndex = 0; fanIndex < fanSize; fanIndex++) {
|
for (size_t fanIndex = 0; fanIndex < fanSize; fanIndex++) {
|
||||||
g_reducedToFullInterfaceViMap[reducedModelInterfaceVertexOffset * fanIndex +
|
reducedToFullInterfaceViMap[reducedModelInterfaceVertexOffset * fanIndex +
|
||||||
reducedModelBaseTriangleInterfaceVi] =
|
reducedModelBaseTriangleInterfaceVi] =
|
||||||
fullModelBaseTriangleInterfaceVi +
|
fullModelBaseTriangleInterfaceVi +
|
||||||
fanIndex * fullPatternInterfaceVertexOffset;
|
fanIndex * fullPatternInterfaceVertexOffset;
|
||||||
}
|
}
|
||||||
m_fullToReducedInterfaceViMap.clear();
|
m_fullToReducedInterfaceViMap.clear();
|
||||||
constructInverseMap(g_reducedToFullInterfaceViMap,
|
constructInverseMap(reducedToFullInterfaceViMap,
|
||||||
m_fullToReducedInterfaceViMap);
|
m_fullToReducedInterfaceViMap);
|
||||||
|
|
||||||
// fullPattern.setLabel("FullPattern");
|
// fullPattern.setLabel("FullPattern");
|
||||||
|
|
@ -288,6 +296,8 @@ void ReducedModelOptimizer::computeMaps(
|
||||||
m_fullPatternOppositeInterfaceViMap[vi0] = vi1;
|
m_fullPatternOppositeInterfaceViMap[vi0] = vi1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_reducedToFullViMap = reducedToFullInterfaceViMap;
|
||||||
|
|
||||||
const bool debugMapping = false;
|
const bool debugMapping = false;
|
||||||
if (debugMapping) {
|
if (debugMapping) {
|
||||||
reducedPattern.registerForDrawing();
|
reducedPattern.registerForDrawing();
|
||||||
|
|
@ -322,11 +332,11 @@ void ReducedModelOptimizer::computeMaps(
|
||||||
std::vector<glm::vec3> nodeColorsReducedToFull_full(fullPattern.VN(),
|
std::vector<glm::vec3> nodeColorsReducedToFull_full(fullPattern.VN(),
|
||||||
glm::vec3(0, 0, 0));
|
glm::vec3(0, 0, 0));
|
||||||
for (size_t vi = 0; vi < reducedPattern.VN(); vi++) {
|
for (size_t vi = 0; vi < reducedPattern.VN(); vi++) {
|
||||||
if (g_reducedToFullInterfaceViMap.contains(vi)) {
|
if (reducedToFullInterfaceViMap.contains(vi)) {
|
||||||
|
|
||||||
auto color = polyscope::getNextUniqueColor();
|
auto color = polyscope::getNextUniqueColor();
|
||||||
nodeColorsReducedToFull_reduced[vi] = color;
|
nodeColorsReducedToFull_reduced[vi] = color;
|
||||||
nodeColorsReducedToFull_full[g_reducedToFullInterfaceViMap[vi]] = color;
|
nodeColorsReducedToFull_full[reducedToFullInterfaceViMap[vi]] = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
polyscope::getCurveNetwork(reducedPattern.getLabel())
|
polyscope::getCurveNetwork(reducedPattern.getLabel())
|
||||||
|
|
@ -352,10 +362,10 @@ void ReducedModelOptimizer::createSimulationMeshes(FlatPattern &fullModel,
|
||||||
m_pReducedPatternSimulationMesh->setBeamCrossSection(
|
m_pReducedPatternSimulationMesh->setBeamCrossSection(
|
||||||
CrossSectionType{0.002, 0.002});
|
CrossSectionType{0.002, 0.002});
|
||||||
m_pReducedPatternSimulationMesh->setBeamMaterial(0.3, 1);
|
m_pReducedPatternSimulationMesh->setBeamMaterial(0.3, 1);
|
||||||
m_pFullModelSimulationMesh = std::make_shared<SimulationMesh>(fullModel);
|
m_pFullPatternSimulationMesh = std::make_shared<SimulationMesh>(fullModel);
|
||||||
m_pFullModelSimulationMesh->setBeamCrossSection(
|
m_pFullPatternSimulationMesh->setBeamCrossSection(
|
||||||
CrossSectionType{0.002, 0.002});
|
CrossSectionType{0.002, 0.002});
|
||||||
m_pFullModelSimulationMesh->setBeamMaterial(0.3, 1);
|
m_pFullPatternSimulationMesh->setBeamMaterial(0.3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReducedModelOptimizer::ReducedModelOptimizer(
|
ReducedModelOptimizer::ReducedModelOptimizer(
|
||||||
|
|
@ -367,6 +377,8 @@ ReducedModelOptimizer::ReducedModelOptimizer(
|
||||||
void ReducedModelOptimizer::initializePatterns(
|
void ReducedModelOptimizer::initializePatterns(
|
||||||
FlatPattern &fullPattern, FlatPattern &reducedPattern,
|
FlatPattern &fullPattern, FlatPattern &reducedPattern,
|
||||||
const std::unordered_set<size_t> &reducedModelExcludedEdges) {
|
const std::unordered_set<size_t> &reducedModelExcludedEdges) {
|
||||||
|
fullPattern.setLabel("full_pattern_" + fullPattern.getLabel());
|
||||||
|
reducedPattern.setLabel("reduced_pattern_" + reducedPattern.getLabel());
|
||||||
assert(fullPattern.VN() == reducedPattern.VN() &&
|
assert(fullPattern.VN() == reducedPattern.VN() &&
|
||||||
fullPattern.EN() >= reducedPattern.EN());
|
fullPattern.EN() >= reducedPattern.EN());
|
||||||
polyscope::removeAllStructures();
|
polyscope::removeAllStructures();
|
||||||
|
|
@ -375,7 +387,8 @@ void ReducedModelOptimizer::initializePatterns(
|
||||||
FlatPattern copyReducedPattern;
|
FlatPattern copyReducedPattern;
|
||||||
copyFullPattern.copy(fullPattern);
|
copyFullPattern.copy(fullPattern);
|
||||||
copyReducedPattern.copy(reducedPattern);
|
copyReducedPattern.copy(reducedPattern);
|
||||||
if (copyReducedPattern.EN() == 2) {
|
g_optimizeInnerHexagonSize = copyReducedPattern.EN() == 2;
|
||||||
|
if (g_optimizeInnerHexagonSize) {
|
||||||
const double h = copyReducedPattern.getBaseTriangleHeight();
|
const double h = copyReducedPattern.getBaseTriangleHeight();
|
||||||
double baseTriangle_bottomEdgeSize = 2 * h / tan(vcg::math::ToRad(60.0));
|
double baseTriangle_bottomEdgeSize = 2 * h / tan(vcg::math::ToRad(60.0));
|
||||||
VectorType baseTriangle_leftBottomNode(-baseTriangle_bottomEdgeSize / 2, -h,
|
VectorType baseTriangle_leftBottomNode(-baseTriangle_bottomEdgeSize / 2, -h,
|
||||||
|
|
@ -391,19 +404,20 @@ void ReducedModelOptimizer::initializePatterns(
|
||||||
baseTriangle_leftBottomNode;
|
baseTriangle_leftBottomNode;
|
||||||
g_innerHexagonVectors[rotationCounter] = rotatedVector;
|
g_innerHexagonVectors[rotationCounter] = rotatedVector;
|
||||||
}
|
}
|
||||||
|
const double innerHexagonInitialPos_x =
|
||||||
|
copyReducedPattern.vert[0].cP()[0] / g_innerHexagonVectors[0][0];
|
||||||
|
const double innerHexagonInitialPos_y =
|
||||||
|
copyReducedPattern.vert[0].cP()[1] / g_innerHexagonVectors[0][1];
|
||||||
|
g_innerHexagonInitialPos = innerHexagonInitialPos_x;
|
||||||
}
|
}
|
||||||
computeMaps(copyFullPattern, copyReducedPattern, reducedModelExcludedEdges);
|
computeMaps(copyFullPattern, copyReducedPattern, reducedModelExcludedEdges);
|
||||||
const double innerHexagonInitialPos_x =
|
|
||||||
copyReducedPattern.vert[0].cP()[0] / g_innerHexagonVectors[0][0];
|
|
||||||
const double innerHexagonInitialPos_y =
|
|
||||||
copyReducedPattern.vert[0].cP()[1] / g_innerHexagonVectors[0][1];
|
|
||||||
g_innerHexagonInitialPos = innerHexagonInitialPos_x;
|
|
||||||
createSimulationMeshes(copyFullPattern, copyReducedPattern);
|
createSimulationMeshes(copyFullPattern, copyReducedPattern);
|
||||||
initializeStiffnesses();
|
initializeStiffnesses(m_pReducedPatternSimulationMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReducedModelOptimizer::initializeStiffnesses() {
|
void ReducedModelOptimizer::initializeStiffnesses(
|
||||||
g_initialParameters.resize(4);
|
const std::shared_ptr<SimulationMesh> &mesh) {
|
||||||
|
g_initialParameters.resize(g_optimizeInnerHexagonSize ? 5 : 4);
|
||||||
// Save save the beam stiffnesses
|
// Save save the beam stiffnesses
|
||||||
// for (size_t ei = 0; ei < pReducedModelElementalMesh->EN(); ei++) {
|
// for (size_t ei = 0; ei < pReducedModelElementalMesh->EN(); ei++) {
|
||||||
// Element &e = pReducedModelElementalMesh->elements[ei];
|
// Element &e = pReducedModelElementalMesh->elements[ei];
|
||||||
|
|
@ -417,73 +431,62 @@ void ReducedModelOptimizer::initializeStiffnesses() {
|
||||||
// g_initialParameters =
|
// g_initialParameters =
|
||||||
// m_pReducedPatternSimulationMesh->elements[0].properties.E;
|
// m_pReducedPatternSimulationMesh->elements[0].properties.E;
|
||||||
// for (size_t ei = 0; ei < m_pReducedPatternSimulationMesh->EN(); ei++) {
|
// for (size_t ei = 0; ei < m_pReducedPatternSimulationMesh->EN(); ei++) {
|
||||||
// g_initialParameters(ei, 0) =
|
|
||||||
// m_pReducedPatternSimulationMesh->elements[ei].properties.E;
|
|
||||||
// }
|
// }
|
||||||
// g_initialParameters(1) =
|
// g_initialParameters(0) = mesh->elements[0].properties.E;
|
||||||
// pReducedModelElementalMesh->elements[0].properties.G;
|
// g_initialParameters(1) = mesh->elements[0].properties.G;
|
||||||
g_initialParameters(0) =
|
g_initialParameters(0) = mesh->elements[0].properties.A;
|
||||||
m_pReducedPatternSimulationMesh->elements[0].properties.A;
|
g_initialParameters(1) = mesh->elements[0].properties.J;
|
||||||
g_initialParameters(1) =
|
g_initialParameters(2) = mesh->elements[0].properties.I2;
|
||||||
m_pReducedPatternSimulationMesh->elements[0].properties.J;
|
g_initialParameters(3) = mesh->elements[0].properties.I3;
|
||||||
g_initialParameters(2) =
|
|
||||||
m_pReducedPatternSimulationMesh->elements[0].properties.I2;
|
|
||||||
g_initialParameters(3) =
|
|
||||||
m_pReducedPatternSimulationMesh->elements[0].properties.I3;
|
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReducedModelOptimizer::computeReducedModelSimulationJob(
|
void ReducedModelOptimizer::computeReducedModelSimulationJob(
|
||||||
const SimulationJob &simulationJobOfFullModel,
|
const SimulationJob &simulationJobOfFullModel,
|
||||||
|
const std::unordered_map<size_t, size_t> &simulationJobFullToReducedMap,
|
||||||
SimulationJob &simulationJobOfReducedModel) {
|
SimulationJob &simulationJobOfReducedModel) {
|
||||||
|
assert(simulationJobOfReducedModel.pMesh->VN() != 0);
|
||||||
std::unordered_map<VertexIndex, std::unordered_set<DoFType>>
|
std::unordered_map<VertexIndex, std::unordered_set<DoFType>>
|
||||||
reducedModelFixedVertices;
|
reducedModelFixedVertices;
|
||||||
for (auto fullModelFixedVertex : simulationJobOfFullModel.fixedVertices) {
|
for (auto fullModelFixedVertex :
|
||||||
reducedModelFixedVertices[m_fullToReducedInterfaceViMap.at(
|
simulationJobOfFullModel.constrainedVertices) {
|
||||||
|
reducedModelFixedVertices[simulationJobFullToReducedMap.at(
|
||||||
fullModelFixedVertex.first)] = fullModelFixedVertex.second;
|
fullModelFixedVertex.first)] = fullModelFixedVertex.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<VertexIndex, Vector6d> reducedModelNodalForces;
|
std::unordered_map<VertexIndex, Vector6d> reducedModelNodalForces;
|
||||||
for (auto fullModelNodalForce :
|
for (auto fullModelNodalForce :
|
||||||
simulationJobOfFullModel.nodalExternalForces) {
|
simulationJobOfFullModel.nodalExternalForces) {
|
||||||
reducedModelNodalForces[m_fullToReducedInterfaceViMap.at(
|
reducedModelNodalForces[simulationJobFullToReducedMap.at(
|
||||||
fullModelNodalForce.first)] = fullModelNodalForce.second;
|
fullModelNodalForce.first)] = fullModelNodalForce.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<VertexIndex, VectorType> reducedModelNodalForcedNormals;
|
// std::unordered_map<VertexIndex, VectorType>
|
||||||
for (auto fullModelNodalForcedRotation :
|
// reducedModelNodalForcedNormals; for (auto fullModelNodalForcedRotation :
|
||||||
simulationJobOfFullModel.nodalForcedNormals) {
|
// simulationJobOfFullModel.nodalForcedNormals) {
|
||||||
reducedModelNodalForcedNormals[m_fullToReducedInterfaceViMap.at(
|
// reducedModelNodalForcedNormals[simulationJobFullToReducedMap.at(
|
||||||
fullModelNodalForcedRotation.first)] =
|
// fullModelNodalForcedRotation.first)] =
|
||||||
fullModelNodalForcedRotation.second;
|
// fullModelNodalForcedRotation.second;
|
||||||
}
|
// }
|
||||||
|
simulationJobOfReducedModel.constrainedVertices = reducedModelFixedVertices;
|
||||||
simulationJobOfReducedModel = SimulationJob{m_pReducedPatternSimulationMesh,
|
simulationJobOfReducedModel.nodalExternalForces = reducedModelNodalForces;
|
||||||
reducedModelFixedVertices,
|
simulationJobOfReducedModel.label = simulationJobOfFullModel.getLabel();
|
||||||
reducedModelNodalForces,
|
// simulationJobOfReducedModel.nodalForcedNormals =
|
||||||
{},
|
// reducedModelNodalForcedNormals;
|
||||||
reducedModelNodalForcedNormals};
|
|
||||||
}
|
|
||||||
|
|
||||||
SimulationJob ReducedModelOptimizer::getReducedSimulationJob(
|
|
||||||
const SimulationJob &fullModelSimulationJob) {
|
|
||||||
SimulationJob reducedModelSimulationJob;
|
|
||||||
computeReducedModelSimulationJob(fullModelSimulationJob,
|
|
||||||
reducedModelSimulationJob);
|
|
||||||
return reducedModelSimulationJob;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReducedModelOptimizer::computeDesiredReducedModelDisplacements(
|
void ReducedModelOptimizer::computeDesiredReducedModelDisplacements(
|
||||||
const SimulationResults &fullModelResults,
|
const SimulationResults &fullModelResults,
|
||||||
|
const std::unordered_map<size_t, size_t> &displacementsReducedToFullMap,
|
||||||
Eigen::MatrixX3d &optimalDisplacementsOfReducedModel) {
|
Eigen::MatrixX3d &optimalDisplacementsOfReducedModel) {
|
||||||
|
|
||||||
optimalDisplacementsOfReducedModel.resize(
|
assert(optimalDisplacementsOfReducedModel.rows() != 0 &&
|
||||||
m_pReducedPatternSimulationMesh->VN(), 3);
|
optimalDisplacementsOfReducedModel.cols() == 3);
|
||||||
optimalDisplacementsOfReducedModel.setZero(
|
optimalDisplacementsOfReducedModel.setZero(
|
||||||
optimalDisplacementsOfReducedModel.rows(),
|
optimalDisplacementsOfReducedModel.rows(),
|
||||||
optimalDisplacementsOfReducedModel.cols());
|
optimalDisplacementsOfReducedModel.cols());
|
||||||
|
|
||||||
for (auto reducedFullViPair : g_reducedToFullInterfaceViMap) {
|
for (auto reducedFullViPair : displacementsReducedToFullMap) {
|
||||||
const VertexIndex fullModelVi = reducedFullViPair.second;
|
const VertexIndex fullModelVi = reducedFullViPair.second;
|
||||||
const Vector6d fullModelViDisplacements =
|
const Vector6d fullModelViDisplacements =
|
||||||
fullModelResults.displacements[fullModelVi];
|
fullModelResults.displacements[fullModelVi];
|
||||||
|
|
@ -499,7 +502,7 @@ Eigen::VectorXd ReducedModelOptimizer::runOptimization(
|
||||||
|
|
||||||
gObjectiveValueHistory.clear();
|
gObjectiveValueHistory.clear();
|
||||||
|
|
||||||
const size_t n = m_pReducedPatternSimulationMesh->EN() == 12 ? 5 : 4;
|
const size_t n = g_optimizeInnerHexagonSize ? 5 : 4;
|
||||||
const size_t npt = 2 * n;
|
const size_t npt = 2 * n;
|
||||||
// ((n + 2) + ((n + 1) * (n + 2) / 2)) / 2;
|
// ((n + 2) + ((n + 1) * (n + 2) / 2)) / 2;
|
||||||
assert(npt <= (n + 1) * (n + 2) / 2 && npt >= n + 2);
|
assert(npt <= (n + 1) * (n + 2) / 2 && npt >= n + 2);
|
||||||
|
|
@ -507,39 +510,58 @@ Eigen::VectorXd ReducedModelOptimizer::runOptimization(
|
||||||
"conditions is not recommended.");
|
"conditions is not recommended.");
|
||||||
// Set initial guess of solution
|
// Set initial guess of solution
|
||||||
|
|
||||||
std::vector<double> x(n, 100);
|
std::vector<double> x(n, 50);
|
||||||
x[4] = g_innerHexagonInitialPos;
|
if (g_optimizeInnerHexagonSize) {
|
||||||
if (!initialGuess.empty()) {
|
x[n - 1] = g_innerHexagonInitialPos;
|
||||||
x = initialGuess;
|
}
|
||||||
} // {0.10000000000000 001, 2, 1.9999999971613847, 6.9560343643347764};
|
/*if (!initialGuess.empty()) {
|
||||||
|
x = g_optimizationInitialGuess;
|
||||||
|
}*/ // {0.10000000000000 001,
|
||||||
|
// 2, 1.9999999971613847, 6.9560343643347764};
|
||||||
// {1, 5.9277};
|
// {1, 5.9277};
|
||||||
// {0.0001, 2, 2.000000005047502, 1.3055270196964464};
|
// {0.0001, 2, 2.000000005047502, 1.3055270196964464};
|
||||||
// {initialGuess(0), initialGuess(1), initialGuess(2),
|
// {initialGuess(0), initialGuess(1), initialGuess(2),
|
||||||
// initialGuess(3)};
|
// initialGuess(3)};
|
||||||
const double xMin = 1e-2;
|
const double xMin = 1e-2;
|
||||||
const double xMax = 5000;
|
const double xMax = 500;
|
||||||
// assert(x.end() == find_if(x.begin(), x.end(), [&](const double &d) {
|
// assert(x.end() == find_if(x.begin(), x.end(), [&](const double &d) {
|
||||||
// return d >= xMax || d <= xMin;
|
// return d >= xMax || d <= xMin;
|
||||||
// }));
|
// }));
|
||||||
std::vector<double> xLow(x.size(), xMin);
|
std::vector<double> xLow(x.size(), xMin);
|
||||||
std::vector<double> xUpper(x.size(), xMax);
|
std::vector<double> xUpper(x.size(), xMax);
|
||||||
if (n == 5) {
|
if (g_optimizeInnerHexagonSize) {
|
||||||
xLow[4] = 0.1;
|
xLow[n - 1] = 0.1;
|
||||||
xUpper[4] = 1;
|
xUpper[n - 1] = 0.9;
|
||||||
}
|
}
|
||||||
const double maxX = *std::max_element(
|
const double maxX = *std::max_element(
|
||||||
x.begin(), x.end(),
|
x.begin(), x.end(),
|
||||||
[](const double &a, const double &b) { return abs(a) < abs(b); });
|
[](const double &a, const double &b) { return abs(a) < abs(b); });
|
||||||
// const double rhobeg = std::min(0.95, 0.2 * maxX);
|
// const double rhobeg = std::min(0.95, 0.2 * maxX);
|
||||||
const double rhobeg = 0.01;
|
const double rhobeg = 1;
|
||||||
// const double rhobeg = 10;
|
// const double rhobeg = 10;
|
||||||
const double rhoend = rhobeg * 1e-6;
|
const double rhoend = rhobeg * 1e-6;
|
||||||
const size_t wSize = (npt + 5) * (npt + n) + 3 * n * (n + 5) / 2;
|
const size_t wSize = (npt + 5) * (npt + n) + 3 * n * (n + 5) / 2;
|
||||||
std::vector<double> w(wSize);
|
std::vector<double> w(wSize);
|
||||||
// const size_t maxFun = 10 * (x.size() ^ 2);
|
// const size_t maxFun = 10 * (x.size() ^ 2);
|
||||||
const size_t maxFun = 120;
|
const size_t maxFun = 200;
|
||||||
bobyqa(pObjectiveFunction, n, npt, x.data(), xLow.data(), xUpper.data(),
|
bobyqa(pObjectiveFunction, n, npt, x.data(), xLow.data(), xUpper.data(),
|
||||||
rhobeg, rhoend, maxFun, w.data());
|
rhobeg, rhoend, maxFun, w.data());
|
||||||
|
std::cout << "Finished first optimization round" << std::endl;
|
||||||
|
firstOptimizationRoundResults.resize(6);
|
||||||
|
for (int simulationScenarioIndex = SimulationScenario::Axial;
|
||||||
|
simulationScenarioIndex !=
|
||||||
|
SimulationScenario::NumberOfSimulationScenarios;
|
||||||
|
simulationScenarioIndex++) {
|
||||||
|
SimulationResults reducedModelResults = simulator.executeSimulation(
|
||||||
|
g_reducedPatternSimulationJob[simulationScenarioIndex], false, false);
|
||||||
|
reducedModelResults.setLabelPrefix("FirstRound");
|
||||||
|
firstOptimizationRoundResults[simulationScenarioIndex] =
|
||||||
|
std::move(reducedModelResults);
|
||||||
|
}
|
||||||
|
g_firstRoundIterationIndex = gObjectiveValueHistory.size();
|
||||||
|
bobyqa(pObjectiveFunction, n, npt, x.data(), xLow.data(), xUpper.data(),
|
||||||
|
rhobeg * 1e-3, rhoend, maxFun, w.data());
|
||||||
|
std::cout << "Finished second optimization round" << std::endl;
|
||||||
|
|
||||||
Eigen::VectorXd eigenX(x.size(), 1);
|
Eigen::VectorXd eigenX(x.size(), 1);
|
||||||
for (size_t xi = 0; xi < x.size(); xi++) {
|
for (size_t xi = 0; xi < x.size(); xi++) {
|
||||||
|
|
@ -552,12 +574,13 @@ void ReducedModelOptimizer::setInitialGuess(std::vector<double> v) {
|
||||||
initialGuess = v;
|
initialGuess = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SimulationJob> ReducedModelOptimizer::createScenarios(
|
std::vector<std::shared_ptr<SimulationJob>>
|
||||||
|
ReducedModelOptimizer::createScenarios(
|
||||||
const std::shared_ptr<SimulationMesh> &pMesh) {
|
const std::shared_ptr<SimulationMesh> &pMesh) {
|
||||||
std::vector<SimulationJob> scenarios;
|
std::vector<std::shared_ptr<SimulationJob>> scenarios;
|
||||||
|
scenarios.resize(SimulationScenario::NumberOfSimulationScenarios);
|
||||||
std::unordered_map<VertexIndex, std::unordered_set<DoFType>> fixedVertices;
|
std::unordered_map<VertexIndex, std::unordered_set<DoFType>> fixedVertices;
|
||||||
std::unordered_map<VertexIndex, Vector6d> nodalForces;
|
std::unordered_map<VertexIndex, Vector6d> nodalForces;
|
||||||
// NOTE: Assuming that the first interface node lays on the y axis
|
|
||||||
const double forceMagnitude = 1;
|
const double forceMagnitude = 1;
|
||||||
// Assuming the patterns lays on the x-y plane
|
// Assuming the patterns lays on the x-y plane
|
||||||
const CoordType patternPlaneNormal(0, 0, 1);
|
const CoordType patternPlaneNormal(0, 0, 1);
|
||||||
|
|
@ -594,6 +617,7 @@ std::vector<SimulationJob> ReducedModelOptimizer::createScenarios(
|
||||||
// m_pReducedPatternSimulationMesh->updateEigenEdgeAndVertices();
|
// m_pReducedPatternSimulationMesh->updateEigenEdgeAndVertices();
|
||||||
|
|
||||||
//// Axial
|
//// Axial
|
||||||
|
SimulationScenario scenarioName = SimulationScenario::Axial;
|
||||||
for (const auto &viPair : m_fullPatternOppositeInterfaceViMap) {
|
for (const auto &viPair : m_fullPatternOppositeInterfaceViMap) {
|
||||||
CoordType forceDirection =
|
CoordType forceDirection =
|
||||||
(pMesh->vert[viPair.first].cP() - pMesh->vert[viPair.second].cP())
|
(pMesh->vert[viPair.first].cP() - pMesh->vert[viPair.second].cP())
|
||||||
|
|
@ -604,9 +628,12 @@ std::vector<SimulationJob> ReducedModelOptimizer::createScenarios(
|
||||||
fixedVertices[viPair.second] =
|
fixedVertices[viPair.second] =
|
||||||
std::unordered_set<DoFType>{0, 1, 2, 3, 4, 5};
|
std::unordered_set<DoFType>{0, 1, 2, 3, 4, 5};
|
||||||
}
|
}
|
||||||
scenarios.push_back({pMesh, fixedVertices, nodalForces, {}});
|
scenarios[scenarioName] = std::make_shared<SimulationJob>(
|
||||||
|
SimulationJob(pMesh, simulationScenarioStrings[scenarioName],
|
||||||
|
fixedVertices, nodalForces, {}));
|
||||||
|
|
||||||
//// In-plane Bending
|
//// Shear
|
||||||
|
scenarioName = SimulationScenario::Shear;
|
||||||
fixedVertices.clear();
|
fixedVertices.clear();
|
||||||
nodalForces.clear();
|
nodalForces.clear();
|
||||||
for (const auto &viPair : m_fullPatternOppositeInterfaceViMap) {
|
for (const auto &viPair : m_fullPatternOppositeInterfaceViMap) {
|
||||||
|
|
@ -620,7 +647,9 @@ std::vector<SimulationJob> ReducedModelOptimizer::createScenarios(
|
||||||
fixedVertices[viPair.second] =
|
fixedVertices[viPair.second] =
|
||||||
std::unordered_set<DoFType>{0, 1, 2, 3, 4, 5};
|
std::unordered_set<DoFType>{0, 1, 2, 3, 4, 5};
|
||||||
}
|
}
|
||||||
scenarios.push_back({pMesh, fixedVertices, nodalForces, {}});
|
scenarios[scenarioName] = std::make_shared<SimulationJob>(
|
||||||
|
SimulationJob(pMesh, simulationScenarioStrings[scenarioName],
|
||||||
|
fixedVertices, nodalForces, {}));
|
||||||
|
|
||||||
// //// Torsion
|
// //// Torsion
|
||||||
// fixedVertices.clear();
|
// fixedVertices.clear();
|
||||||
|
|
@ -645,7 +674,8 @@ std::vector<SimulationJob> ReducedModelOptimizer::createScenarios(
|
||||||
// }
|
// }
|
||||||
// scenarios.push_back({pMesh, fixedVertices, nodalForces});
|
// scenarios.push_back({pMesh, fixedVertices, nodalForces});
|
||||||
|
|
||||||
//// Out - of - plane bending.Pull towards Z
|
//// Bending
|
||||||
|
scenarioName = SimulationScenario::Bending;
|
||||||
fixedVertices.clear();
|
fixedVertices.clear();
|
||||||
nodalForces.clear();
|
nodalForces.clear();
|
||||||
for (const auto &viPair : m_fullPatternOppositeInterfaceViMap) {
|
for (const auto &viPair : m_fullPatternOppositeInterfaceViMap) {
|
||||||
|
|
@ -653,9 +683,12 @@ std::vector<SimulationJob> ReducedModelOptimizer::createScenarios(
|
||||||
fixedVertices[viPair.second] =
|
fixedVertices[viPair.second] =
|
||||||
std::unordered_set<DoFType>{0, 1, 2, 3, 4, 5};
|
std::unordered_set<DoFType>{0, 1, 2, 3, 4, 5};
|
||||||
}
|
}
|
||||||
scenarios.push_back({pMesh, fixedVertices, nodalForces, {}});
|
scenarios[scenarioName] = std::make_shared<SimulationJob>(
|
||||||
|
SimulationJob(pMesh, simulationScenarioStrings[scenarioName],
|
||||||
|
fixedVertices, nodalForces, {}));
|
||||||
|
|
||||||
//// Double using moments
|
//// Double using moments
|
||||||
|
scenarioName = SimulationScenario::Dome;
|
||||||
fixedVertices.clear();
|
fixedVertices.clear();
|
||||||
nodalForces.clear();
|
nodalForces.clear();
|
||||||
for (auto viPairIt = m_fullPatternOppositeInterfaceViMap.begin();
|
for (auto viPairIt = m_fullPatternOppositeInterfaceViMap.begin();
|
||||||
|
|
@ -676,9 +709,12 @@ std::vector<SimulationJob> ReducedModelOptimizer::createScenarios(
|
||||||
nodalForces[viPair.second] =
|
nodalForces[viPair.second] =
|
||||||
Vector6d({0, 0, 0, -v[0], -v[1], 0}) * forceMagnitude * 0.1;
|
Vector6d({0, 0, 0, -v[0], -v[1], 0}) * forceMagnitude * 0.1;
|
||||||
}
|
}
|
||||||
scenarios.push_back({pMesh, fixedVertices, nodalForces, {}});
|
scenarios[scenarioName] = std::make_shared<SimulationJob>(
|
||||||
|
SimulationJob(pMesh, simulationScenarioStrings[scenarioName],
|
||||||
|
fixedVertices, nodalForces, {}));
|
||||||
|
|
||||||
//// Saddle
|
//// Saddle
|
||||||
|
scenarioName = SimulationScenario::Saddle;
|
||||||
fixedVertices.clear();
|
fixedVertices.clear();
|
||||||
nodalForces.clear();
|
nodalForces.clear();
|
||||||
for (auto viPairIt = m_fullPatternOppositeInterfaceViMap.begin();
|
for (auto viPairIt = m_fullPatternOppositeInterfaceViMap.begin();
|
||||||
|
|
@ -702,76 +738,177 @@ std::vector<SimulationJob> ReducedModelOptimizer::createScenarios(
|
||||||
Vector6d({0, 0, 0, v[0], v[1], 0}) * 0.01 * forceMagnitude;
|
Vector6d({0, 0, 0, v[0], v[1], 0}) * 0.01 * forceMagnitude;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scenarios.push_back({pMesh, fixedVertices, nodalForces, {}});
|
scenarios[scenarioName] = std::make_shared<SimulationJob>(
|
||||||
|
SimulationJob(pMesh, simulationScenarioStrings[scenarioName],
|
||||||
|
fixedVertices, nodalForces, {}));
|
||||||
|
|
||||||
return scenarios;
|
return scenarios;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReducedModelOptimizer::optimize(const int &simulationScenario) {
|
void ReducedModelOptimizer::runBeamOptimization() {
|
||||||
|
// load beams
|
||||||
|
VCGEdgeMesh fullBeam;
|
||||||
|
fullBeam.loadFromPly("/home/iason/Models/simple_beam_model_10elem_1m.ply");
|
||||||
|
VCGEdgeMesh reducedBeam;
|
||||||
|
reducedBeam.loadFromPly("/home/iason/Models/simple_beam_model_4elem_1m.ply");
|
||||||
|
fullBeam.registerForDrawing();
|
||||||
|
reducedBeam.registerForDrawing();
|
||||||
|
// polyscope::show();
|
||||||
|
// maps
|
||||||
|
std::unordered_map<size_t, size_t> displacementReducedToFullMap;
|
||||||
|
displacementReducedToFullMap[reducedBeam.VN() / 2] = fullBeam.VN() / 2;
|
||||||
|
g_reducedToFullViMap = displacementReducedToFullMap;
|
||||||
|
std::unordered_map<size_t, size_t> jobFullToReducedMap;
|
||||||
|
jobFullToReducedMap[0] = 0;
|
||||||
|
jobFullToReducedMap[fullBeam.VN() - 1] = reducedBeam.VN() - 1;
|
||||||
|
|
||||||
std::vector<SimulationJob> simulationJobs =
|
// full model simuilation job
|
||||||
createScenarios(m_pFullModelSimulationMesh);
|
auto pFullPatternSimulationMesh = std::make_shared<SimulationMesh>(fullBeam);
|
||||||
|
pFullPatternSimulationMesh->setBeamCrossSection(CrossSectionType{0.02, 0.02});
|
||||||
|
pFullPatternSimulationMesh->setBeamMaterial(0.3, 1);
|
||||||
|
std::unordered_map<VertexIndex, std::unordered_set<int>> fixedVertices;
|
||||||
|
fixedVertices[0] = ::unordered_set<int>({0, 1, 2, 3, 4, 5});
|
||||||
|
std::unordered_map<VertexIndex, Vector6d> forces;
|
||||||
|
forces[fullBeam.VN() - 1] = Vector6d({0, 0, 10, 0, 0, 0});
|
||||||
|
const std::string fullBeamSimulationJobLabel = "Pull_Z";
|
||||||
|
std::shared_ptr<SimulationJob> pFullModelSimulationJob =
|
||||||
|
make_shared<SimulationJob>(SimulationJob(pFullPatternSimulationMesh,
|
||||||
|
fullBeamSimulationJobLabel,
|
||||||
|
fixedVertices, forces));
|
||||||
|
FormFinder formFinder;
|
||||||
|
auto fullModelResults = formFinder.executeSimulation(pFullModelSimulationJob);
|
||||||
|
|
||||||
|
// Optimal reduced model displacements
|
||||||
|
const size_t numberOfSimulationScenarios = 1;
|
||||||
|
g_optimalReducedModelDisplacements.resize(numberOfSimulationScenarios);
|
||||||
|
g_optimalReducedModelDisplacements[numberOfSimulationScenarios - 1].resize(
|
||||||
|
reducedBeam.VN(), 3);
|
||||||
|
computeDesiredReducedModelDisplacements(
|
||||||
|
fullModelResults, displacementReducedToFullMap,
|
||||||
|
g_optimalReducedModelDisplacements[numberOfSimulationScenarios - 1]);
|
||||||
|
|
||||||
|
// reduced model simuilation job
|
||||||
|
auto reducedSimulationMesh = std::make_shared<SimulationMesh>(reducedBeam);
|
||||||
|
reducedSimulationMesh->setBeamCrossSection(CrossSectionType{0.02, 0.02});
|
||||||
|
reducedSimulationMesh->setBeamMaterial(0.3, 1);
|
||||||
|
g_reducedPatternSimulationJob.resize(numberOfSimulationScenarios);
|
||||||
|
SimulationJob reducedSimJob;
|
||||||
|
computeReducedModelSimulationJob(*pFullModelSimulationJob,
|
||||||
|
jobFullToReducedMap, reducedSimJob);
|
||||||
|
reducedSimJob.nodalExternalForces[reducedBeam.VN() - 1] =
|
||||||
|
reducedSimJob.nodalExternalForces[reducedBeam.VN() - 1] * 0.1;
|
||||||
|
g_reducedPatternSimulationJob[numberOfSimulationScenarios - 1] =
|
||||||
|
make_shared<SimulationJob>(
|
||||||
|
reducedSimulationMesh, fullBeamSimulationJobLabel,
|
||||||
|
reducedSimJob.constrainedVertices, reducedSimJob.nodalExternalForces);
|
||||||
|
initializeStiffnesses(reducedSimulationMesh);
|
||||||
|
|
||||||
|
// const std::string simulationJobsPath = "SimulationJobs";
|
||||||
|
// std::filesystem::create_directory(simulationJobsPath);
|
||||||
|
// g_reducedPatternSimulationJob[0].save(simulationJobsPath);
|
||||||
|
// g_reducedPatternSimulationJob[0].load(
|
||||||
|
// std::filesystem::path(simulationJobsPath)
|
||||||
|
// .append(g_reducedPatternSimulationJob[0].mesh->getLabel() +
|
||||||
|
// "_simScenario.json"));
|
||||||
|
|
||||||
|
runOptimization(&objective);
|
||||||
|
|
||||||
|
fullModelResults.registerForDrawing();
|
||||||
|
SimulationResults reducedModelResults = simulator.executeSimulation(
|
||||||
|
g_reducedPatternSimulationJob[numberOfSimulationScenarios - 1], false,
|
||||||
|
false);
|
||||||
|
double error = computeError(
|
||||||
|
reducedModelResults,
|
||||||
|
g_optimalReducedModelDisplacements[numberOfSimulationScenarios - 1]);
|
||||||
|
reducedModelResults.registerForDrawing();
|
||||||
|
std::cout << "Error between beams:" << error << endl;
|
||||||
|
// registerWorldAxes();
|
||||||
|
polyscope::show();
|
||||||
|
fullModelResults.unregister();
|
||||||
|
reducedModelResults.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReducedModelOptimizer::visualizeResults(
|
||||||
|
const std::vector<std::shared_ptr<SimulationJob>>
|
||||||
|
&fullPatternSimulationJobs,
|
||||||
|
const std::vector<SimulationScenario> &simulationScenarios) {
|
||||||
|
m_pFullPatternSimulationMesh->registerForDrawing();
|
||||||
|
double error = 0;
|
||||||
|
for (const int simulationScenarioIndex : simulationScenarios) {
|
||||||
|
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob =
|
||||||
|
fullPatternSimulationJobs[simulationScenarioIndex];
|
||||||
|
pFullPatternSimulationJob->registerForDrawing(
|
||||||
|
m_pFullPatternSimulationMesh->getLabel());
|
||||||
|
SimulationResults fullModelResults =
|
||||||
|
simulator.executeSimulation(pFullPatternSimulationJob, false);
|
||||||
|
fullModelResults.registerForDrawing();
|
||||||
|
fullModelResults.saveDeformedModel();
|
||||||
|
const std::shared_ptr<SimulationJob> &pReducedPatternSimulationJob =
|
||||||
|
g_reducedPatternSimulationJob[simulationScenarioIndex];
|
||||||
|
SimulationResults reducedModelResults =
|
||||||
|
simulator.executeSimulation(pReducedPatternSimulationJob, false, false);
|
||||||
|
error += computeError(
|
||||||
|
reducedModelResults,
|
||||||
|
g_optimalReducedModelDisplacements[simulationScenarioIndex]);
|
||||||
|
std::cout << "Error of simulation scenario "
|
||||||
|
<< simulationScenarioStrings[simulationScenarioIndex] << " is "
|
||||||
|
<< error << std::endl;
|
||||||
|
reducedModelResults.registerForDrawing();
|
||||||
|
firstOptimizationRoundResults[simulationScenarioIndex].registerForDrawing();
|
||||||
|
reducedModelResults.saveDeformedModel();
|
||||||
|
// registerWorldAxes();
|
||||||
|
polyscope::show();
|
||||||
|
fullModelResults.unregister();
|
||||||
|
reducedModelResults.unregister();
|
||||||
|
firstOptimizationRoundResults[simulationScenarioIndex].unregister();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReducedModelOptimizer::optimize(
|
||||||
|
const std::vector<SimulationScenario> &simulationScenariosIndices) {
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<SimulationJob>> simulationJobs =
|
||||||
|
createScenarios(m_pFullPatternSimulationMesh);
|
||||||
g_optimalReducedModelDisplacements.resize(6);
|
g_optimalReducedModelDisplacements.resize(6);
|
||||||
g_reducedPatternSimulationJob.resize(6);
|
g_reducedPatternSimulationJob.resize(6);
|
||||||
|
g_firstRoundIterationIndex = 0;
|
||||||
// polyscope::removeAllStructures();
|
// polyscope::removeAllStructures();
|
||||||
|
|
||||||
for (int simulationScenarioIndex = SimulationScenario::Axial;
|
for (int simulationScenarioIndex = SimulationScenario::Axial;
|
||||||
simulationScenarioIndex !=
|
simulationScenarioIndex !=
|
||||||
SimulationScenario::NumberOfSimulationScenarios;
|
SimulationScenario::NumberOfSimulationScenarios;
|
||||||
simulationScenarioIndex++) {
|
simulationScenarioIndex++) {
|
||||||
const SimulationJob &fullPatternSimulationJob =
|
const std::shared_ptr<SimulationJob> &pFullPatternSimulationJob =
|
||||||
simulationJobs[simulationScenarioIndex];
|
simulationJobs[simulationScenarioIndex];
|
||||||
// fullPatternSimulationJob.mesh->savePly(
|
// fullPatternSimulationJob.mesh->savePly(
|
||||||
// "Fanned_" + m_pFullModelSimulationMesh->getLabel() + ".ply");
|
// "Fanned_" + m_pFullModelSimulationMesh->getLabel() + ".ply");
|
||||||
SimulationResults fullModelResults =
|
SimulationResults fullModelResults =
|
||||||
simulator.executeSimulation(fullPatternSimulationJob, false);
|
simulator.executeSimulation(pFullPatternSimulationJob);
|
||||||
// fullModelResults.label =
|
// fullModelResults.label =
|
||||||
// "fullModel_" + SimulationScenarioStrings[simulationScenarioIndex];
|
// "fullModel_" + SimulationScenarioStrings[simulationScenarioIndex];
|
||||||
// fullModelResults.registerForDrawing(fullPatternSimulationJob);
|
// fullModelResults.registerForDrawing(fullPatternSimulationJob);
|
||||||
|
g_optimalReducedModelDisplacements[simulationScenarioIndex].resize(
|
||||||
|
m_pReducedPatternSimulationMesh->VN(), 3);
|
||||||
computeDesiredReducedModelDisplacements(
|
computeDesiredReducedModelDisplacements(
|
||||||
fullModelResults,
|
fullModelResults, g_reducedToFullViMap,
|
||||||
g_optimalReducedModelDisplacements[simulationScenarioIndex]);
|
g_optimalReducedModelDisplacements[simulationScenarioIndex]);
|
||||||
computeReducedModelSimulationJob(
|
SimulationJob reducedPatternSimulationJob;
|
||||||
fullPatternSimulationJob,
|
reducedPatternSimulationJob.pMesh = m_pReducedPatternSimulationMesh;
|
||||||
g_reducedPatternSimulationJob[simulationScenarioIndex]);
|
computeReducedModelSimulationJob(*pFullPatternSimulationJob,
|
||||||
|
m_fullToReducedInterfaceViMap,
|
||||||
|
reducedPatternSimulationJob);
|
||||||
|
g_reducedPatternSimulationJob[simulationScenarioIndex] =
|
||||||
|
std::make_shared<SimulationJob>(reducedPatternSimulationJob);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simulationScenario == -1) {
|
g_simulationScenarioIndices = simulationScenariosIndices;
|
||||||
double (*pObjectiveFunction)(long, const double *) = &objectiveAllScenarios;
|
if (simulationScenariosIndices.empty()) {
|
||||||
runOptimization(pObjectiveFunction);
|
g_simulationScenarioIndices = {
|
||||||
} else { // run chosen
|
SimulationScenario::Axial, SimulationScenario::Shear,
|
||||||
g_chosenSimulationScenarioName = SimulationScenario(simulationScenario);
|
SimulationScenario::Bending, SimulationScenario::Dome,
|
||||||
double (*pObjectiveFunction)(long, const double *) =
|
SimulationScenario::Saddle};
|
||||||
&objectiveSingleScenario;
|
|
||||||
runOptimization(pObjectiveFunction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pFullModelSimulationMesh->registerForDrawing();
|
runOptimization(&objective);
|
||||||
double error = 0;
|
visualizeResults(simulationJobs, g_simulationScenarioIndices);
|
||||||
for (int simulationScenarioIndex = SimulationScenario::Axial;
|
|
||||||
simulationScenarioIndex !=
|
|
||||||
SimulationScenario::NumberOfSimulationScenarios;
|
|
||||||
simulationScenarioIndex++) {
|
|
||||||
const SimulationJob &fullPatternSimulationJob =
|
|
||||||
simulationJobs[simulationScenarioIndex];
|
|
||||||
SimulationResults fullModelResults =
|
|
||||||
simulator.executeSimulation(fullPatternSimulationJob, false);
|
|
||||||
fullModelResults.label =
|
|
||||||
"fullModel_" + SimulationScenarioStrings[simulationScenarioIndex];
|
|
||||||
fullModelResults.registerForDrawing(fullPatternSimulationJob);
|
|
||||||
const SimulationJob &reducedPatternSimulationJob =
|
|
||||||
g_reducedPatternSimulationJob[simulationScenarioIndex];
|
|
||||||
SimulationResults reducedModelResults =
|
|
||||||
simulator.executeSimulation(reducedPatternSimulationJob, false, false);
|
|
||||||
error += computeError(
|
|
||||||
reducedModelResults,
|
|
||||||
g_optimalReducedModelDisplacements[simulationScenarioIndex]);
|
|
||||||
reducedModelResults.label =
|
|
||||||
"reducedModel_" + SimulationScenarioStrings[simulationScenarioIndex];
|
|
||||||
reducedModelResults.registerForDrawing(reducedPatternSimulationJob);
|
|
||||||
// registerWorldAxes();
|
|
||||||
polyscope::show();
|
|
||||||
fullModelResults.unregister();
|
|
||||||
reducedModelResults.unregister();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ using ReducedPatternVertexIndex = VertexIndex;
|
||||||
|
|
||||||
class ReducedModelOptimizer {
|
class ReducedModelOptimizer {
|
||||||
std::shared_ptr<SimulationMesh> m_pReducedPatternSimulationMesh;
|
std::shared_ptr<SimulationMesh> m_pReducedPatternSimulationMesh;
|
||||||
std::shared_ptr<SimulationMesh> m_pFullModelSimulationMesh;
|
std::shared_ptr<SimulationMesh> m_pFullPatternSimulationMesh;
|
||||||
std::unordered_map<FullPatternVertexIndex, ReducedPatternVertexIndex>
|
std::unordered_map<FullPatternVertexIndex, ReducedPatternVertexIndex>
|
||||||
m_fullToReducedInterfaceViMap;
|
m_fullToReducedInterfaceViMap;
|
||||||
std::unordered_map<FullPatternVertexIndex, FullPatternVertexIndex>
|
std::unordered_map<FullPatternVertexIndex, FullPatternVertexIndex>
|
||||||
|
|
@ -26,18 +26,19 @@ public:
|
||||||
Axial,
|
Axial,
|
||||||
Shear,
|
Shear,
|
||||||
Bending,
|
Bending,
|
||||||
Double,
|
Dome,
|
||||||
Saddle,
|
Saddle,
|
||||||
NumberOfSimulationScenarios
|
NumberOfSimulationScenarios
|
||||||
};
|
};
|
||||||
inline static const std::string SimulationScenarioStrings[] = {
|
inline static const std::string simulationScenarioStrings[] = {
|
||||||
"Axial", "Shear", "Bending", "Double", "Saddle"};
|
"Axial", "Shear", "Bending", "Double", "Saddle"};
|
||||||
void optimize(const int &simulationScenario = -1);
|
void optimize(const std::vector<SimulationScenario> &simulationScenarios);
|
||||||
double operator()(const Eigen::VectorXd &x, Eigen::VectorXd &) const;
|
double operator()(const Eigen::VectorXd &x, Eigen::VectorXd &) const;
|
||||||
|
|
||||||
ReducedModelOptimizer(const std::vector<size_t> &numberOfNodesPerSlot);
|
ReducedModelOptimizer(const std::vector<size_t> &numberOfNodesPerSlot);
|
||||||
void computeReducedModelSimulationJob(
|
static void computeReducedModelSimulationJob(
|
||||||
const SimulationJob &simulationJobOfFullModel,
|
const SimulationJob &simulationJobOfFullModel,
|
||||||
|
const std::unordered_map<size_t, size_t> &simulationJobFullToReducedMap,
|
||||||
SimulationJob &simulationJobOfReducedModel);
|
SimulationJob &simulationJobOfReducedModel);
|
||||||
|
|
||||||
SimulationJob
|
SimulationJob
|
||||||
|
|
@ -49,25 +50,35 @@ public:
|
||||||
|
|
||||||
void setInitialGuess(std::vector<double> v);
|
void setInitialGuess(std::vector<double> v);
|
||||||
|
|
||||||
|
static void runBeamOptimization();
|
||||||
|
|
||||||
|
static void runSimulation(const std::string &filename,
|
||||||
|
std::vector<double> &x);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void computeDesiredReducedModelDisplacements(
|
void
|
||||||
|
visualizeResults(const std::vector<std::shared_ptr<SimulationJob>>
|
||||||
|
&fullPatternSimulationJobs,
|
||||||
|
const std::vector<SimulationScenario> &simulationScenarios);
|
||||||
|
static void computeDesiredReducedModelDisplacements(
|
||||||
const SimulationResults &fullModelResults,
|
const SimulationResults &fullModelResults,
|
||||||
|
const std::unordered_map<size_t, size_t> &displacementsReducedToFullMap,
|
||||||
Eigen::MatrixX3d &optimalDisplacementsOfReducedModel);
|
Eigen::MatrixX3d &optimalDisplacementsOfReducedModel);
|
||||||
Eigen::VectorXd runOptimization(double (*pObjectiveFunction)(long,
|
static Eigen::VectorXd
|
||||||
const double *));
|
runOptimization(double (*pObjectiveFunction)(long, const double *));
|
||||||
std::vector<SimulationJob>
|
std::vector<std::shared_ptr<SimulationJob>>
|
||||||
createScenarios(const std::shared_ptr<SimulationMesh> &pMesh);
|
createScenarios(const std::shared_ptr<SimulationMesh> &pMesh);
|
||||||
void computeMaps(FlatPattern &fullModel, FlatPattern &reducedPattern,
|
void computeMaps(FlatPattern &fullModel, FlatPattern &reducedPattern,
|
||||||
const std::unordered_set<size_t> &reducedModelExcludedEges);
|
const std::unordered_set<size_t> &reducedModelExcludedEges);
|
||||||
void createSimulationMeshes(FlatPattern &fullModel,
|
void createSimulationMeshes(FlatPattern &fullModel,
|
||||||
FlatPattern &reducedModel);
|
FlatPattern &reducedModel);
|
||||||
void initializeStiffnesses();
|
static void
|
||||||
|
initializeStiffnesses(const std::shared_ptr<SimulationMesh> &mesh);
|
||||||
|
|
||||||
static double
|
static double
|
||||||
computeError(const SimulationResults &reducedPatternResults,
|
computeError(const SimulationResults &reducedPatternResults,
|
||||||
const Eigen::MatrixX3d &optimalReducedPatternDisplacements);
|
const Eigen::MatrixX3d &optimalReducedPatternDisplacements);
|
||||||
static double objectiveSingleScenario(long n, const double *x);
|
static double objective(long n, const double *x);
|
||||||
static double objectiveAllScenarios(long n, const double *x);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // REDUCEDMODELOPTIMIZER_HPP
|
#endif // REDUCEDMODELOPTIMIZER_HPP
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue