Added code for exporting pe.gradual application of external forces. average residual forces threshold

This commit is contained in:
iasonmanolas 2021-07-07 22:43:44 +03:00
parent 992f0fe6ae
commit 2509b0a795
6 changed files with 193 additions and 100 deletions

View File

@ -231,6 +231,7 @@ void DRMSimulationModel::reset()
Dt = mSettings.Dtini; Dt = mSettings.Dtini;
numOfDampings = 0; numOfDampings = 0;
shouldTemporarilyDampForces = false; shouldTemporarilyDampForces = false;
externalLoadStep = 1;
} }
VectorType DRMSimulationModel::computeDisplacementDifferenceDerivative( VectorType DRMSimulationModel::computeDisplacementDifferenceDerivative(
@ -958,7 +959,6 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
force.residual = force.external; force.residual = force.external;
force.internal = 0; force.internal = 0;
} }
double totalResidualForcesNorm = 0;
for (size_t ei = 0; ei < pMesh->EN(); ei++) { for (size_t ei = 0; ei < pMesh->EN(); ei++) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
std::pair<int, Vector6d> internalForcePair std::pair<int, Vector6d> internalForcePair
@ -972,6 +972,7 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
force.residual = force.residual + (internalForcePair.second * -1); force.residual = force.residual + (internalForcePair.second * -1);
} }
} }
double totalResidualForcesNorm = 0;
Vector6d sumOfResidualForces(0); Vector6d sumOfResidualForces(0);
for (size_t vi = 0; vi < pMesh->VN(); vi++) { for (size_t vi = 0; vi < pMesh->VN(); vi++) {
Node::Forces &force = pMesh->nodes[vi].force; Node::Forces &force = pMesh->nodes[vi].force;
@ -984,7 +985,8 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
} }
pMesh->previousTotalResidualForcesNorm = pMesh->totalResidualForcesNorm; pMesh->previousTotalResidualForcesNorm = pMesh->totalResidualForcesNorm;
pMesh->totalResidualForcesNorm = totalResidualForcesNorm; pMesh->totalResidualForcesNorm = totalResidualForcesNorm;
// mesh->totalResidualForcesNorm = sumOfResidualForces.norm(); pMesh->averageResidualForcesNorm = totalResidualForcesNorm / pMesh->VN();
// pMesh->averageResidualForcesNorm = sumOfResidualForces.norm() / pMesh->VN();
// plotYValues.push_back(totalResidualForcesNorm); // plotYValues.push_back(totalResidualForcesNorm);
// auto xPlot = matplot::linspace(0, plotYValues.size(), plotYValues.size()); // auto xPlot = matplot::linspace(0, plotYValues.size(), plotYValues.size());
@ -1147,7 +1149,7 @@ DRMSimulationModel::DRMSimulationModel() {}
void DRMSimulationModel::updateNodalMasses() void DRMSimulationModel::updateNodalMasses()
{ {
double gamma = mSettings.gamma; double gamma = mSettings.gamma;
const size_t untilStep = 500; const size_t untilStep = 4000;
if (shouldTemporarilyDampForces && mCurrentSimulationStep < untilStep) { if (shouldTemporarilyDampForces && mCurrentSimulationStep < untilStep) {
gamma *= 1e6 * (1 - static_cast<double>(mCurrentSimulationStep) / untilStep); gamma *= 1e6 * (1 - static_cast<double>(mCurrentSimulationStep) / untilStep);
} }
@ -1233,10 +1235,9 @@ void DRMSimulationModel::updateNodalVelocities()
const VertexIndex vi = pMesh->getIndex(v); const VertexIndex vi = pMesh->getIndex(v);
Node &node = pMesh->nodes[v]; Node &node = pMesh->nodes[v];
node.velocity = node.velocity + node.acceleration * Dt; node.velocity = node.velocity + node.acceleration * Dt;
// if (vi == 10) { if (std::isnan(node.velocity.norm())) {
// std::cout << "Velocity:" << node.velocity[0] << " " << node.velocity[1] << " " std::cout << "Velocity:" << node.velocity.toString() << std::endl;
// << node.velocity[2] << std::endl; }
// }
} }
updateKineticEnergy(); updateKineticEnergy();
} }
@ -1461,7 +1462,7 @@ void DRMSimulationModel::updateKineticEnergy()
+ node.mass.rotationalI3 * pow(node.velocity[4], 2) + node.mass.rotationalI3 * pow(node.velocity[4], 2)
+ node.mass.rotationalI2 * pow(node.velocity[5], 2)); + node.mass.rotationalI2 * pow(node.velocity[5], 2));
node.kineticEnergy += nodeTranslationalKineticEnergy + nodeRotationalKineticEnergy; node.kineticEnergy = nodeTranslationalKineticEnergy + nodeRotationalKineticEnergy;
assert(node.kineticEnergy < 1e15); assert(node.kineticEnergy < 1e15);
pMesh->currentTotalKineticEnergy += node.kineticEnergy; pMesh->currentTotalKineticEnergy += node.kineticEnergy;
@ -1959,26 +1960,10 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
const SimulationResults &solutionGuess) const SimulationResults &solutionGuess)
{ {
assert(pJob->pMesh.operator bool()); assert(pJob->pMesh.operator bool());
auto t1 = std::chrono::high_resolution_clock::now(); auto beginTime = std::chrono::high_resolution_clock::now();
mSettings = settings; mSettings = settings;
reset(); reset();
double totalExternalForcesNorm = 0;
for (const std::pair<VertexIndex, Vector6d> &externalForce : pJob->nodalExternalForces) {
totalExternalForcesNorm += externalForce.second.norm();
}
if (!pJob->nodalExternalForces.empty()) {
mSettings.totalResidualForcesNormThreshold
= settings.totalExternalForcesNormPercentageTermination * totalExternalForcesNorm;
} else {
mSettings.totalResidualForcesNormThreshold = 1e-3;
std::cout << "No forces setted default residual forces norm threshold" << std::endl;
}
if (mSettings.beVerbose) {
std::cout << "totalResidualForcesNormThreshold:"
<< mSettings.totalResidualForcesNormThreshold << std::endl;
}
history.label = pJob->pMesh->getLabel() + "_" + pJob->getLabel(); history.label = pJob->pMesh->getLabel() + "_" + pJob->getLabel();
// if (!pJob->nodalExternalForces.empty()) { // if (!pJob->nodalExternalForces.empty()) {
@ -2044,12 +2029,38 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
} }
updateNodalMasses(); updateNodalMasses();
updateNodalExternalForces(pJob->nodalExternalForces, constrainedVertices); std::unordered_map<VertexIndex, Vector6d> nodalExternalForces = pJob->nodalExternalForces;
const size_t movingAverageSampleSize = 200; double totalExternalForcesNorm = 0;
std::queue<double> residualForcesMovingAverageHistorySample; // Vector6d sumOfExternalForces(0);
for (auto &nodalForce : nodalExternalForces) {
const double percentageOfExternalLoads = double(externalLoadStep)
/ mSettings.desiredGradualExternalLoadsSteps;
nodalForce.second = nodalForce.second * percentageOfExternalLoads;
totalExternalForcesNorm += nodalForce.second.norm();
// sumOfExternalForces = sumOfExternalForces + nodalForce.second;
}
updateNodalExternalForces(nodalExternalForces, constrainedVertices);
double averageExternalForcesNorm =
// sumOfExternalForces.norm() / pMesh->VN();
totalExternalForcesNorm / pMesh->VN();
if (!nodalExternalForces.empty()) {
mSettings.totalResidualForcesNormThreshold
= std::min(settings.totalExternalForcesNormPercentageTermination
* totalExternalForcesNorm,
1e-3);
} else {
mSettings.totalResidualForcesNormThreshold = 1e-3;
std::cout << "No forces setted default residual forces norm threshold" << std::endl;
}
if (mSettings.beVerbose) {
std::cout << "totalResidualForcesNormThreshold:"
<< mSettings.totalResidualForcesNormThreshold << std::endl;
}
// const size_t movingAverageSampleSize = 200;
// std::queue<double> residualForcesMovingAverageHistorySample;
std::vector<double> percentageOfConvergence; std::vector<double> percentageOfConvergence;
double residualForcesMovingAverageDerivativeMax = 0; // double residualForcesMovingAverageDerivativeMax = 0;
while (settings.maxDRMIterations == 0 || mCurrentSimulationStep < settings.maxDRMIterations) { while (settings.maxDRMIterations == 0 || mCurrentSimulationStep < settings.maxDRMIterations) {
if ((mSettings.isDebugMode && mCurrentSimulationStep == 50000)) { if ((mSettings.isDebugMode && mCurrentSimulationStep == 50000)) {
// std::filesystem::create_directory("./PatternOptimizationNonConv"); // std::filesystem::create_directory("./PatternOptimizationNonConv");
@ -2087,39 +2098,47 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
// } // }
updateElementalLengths(); updateElementalLengths();
mCurrentSimulationStep++; mCurrentSimulationStep++;
if (std::isnan(pMesh->currentTotalKineticEnergy)) {
double sumOfDisplacementsNorm = 0; std::cout << pMesh->currentTotalKineticEnergy << std::endl;
for (size_t vi = 0; vi < pMesh->VN(); vi++) { if (mSettings.beVerbose) {
sumOfDisplacementsNorm += pMesh->nodes[vi].displacements.getTranslation().norm(); std::cerr << "Infinite kinetic energy at step " << mCurrentSimulationStep
<< ". Exiting.." << std::endl;
} }
sumOfDisplacementsNorm /= pMesh->bbox.Diag(); break;
pMesh->sumOfNormalizedDisplacementNorms = sumOfDisplacementsNorm;
// pMesh->residualForcesMovingAverage = (pMesh->totalResidualForcesNorm
// + mCurrentSimulationStep
// * pMesh->residualForcesMovingAverage)
// / (1 + mCurrentSimulationStep);
pMesh->residualForcesMovingAverage += pMesh->totalResidualForcesNorm
/ movingAverageSampleSize;
residualForcesMovingAverageHistorySample.push(pMesh->residualForcesMovingAverage);
if (movingAverageSampleSize < residualForcesMovingAverageHistorySample.size()) {
const double firstElementValue = residualForcesMovingAverageHistorySample.front();
pMesh->residualForcesMovingAverage -= firstElementValue / movingAverageSampleSize;
residualForcesMovingAverageHistorySample.pop();
pMesh->residualForcesMovingAverageDerivativeNorm
= std::abs((residualForcesMovingAverageHistorySample.back()
- residualForcesMovingAverageHistorySample.front()))
/ (movingAverageSampleSize);
residualForcesMovingAverageDerivativeMax
= std::max(pMesh->residualForcesMovingAverageDerivativeNorm,
residualForcesMovingAverageDerivativeMax);
pMesh->residualForcesMovingAverageDerivativeNorm
/= residualForcesMovingAverageDerivativeMax;
// std::cout << "Normalized derivative:"
// << residualForcesMovingAverageDerivativeNorm
// << std::endl;
} }
// double sumOfDisplacementsNorm = 0;
// for (size_t vi = 0; vi < pMesh->VN(); vi++) {
// sumOfDisplacementsNorm += pMesh->nodes[vi].displacements.getTranslation().norm();
// }
// sumOfDisplacementsNorm /= pMesh->bbox.Diag();
// pMesh->sumOfNormalizedDisplacementNorms = sumOfDisplacementsNorm;
// // pMesh->residualForcesMovingAverage = (pMesh->totalResidualForcesNorm
// // + mCurrentSimulationStep
// // * pMesh->residualForcesMovingAverage)
// // / (1 + mCurrentSimulationStep);
// pMesh->residualForcesMovingAverage += pMesh->totalResidualForcesNorm
// / movingAverageSampleSize;
// residualForcesMovingAverageHistorySample.push(pMesh->residualForcesMovingAverage);
// if (movingAverageSampleSize < residualForcesMovingAverageHistorySample.size()) {
// const double firstElementValue = residualForcesMovingAverageHistorySample.front();
// pMesh->residualForcesMovingAverage -= firstElementValue / movingAverageSampleSize;
// residualForcesMovingAverageHistorySample.pop();
// pMesh->residualForcesMovingAverageDerivativeNorm
// = std::abs((residualForcesMovingAverageHistorySample.back()
// - residualForcesMovingAverageHistorySample.front()))
// / (movingAverageSampleSize);
// residualForcesMovingAverageDerivativeMax
// = std::max(pMesh->residualForcesMovingAverageDerivativeNorm,
// residualForcesMovingAverageDerivativeMax);
// pMesh->residualForcesMovingAverageDerivativeNorm
// /= residualForcesMovingAverageDerivativeMax;
// // std::cout << "Normalized derivative:"
// // << residualForcesMovingAverageDerivativeNorm
// // << std::endl;
// }
// pMesh->previousTotalPotentialEnergykN = // pMesh->previousTotalPotentialEnergykN =
// pMesh->currentTotalPotentialEnergykN; // pMesh->currentTotalPotentialEnergykN;
// pMesh->currentTotalPotentialEnergykN = computeTotalPotentialEnergy() / 1000; // pMesh->currentTotalPotentialEnergykN = computeTotalPotentialEnergy() / 1000;
@ -2127,10 +2146,21 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
if (mSettings.beVerbose && mSettings.isDebugMode if (mSettings.beVerbose && mSettings.isDebugMode
&& mCurrentSimulationStep % mSettings.debugModeStep == 0) { && mCurrentSimulationStep % mSettings.debugModeStep == 0) {
printCurrentState(); printCurrentState();
// auto t2 = std::chrono::high_resolution_clock::now();
// const double executionTime_min
// = std::chrono::duration_cast<std::chrono::minutes>(t2 - beginTime).count();
// std::cout << "Execution time(min):" << executionTime_min << std::endl;
if (mSettings.useAverageResidualForcesNorm) {
const double percOfConv = averageExternalForcesNorm
/ pMesh->averageResidualForcesNorm;
std::cout << "Percentage of target:" << percOfConv << "%" << std::endl;
} else {
std::cout << "Percentage of target:" std::cout << "Percentage of target:"
<< 100 * mSettings.totalResidualForcesNormThreshold << 100 * mSettings.totalResidualForcesNormThreshold
/ pMesh->totalResidualForcesNorm / pMesh->totalResidualForcesNorm
<< "%" << std::endl; << "%" << std::endl;
}
// SimulationResultsReporter::createPlot("Number of Steps", // SimulationResultsReporter::createPlot("Number of Steps",
// "Residual Forces mov aver", // "Residual Forces mov aver",
// movingAverages); // movingAverages);
@ -2149,13 +2179,6 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
/ pMesh->totalResidualForcesNorm); / pMesh->totalResidualForcesNorm);
} }
if (std::isnan(pMesh->currentTotalKineticEnergy)) {
if (mSettings.beVerbose) {
std::cout << "Infinite kinetic energy detected.Exiting.." << std::endl;
}
break;
}
if (mSettings.shouldCreatePlots && mSettings.isDebugMode if (mSettings.shouldCreatePlots && mSettings.isDebugMode
&& mCurrentSimulationStep % mSettings.debugModeStep == 0) { && mCurrentSimulationStep % mSettings.debugModeStep == 0) {
// SimulationResultsReporter::createPlot("Number of Steps", // SimulationResultsReporter::createPlot("Number of Steps",
@ -2164,18 +2187,18 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
// SimulationResultsReporter::createPlot("Number of Steps", // SimulationResultsReporter::createPlot("Number of Steps",
// "Residual Forces mov aver", // "Residual Forces mov aver",
// history.residualForcesMovingAverage); // history.residualForcesMovingAverage);
// SimulationResultsReporter::createPlot("Number of Steps", SimulationResultsReporter::createPlot("Number of Steps",
// "Log of Residual Forces", "Log of Residual Forces",
// history.logResidualForces, history.logResidualForces,
// {}, {},
// history.redMarks); history.redMarks);
// SimulationResultsReporter::createPlot("Number of Steps", // SimulationResultsReporter::createPlot("Number of Steps",
// "Log of Kinetic energy", // "Log of Kinetic energy",
// history.kineticEnergy, // history.kineticEnergy,
// {}, // {},
// history.redMarks); // history.redMarks);
SimulationResultsReporter reporter; // SimulationResultsReporter reporter;
reporter.reportHistory(history, "IntermediateResults", pJob->pMesh->getLabel()); // reporter.reportHistory(history, "IntermediateResults", pJob->pMesh->getLabel());
// SimulationResultsReporter::createPlot("Number of Iterations", // SimulationResultsReporter::createPlot("Number of Iterations",
// "Sum of normalized displacement norms", // "Sum of normalized displacement norms",
// history.sumOfNormalizedDisplacementNorms /*, // history.sumOfNormalizedDisplacementNorms /*,
@ -2234,8 +2257,12 @@ mesh->currentTotalPotentialEnergykN*/
&& pMesh->currentTotalTranslationalKineticEnergy && pMesh->currentTotalTranslationalKineticEnergy
< mSettings.totalTranslationalKineticEnergyThreshold < mSettings.totalTranslationalKineticEnergyThreshold
&& mCurrentSimulationStep > 20 && numOfDampings > 0; && mCurrentSimulationStep > 20 && numOfDampings > 0;
const bool fullfillsAverageResidualForcesNormCriterion
= mSettings.useAverageResidualForcesNorm
&& pMesh->averageResidualForcesNorm / averageExternalForcesNorm < 1e-2;
const bool fullfillsResidualForcesNormTerminationCriterion const bool fullfillsResidualForcesNormTerminationCriterion
= pMesh->totalResidualForcesNorm < mSettings.totalResidualForcesNormThreshold; = mSettings.useResidualForcesNorm
&& pMesh->totalResidualForcesNorm < mSettings.totalResidualForcesNormThreshold;
const bool fullfillsMovingAverageNormTerminationCriterion const bool fullfillsMovingAverageNormTerminationCriterion
= pMesh->residualForcesMovingAverage = pMesh->residualForcesMovingAverage
< mSettings.residualForcesMovingAverageNormThreshold; < mSettings.residualForcesMovingAverageNormThreshold;
@ -2246,7 +2273,8 @@ mesh->currentTotalPotentialEnergykN*/
= fullfillsKineticEnergyTerminationCriterion = fullfillsKineticEnergyTerminationCriterion
// || fullfillsMovingAverageNormTerminationCriterion // || fullfillsMovingAverageNormTerminationCriterion
// || fullfillsMovingAverageDerivativeNormTerminationCriterion // || fullfillsMovingAverageDerivativeNormTerminationCriterion
|| fullfillsResidualForcesNormTerminationCriterion; || fullfillsResidualForcesNormTerminationCriterion
|| fullfillsAverageResidualForcesNormCriterion;
if (shouldTerminate) { if (shouldTerminate) {
if (mSettings.beVerbose && !mSettings.isDebugMode) { if (mSettings.beVerbose && !mSettings.isDebugMode) {
std::cout << "Simulation converged." << std::endl; std::cout << "Simulation converged." << std::endl;
@ -2265,29 +2293,52 @@ mesh->currentTotalPotentialEnergykN*/
<< std::endl; << std::endl;
} }
} }
if (mSettings.desiredGradualExternalLoadsSteps == externalLoadStep) {
break; break;
} else {
externalLoadStep++;
std::unordered_map<VertexIndex, Vector6d> nodalExternalForces
= pJob->nodalExternalForces;
double totalExternalForcesNorm = 0;
for (auto &nodalForce : nodalExternalForces) {
const double percentageOfExternalLoads
= double(externalLoadStep) / mSettings.desiredGradualExternalLoadsSteps;
nodalForce.second = nodalForce.second * percentageOfExternalLoads;
totalExternalForcesNorm += nodalForce.second.norm();
}
updateNodalExternalForces(nodalExternalForces, constrainedVertices);
averageExternalForcesNorm = totalExternalForcesNorm / pMesh->VN();
if (!nodalExternalForces.empty()) {
mSettings.totalResidualForcesNormThreshold = 1e-2 * totalExternalForcesNorm;
}
if (mSettings.beVerbose) {
std::cout << "totalResidualForcesNormThreshold:"
<< mSettings.totalResidualForcesNormThreshold << std::endl;
}
}
// } // }
} }
// const bool shouldCapDisplacements = mSettings.displacementCap.has_value(); const bool shouldCapDisplacements = mSettings.displacementCap.has_value();
// for (VertexType &v : pMesh->vert) { for (VertexType &v : pMesh->vert) {
// Node &node = pMesh->nodes[v]; Node &node = pMesh->nodes[v];
// Vector6d stepDisplacement = node.velocity * Dt; Vector6d stepDisplacement = node.velocity * Dt;
// if (shouldCapDisplacements if (shouldCapDisplacements
// && stepDisplacement.getTranslation().norm() > mSettings.displacementCap) { && stepDisplacement.getTranslation().norm() > mSettings.displacementCap) {
// stepDisplacement = stepDisplacement stepDisplacement = stepDisplacement
// * (*mSettings.displacementCap * (*mSettings.displacementCap
// / stepDisplacement.getTranslation().norm()); / stepDisplacement.getTranslation().norm());
// } }
// node.displacements = node.displacements - stepDisplacement; node.displacements = node.displacements - stepDisplacement;
// } }
// applyDisplacements(constrainedVertices); applyDisplacements(constrainedVertices);
// if (!pJob->nodalForcedDisplacements.empty()) { if (!pJob->nodalForcedDisplacements.empty()) {
// applyForcedDisplacements( applyForcedDisplacements(
// pJob->nodalForcedDisplacements); pJob->nodalForcedDisplacements);
// } }
// updateElementalLengths(); updateElementalLengths();
// const double triggerPercentage = 0.01; // const double triggerPercentage = 0.01;
// const double xi_min = 0.55; // const double xi_min = 0.55;
@ -2313,8 +2364,11 @@ mesh->currentTotalPotentialEnergykN*/
// draw(); // draw();
} }
} }
auto endTime = std::chrono::high_resolution_clock::now();
SimulationResults results = computeResults(pJob); SimulationResults results = computeResults(pJob);
results.executionTime = std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime)
.count();
if (mCurrentSimulationStep == settings.maxDRMIterations && mCurrentSimulationStep != 0) { if (mCurrentSimulationStep == settings.maxDRMIterations && mCurrentSimulationStep != 0) {
if (mSettings.beVerbose) { if (mSettings.beVerbose) {

View File

@ -39,10 +39,13 @@ public:
int maxDRMIterations{0}; int maxDRMIterations{0};
bool shouldUseTranslationalKineticEnergyThreshold{false}; bool shouldUseTranslationalKineticEnergyThreshold{false};
int gradualForcedDisplacementSteps{100}; int gradualForcedDisplacementSteps{100};
int desiredGradualExternalLoadsSteps{1};
double gamma{0.8}; double gamma{0.8};
std::optional<double> displacementCap; std::optional<double> displacementCap;
double totalResidualForcesNormThreshold{1e-3}; double totalResidualForcesNormThreshold{1e-3};
double totalExternalForcesNormPercentageTermination{1e-3}; double totalExternalForcesNormPercentageTermination{1e-3};
bool useResidualForcesNorm{true};
bool useAverageResidualForcesNorm{false};
Settings() {} Settings() {}
}; };
@ -57,6 +60,7 @@ private:
matplot::line_handle plotHandle; matplot::line_handle plotHandle;
std::vector<double> plotYValues; std::vector<double> plotYValues;
size_t numOfDampings{0}; size_t numOfDampings{0};
int externalLoadStep{1};
const std::string meshPolyscopeLabel{"Simulation mesh"}; const std::string meshPolyscopeLabel{"Simulation mesh"};
std::unique_ptr<SimulationMesh> pMesh; std::unique_ptr<SimulationMesh> pMesh;

View File

@ -267,6 +267,7 @@ struct Colors
std::vector<double> perSimulationScenario_rotational; std::vector<double> perSimulationScenario_rotational;
std::vector<double> perSimulationScenario_total; std::vector<double> perSimulationScenario_total;
} objectiveValue; } objectiveValue;
std::vector<double> perScenario_fullPatternPotentialEnergy;
// std::vector<std::pair<std::string,double>> optimalXNameValuePairs; // std::vector<std::pair<std::string,double>> optimalXNameValuePairs;
std::vector<std::pair<std::string, double>> optimalXNameValuePairs; std::vector<std::pair<std::string, double>> optimalXNameValuePairs;
std::vector<std::shared_ptr<SimulationJob>> fullPatternSimulationJobs; std::vector<std::shared_ptr<SimulationJob>> fullPatternSimulationJobs;
@ -284,6 +285,7 @@ struct Colors
inline static std::string Label{"Label"}; inline static std::string Label{"Label"};
inline static std::string FullPatternLabel{"FullPatternLabel"}; inline static std::string FullPatternLabel{"FullPatternLabel"};
inline static std::string Settings{"OptimizationSettings"}; inline static std::string Settings{"OptimizationSettings"};
inline static std::string FullPatternPotentialEnergies{"PE"};
}; };
void save(const string &saveToPath, const bool shouldExportDebugFiles = false) void save(const string &saveToPath, const bool shouldExportDebugFiles = false)
@ -323,6 +325,16 @@ struct Colors
baseTriangle.cP2(0)[2]}; baseTriangle.cP2(0)[2]};
baseTriangleFullPattern.save(std::filesystem::path(saveToPath).string()); baseTriangleFullPattern.save(std::filesystem::path(saveToPath).string());
json_optimizationResults[JsonKeys::FullPatternLabel] = baseTriangleFullPattern.getLabel(); json_optimizationResults[JsonKeys::FullPatternLabel] = baseTriangleFullPattern.getLabel();
//potential energies
const int numberOfSimulationJobs = fullPatternSimulationJobs.size();
std::vector<double> fullPatternPE(numberOfSimulationJobs);
for (int simulationScenarioIndex = 0; simulationScenarioIndex < numberOfSimulationJobs;
simulationScenarioIndex++) {
fullPatternPE[simulationScenarioIndex]
= perScenario_fullPatternPotentialEnergy[simulationScenarioIndex];
}
json_optimizationResults[JsonKeys::FullPatternPotentialEnergies] = fullPatternPE;
////Save to json file ////Save to json file
std::filesystem::path jsonFilePath( std::filesystem::path jsonFilePath(
std::filesystem::path(saveToPath).append(JsonKeys::filename)); std::filesystem::path(saveToPath).append(JsonKeys::filename));
@ -652,6 +664,13 @@ struct Colors
os << "Obj value Rot " + simulationScenarioName; os << "Obj value Rot " + simulationScenarioName;
os << "Obj value Total " + simulationScenarioName; os << "Obj value Total " + simulationScenarioName;
} }
for (int simulationScenarioIndex = 0;
simulationScenarioIndex < fullPatternSimulationJobs.size();
simulationScenarioIndex++) {
const std::string simulationScenarioName
= fullPatternSimulationJobs[simulationScenarioIndex]->getLabel();
os << "PE " + simulationScenarioName;
}
for (const auto &nameValuePair : optimalXNameValuePairs) { for (const auto &nameValuePair : optimalXNameValuePairs) {
os << nameValuePair.first; os << nameValuePair.first;
} }
@ -671,6 +690,11 @@ struct Colors
os << objectiveValue.perSimulationScenario_rotational[simulationScenarioIndex]; os << objectiveValue.perSimulationScenario_rotational[simulationScenarioIndex];
os << objectiveValue.perSimulationScenario_total[simulationScenarioIndex]; os << objectiveValue.perSimulationScenario_total[simulationScenarioIndex];
} }
for (int simulationScenarioIndex = 0;
simulationScenarioIndex < fullPatternSimulationJobs.size();
simulationScenarioIndex++) {
os << perScenario_fullPatternPotentialEnergy[simulationScenarioIndex];
}
for (const auto &optimalXNameValuePair : optimalXNameValuePairs) { for (const auto &optimalXNameValuePair : optimalXNameValuePairs) {
os << optimalXNameValuePair.second; os << optimalXNameValuePair.second;
} }

