Refactoring
This commit is contained in:
parent
2509b0a795
commit
5ebf354dcf
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue