Refactoring

This commit is contained in:
iasonmanolas 2021-06-30 10:28:13 +03:00
parent 3e3d32399b
commit a58414892c
6 changed files with 293 additions and 257 deletions

View File

@ -794,7 +794,7 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
// omp_lock_t writelock; // omp_lock_t writelock;
// omp_init_lock(&writelock); // omp_init_lock(&writelock);
#ifdef ENABLE_OPENMP #ifdef ENABLE_OPENMP
#pragma omp parallel for schedule(static) num_threads(8) #pragma omp parallel for schedule(static) num_threads(6)
#endif #endif
for (int ei = 0; ei < pMesh->EN(); ei++) { for (int ei = 0; ei < pMesh->EN(); ei++) {
const EdgeType &e = pMesh->edge[ei]; const EdgeType &e = pMesh->edge[ei];
@ -1151,6 +1151,9 @@ void DRMSimulationModel::updateNodalMasses()
if (shouldTemporarilyDampForces && mCurrentSimulationStep < untilStep) { if (shouldTemporarilyDampForces && mCurrentSimulationStep < untilStep) {
gamma *= 1e6 * (1 - static_cast<double>(mCurrentSimulationStep) / untilStep); gamma *= 1e6 * (1 - static_cast<double>(mCurrentSimulationStep) / untilStep);
} }
if (mCurrentSimulationStep == untilStep && shouldTemporarilyDampForces) {
Dt = mSettings.Dtini * 0.95;
}
for (VertexType &v : pMesh->vert) { for (VertexType &v : pMesh->vert) {
const size_t vi = pMesh->getIndex(v); const size_t vi = pMesh->getIndex(v);
double translationalSumSk = 0; double translationalSumSk = 0;
@ -2037,6 +2040,7 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
applySolutionGuess(solutionGuess, pJob); applySolutionGuess(solutionGuess, pJob);
shouldTemporarilyDampForces = true; shouldTemporarilyDampForces = true;
// Dt = mSettings.Dtini * 0.9;
} }
updateNodalMasses(); updateNodalMasses();
@ -2047,6 +2051,14 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
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)) {
// std::filesystem::create_directory("./PatternOptimizationNonConv");
// pJob->save("./PatternOptimizationNonConv");
// Dt = mSettings.Dtini;
}
if (mCurrentSimulationStep == 500 && shouldTemporarilyDampForces) {
Dt = mSettings.Dtini;
}
// while (true) { // while (true) {
updateNormalDerivatives(); updateNormalDerivatives();
updateT1Derivatives(); updateT1Derivatives();
@ -2144,6 +2156,42 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
break; break;
} }
if (mSettings.shouldCreatePlots && mSettings.isDebugMode
&& mCurrentSimulationStep % mSettings.debugModeStep == 0) {
// SimulationResultsReporter::createPlot("Number of Steps",
// "Residual Forces mov aver deriv",
// movingAveragesDerivatives_norm);
// SimulationResultsReporter::createPlot("Number of Steps",
// "Residual Forces mov aver",
// history.residualForcesMovingAverage);
// SimulationResultsReporter::createPlot("Number of Steps",
// "Log of Residual Forces",
// history.logResidualForces,
// {},
// history.redMarks);
// SimulationResultsReporter::createPlot("Number of Steps",
// "Log of Kinetic energy",
// history.kineticEnergy,
// {},
// history.redMarks);
SimulationResultsReporter reporter;
reporter.reportHistory(history, "IntermediateResults", pJob->pMesh->getLabel());
// SimulationResultsReporter::createPlot("Number of Iterations",
// "Sum of normalized displacement norms",
// history.sumOfNormalizedDisplacementNorms /*,
// std::filesystem::path("./")
// .append("SumOfNormalizedDisplacementNorms_" + graphSuffix + ".png")
// .string()*/
// ,
// {},
// history.redMarks);
// SimulationResultsReporter::createPlot("Number of Steps",
// "Percentage of convergence",
// percentageOfConvergence,
// {},
// history.redMarks);
}
#ifdef POLYSCOPE_DEFINED #ifdef POLYSCOPE_DEFINED
if (mSettings.shouldDraw && mSettings.isDebugMode if (mSettings.shouldDraw && mSettings.isDebugMode
&& mCurrentSimulationStep % mSettings.drawingStep == 0) /* && && mCurrentSimulationStep % mSettings.drawingStep == 0) /* &&
@ -2163,253 +2211,231 @@ currentSimulationStep > maxDRMIterations*/
// shouldUseKineticEnergyThreshold = true; // shouldUseKineticEnergyThreshold = true;
} }
#endif #endif
if (mSettings.shouldCreatePlots && mSettings.isDebugMode
&& mCurrentSimulationStep % mSettings.debugModeStep == 0) { // t = t + Dt;
// SimulationResultsReporter::createPlot("Number of Steps", // std::cout << "Kinetic energy:" << mesh.currentTotalKineticEnergy
// "Residual Forces mov aver deriv", // << std::endl;
// movingAveragesDerivatives_norm); // std::cout << "Residual forces norm:" << mesh.totalResidualForcesNorm
// SimulationResultsReporter::createPlot("Number of Steps", // << std::endl;
// "Residual Forces mov aver", // Residual forces norm convergence
// history.residualForcesMovingAverage); if ((pMesh->previousTotalKineticEnergy > pMesh->currentTotalKineticEnergy
SimulationResultsReporter::createPlot("Number of Steps", // && mCurrentSimulationStep > movingAverageSampleSize
"Log of Residual Forces", && (pJob->nodalForcedDisplacements.empty()
history.logResidualForces, || mCurrentSimulationStep > mSettings.gradualForcedDisplacementSteps))
{}, /* || (pMesh->totalResidualForcesNorm / mSettings.totalResidualForcesNormThreshold <= 1
history.redMarks); && mCurrentSimulationStep > 1)*/
// SimulationResultsReporter::createPlot("Number of Steps", /*||
// "Log of Kinetic energy",
// history.kineticEnergy);
// SimulationResultsReporter reporter;
// reporter.reportHistory(history, "Results");
// SimulationResultsReporter::createPlot("Number of Steps",
// "Percentage of convergence",
// percentageOfConvergence,
// {},
// history.redMarks);
}
// t = t + Dt;
// std::cout << "Kinetic energy:" << mesh.currentTotalKineticEnergy
// << std::endl;
// std::cout << "Residual forces norm:" << mesh.totalResidualForcesNorm
// << std::endl;
// Residual forces norm convergence
if (pMesh->previousTotalKineticEnergy > pMesh->currentTotalKineticEnergy
&& mCurrentSimulationStep > movingAverageSampleSize
&& (pJob->nodalForcedDisplacements.empty()
|| mCurrentSimulationStep > mSettings.gradualForcedDisplacementSteps)
/*||
mesh->previousTotalPotentialEnergykN > mesh->previousTotalPotentialEnergykN >
mesh->currentTotalPotentialEnergykN*/ mesh->currentTotalPotentialEnergykN*/
/*|| mesh->currentTotalPotentialEnergykN < minPotentialEnergy*/) { /*|| mesh->currentTotalPotentialEnergykN < minPotentialEnergy*/) {
// if (pMesh->totalResidualForcesNorm < totalResidualForcesNormThreshold) { // if (pMesh->totalResidualForcesNorm < totalResidualForcesNormThreshold) {
const bool fullfillsKineticEnergyTerminationCriterion const bool fullfillsKineticEnergyTerminationCriterion
= mSettings.shouldUseTranslationalKineticEnergyThreshold = mSettings.shouldUseTranslationalKineticEnergyThreshold
&& pMesh->currentTotalTranslationalKineticEnergy && pMesh->currentTotalTranslationalKineticEnergy
< mSettings.totalTranslationalKineticEnergyThreshold < mSettings.totalTranslationalKineticEnergyThreshold
&& mCurrentSimulationStep > 20 && numOfDampings > 0; && mCurrentSimulationStep > 20 && numOfDampings > 0;
const bool fullfillsResidualForcesNormTerminationCriterion const bool fullfillsResidualForcesNormTerminationCriterion
= pMesh->totalResidualForcesNorm < mSettings.totalResidualForcesNormThreshold; = pMesh->totalResidualForcesNorm < mSettings.totalResidualForcesNormThreshold;
const bool fullfillsMovingAverageNormTerminationCriterion const bool fullfillsMovingAverageNormTerminationCriterion
= pMesh->residualForcesMovingAverage = pMesh->residualForcesMovingAverage
< mSettings.residualForcesMovingAverageNormThreshold; < mSettings.residualForcesMovingAverageNormThreshold;
/*pMesh->residualForcesMovingAverage < totalResidualForcesNormThreshold*/ /*pMesh->residualForcesMovingAverage < totalResidualForcesNormThreshold*/
const bool fullfillsMovingAverageDerivativeNormTerminationCriterion const bool fullfillsMovingAverageDerivativeNormTerminationCriterion
= pMesh->residualForcesMovingAverageDerivativeNorm < 1e-4; = pMesh->residualForcesMovingAverageDerivativeNorm < 1e-4;
const bool shouldTerminate const bool shouldTerminate
= fullfillsKineticEnergyTerminationCriterion = fullfillsKineticEnergyTerminationCriterion
// || fullfillsMovingAverageNormTerminationCriterion // || fullfillsMovingAverageNormTerminationCriterion
// || fullfillsMovingAverageDerivativeNormTerminationCriterion // || fullfillsMovingAverageDerivativeNormTerminationCriterion
|| fullfillsResidualForcesNormTerminationCriterion; || fullfillsResidualForcesNormTerminationCriterion;
if (shouldTerminate) { if (shouldTerminate) {
if (mSettings.beVerbose) { if (mSettings.beVerbose && !mSettings.isDebugMode) {
std::cout << "Simulation converged." << std::endl; std::cout << "Simulation converged." << std::endl;
printCurrentState(); printCurrentState();
if (fullfillsResidualForcesNormTerminationCriterion) { if (fullfillsResidualForcesNormTerminationCriterion) {
std::cout << "Converged using residual forces norm threshold criterion" std::cout << "Converged using residual forces norm threshold criterion"
<< std::endl; << std::endl;
} else if (fullfillsKineticEnergyTerminationCriterion) { } else if (fullfillsKineticEnergyTerminationCriterion) {
std::cout << "Warning: The kinetic energy of the system was " std::cout << "Warning: The kinetic energy of the system was "
" used as a convergence criterion" " used as a convergence criterion"
<< std::endl; << std::endl;
} else if (fullfillsMovingAverageNormTerminationCriterion) { } else if (fullfillsMovingAverageNormTerminationCriterion) {
std::cout << "Converged using residual forces moving average derivative norm " std::cout
"threshold criterion" << "Converged using residual forces moving average derivative norm "
<< std::endl; "threshold criterion"
} << std::endl;
} }
break; }
// } break;
} // }
}
// if (mSettings.beVerbose) { // const bool shouldCapDisplacements = mSettings.displacementCap.has_value();
// printCurrentState(); // for (VertexType &v : pMesh->vert) {
// } // Node &node = pMesh->nodes[v];
// const bool shouldCapDisplacements = mSettings.displacementCap.has_value(); // Vector6d stepDisplacement = node.velocity * Dt;
// for (VertexType &v : pMesh->vert) { // if (shouldCapDisplacements
// Node &node = pMesh->nodes[v]; // && stepDisplacement.getTranslation().norm() > mSettings.displacementCap) {
// Vector6d stepDisplacement = node.velocity * Dt; // stepDisplacement = stepDisplacement
// if (shouldCapDisplacements // * (*mSettings.displacementCap
// && stepDisplacement.getTranslation().norm() > mSettings.displacementCap) { // / stepDisplacement.getTranslation().norm());
// stepDisplacement = stepDisplacement // }
// * (*mSettings.displacementCap // node.displacements = node.displacements - stepDisplacement;
// / stepDisplacement.getTranslation().norm()); // }
// } // applyDisplacements(constrainedVertices);
// node.displacements = node.displacements - stepDisplacement; // if (!pJob->nodalForcedDisplacements.empty()) {
// } // applyForcedDisplacements(
// applyDisplacements(constrainedVertices);
// if (!pJob->nodalForcedDisplacements.empty()) {
// applyForcedDisplacements(
// pJob->nodalForcedDisplacements); // pJob->nodalForcedDisplacements);
// } // }
// updateElementalLengths(); // updateElementalLengths();
// const double triggerPercentage = 0.001; // const double triggerPercentage = 0.01;
// const double xi_min = 0.85; // const double xi_min = 0.55;
// const double xi_init = 0.9969; // const double xi_init = 0.9969;
// if (mSettings.totalResidualForcesNormThreshold / pMesh->totalResidualForcesNorm // if (mSettings.totalResidualForcesNormThreshold / pMesh->totalResidualForcesNorm
// > triggerPercentage) { // > triggerPercentage) {
// mSettings.xi = ((xi_min - xi_init) // mSettings.xi = ((xi_min - xi_init)
// * (mSettings.totalResidualForcesNormThreshold // * (mSettings.totalResidualForcesNormThreshold
// / pMesh->totalResidualForcesNorm) // / pMesh->totalResidualForcesNorm)
// + xi_init - triggerPercentage * xi_min) // + xi_init - triggerPercentage * xi_min)
// / (1 - triggerPercentage); // / (1 - triggerPercentage);
// } // }
Dt *= mSettings.xi; Dt *= mSettings.xi;
resetVelocities(); // if (mSettings.isDebugMode) {
++numOfDampings; // std::cout << Dt << std::endl;
if (mSettings.shouldCreatePlots) { // }
history.redMarks.push_back(mCurrentSimulationStep); resetVelocities();
} ++numOfDampings;
// std::cout << "Number of dampings:" << numOfDampings << endl; if (mSettings.shouldCreatePlots) {
// draw(); history.redMarks.push_back(mCurrentSimulationStep);
} }
// std::cout << "Number of dampings:" << numOfDampings << endl;
// draw();
}
} }
SimulationResults results = computeResults(pJob); SimulationResults results = computeResults(pJob);
if (mCurrentSimulationStep == settings.maxDRMIterations && mCurrentSimulationStep != 0) { if (mCurrentSimulationStep == settings.maxDRMIterations && mCurrentSimulationStep != 0) {
std::cout << "Did not reach equilibrium before reaching the maximum number " if (mSettings.beVerbose) {
"of DRM steps (" std::cout << "Did not reach equilibrium before reaching the maximum number "
<< settings.maxDRMIterations << "). Breaking simulation" << std::endl; "of DRM steps ("
results.converged = false; << settings.maxDRMIterations << "). Breaking simulation" << std::endl;
} else if (std::isnan(pMesh->currentTotalKineticEnergy)) { }
std::cerr << "Simulation did not converge due to infinite kinetic energy." << std::endl; results.converged = false;
results.converged = false; } else if (std::isnan(pMesh->currentTotalKineticEnergy)) {
if (mSettings.beVerbose) {
} else if (mSettings.beVerbose) { std::cerr << "Simulation did not converge due to infinite kinetic energy." << std::endl;
auto t2 = std::chrono::high_resolution_clock::now(); }
double simulationDuration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1) results.converged = false;
.count(); }
simulationDuration /= 1000; // mesh.printVertexCoordinates(mesh.VN() / 2);
std::cout << "Simulation converged after " << simulationDuration << "s" << std::endl;
std::cout << "Time/(node*iteration) "
<< simulationDuration / (static_cast<double>(mCurrentSimulationStep) * pMesh->VN())
<< "s" << std::endl;
std::cout << "Number of dampings:" << numOfDampings << endl;
std::cout << "Number of steps:" << mCurrentSimulationStep << endl;
}
// mesh.printVertexCoordinates(mesh.VN() / 2);
#ifdef POLYSCOPE_DEFINED #ifdef POLYSCOPE_DEFINED
if (settings.shouldDraw) { if (mSettings.shouldDraw && !mSettings.isDebugMode) {
draw(); draw();
} }
#endif #endif
if (results.converged) { if (!std::isnan(pMesh->currentTotalKineticEnergy)) {
results.debug_drmDisplacements = results.displacements; results.debug_drmDisplacements = results.displacements;
results.internalPotentialEnergy = computeTotalInternalPotentialEnergy(); results.internalPotentialEnergy = computeTotalInternalPotentialEnergy();
results.rotationalDisplacementQuaternion.resize(pMesh->VN()); results.rotationalDisplacementQuaternion.resize(pMesh->VN());
results.debug_q_f1.resize(pMesh->VN()); results.debug_q_f1.resize(pMesh->VN());
results.debug_q_normal.resize(pMesh->VN()); results.debug_q_normal.resize(pMesh->VN());
results.debug_q_nr.resize(pMesh->VN()); results.debug_q_nr.resize(pMesh->VN());
for (int vi = 0; vi < pMesh->VN(); vi++) { for (int vi = 0; vi < pMesh->VN(); vi++) {
const Node &node = pMesh->nodes[vi]; const Node &node = pMesh->nodes[vi];
const Eigen::Vector3d nInitial_eigen = node.initialNormal.ToEigenVector<Eigen::Vector3d>(); const Eigen::Vector3d nInitial_eigen = node.initialNormal
const Eigen::Vector3d nDeformed_eigen .ToEigenVector<Eigen::Vector3d>();
= pMesh->vert[vi].cN().ToEigenVector<Eigen::Vector3d>(); const Eigen::Vector3d nDeformed_eigen
= pMesh->vert[vi].cN().ToEigenVector<Eigen::Vector3d>();
Eigen::Quaternion<double> q_normal; Eigen::Quaternion<double> q_normal;
q_normal.setFromTwoVectors(nInitial_eigen, nDeformed_eigen); q_normal.setFromTwoVectors(nInitial_eigen, nDeformed_eigen);
Eigen::Quaternion<double> q_nr_nDeformed; Eigen::Quaternion<double> q_nr_nDeformed;
q_nr_nDeformed = Eigen::AngleAxis<double>(pMesh->nodes[vi].nR, nDeformed_eigen); q_nr_nDeformed = Eigen::AngleAxis<double>(pMesh->nodes[vi].nR, nDeformed_eigen);
Eigen::Quaternion<double> q_nr_nInit; Eigen::Quaternion<double> q_nr_nInit;
q_nr_nInit = Eigen::AngleAxis<double>(pMesh->nodes[vi].nR, nInitial_eigen); q_nr_nInit = Eigen::AngleAxis<double>(pMesh->nodes[vi].nR, nInitial_eigen);
const auto w = q_nr_nDeformed.w(); const auto w = q_nr_nDeformed.w();
const auto theta = 2 * acos(q_nr_nDeformed.w()); const auto theta = 2 * acos(q_nr_nDeformed.w());
const auto nr = pMesh->nodes[vi].nR; const auto nr = pMesh->nodes[vi].nR;
Eigen::Vector3d deformedNormal_debug(q_nr_nDeformed.x() * sin(theta / 2), Eigen::Vector3d deformedNormal_debug(q_nr_nDeformed.x() * sin(theta / 2),
q_nr_nDeformed.y() * sin(theta / 2), q_nr_nDeformed.y() * sin(theta / 2),
q_nr_nDeformed.z() * sin(theta / 2)); q_nr_nDeformed.z() * sin(theta / 2));
deformedNormal_debug.normalize(); deformedNormal_debug.normalize();
// const double nr = nr_0To2pi <= M_PI ? nr_0To2pi : (nr_0To2pi - 2 * M_PI); // const double nr = nr_0To2pi <= M_PI ? nr_0To2pi : (nr_0To2pi - 2 * M_PI);
const double nr_debug = deformedNormal_debug.dot(nDeformed_eigen) > 0 ? theta : -theta; const double nr_debug = deformedNormal_debug.dot(nDeformed_eigen) > 0 ? theta : -theta;
assert(pMesh->nodes[vi].nR - nr_debug < 1e-6); assert(pMesh->nodes[vi].nR - nr_debug < 1e-6);
VectorType referenceT1_deformed = pMesh->elements[node.referenceElement].frame.t1; VectorType referenceT1_deformed = pMesh->elements[node.referenceElement].frame.t1;
const VectorType &nDeformed = pMesh->vert[vi].cN(); const VectorType &nDeformed = pMesh->vert[vi].cN();
const VectorType referenceF1_deformed = (referenceT1_deformed const VectorType referenceF1_deformed
- (node.initialNormal = (referenceT1_deformed
* (referenceT1_deformed * node.initialNormal))) - (node.initialNormal * (referenceT1_deformed * node.initialNormal)))
.Normalize(); .Normalize();
const VectorType referenceT1_initial const VectorType referenceT1_initial
= computeT1Vector(pMesh->nodes[node.referenceElement->cV(0)].initialLocation, = computeT1Vector(pMesh->nodes[node.referenceElement->cV(0)].initialLocation,
pMesh->nodes[node.referenceElement->cV(1)].initialLocation); pMesh->nodes[node.referenceElement->cV(1)].initialLocation);
// const VectorType &n_initial = node.initialNormal; // const VectorType &n_initial = node.initialNormal;
const VectorType referenceF1_initial = (referenceT1_initial const VectorType referenceF1_initial = (referenceT1_initial
- (node.initialNormal - (node.initialNormal
* (referenceT1_initial * node.initialNormal))) * (referenceT1_initial * node.initialNormal)))
.Normalize(); .Normalize();
Eigen::Quaternion<double> q_f1_nInit; //nr is with respect to f1 Eigen::Quaternion<double> q_f1_nInit; //nr is with respect to f1
q_f1_nInit.setFromTwoVectors(referenceF1_initial.ToEigenVector<Eigen::Vector3d>(), q_f1_nInit.setFromTwoVectors(referenceF1_initial.ToEigenVector<Eigen::Vector3d>(),
referenceF1_deformed.ToEigenVector<Eigen::Vector3d>()); referenceF1_deformed.ToEigenVector<Eigen::Vector3d>());
Eigen::Quaternion<double> q_f1_nDeformed; //nr is with respect to f1 Eigen::Quaternion<double> q_f1_nDeformed; //nr is with respect to f1
// const VectorType &n_initial = node.initialNormal; // const VectorType &n_initial = node.initialNormal;
const VectorType referenceF1_initial_def const VectorType referenceF1_initial_def
= (referenceT1_initial - (nDeformed * (referenceT1_initial * nDeformed))).Normalize(); = (referenceT1_initial - (nDeformed * (referenceT1_initial * nDeformed))).Normalize();
const VectorType referenceF1_deformed_def const VectorType referenceF1_deformed_def = (referenceT1_deformed
= (referenceT1_deformed - (nDeformed * (referenceT1_deformed * nDeformed))).Normalize(); - (nDeformed
q_f1_nDeformed.setFromTwoVectors(referenceF1_initial_def.ToEigenVector<Eigen::Vector3d>(), * (referenceT1_deformed * nDeformed)))
referenceF1_deformed_def.ToEigenVector<Eigen::Vector3d>()); .Normalize();
const auto debug_qf1_nDef = (q_f1_nDeformed * q_nr_nDeformed) * nDeformed_eigen; q_f1_nDeformed
const auto debug_qf1_nInit = (q_f1_nInit * q_nr_nInit) * nInitial_eigen; .setFromTwoVectors(referenceF1_initial_def.ToEigenVector<Eigen::Vector3d>(),
const auto debug_deformedNormal_f1Init = (q_normal * (q_f1_nInit * q_nr_nInit)) referenceF1_deformed_def.ToEigenVector<Eigen::Vector3d>());
* nInitial_eigen; const auto debug_qf1_nDef = (q_f1_nDeformed * q_nr_nDeformed) * nDeformed_eigen;
const auto debug_deformedNormal_f1Def = ((q_nr_nDeformed * q_f1_nDeformed) * q_normal) const auto debug_qf1_nInit = (q_f1_nInit * q_nr_nInit) * nInitial_eigen;
* nInitial_eigen; const auto debug_deformedNormal_f1Init = (q_normal * (q_f1_nInit * q_nr_nInit))
// Eigen::Quaternion<double> q_t1; * nInitial_eigen;
// q_t1.setFromTwoVectors(referenceT1_initial.ToEigenVector<Eigen::Vector3d>(), const auto debug_deformedNormal_f1Def = ((q_nr_nDeformed * q_f1_nDeformed) * q_normal)
// referenceT1_deformed.ToEigenVector<Eigen::Vector3d>()); * nInitial_eigen;
// Eigen::Quaternion<double> q_t1;
// q_t1.setFromTwoVectors(referenceT1_initial.ToEigenVector<Eigen::Vector3d>(),
// referenceT1_deformed.ToEigenVector<Eigen::Vector3d>());
results.debug_q_f1[vi] = q_f1_nInit; results.debug_q_f1[vi] = q_f1_nInit;
results.debug_q_normal[vi] = q_normal; results.debug_q_normal[vi] = q_normal;
results.debug_q_nr[vi] = q_nr_nInit; results.debug_q_nr[vi] = q_nr_nInit;
results.rotationalDisplacementQuaternion[vi] results.rotationalDisplacementQuaternion[vi]
= (q_normal * (q_f1_nInit * q_nr_nInit)); //q_f1_nDeformed * q_nr_nDeformed * q_normal; = (q_normal
//Update the displacement vector to contain the euler angles * (q_f1_nInit * q_nr_nInit)); //q_f1_nDeformed * q_nr_nDeformed * q_normal;
const Eigen::Vector3d eulerAngles //Update the displacement vector to contain the euler angles
= results.rotationalDisplacementQuaternion[vi].toRotationMatrix().eulerAngles(0, 1, 2); const Eigen::Vector3d eulerAngles = results.rotationalDisplacementQuaternion[vi]
results.displacements[vi][3] = eulerAngles[0]; .toRotationMatrix()
results.displacements[vi][4] = eulerAngles[1]; .eulerAngles(0, 1, 2);
results.displacements[vi][5] = eulerAngles[2]; results.displacements[vi][3] = eulerAngles[0];
results.displacements[vi][4] = eulerAngles[1];
results.displacements[vi][5] = eulerAngles[2];
// Eigen::Quaterniond q_test = Eigen::AngleAxisd(eulerAngles[0], Eigen::Vector3d::UnitX()) // Eigen::Quaterniond q_test = Eigen::AngleAxisd(eulerAngles[0], Eigen::Vector3d::UnitX())
// * Eigen::AngleAxisd(eulerAngles[1], Eigen::Vector3d::UnitY()) // * Eigen::AngleAxisd(eulerAngles[1], Eigen::Vector3d::UnitY())
// * Eigen::AngleAxisd(eulerAngles[2], Eigen::Vector3d::UnitZ()); // * Eigen::AngleAxisd(eulerAngles[2], Eigen::Vector3d::UnitZ());
// const double dot_test = results.rotationalDisplacementQuaternion[vi].dot(q_test); // const double dot_test = results.rotationalDisplacementQuaternion[vi].dot(q_test);
// assert(dot_test > 1 - 1e5); // assert(dot_test > 1 - 1e5);
int i = 0; int i = 0;
i++; i++;
} }
} }
if (mSettings.shouldCreatePlots && results.converged) { if (!mSettings.isDebugMode && mSettings.shouldCreatePlots) {
SimulationResultsReporter reporter; SimulationResultsReporter reporter;
reporter.reportResults({results}, "Results", pJob->pMesh->getLabel()); reporter.reportResults({results}, "Results", pJob->pMesh->getLabel());
} }
return results; return results;
} }