View File

@ -492,7 +492,7 @@ struct SimulationResults
return labelPrefix + deliminator + job->pMesh->getLabel() + deliminator + job->getLabel(); return labelPrefix + deliminator + job->pMesh->getLabel() + deliminator + job->getLabel();
} }
void saveDeformedModel(const std::string &outputFolder = std::string()) bool saveDeformedModel(const std::string &outputFolder = std::string())
{ {
VCGEdgeMesh m; VCGEdgeMesh m;
vcg::tri::Append<VCGEdgeMesh, SimulationMesh>::MeshCopy(m, *job->pMesh); vcg::tri::Append<VCGEdgeMesh, SimulationMesh>::MeshCopy(m, *job->pMesh);
@ -503,7 +503,7 @@ struct SimulationResults
displacements[vi][1], displacements[vi][1],
displacements[vi][2]); displacements[vi][2]);
} }
m.save(std::filesystem::path(outputFolder).append(getLabel() + ".ply").string()); return m.save(std::filesystem::path(outputFolder).append(getLabel() + ".ply").string());
} }
void save(const std::string &outputFolder = std::string()) void save(const std::string &outputFolder = std::string())

View File

@ -43,6 +43,7 @@ public:
double currentTotalKineticEnergy{0}; double currentTotalKineticEnergy{0};
double currentTotalTranslationalKineticEnergy{0}; double currentTotalTranslationalKineticEnergy{0};
double totalResidualForcesNorm{0}; double totalResidualForcesNorm{0};
double averageResidualForcesNorm{0};
double currentTotalPotentialEnergykN{0}; double currentTotalPotentialEnergykN{0};
double previousTotalPotentialEnergykN{0}; double previousTotalPotentialEnergykN{0};
double residualForcesMovingAverageDerivativeNorm{0}; double residualForcesMovingAverageDerivativeNorm{0};

View File

@ -116,6 +116,16 @@ struct Vector6d : public std::array<double, 6> {
{ {
return Eigen::Vector3d(this->operator[](3), this->operator[](4), this->operator[](5)); return Eigen::Vector3d(this->operator[](3), this->operator[](4), this->operator[](5));
} }
std::string toString() const
{
std::string s;
for (int i = 0; i < 6; i++) {
s.append(std::to_string(this->operator[](i)) + ",");
}
s.pop_back();
return s;
}
}; };
namespace Utilities { namespace Utilities {