Refactoring

This commit is contained in:
iasonmanolas 2021-07-12 23:53:04 +03:00
parent 2509b0a795
commit 5ebf354dcf
4 changed files with 156 additions and 91 deletions

View File

@ -640,6 +640,9 @@ double DRMSimulationModel::computeDerivativeTheta3(const EdgeType &e,
? node.derivativeOfNormal[dui.dofi] ? node.derivativeOfNormal[dui.dofi]
: VectorType(0, 0, 0); : VectorType(0, 0, 0);
derivativeTheta3_dofi = derivativeG1 * n + g1 * derivativeNormal; derivativeTheta3_dofi = derivativeG1 * n + g1 * derivativeNormal;
if (std::isnan(derivativeTheta3_dofi)) {
std::cerr << "nan derivative theta3 rigid" << std::endl;
}
return derivativeTheta3_dofi; return derivativeTheta3_dofi;
} }
EdgeType &refElem = *node.referenceElement; EdgeType &refElem = *node.referenceElement;
@ -718,6 +721,9 @@ double DRMSimulationModel::computeDerivativeTheta3(const EdgeType &e,
derivativeTheta3_dofi = derivativeF3 * n + f3 * derivativeOfNormal; derivativeTheta3_dofi = derivativeF3 * n + f3 * derivativeOfNormal;
} }
} }
if (std::isnan(derivativeTheta3_dofi)) {
std::cerr << "nan derivative theta3" << std::endl;
}
return derivativeTheta3_dofi; return derivativeTheta3_dofi;
} }
@ -794,9 +800,9 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
pMesh->EN(), std::vector<std::pair<int, Vector6d>>(4, {-1, Vector6d()})); pMesh->EN(), std::vector<std::pair<int, Vector6d>>(4, {-1, Vector6d()}));
// 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(6) //#pragma omp parallel for schedule(static) num_threads(8)
#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];
const SimulationMesh::VertexType &ev_j = *e.cV(0); const SimulationMesh::VertexType &ev_j = *e.cV(0);
@ -846,6 +852,12 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
const double e_kDeriv = computeDerivativeElementLength(e, dui); const double e_kDeriv = computeDerivativeElementLength(e, dui);
const double axialForce_dofi = e_kDeriv * e_k * element.rigidity.axial; const double axialForce_dofi = e_kDeriv * e_k * element.rigidity.axial;
#ifdef POLYSCOPE_DEFINED
if (std::isnan(axialForce_dofi)) {
std::cerr << "nan in axial" << evi << std::endl;
}
#endif
// Torsional force computation // Torsional force computation
const double theta1_j_deriv = computeDerivativeTheta1(e, 0, evi, dofi); const double theta1_j_deriv = computeDerivativeTheta1(e, 0, evi, dofi);
const double theta1_jplus1_deriv = computeDerivativeTheta1(e, 1, evi, dofi); const double theta1_jplus1_deriv = computeDerivativeTheta1(e, 1, evi, dofi);
@ -853,6 +865,11 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
const double theta1DiffDerivative = theta1_jplus1_deriv - theta1_j_deriv; const double theta1DiffDerivative = theta1_jplus1_deriv - theta1_j_deriv;
const double torsionalForce_dofi = theta1DiffDerivative * theta1Diff const double torsionalForce_dofi = theta1DiffDerivative * theta1Diff
* element.rigidity.torsional; * element.rigidity.torsional;
#ifdef POLYSCOPE_DEFINED
if (std::isnan(torsionalForce_dofi)) {
std::cerr << "nan in torsional" << evi << std::endl;
}
#endif
// First bending force computation // First bending force computation
////theta2_j derivative ////theta2_j derivative
@ -970,6 +987,11 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
Node::Forces &force = pMesh->nodes[vi].force; Node::Forces &force = pMesh->nodes[vi].force;
force.internal = force.internal + internalForcePair.second; force.internal = force.internal + internalForcePair.second;
force.residual = force.residual + (internalForcePair.second * -1); force.residual = force.residual + (internalForcePair.second * -1);
#ifdef POLYSCOPE_DEFINED
if (std::isnan(internalForcePair.second.norm())) {
std::cerr << "nan on edge" << ei << std::endl;
}
#endif
} }
} }
double totalResidualForcesNorm = 0; double totalResidualForcesNorm = 0;
@ -982,6 +1004,11 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
// const double residualForceNorm = nodeResidualForce.getTranslation().norm(); // const double residualForceNorm = nodeResidualForce.getTranslation().norm();
const bool shouldTrigger = std::isnan(residualForceNorm); const bool shouldTrigger = std::isnan(residualForceNorm);
totalResidualForcesNorm += residualForceNorm; totalResidualForcesNorm += residualForceNorm;
#ifdef POLYSCOPE_DEFINED
if (std::isnan(force.residual.norm())) {
std::cout << "residual " << vi << ":" << force.residual.toString() << std::endl;
}
#endif
} }
pMesh->previousTotalResidualForcesNorm = pMesh->totalResidualForcesNorm; pMesh->previousTotalResidualForcesNorm = pMesh->totalResidualForcesNorm;
pMesh->totalResidualForcesNorm = totalResidualForcesNorm; pMesh->totalResidualForcesNorm = totalResidualForcesNorm;
@ -1218,6 +1245,11 @@ void DRMSimulationModel::updateNodalAccelerations()
node.acceleration[dofi] = node.force.residual[dofi] / node.mass.rotationalI2; node.acceleration[dofi] = node.force.residual[dofi] / node.mass.rotationalI2;
} }
} }
#ifdef POLYSCOPE_DEFINED
if (std::isnan(node.acceleration.norm())) {
std::cout << "acceleration " << vi << ":" << node.acceleration.toString() << std::endl;
}
#endif
// if (vi == 10) { // if (vi == 10) {
// std::cout << "Acceleration:" << node.acceleration[0] << " " << node.acceleration[1] // std::cout << "Acceleration:" << node.acceleration[0] << " " << node.acceleration[1]
// << " " << node.acceleration[2] << std::endl; // << " " << node.acceleration[2] << std::endl;
@ -1234,10 +1266,12 @@ void DRMSimulationModel::updateNodalVelocities()
for (VertexType &v : pMesh->vert) { for (VertexType &v : pMesh->vert) {
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; #ifdef POLYSCOPE_DEFINED
if (std::isnan(node.velocity.norm())) { if (std::isnan(node.velocity.norm())) {
std::cout << "Velocity:" << node.velocity.toString() << std::endl; std::cout << "Velocity " << vi << ":" << node.velocity.toString() << std::endl;
} }
#endif
node.velocity = node.velocity + node.acceleration * Dt;
} }
updateKineticEnergy(); updateKineticEnergy();
} }
@ -1609,6 +1643,11 @@ void DRMSimulationModel::printCurrentState() const
{ {
std::cout << "Simulation steps executed:" << mCurrentSimulationStep << std::endl; std::cout << "Simulation steps executed:" << mCurrentSimulationStep << std::endl;
std::cout << "Residual forces norm: " << pMesh->totalResidualForcesNorm << std::endl; std::cout << "Residual forces norm: " << pMesh->totalResidualForcesNorm << std::endl;
std::cout << "Average Residual forces norm/extForcesNorm: "
<< pMesh->totalResidualForcesNorm / pMesh->VN() / pMesh->totalExternalForcesNorm
<< std::endl;
std::cout << "Moving average residual forces:" << pMesh->residualForcesMovingAverage
<< std::endl;
std::cout << "Kinetic energy:" << pMesh->currentTotalKineticEnergy << std::endl; std::cout << "Kinetic energy:" << pMesh->currentTotalKineticEnergy << std::endl;
static std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); static std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
const auto timePerNodePerIteration = std::chrono::duration_cast<std::chrono::microseconds>( const auto timePerNodePerIteration = std::chrono::duration_cast<std::chrono::microseconds>(
@ -1758,8 +1797,7 @@ void DRMSimulationModel::draw(const std::string &screenshotsFolder)
polyscope::getCurveNetwork(meshPolyscopeLabel)->addEdgeScalarQuantity("J", J); polyscope::getCurveNetwork(meshPolyscopeLabel)->addEdgeScalarQuantity("J", J);
polyscope::getCurveNetwork(meshPolyscopeLabel) polyscope::getCurveNetwork(meshPolyscopeLabel)
->addEdgeScalarQuantity("I2", I2); ->addEdgeScalarQuantity("I2", I2);
polyscope::getCurveNetwork(meshPolyscopeLabel) polyscope::getCurveNetwork(meshPolyscopeLabel)->addEdgeScalarQuantity("I3", I3);
->addEdgeScalarQuantity("I3", I3);
// Specify the callback // Specify the callback
static bool calledOnce = false; static bool calledOnce = false;
@ -1798,9 +1836,8 @@ void DRMSimulationModel::draw(const std::string &screenshotsFolder)
.append(std::to_string(mCurrentSimulationStep) + ".png") .append(std::to_string(mCurrentSimulationStep) + ".png")
.string(), .string(),
false); false);
} else {
polyscope::show();
} }
polyscope::show();
} }
#endif #endif
@ -1873,6 +1910,9 @@ void DRMSimulationModel::applySolutionGuess(const SimulationResults &solutionGue
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 = q_f1.inverse() * q_normal.inverse() * q; Eigen::Quaternion<double> q_nr = q_f1.inverse() * q_normal.inverse() * q;
q_nr.w() = q_nr.w() >= 1 ? 1 : q_nr.w();
q_nr.w() = q_nr.w() <= -1 ? -1 : q_nr.w();
const double nr_0To2pi_pos = 2 * std::acos(q_nr.w()); const double nr_0To2pi_pos = 2 * std::acos(q_nr.w());
// const double nr_0To2pi_groundOfTruth = 2 * std::acos(solutionGuess.debug_q_nr[vi].w()); // const double nr_0To2pi_groundOfTruth = 2 * std::acos(solutionGuess.debug_q_nr[vi].w());
const double nr_0To2pi = nr_0To2pi_pos <= M_PI ? nr_0To2pi_pos : (nr_0To2pi_pos - 2 * M_PI); const double nr_0To2pi = nr_0To2pi_pos <= M_PI ? nr_0To2pi_pos : (nr_0To2pi_pos - 2 * M_PI);
@ -1880,6 +1920,16 @@ void DRMSimulationModel::applySolutionGuess(const SimulationResults &solutionGue
q_nr.y() * sin(nr_0To2pi_pos / 2), q_nr.y() * sin(nr_0To2pi_pos / 2),
q_nr.z() * sin(nr_0To2pi_pos / 2)); q_nr.z() * sin(nr_0To2pi_pos / 2));
/*deformedNormal_debug =*/deformedNormal_debug.normalize(); /*deformedNormal_debug =*/deformedNormal_debug.normalize();
#ifdef POLYSCOPE_DEFINED
if (std::isnan(deformedNormal_debug.norm())) {
std::cerr << "nr_0To2pi_pos:" << nr_0To2pi_pos << std::endl;
std::cerr << "q_nrx:" << q_nr.x() << std::endl;
std::cerr << "q_nry:" << q_nr.y() << std::endl;
std::cerr << "q_nrz:" << q_nr.z() << std::endl;
std::cerr << "q_nrw:" << q_nr.w() << std::endl;
std::cerr << "nan deformedNormal in guess" << std::endl;
}
#endif
const double nr = deformedNormal_debug.dot(nDeformed_eigen) > 0 ? nr_0To2pi : -nr_0To2pi; const double nr = deformedNormal_debug.dot(nDeformed_eigen) > 0 ? nr_0To2pi : -nr_0To2pi;
if (!pJob->constrainedVertices.contains(vi) if (!pJob->constrainedVertices.contains(vi)
|| !pJob->constrainedVertices.at(vi).contains(5)) { || !pJob->constrainedVertices.at(vi).contains(5)) {
@ -2006,6 +2056,9 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
polyscope::registerCurveNetwork(meshPolyscopeLabel, polyscope::registerCurveNetwork(meshPolyscopeLabel,
pMesh->getEigenVertices(), pMesh->getEigenVertices(),
pMesh->getEigenEdges()); pMesh->getEigenEdges());
polyscope::registerCurveNetwork("Initial_" + meshPolyscopeLabel,
pMesh->getEigenVertices(),
pMesh->getEigenEdges());
// registerWorldAxes(); // registerWorldAxes();
} }
#endif #endif
@ -2039,15 +2092,11 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
totalExternalForcesNorm += nodalForce.second.norm(); totalExternalForcesNorm += nodalForce.second.norm();
// sumOfExternalForces = sumOfExternalForces + nodalForce.second; // sumOfExternalForces = sumOfExternalForces + nodalForce.second;
} }
pMesh->totalExternalForcesNorm = totalExternalForcesNorm;
updateNodalExternalForces(nodalExternalForces, constrainedVertices); updateNodalExternalForces(nodalExternalForces, constrainedVertices);
double averageExternalForcesNorm =
// sumOfExternalForces.norm() / pMesh->VN();
totalExternalForcesNorm / pMesh->VN();
if (!nodalExternalForces.empty()) { if (!nodalExternalForces.empty()) {
mSettings.totalResidualForcesNormThreshold mSettings.totalResidualForcesNormThreshold
= std::min(settings.totalExternalForcesNormPercentageTermination = settings.totalExternalForcesNormPercentageTermination * totalExternalForcesNorm;
* totalExternalForcesNorm,
1e-3);
} else { } else {
mSettings.totalResidualForcesNormThreshold = 1e-3; mSettings.totalResidualForcesNormThreshold = 1e-3;
std::cout << "No forces setted default residual forces norm threshold" << std::endl; std::cout << "No forces setted default residual forces norm threshold" << std::endl;
@ -2055,9 +2104,13 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
if (mSettings.beVerbose) { if (mSettings.beVerbose) {
std::cout << "totalResidualForcesNormThreshold:" std::cout << "totalResidualForcesNormThreshold:"
<< mSettings.totalResidualForcesNormThreshold << std::endl; << mSettings.totalResidualForcesNormThreshold << std::endl;
if (mSettings.useAverage) {
std::cout << "average/extNorm threshold:"
<< mSettings.averageResidualForcesCriterionThreshold << std::endl;
}
} }
// const size_t movingAverageSampleSize = 200; const size_t movingAverageSampleSize = 200;
// std::queue<double> residualForcesMovingAverageHistorySample; std::queue<double> residualForcesMovingAverageHistorySample;
std::vector<double> percentageOfConvergence; std::vector<double> percentageOfConvergence;
// double residualForcesMovingAverageDerivativeMax = 0; // double residualForcesMovingAverageDerivativeMax = 0;
@ -2107,37 +2160,40 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
break; break;
} }
//normalized sum of displacements
// double sumOfDisplacementsNorm = 0; // double sumOfDisplacementsNorm = 0;
// for (size_t vi = 0; vi < pMesh->VN(); vi++) { // for (size_t vi = 0; vi < pMesh->VN(); vi++) {
// sumOfDisplacementsNorm += pMesh->nodes[vi].displacements.getTranslation().norm(); // sumOfDisplacementsNorm += pMesh->nodes[vi].displacements.getTranslation().norm();
// } // }
// sumOfDisplacementsNorm /= pMesh->bbox.Diag(); // sumOfDisplacementsNorm /= pMesh->bbox.Diag();
// pMesh->sumOfNormalizedDisplacementNorms = sumOfDisplacementsNorm; // pMesh->sumOfNormalizedDisplacementNorms = sumOfDisplacementsNorm;
//moving average
// // pMesh->residualForcesMovingAverage = (pMesh->totalResidualForcesNorm // // pMesh->residualForcesMovingAverage = (pMesh->totalResidualForcesNorm
// // + mCurrentSimulationStep // // + mCurrentSimulationStep
// // * pMesh->residualForcesMovingAverage) // // * pMesh->residualForcesMovingAverage)
// // / (1 + mCurrentSimulationStep); // // / (1 + mCurrentSimulationStep);
// pMesh->residualForcesMovingAverage += pMesh->totalResidualForcesNorm pMesh->residualForcesMovingAverage += pMesh->totalResidualForcesNorm
// / movingAverageSampleSize; / movingAverageSampleSize;
// residualForcesMovingAverageHistorySample.push(pMesh->residualForcesMovingAverage); residualForcesMovingAverageHistorySample.push(pMesh->residualForcesMovingAverage);
// if (movingAverageSampleSize < residualForcesMovingAverageHistorySample.size()) { if (movingAverageSampleSize < residualForcesMovingAverageHistorySample.size()) {
// const double firstElementValue = residualForcesMovingAverageHistorySample.front(); const double firstElementValue = residualForcesMovingAverageHistorySample.front();
// pMesh->residualForcesMovingAverage -= firstElementValue / movingAverageSampleSize; pMesh->residualForcesMovingAverage -= firstElementValue / movingAverageSampleSize;
// residualForcesMovingAverageHistorySample.pop(); residualForcesMovingAverageHistorySample.pop();
// pMesh->residualForcesMovingAverageDerivativeNorm // pMesh->residualForcesMovingAverageDerivativeNorm
// = std::abs((residualForcesMovingAverageHistorySample.back() // = std::abs((residualForcesMovingAverageHistorySample.back()
// - residualForcesMovingAverageHistorySample.front())) // - residualForcesMovingAverageHistorySample.front()))
// / (movingAverageSampleSize); // / (movingAverageSampleSize);
// residualForcesMovingAverageDerivativeMax // residualForcesMovingAverageDerivativeMax
// = std::max(pMesh->residualForcesMovingAverageDerivativeNorm, // = std::max(pMesh->residualForcesMovingAverageDerivativeNorm,
// residualForcesMovingAverageDerivativeMax); // residualForcesMovingAverageDerivativeMax);
// pMesh->residualForcesMovingAverageDerivativeNorm // pMesh->residualForcesMovingAverageDerivativeNorm
// /= residualForcesMovingAverageDerivativeMax; // /= residualForcesMovingAverageDerivativeMax;
// // std::cout << "Normalized derivative:" // // std::cout << "Normalized derivative:"
// // << residualForcesMovingAverageDerivativeNorm // // << residualForcesMovingAverageDerivativeNorm
// // << std::endl; // // << std::endl;
// } }
// pMesh->previousTotalPotentialEnergykN = // pMesh->previousTotalPotentialEnergykN =
// pMesh->currentTotalPotentialEnergykN; // pMesh->currentTotalPotentialEnergykN;
@ -2151,19 +2207,20 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
// const double executionTime_min // const double executionTime_min
// = std::chrono::duration_cast<std::chrono::minutes>(t2 - beginTime).count(); // = std::chrono::duration_cast<std::chrono::minutes>(t2 - beginTime).count();
// std::cout << "Execution time(min):" << executionTime_min << std::endl; // std::cout << "Execution time(min):" << executionTime_min << std::endl;
if (mSettings.useAverageResidualForcesNorm) { if (mSettings.useAverage) {
const double percOfConv = averageExternalForcesNorm std::cout << "Percentage of target (average):"
/ pMesh->averageResidualForcesNorm; << 100 * mSettings.averageResidualForcesCriterionThreshold
std::cout << "Percentage of target:" << percOfConv << "%" << std::endl; * totalExternalForcesNorm
} else { / (pMesh->totalResidualForcesNorm / pMesh->VN())
std::cout << "Percentage of target:"
<< 100 * mSettings.totalResidualForcesNormThreshold
/ pMesh->totalResidualForcesNorm
<< "%" << std::endl; << "%" << std::endl;
} }
// SimulationResultsReporter::createPlot("Number of Steps", std::cout << "Percentage of target:"
// "Residual Forces mov aver", << 100 * mSettings.totalExternalForcesNormPercentageTermination
// movingAverages); * totalExternalForcesNorm / pMesh->totalResidualForcesNorm
<< "%" << std::endl;
SimulationResultsReporter::createPlot("Number of Steps",
"Residual Forces mov aver",
history.residualForcesMovingAverage);
// SimulationResultsReporter::createPlot("Number of Steps", // SimulationResultsReporter::createPlot("Number of Steps",
// "Residual Forces mov aver deriv", // "Residual Forces mov aver deriv",
// movingAveragesDerivatives); // movingAveragesDerivatives);
@ -2184,14 +2241,14 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
// SimulationResultsReporter::createPlot("Number of Steps", // SimulationResultsReporter::createPlot("Number of Steps",
// "Residual Forces mov aver deriv", // "Residual Forces mov aver deriv",
// movingAveragesDerivatives_norm); // movingAveragesDerivatives_norm);
// SimulationResultsReporter::createPlot("Number of Steps",
// "Residual Forces mov aver",
// history.residualForcesMovingAverage);
SimulationResultsReporter::createPlot("Number of Steps", SimulationResultsReporter::createPlot("Number of Steps",
"Log of Residual Forces", "Residual Forces mov aver",
history.logResidualForces, history.residualForcesMovingAverage);
{}, // SimulationResultsReporter::createPlot("Number of Steps",
history.redMarks); // "Log of Residual Forces",
// history.logResidualForces,
// {},
// history.redMarks);
// SimulationResultsReporter::createPlot("Number of Steps", // SimulationResultsReporter::createPlot("Number of Steps",
// "Log of Kinetic energy", // "Log of Kinetic energy",
// history.kineticEnergy, // history.kineticEnergy,
@ -2202,9 +2259,9 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
// SimulationResultsReporter::createPlot("Number of Iterations", // SimulationResultsReporter::createPlot("Number of Iterations",
// "Sum of normalized displacement norms", // "Sum of normalized displacement norms",
// history.sumOfNormalizedDisplacementNorms /*, // history.sumOfNormalizedDisplacementNorms /*,
// std::filesystem::path("./") // std::filesystem::path("./")
// .append("SumOfNormalizedDisplacementNorms_" + graphSuffix + ".png") // .append("SumOfNormalizedDisplacementNorms_" + graphSuffix + ".png")
// .string()*/ // .string()*/
// , // ,
// {}, // {},
// history.redMarks); // history.redMarks);
@ -2257,12 +2314,13 @@ 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
= mSettings.useResidualForcesNorm = pMesh->totalResidualForcesNorm / totalExternalForcesNorm
&& pMesh->totalResidualForcesNorm < mSettings.totalResidualForcesNormThreshold; < mSettings.totalExternalForcesNormPercentageTermination;
const bool fullfillsAverageResidualForcesNormTerminationCriterion
= mSettings.useAverage
&& (pMesh->totalResidualForcesNorm / pMesh->VN()) / totalExternalForcesNorm
< mSettings.averageResidualForcesCriterionThreshold;
const bool fullfillsMovingAverageNormTerminationCriterion const bool fullfillsMovingAverageNormTerminationCriterion
= pMesh->residualForcesMovingAverage = pMesh->residualForcesMovingAverage
< mSettings.residualForcesMovingAverageNormThreshold; < mSettings.residualForcesMovingAverageNormThreshold;
@ -2273,10 +2331,10 @@ mesh->currentTotalPotentialEnergykN*/
= fullfillsKineticEnergyTerminationCriterion = fullfillsKineticEnergyTerminationCriterion
// || fullfillsMovingAverageNormTerminationCriterion // || fullfillsMovingAverageNormTerminationCriterion
// || fullfillsMovingAverageDerivativeNormTerminationCriterion // || fullfillsMovingAverageDerivativeNormTerminationCriterion
|| fullfillsResidualForcesNormTerminationCriterion || fullfillsAverageResidualForcesNormTerminationCriterion
|| fullfillsAverageResidualForcesNormCriterion; || fullfillsResidualForcesNormTerminationCriterion;
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;
printCurrentState(); printCurrentState();
if (fullfillsResidualForcesNormTerminationCriterion) { if (fullfillsResidualForcesNormTerminationCriterion) {
@ -2308,7 +2366,6 @@ mesh->currentTotalPotentialEnergykN*/
} }
updateNodalExternalForces(nodalExternalForces, constrainedVertices); updateNodalExternalForces(nodalExternalForces, constrainedVertices);
averageExternalForcesNorm = totalExternalForcesNorm / pMesh->VN();
if (!nodalExternalForces.empty()) { if (!nodalExternalForces.empty()) {
mSettings.totalResidualForcesNormThreshold = 1e-2 * totalExternalForcesNorm; mSettings.totalResidualForcesNormThreshold = 1e-2 * totalExternalForcesNorm;
} }
@ -2320,25 +2377,25 @@ mesh->currentTotalPotentialEnergykN*/
// } // }
} }
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;
@ -2491,5 +2548,12 @@ mesh->currentTotalPotentialEnergykN*/
reporter.reportResults({results}, "Results", pJob->pMesh->getLabel()); reporter.reportResults({results}, "Results", pJob->pMesh->getLabel());
} }
return results; #ifdef POLYSCOPE_DEFINED
if (mSettings.shouldDraw || mSettings.isDebugMode) {
polyscope::removeCurveNetwork(meshPolyscopeLabel);
polyscope::removeCurveNetwork("Initial_" + meshPolyscopeLabel);
}
#endif
return results;
} }