View File

@ -31,8 +31,7 @@ public:
bool beVerbose{false}; bool beVerbose{false};
bool shouldCreatePlots{false}; bool shouldCreatePlots{false};
int drawingStep{1}; int drawingStep{1};
double totalTranslationalKineticEnergyThreshold{1e-10}; double totalTranslationalKineticEnergyThreshold{1e-8};
double totalExternalForcesNormPercentageTermination{1e-3};
double residualForcesMovingAverageDerivativeNormThreshold{1e-8}; double residualForcesMovingAverageDerivativeNormThreshold{1e-8};
double residualForcesMovingAverageNormThreshold{1e-8}; double residualForcesMovingAverageNormThreshold{1e-8};
double Dtini{0.1}; double Dtini{0.1};

View File

@ -254,7 +254,8 @@ struct Colors
{ {
std::string label{"EmptyLabel"}; std::string label{"EmptyLabel"};
double time{-1}; double time{-1};
int numberOfSimulationCrashes{0}; bool wasSuccessful{true};
// int numberOfSimulationCrashes{0};
Settings settings; Settings settings;
struct ObjectiveValues struct ObjectiveValues
{ {
@ -273,6 +274,7 @@ struct Colors
PatternGeometry baseTriangleFullPattern; //non-fanned,non-tiled full pattern PatternGeometry baseTriangleFullPattern; //non-fanned,non-tiled full pattern
vcg::Triangle3<double> baseTriangle; vcg::Triangle3<double> baseTriangle;
std::string notes;
struct JsonKeys struct JsonKeys
{ {
@ -294,15 +296,19 @@ struct Colors
//Save optimal X //Save optimal X
nlohmann::json json_optimizationResults; nlohmann::json json_optimizationResults;
json_optimizationResults[JsonKeys::Label] = label; json_optimizationResults[JsonKeys::Label] = label;
std::string jsonValue_optimizationVariables; if (wasSuccessful) {
for (const auto &optimalXNameValuePair : optimalXNameValuePairs) { std::string jsonValue_optimizationVariables;
jsonValue_optimizationVariables.append(optimalXNameValuePair.first + ","); for (const auto &optimalXNameValuePair : optimalXNameValuePairs) {
} jsonValue_optimizationVariables.append(optimalXNameValuePair.first + ",");
jsonValue_optimizationVariables.pop_back(); // for deleting the last comma }
json_optimizationResults[JsonKeys::optimizationVariables] = jsonValue_optimizationVariables; jsonValue_optimizationVariables.pop_back(); // for deleting the last comma
json_optimizationResults[JsonKeys::optimizationVariables]
= jsonValue_optimizationVariables;
for (const auto &optimalXNameValuePair : optimalXNameValuePairs) { for (const auto &optimalXNameValuePair : optimalXNameValuePairs) {
json_optimizationResults[optimalXNameValuePair.first] = optimalXNameValuePair.second; json_optimizationResults[optimalXNameValuePair.first] = optimalXNameValuePair
.second;
}
} }
//base triangle //base triangle
json_optimizationResults[JsonKeys::baseTriangle] json_optimizationResults[JsonKeys::baseTriangle]
@ -650,7 +656,8 @@ struct Colors
os << nameValuePair.first; os << nameValuePair.first;
} }
os << "Time(s)"; os << "Time(s)";
os << "#Crashes"; // os << "#Crashes";
// os << "notes";
} }
void writeResultsTo(const Settings &settings_optimization, csvFile &os) const void writeResultsTo(const Settings &settings_optimization, csvFile &os) const
@ -669,11 +676,12 @@ struct Colors
} }
os << time; os << time;
if (numberOfSimulationCrashes == 0) { // if (numberOfSimulationCrashes == 0) {
os << "-"; // os << "-";
} else { // } else {
os << numberOfSimulationCrashes; // os << numberOfSimulationCrashes;
} // }
// os << notes;
} }
}; };

View File

@ -63,7 +63,7 @@ struct SimulationResultsReporter {
const std::string &graphSuffix = std::string()) const std::string &graphSuffix = std::string())
{ {
const auto simulationResultPath = std::filesystem::path(reportFolderPath).append(history.label); const auto simulationResultPath = std::filesystem::path(reportFolderPath).append(history.label);
std::filesystem::create_directory(simulationResultPath); std::filesystem::create_directories(simulationResultPath);
createPlots(history, simulationResultPath, graphSuffix); createPlots(history, simulationResultPath, graphSuffix);
} }

View File

@ -177,7 +177,12 @@ void TopologyEnumerator::computeValidPatterns(const std::vector<size_t> &reduced
auto perEdgeResultPath = std::filesystem::path(resultsPath) auto perEdgeResultPath = std::filesystem::path(resultsPath)
.append(std::to_string(numberOfEdges)); .append(std::to_string(numberOfEdges));
if (std::filesystem::exists(perEdgeResultPath)) { if (std::filesystem::exists(perEdgeResultPath)) {
continue; if (debugIsOn) {
std::filesystem::remove_all(perEdgeResultPath);
} else {
continue;
}
} }
std::filesystem::create_directory(perEdgeResultPath); std::filesystem::create_directory(perEdgeResultPath);
computeValidPatterns(numberOfNodesPerSlot, computeValidPatterns(numberOfNodesPerSlot,
@ -517,8 +522,7 @@ void TopologyEnumerator::computeValidPatterns(
// Check dangling edges with vcg method // Check dangling edges with vcg method
// const bool vcg_tiledPatternHasDangling = // const bool vcg_tiledPatternHasDangling =
// tiledPatternGeometry.hasUntiledDanglingEdges(); // tiledPatternGeometry.hasUntiledDanglingEdges();
if (tiledPatternHasDanglingEdges /*&& !hasFloatingComponents && if (tiledPatternHasDanglingEdges && !hasFloatingComponents /*&& !hasArticulationPoints*/) {
!hasArticulationPoints*/) {
statistics.numberOfPatternsWithADanglingEdgeOrNode++; statistics.numberOfPatternsWithADanglingEdgeOrNode++;
if (debugIsOn) { if (debugIsOn) {
if (savePlyFiles) { if (savePlyFiles) {
@ -539,8 +543,7 @@ void TopologyEnumerator::computeValidPatterns(
} }
} }
if (hasFloatingComponents /*&& !hasArticulationPoints && if (hasFloatingComponents && !hasArticulationPoints && !tiledPatternHasDanglingEdges) {
!tiledPatternHasDanglingEdges*/) {
statistics.numberOfPatternsWithMoreThanASingleCC++; statistics.numberOfPatternsWithMoreThanASingleCC++;
if (debugIsOn) { if (debugIsOn) {
if (savePlyFiles) { if (savePlyFiles) {

View File

@ -15,12 +15,12 @@ bool VCGTriMesh::load(const std::string &filename) {
mask |= nanoply::NanoPlyWrapper<VCGTriMesh>::IO_EDGEINDEX; mask |= nanoply::NanoPlyWrapper<VCGTriMesh>::IO_EDGEINDEX;
mask |= nanoply::NanoPlyWrapper<VCGTriMesh>::IO_FACEINDEX; mask |= nanoply::NanoPlyWrapper<VCGTriMesh>::IO_FACEINDEX;
if (nanoply::NanoPlyWrapper<VCGTriMesh>::LoadModel( // if (nanoply::NanoPlyWrapper<VCGTriMesh>::LoadModel(
std::filesystem::absolute(filename).string().c_str(), *this, mask) // std::filesystem::absolute(filename).string().c_str(), *this, mask)
// != 0) {
if (vcg::tri::io::Importer<VCGTriMesh>::Open(*this,
std::filesystem::absolute(filename).string().c_str())
!= 0) { != 0) {
// if (vcg::tri::io::Importer<VCGTriMesh>::Open(*this,
// std::filesystem::absolute(filename).string().c_str())
// != 0) {
std::cout << "Could not load tri mesh" << std::endl; std::cout << "Could not load tri mesh" << std::endl;
return false; return false;
} }