View File

@ -38,14 +38,14 @@ public:
double xi{0.9969}; double xi{0.9969};
int maxDRMIterations{0}; int maxDRMIterations{0};
bool shouldUseTranslationalKineticEnergyThreshold{false}; bool shouldUseTranslationalKineticEnergyThreshold{false};
int gradualForcedDisplacementSteps{100}; int gradualForcedDisplacementSteps{50};
int desiredGradualExternalLoadsSteps{1}; 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 useAverage{false};
bool useAverageResidualForcesNorm{false}; double averageResidualForcesCriterionThreshold{1e-3};
Settings() {} Settings() {}
}; };

View File

@ -53,8 +53,8 @@ struct SimulationHistory {
kineticEnergy.push_back(std::log10(mesh.currentTotalKineticEnergy)); kineticEnergy.push_back(std::log10(mesh.currentTotalKineticEnergy));
// potentialEnergy.push_back(mesh.totalPotentialEnergykN); // potentialEnergy.push_back(mesh.totalPotentialEnergykN);
logResidualForces.push_back(std::log10(mesh.totalResidualForcesNorm)); logResidualForces.push_back(std::log10(mesh.totalResidualForcesNorm));
residualForcesMovingAverage.push_back(mesh.residualForcesMovingAverage); residualForcesMovingAverage.push_back(std::log10(mesh.residualForcesMovingAverage));
sumOfNormalizedDisplacementNorms.push_back(mesh.sumOfNormalizedDisplacementNorms); sumOfNormalizedDisplacementNorms.push_back(std::log10(mesh.sumOfNormalizedDisplacementNorms));
// residualForcesMovingAverageDerivativesLog.push_back( // residualForcesMovingAverageDerivativesLog.push_back(
// std::log(mesh.residualForcesMovingAverageDerivativeNorm)); // std::log(mesh.residualForcesMovingAverageDerivativeNorm));
} }

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 totalExternalForcesNorm{0};
double averageResidualForcesNorm{0}; double averageResidualForcesNorm{0};
double currentTotalPotentialEnergykN{0}; double currentTotalPotentialEnergykN{0};
double previousTotalPotentialEnergykN{0}; double previousTotalPotentialEnergykN{0};