Refactoring
This commit is contained in:
parent
436ece0d88
commit
e9707e2cfb
|
|
@ -263,10 +263,10 @@ void DRMSimulationModel::reset(const std::shared_ptr<SimulationJob> &pJob, const
|
|||
#ifdef POLYSCOPE_DEFINED
|
||||
if (mSettings.shouldDraw || mSettings.debugModeStep.has_value()) {
|
||||
PolyscopeInterface::init();
|
||||
polyscope::registerCurveNetwork(meshPolyscopeLabel,
|
||||
polyscope::registerCurveNetwork(meshPolyscopeLabel + "_" + pMesh->getLabel(),
|
||||
pMesh->getEigenVertices(),
|
||||
pMesh->getEigenEdges());
|
||||
polyscope::registerCurveNetwork("Initial_" + meshPolyscopeLabel,
|
||||
polyscope::registerCurveNetwork("Initial_" + meshPolyscopeLabel + "_" + pMesh->getLabel(),
|
||||
pMesh->getEigenVertices(),
|
||||
pMesh->getEigenEdges())
|
||||
->setRadius(0.002);
|
||||
|
|
@ -274,9 +274,9 @@ void DRMSimulationModel::reset(const std::shared_ptr<SimulationJob> &pJob, const
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!pJob->nodalForcedDisplacements.empty() && pJob->nodalExternalForces.empty()) {
|
||||
shouldApplyInitialDistortion = true;
|
||||
}
|
||||
// if (!pJob->nodalForcedDisplacements.empty() && pJob->nodalExternalForces.empty()) {
|
||||
// shouldApplyInitialDistortion = true;
|
||||
// }
|
||||
updateElementalFrames();
|
||||
}
|
||||
|
||||
|
|
@ -584,8 +584,7 @@ double DRMSimulationModel::computeTheta3(const EdgeType &e, const VertexType &v)
|
|||
const double &nR = node.nR; // TODO: This makes the function non-const.
|
||||
// Should be refactored in the future
|
||||
|
||||
double theta3;
|
||||
const bool shouldBreak = mCurrentSimulationStep == 12970;
|
||||
// const bool shouldBreak = mCurrentSimulationStep == 12970;
|
||||
if (&e == node.referenceElement) {
|
||||
// Use nR as theta3 only for the first star edge
|
||||
return nR;
|
||||
|
|
@ -631,7 +630,7 @@ double DRMSimulationModel::computeTheta3(const EdgeType &e, const VertexType &v)
|
|||
element.cosRotationAngle_jplus1 = cosRotationAngle;
|
||||
element.sinRotationAngle_jplus1 = sinRotationAngle;
|
||||
}
|
||||
theta3 = f3.dot(n);
|
||||
const double theta3 = f3.dot(n);
|
||||
|
||||
return theta3;
|
||||
}
|
||||
|
|
@ -845,9 +844,18 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices)
|
||||
{
|
||||
// std::vector<Vector6d> internalForcesParallel(mesh->vert.size());
|
||||
std::for_each(pMesh->nodes._handle->data.begin(),
|
||||
pMesh->nodes._handle->data.end(),
|
||||
[](Node &node) {
|
||||
node.force.internalAxial = 0;
|
||||
node.force.internalTorsion = 0;
|
||||
node.force.internalFirstBending = 0;
|
||||
node.force.internalSecondBending = 0;
|
||||
});
|
||||
|
||||
std::vector<std::vector<std::pair<int, Vector6d>>> internalForcesContributionsFromEachEdge(
|
||||
pMesh->EN(), std::vector<std::pair<int, Vector6d>>(4, {-1, Vector6d()}));
|
||||
|
||||
// omp_lock_t writelock;
|
||||
// omp_init_lock(&writelock);
|
||||
//#ifdef ENABLE_OPENMP
|
||||
|
|
@ -909,6 +917,7 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
const double e_k = element.length - element.initialLength;
|
||||
const double e_kDeriv = computeDerivativeElementLength(e, dui);
|
||||
const double axialForce_dofi = e_kDeriv * e_k * element.rigidity.axial;
|
||||
pMesh->nodes[edgeNode.vi].force.internalAxial[dofi] += axialForce_dofi;
|
||||
|
||||
#ifdef POLYSCOPE_DEFINED
|
||||
if (std::isnan(axialForce_dofi)) {
|
||||
|
|
@ -923,9 +932,11 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
const double theta1DiffDerivative = theta1_jplus1_deriv - theta1_j_deriv;
|
||||
const double torsionalForce_dofi = theta1DiffDerivative * theta1Diff
|
||||
* element.rigidity.torsional;
|
||||
pMesh->nodes[edgeNode.vi].force.internalTorsion[dofi] += torsionalForce_dofi;
|
||||
#ifdef POLYSCOPE_DEFINED
|
||||
if (std::isnan(torsionalForce_dofi)) {
|
||||
std::cerr << "nan in torsional" << evi << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -954,6 +965,8 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
+ firstBendingForce_inBracketsTerm_3;
|
||||
const double firstBendingForce_dofi = firstBendingForce_inBracketsTerm
|
||||
* element.rigidity.firstBending;
|
||||
pMesh->nodes[edgeNode.vi].force.internalFirstBending[dofi]
|
||||
+= firstBendingForce_dofi;
|
||||
|
||||
// Second bending force computation
|
||||
////theta2_j derivative
|
||||
|
|
@ -982,6 +995,8 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
+ secondBendingForce_inBracketsTerm_3;
|
||||
double secondBendingForce_dofi = secondBendingForce_inBracketsTerm
|
||||
* element.rigidity.secondBending;
|
||||
pMesh->nodes[edgeNode.vi].force.internalSecondBending[dofi]
|
||||
+= secondBendingForce_dofi;
|
||||
internalForcesContributionFromThisEdge[evi].second[dofi]
|
||||
= axialForce_dofi + firstBendingForce_dofi + secondBendingForce_dofi
|
||||
+ torsionalForce_dofi;
|
||||
|
|
@ -1021,6 +1036,8 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
* element.rigidity.secondBending;
|
||||
internalForcesContributionFromThisEdge[evi + 2].second[dofi]
|
||||
= secondBendingForce_dofi;
|
||||
pMesh->nodes[refElemOtherVertexNode.vi].force.internalSecondBending[dofi]
|
||||
+= secondBendingForce_dofi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1028,18 +1045,14 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
internalForcesContributionsFromEachEdge[ei] = internalForcesContributionFromThisEdge;
|
||||
});
|
||||
|
||||
//#pragma omp parallel for schedule(static) num_threads(8)
|
||||
|
||||
for (size_t vi = 0; vi < pMesh->VN(); vi++) {
|
||||
Node::Forces &force = pMesh->nodes[vi].force;
|
||||
// Vector6d ext = force.external;
|
||||
// if (mCurrentSimulationStep <= 100) {
|
||||
// ext[3] = 0;
|
||||
// ext[4] = 0;
|
||||
// }
|
||||
std::for_each(pMesh->nodes._handle->data.begin(),
|
||||
pMesh->nodes._handle->data.end(),
|
||||
[](Node &node) {
|
||||
Node::Forces &force = node.force;
|
||||
force.residual = force.external;
|
||||
force.internal = 0;
|
||||
}
|
||||
});
|
||||
|
||||
for (size_t ei = 0; ei < pMesh->EN(); ei++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
std::pair<int, Vector6d> internalForcePair
|
||||
|
|
@ -1054,10 +1067,23 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
#ifdef POLYSCOPE_DEFINED
|
||||
if (std::isnan(internalForcePair.second.norm())) {
|
||||
std::cerr << "nan on edge" << ei << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef POLYSCOPE_DEFINED
|
||||
std::for_each(pMesh->nodes._handle->data.begin(),
|
||||
pMesh->nodes._handle->data.end(),
|
||||
[](Node &node) {
|
||||
Node::Forces &force = node.force;
|
||||
const Vector6d debug_residual = force.external - force.internalAxial
|
||||
- force.internalTorsion
|
||||
- force.internalFirstBending
|
||||
- force.internalSecondBending;
|
||||
assert((force.residual - debug_residual).norm() < 1e-5);
|
||||
});
|
||||
#endif
|
||||
double totalResidualForcesNorm = 0;
|
||||
Vector6d sumOfResidualForces(0);
|
||||
for (size_t vi = 0; vi < pMesh->VN(); vi++) {
|
||||
|
|
@ -1070,7 +1096,9 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
#ifdef POLYSCOPE_DEFINED
|
||||
if (std::isnan(force.residual.norm())) {
|
||||
std::cout << "residual " << vi << ":" << force.residual.toString() << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
// std::cout << "residual " << vi << ":" << force.residual.norm() << std::endl;
|
||||
#endif
|
||||
}
|
||||
pMesh->totalResidualForcesNorm = totalResidualForcesNorm;
|
||||
|
|
@ -1448,6 +1476,7 @@ void DRMSimulationModel::updateT2Derivatives()
|
|||
{
|
||||
for (const EdgeType &e : pMesh->edge) {
|
||||
for (DoFType dofi = DoF::Ux; dofi < DoF::NumDoF; dofi++) {
|
||||
const auto ei = pMesh->getIndex(e);
|
||||
DifferentiateWithRespectTo dui_v0{*e.cV(0), dofi};
|
||||
pMesh->elements[e].derivativeT2_j[dofi] = computeDerivativeT2(e, dui_v0);
|
||||
DifferentiateWithRespectTo dui_v1{*e.cV(1), dofi};
|
||||
|
|
@ -1830,8 +1859,11 @@ void DRMSimulationModel::applyForcedNormals(
|
|||
void DRMSimulationModel::updateKineticEnergy()
|
||||
{
|
||||
pMesh->previousTotalKineticEnergy = pMesh->currentTotalKineticEnergy;
|
||||
pMesh->previousTranslationalKineticEnergy = pMesh->currentTotalTranslationalKineticEnergy;
|
||||
pMesh->previousTotalRotationalKineticEnergy = pMesh->currentTotalRotationalKineticEnergy;
|
||||
pMesh->currentTotalKineticEnergy = 0;
|
||||
pMesh->currentTotalTranslationalKineticEnergy = 0;
|
||||
pMesh->currentTotalRotationalKineticEnergy = 0;
|
||||
for (const VertexType &v : pMesh->vert) {
|
||||
Node &node = pMesh->nodes[v];
|
||||
node.kineticEnergy = 0;
|
||||
|
|
@ -1853,6 +1885,7 @@ void DRMSimulationModel::updateKineticEnergy()
|
|||
|
||||
pMesh->currentTotalKineticEnergy += node.kineticEnergy;
|
||||
pMesh->currentTotalTranslationalKineticEnergy += nodeTranslationalKineticEnergy;
|
||||
pMesh->currentTotalRotationalKineticEnergy += nodeRotationalKineticEnergy;
|
||||
}
|
||||
// assert(mesh->currentTotalKineticEnergy < 100000000000000);
|
||||
}
|
||||
|
|
@ -2009,7 +2042,7 @@ SimulationResults DRMSimulationModel::computeResults(const std::shared_ptr<Simul
|
|||
// mesh.printVertexCoordinates(mesh.VN() / 2);
|
||||
#ifdef POLYSCOPE_DEFINED
|
||||
if (mSettings.shouldDraw && !mSettings.debugModeStep.has_value()) {
|
||||
draw();
|
||||
draw(pJob);
|
||||
}
|
||||
#endif
|
||||
if (!std::isnan(pMesh->currentTotalKineticEnergy)) {
|
||||
|
|
@ -2018,46 +2051,46 @@ SimulationResults DRMSimulationModel::computeResults(const std::shared_ptr<Simul
|
|||
|
||||
#ifdef COMPUTE_INTERNAL_FORCES
|
||||
results.perVertexInternalForces = computeInternalForces(pJob->constrainedVertices);
|
||||
std::vector<double> perVertexInternalForces_axial = [=]() {
|
||||
std::vector<double> axialInternalForces;
|
||||
axialInternalForces.reserve(results.perVertexInternalForces.size());
|
||||
for (const std::array<Vector6d, 4> &internalForces : results.perVertexInternalForces) {
|
||||
axialInternalForces.push_back(internalForces[0].norm());
|
||||
}
|
||||
return axialInternalForces;
|
||||
}();
|
||||
const auto pCurvNet = pMesh->registerForDrawing();
|
||||
pCurvNet->addNodeScalarQuantity("axial forces", perVertexInternalForces_axial);
|
||||
std::vector<double> perVertexInternalForces_torsion = [=]() {
|
||||
std::vector<double> axialInternalForces;
|
||||
axialInternalForces.reserve(results.perVertexInternalForces.size());
|
||||
for (const std::array<Vector6d, 4> &internalForces : results.perVertexInternalForces) {
|
||||
axialInternalForces.push_back(internalForces[1].norm());
|
||||
}
|
||||
return axialInternalForces;
|
||||
}();
|
||||
pCurvNet->addNodeScalarQuantity("torsional forces", perVertexInternalForces_torsion);
|
||||
std::vector<double> perVertexInternalForces_firstBending = [=]() {
|
||||
std::vector<double> axialInternalForces;
|
||||
axialInternalForces.reserve(results.perVertexInternalForces.size());
|
||||
for (const std::array<Vector6d, 4> &internalForces : results.perVertexInternalForces) {
|
||||
axialInternalForces.push_back(internalForces[2].norm());
|
||||
}
|
||||
return axialInternalForces;
|
||||
}();
|
||||
pCurvNet->addNodeScalarQuantity("first bending forces",
|
||||
perVertexInternalForces_firstBending);
|
||||
std::vector<double> perVertexInternalForces_secondBending = [=]() {
|
||||
std::vector<double> axialInternalForces;
|
||||
axialInternalForces.reserve(results.perVertexInternalForces.size());
|
||||
for (const std::array<Vector6d, 4> &internalForces : results.perVertexInternalForces) {
|
||||
axialInternalForces.push_back(internalForces[3].norm());
|
||||
}
|
||||
return axialInternalForces;
|
||||
}();
|
||||
pCurvNet->addNodeScalarQuantity("second bending forces",
|
||||
perVertexInternalForces_secondBending);
|
||||
polyscope::show();
|
||||
// std::vector<double> perVertexInternalForces_axial = [=]() {
|
||||
// std::vector<double> axialInternalForces;
|
||||
// axialInternalForces.reserve(results.perVertexInternalForces.size());
|
||||
// for (const std::array<Vector6d, 4> &internalForces : results.perVertexInternalForces) {
|
||||
// axialInternalForces.push_back(internalForces[0].norm());
|
||||
// }
|
||||
// return axialInternalForces;
|
||||
// }();
|
||||
// const auto pCurvNet = pMesh->registerForDrawing();
|
||||
// pCurvNet->addNodeScalarQuantity("axial forces", perVertexInternalForces_axial);
|
||||
// std::vector<double> perVertexInternalForces_torsion = [=]() {
|
||||
// std::vector<double> axialInternalForces;
|
||||
// axialInternalForces.reserve(results.perVertexInternalForces.size());
|
||||
// for (const std::array<Vector6d, 4> &internalForces : results.perVertexInternalForces) {
|
||||
// axialInternalForces.push_back(internalForces[1].norm());
|
||||
// }
|
||||
// return axialInternalForces;
|
||||
// }();
|
||||
// pCurvNet->addNodeScalarQuantity("torsional forces", perVertexInternalForces_torsion);
|
||||
// std::vector<double> perVertexInternalForces_firstBending = [=]() {
|
||||
// std::vector<double> axialInternalForces;
|
||||
// axialInternalForces.reserve(results.perVertexInternalForces.size());
|
||||
// for (const std::array<Vector6d, 4> &internalForces : results.perVertexInternalForces) {
|
||||
// axialInternalForces.push_back(internalForces[2].norm());
|
||||
// }
|
||||
// return axialInternalForces;
|
||||
// }();
|
||||
// pCurvNet->addNodeScalarQuantity("first bending forces",
|
||||
// perVertexInternalForces_firstBending);
|
||||
// std::vector<double> perVertexInternalForces_secondBending = [=]() {
|
||||
// std::vector<double> axialInternalForces;
|
||||
// axialInternalForces.reserve(results.perVertexInternalForces.size());
|
||||
// for (const std::array<Vector6d, 4> &internalForces : results.perVertexInternalForces) {
|
||||
// axialInternalForces.push_back(internalForces[3].norm());
|
||||
// }
|
||||
// return axialInternalForces;
|
||||
// }();
|
||||
// pCurvNet->addNodeScalarQuantity("second bending forces",
|
||||
// perVertexInternalForces_secondBending);
|
||||
// polyscope::show();
|
||||
#endif
|
||||
results.rotationalDisplacementQuaternion.resize(pMesh->VN());
|
||||
results.debug_q_f1.resize(pMesh->VN());
|
||||
|
|
@ -2191,11 +2224,14 @@ void DRMSimulationModel::printDebugInfo() const
|
|||
}
|
||||
|
||||
#ifdef POLYSCOPE_DEFINED
|
||||
void DRMSimulationModel::draw(const std::string &screenshotsFolder)
|
||||
void DRMSimulationModel::draw(const std::shared_ptr<SimulationJob> &pJob,
|
||||
const std::string &screenshotsFolder)
|
||||
{
|
||||
// update positions
|
||||
// polyscope::getCurveNetwork("Undeformed edge mesh")->setEnabled(false);
|
||||
polyscope::CurveNetwork *meshPolyscopeHandle = polyscope::getCurveNetwork(meshPolyscopeLabel);
|
||||
auto deformedMeshPolyscopeLabel = meshPolyscopeLabel + "_" + pMesh->getLabel();
|
||||
polyscope::CurveNetwork *meshPolyscopeHandle = polyscope::getCurveNetwork(
|
||||
deformedMeshPolyscopeLabel);
|
||||
meshPolyscopeHandle->updateNodePositions(pMesh->getEigenVertices());
|
||||
|
||||
// Vertex quantities
|
||||
|
|
@ -2259,11 +2295,12 @@ void DRMSimulationModel::draw(const std::string &screenshotsFolder)
|
|||
meshPolyscopeHandle->addNodeScalarQuantity("Kinetic Energy", kineticEnergies)->setEnabled(false);
|
||||
meshPolyscopeHandle->addNodeVectorQuantity("Node normals", nodeNormals)->setEnabled(true);
|
||||
meshPolyscopeHandle->addNodeVectorQuantity("Internal force", internalForces)->setEnabled(false);
|
||||
meshPolyscopeHandle->addNodeVectorQuantity("External force", externalForces)->setEnabled(false);
|
||||
meshPolyscopeHandle->addNodeVectorQuantity("External Moments", externalMoments)->setEnabled(true);
|
||||
meshPolyscopeHandle->addNodeScalarQuantity("Internal force norm", internalForcesNorm)
|
||||
->setEnabled(true);
|
||||
meshPolyscopeHandle->setRadius(0.002);
|
||||
// meshPolyscopeHandle->addNodeVectorQuantity("External force", externalForces)->setEnabled(true);
|
||||
// meshPolyscopeHandle->addNodeVectorQuantity("External Moments", externalMoments)->setEnabled(true);
|
||||
pJob->registerForDrawing(deformedMeshPolyscopeLabel, true);
|
||||
// polyscope::getCurveNetwork(meshPolyscopeLabel)
|
||||
// ->addNodeVectorQuantity("Internal Axial force", internalAxialForces)
|
||||
// ->setEnabled(false);
|
||||
|
|
@ -2284,7 +2321,7 @@ void DRMSimulationModel::draw(const std::string &screenshotsFolder)
|
|||
// ->addNodeVectorQuantity("Second bending force-Rotation",
|
||||
// internalSecondBendingRotationForces)
|
||||
// ->setEnabled(false);
|
||||
polyscope::getCurveNetwork(meshPolyscopeLabel)
|
||||
polyscope::getCurveNetwork(deformedMeshPolyscopeLabel)
|
||||
->addNodeScalarQuantity("nR", nRs)
|
||||
->setEnabled(false);
|
||||
// polyscope::getCurveNetwork(meshPolyscopeLabel)
|
||||
|
|
@ -2293,10 +2330,10 @@ void DRMSimulationModel::draw(const std::string &screenshotsFolder)
|
|||
// polyscope::getCurveNetwork(meshPolyscopeLabel)
|
||||
// ->addNodeScalarQuantity("theta2", theta2)
|
||||
// ->setEnabled(false);
|
||||
polyscope::getCurveNetwork(meshPolyscopeLabel)
|
||||
polyscope::getCurveNetwork(deformedMeshPolyscopeLabel)
|
||||
->addNodeVectorQuantity("Residual force", residualForces)
|
||||
->setEnabled(false);
|
||||
polyscope::getCurveNetwork(meshPolyscopeLabel)
|
||||
polyscope::getCurveNetwork(deformedMeshPolyscopeLabel)
|
||||
->addNodeScalarQuantity("Residual force norm", residualForcesNorm)
|
||||
->setEnabled(false);
|
||||
// polyscope::getCurveNetwork(meshPolyscopeLabel)
|
||||
|
|
@ -2315,11 +2352,10 @@ void DRMSimulationModel::draw(const std::string &screenshotsFolder)
|
|||
I3[ei] = pMesh->elements[e].dimensions.inertia.I3;
|
||||
}
|
||||
|
||||
polyscope::getCurveNetwork(meshPolyscopeLabel)->addEdgeScalarQuantity("A", A);
|
||||
polyscope::getCurveNetwork(meshPolyscopeLabel)->addEdgeScalarQuantity("J", J);
|
||||
polyscope::getCurveNetwork(meshPolyscopeLabel)
|
||||
->addEdgeScalarQuantity("I2", I2);
|
||||
polyscope::getCurveNetwork(meshPolyscopeLabel)->addEdgeScalarQuantity("I3", I3);
|
||||
polyscope::getCurveNetwork(deformedMeshPolyscopeLabel)->addEdgeScalarQuantity("A", A);
|
||||
polyscope::getCurveNetwork(deformedMeshPolyscopeLabel)->addEdgeScalarQuantity("J", J);
|
||||
polyscope::getCurveNetwork(deformedMeshPolyscopeLabel)->addEdgeScalarQuantity("I2", I2);
|
||||
polyscope::getCurveNetwork(deformedMeshPolyscopeLabel)->addEdgeScalarQuantity("I3", I3);
|
||||
|
||||
// Specify the callback
|
||||
static bool calledOnce = false;
|
||||
|
|
@ -2574,7 +2610,19 @@ void DRMSimulationModel::applyKineticDamping(const std::shared_ptr<SimulationJob
|
|||
SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<SimulationJob> &pJob)
|
||||
{
|
||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
updateNodalMasses();
|
||||
// constexpr bool useDRM = true;
|
||||
//#ifdef USE_ENSMALLEN
|
||||
// if (!useDRM) {
|
||||
// setJob(pJob);
|
||||
// // ens::L_BFGS optimizer(20);
|
||||
// ens::SA optimizer;
|
||||
// arma::mat x(pJob->pMesh->VN() * NumDoF, 1);
|
||||
// optimizer.Optimize(*this, x);
|
||||
// // getD
|
||||
// } else {
|
||||
//#endif
|
||||
// std::unordered_map<VertexIndex, Vector6d> nodalExternalForces = pJob->nodalExternalForces;
|
||||
// double totalExternalForcesNorm = 0;
|
||||
// Vector6d sumOfExternalForces(0);
|
||||
|
|
@ -2614,11 +2662,11 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
// double residualForcesMovingAverageDerivativeMax = 0;
|
||||
while (!mSettings.maxDRMIterations.has_value()
|
||||
|| mCurrentSimulationStep < mSettings.maxDRMIterations.value()) {
|
||||
if ((mSettings.debugModeStep.has_value() && mCurrentSimulationStep == 50000)) {
|
||||
// if ((mSettings.debugModeStep.has_value() && mCurrentSimulationStep == 50000)) {
|
||||
// std::filesystem::create_directory("./PatternOptimizationNonConv");
|
||||
// pJob->save("./PatternOptimizationNonConv");
|
||||
// Dt = mSettings.Dtini;
|
||||
}
|
||||
// }
|
||||
// if (mCurrentSimulationStep == 500 && shouldTemporarilyDampForces) {
|
||||
// Dt = mSettings.Dtini;
|
||||
// }
|
||||
|
|
@ -2628,7 +2676,11 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
updateRDerivatives();
|
||||
updateT2Derivatives();
|
||||
updateT3Derivatives();
|
||||
const bool shouldBreak = mCurrentSimulationStep == 12970;
|
||||
const bool shouldBreak = mCurrentSimulationStep == 3935;
|
||||
if (shouldBreak) {
|
||||
int i = 0;
|
||||
i++;
|
||||
}
|
||||
updateResidualForcesOnTheFly(constrainedVertices);
|
||||
|
||||
// TODO: write parallel function for updating positions
|
||||
|
|
@ -2670,41 +2722,6 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
}
|
||||
}
|
||||
|
||||
//normalized sum of displacements
|
||||
// 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;
|
||||
|
||||
//moving average
|
||||
// // 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->currentTotalPotentialEnergykN;
|
||||
// pMesh->currentTotalPotentialEnergykN = computeTotalPotentialEnergy() / 1000;
|
||||
|
|
@ -2743,6 +2760,42 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
|
||||
if ((mSettings.shouldCreatePlots || mSettings.debugModeStep.has_value())
|
||||
&& mCurrentSimulationStep != 0) {
|
||||
//normalized sum of displacements
|
||||
double sumOfDisplacementsNorm = 0;
|
||||
for (size_t vi = 0; vi < pMesh->VN(); vi++) {
|
||||
sumOfDisplacementsNorm += pMesh->nodes[vi].displacements.getTranslation().norm();
|
||||
}
|
||||
pMesh->perVertexAverageNormalizedDisplacementNorm = sumOfDisplacementsNorm
|
||||
/ (pMesh->bbox.Diag()
|
||||
* pMesh->VN());
|
||||
|
||||
//moving average
|
||||
// // 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;
|
||||
}
|
||||
history.stepPulse(*pMesh);
|
||||
percentageOfConvergence.push_back(100 * mSettings.totalResidualForcesNormThreshold
|
||||
/ pMesh->totalResidualForcesNorm);
|
||||
|
|
@ -2752,27 +2805,49 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
&& mCurrentSimulationStep % mSettings.debugModeStep.value() == 0) {
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Residual Forces mov aver deriv",
|
||||
// movingAveragesDerivatives_norm);
|
||||
// history
|
||||
// .residualForcesMovingAverageDerivativesLog);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Residual Forces mov aver",
|
||||
// history.residualForcesMovingAverage,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
SimulationResultsReporter::createPlot("Number of Steps",
|
||||
"Log of Residual Forces",
|
||||
history.logResidualForces,
|
||||
{},
|
||||
history.redMarks);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Log of Kinetic energy",
|
||||
// history.kineticEnergy,
|
||||
// "Log of Sum of axial forces norms",
|
||||
// history.logOfSumOfAxialForcesNorm,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Log of Sum of torsion forces norms",
|
||||
// history.logOfSumOfTorsionForcesNorm,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Log of Sum of 1stBending forces norms",
|
||||
// history.logOfSumOfFirstBendingForcesNorm,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Log of Sum of 2ndBending forces norms",
|
||||
// history.logOfSumOfSecondBendingForcesNorm,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
// 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 /*,
|
||||
// SimulationResultsReporter::createPlot(
|
||||
// "Number of Iterations",
|
||||
// "Per vertex average normalized displacement norms",
|
||||
// history.perVertexAverageNormalizedDisplacementNorm /*,
|
||||
// std::filesystem::path("./")
|
||||
// .append("SumOfNormalizedDisplacementNorms_" + graphSuffix + ".png")
|
||||
// .string()*/
|
||||
|
|
@ -2796,7 +2871,7 @@ currentSimulationStep > maxDRMIterations*/
|
|||
// .append("Debugging_files")
|
||||
// .append("Screenshots")
|
||||
// .string();
|
||||
draw();
|
||||
draw(pJob);
|
||||
// yValues = history.kineticEnergy;
|
||||
// plotHandle = matplot::scatter(xPlot, yValues);
|
||||
// label = "Log of Kinetic energy";
|
||||
|
|
@ -2837,17 +2912,14 @@ currentSimulationStep > maxDRMIterations*/
|
|||
}
|
||||
break;
|
||||
}
|
||||
// Residual forces norm convergence
|
||||
if ((pMesh->previousTotalKineticEnergy > pMesh->currentTotalKineticEnergy
|
||||
// && mCurrentSimulationStep > movingAverageSampleSize
|
||||
)
|
||||
/* || (pMesh->totalResidualForcesNorm / mSettings.totalResidualForcesNormThreshold <= 1
|
||||
&& mCurrentSimulationStep > 1)*/
|
||||
/*||
|
||||
mesh->previousTotalPotentialEnergykN >
|
||||
mesh->currentTotalPotentialEnergykN*/
|
||||
/*|| mesh->currentTotalPotentialEnergykN < minPotentialEnergy*/) {
|
||||
// if (pMesh->totalResidualForcesNorm < totalResidualForcesNormThreshold) {
|
||||
|
||||
const bool isKineticEnergyPeak = (mSettings.useTotalRotationalKineticEnergyForKineticDamping
|
||||
&& pMesh->previousTotalRotationalKineticEnergy
|
||||
> pMesh->currentTotalRotationalKineticEnergy)
|
||||
|| (mSettings.useTranslationalKineticEnergyForKineticDamping
|
||||
&& pMesh->previousTranslationalKineticEnergy
|
||||
> pMesh->currentTotalTranslationalKineticEnergy);
|
||||
if (isKineticEnergyPeak) {
|
||||
const bool fullfillsKineticEnergyTerminationCriterion
|
||||
= mSettings.totalTranslationalKineticEnergyThreshold.has_value()
|
||||
&& pMesh->currentTotalTranslationalKineticEnergy
|
||||
|
|
@ -2899,7 +2971,7 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
// }
|
||||
}
|
||||
|
||||
if (mSettings.useKineticDamping) {
|
||||
if (mSettings.useTranslationalKineticEnergyForKineticDamping) {
|
||||
applyKineticDamping(pJob);
|
||||
Dt *= mSettings.xi;
|
||||
if (mSettings.shouldCreatePlots) {
|
||||
|
|
@ -2913,11 +2985,13 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
// draw();
|
||||
}
|
||||
}
|
||||
//#ifdef USE_ENSMALLEN
|
||||
// }
|
||||
//#endif
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
SimulationResults results = computeResults(pJob);
|
||||
results.executionTime = std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime)
|
||||
.count();
|
||||
results.executionTime
|
||||
= std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime).count();
|
||||
|
||||
if (!mSettings.debugModeStep.has_value() && mSettings.shouldCreatePlots) {
|
||||
SimulationResultsReporter reporter;
|
||||
|
|
@ -2926,8 +3000,8 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
|
||||
#ifdef POLYSCOPE_DEFINED
|
||||
if (mSettings.shouldDraw || mSettings.debugModeStep.has_value()) {
|
||||
polyscope::removeCurveNetwork(meshPolyscopeLabel);
|
||||
polyscope::removeCurveNetwork("Initial_" + meshPolyscopeLabel);
|
||||
polyscope::removeCurveNetwork(meshPolyscopeLabel + "_" + pMesh->getLabel());
|
||||
polyscope::removeCurveNetwork("Initial_" + meshPolyscopeLabel + "_" + pMesh->getLabel());
|
||||
}
|
||||
#endif
|
||||
return results;
|
||||
|
|
@ -2936,6 +3010,7 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
const Settings &settings,
|
||||
const SimulationResults &solutionGuess)
|
||||
{
|
||||
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
|
||||
reset(pJob, settings);
|
||||
assert(pJob->pMesh != nullptr);
|
||||
|
||||
|
|
@ -2953,6 +3028,8 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
LinearSimulationModel linearSimulationModel;
|
||||
SimulationResults simulationResults_fullPatternLinearModel = linearSimulationModel
|
||||
.executeSimulation(pJob);
|
||||
|
||||
if (simulationResults_fullPatternLinearModel.converged) {
|
||||
// simulationResults_fullPatternLinearModel.save(fullResultsFolderPath);
|
||||
for (auto &externalForce : pJob->nodalExternalForces) {
|
||||
externalForce.second = externalForce.second / forceScaleFactor;
|
||||
|
|
@ -2961,8 +3038,16 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
applySolutionGuess(simulationResults_fullPatternLinearModel, pJob);
|
||||
shouldTemporarilyDampForces = true;
|
||||
}
|
||||
}
|
||||
|
||||
SimulationResults results = executeSimulation(pJob); //calling the virtual function
|
||||
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
|
||||
if (settings.beVerbose) {
|
||||
std::cout << "Simulation converged in "
|
||||
<< std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count()
|
||||
/ (60 * 1000.0)
|
||||
<< " min" << std::endl;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
|
@ -2983,7 +3068,8 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
// // }
|
||||
//}
|
||||
|
||||
//SimulationMesh *DRMSimulationModel::getDeformedMesh(const arma::mat &x)
|
||||
//SimulationMesh *DRMSimulationModel::getDeformedMesh(const arma::mat &x,
|
||||
// const std::shared_ptr<SimulationJob> &pJob)
|
||||
//{
|
||||
// for (int vi = 0; vi < pMesh->VN(); vi++) {
|
||||
// Node &node = pMesh->nodes[vi];
|
||||
|
|
@ -3000,6 +3086,32 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
// return pMesh.get();
|
||||
//}
|
||||
|
||||
//double DRMSimulationModel::Evaluate(const arma::mat &x)
|
||||
//{
|
||||
// for (int vi = 0; vi < pMesh->VN(); vi++) {
|
||||
// Node &node = pMesh->nodes[vi];
|
||||
// for (DoFType dofi = DoF::Ux; dofi < DoF::NumDoF; dofi++) {
|
||||
// node.displacements[dofi] = x(vi * DoF::NumDoF + dofi);
|
||||
// }
|
||||
// }
|
||||
|
||||
// applyDisplacements(constrainedVertices);
|
||||
// if (!pJob->nodalForcedDisplacements.empty()) {
|
||||
// applyForcedDisplacements(pJob->nodalForcedDisplacements);
|
||||
// }
|
||||
// updateElementalLengths();
|
||||
// updateNormalDerivatives();
|
||||
// updateT1Derivatives();
|
||||
// updateRDerivatives();
|
||||
// updateT2Derivatives();
|
||||
// updateT3Derivatives();
|
||||
// updateResidualForcesOnTheFly(constrainedVertices);
|
||||
// const double PE = computeTotalPotentialEnergy();
|
||||
// // const double PE = computeTotalInternalPotentialEnergy();
|
||||
// // std::cout << "PE:" << PE << std::endl;
|
||||
// return pMesh->totalResidualForcesNorm;
|
||||
//}
|
||||
|
||||
//double DRMSimulationModel::EvaluateWithGradient(const arma::mat &x, arma::mat &g)
|
||||
//{
|
||||
// for (int vi = 0; vi < pMesh->VN(); vi++) {
|
||||
|
|
@ -3028,7 +3140,13 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
// }
|
||||
// mCurrentSimulationStep++;
|
||||
// const double PE = computeTotalPotentialEnergy();
|
||||
// // const double PE = computeTotalInternalPotentialEnergy();
|
||||
// std::cout << "PE:" << PE << std::endl;
|
||||
// double sumOfDisplacements = 0;
|
||||
// for (int xi = 0; xi < pJob->pMesh->VN() * NumDoF; xi++) {
|
||||
// sumOfDisplacements += x(xi) * x(xi);
|
||||
// }
|
||||
// std::cout << "Sum of disp:" << std::sqrt(sumOfDisplacements) << std::endl;
|
||||
// return PE;
|
||||
//}
|
||||
|
||||
|
|
@ -3043,7 +3161,8 @@ void DRMSimulationModel::Settings::save(const std::filesystem::path &jsonFilePat
|
|||
json[GET_VARIABLE_NAME(Dtini)] = Dtini;
|
||||
json[GET_VARIABLE_NAME(xi)] = xi;
|
||||
json[GET_VARIABLE_NAME(gamma)] = gamma;
|
||||
json[GET_VARIABLE_NAME(useKineticDamping)] = totalResidualForcesNormThreshold;
|
||||
json[GET_VARIABLE_NAME(useTranslationalKineticEnergyForKineticDamping)]
|
||||
= useTranslationalKineticEnergyForKineticDamping;
|
||||
if (maxDRMIterations.has_value()) {
|
||||
json[GET_VARIABLE_NAME(jsonLabels.maxDRMIterations)] = maxDRMIterations.value();
|
||||
}
|
||||
|
|
@ -3064,7 +3183,8 @@ void DRMSimulationModel::Settings::save(const std::filesystem::path &jsonFilePat
|
|||
if (viscousDampingFactor.has_value()) {
|
||||
json[GET_VARIABLE_NAME(viscousDampingFactor)] = viscousDampingFactor.value();
|
||||
}
|
||||
json[GET_VARIABLE_NAME(useKineticDamping)] = useKineticDamping;
|
||||
json[GET_VARIABLE_NAME(useTranslationalKineticEnergyForKineticDamping)]
|
||||
= useTranslationalKineticEnergyForKineticDamping;
|
||||
// if (intermediateResultsSaveStep.has_value()) {
|
||||
// json[GET_VARIABLE_NAME(intermediateResultsSaveStep)] = intermediateResultsSaveStep.value();
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include <ensmallen.hpp>
|
||||
#endif
|
||||
|
||||
struct SimulationJob;
|
||||
class SimulationJob;
|
||||
|
||||
enum DoF { Ux = 0, Uy, Uz, Nx, Ny, Nr, NumDoF };
|
||||
using DoFType = int;
|
||||
|
|
@ -33,6 +33,8 @@ class DRMSimulationModel : public SimulationModel
|
|||
public:
|
||||
struct Settings
|
||||
{
|
||||
bool useTranslationalKineticEnergyForKineticDamping{true};
|
||||
bool useTotalRotationalKineticEnergyForKineticDamping{false};
|
||||
bool shouldDraw{false};
|
||||
bool beVerbose{false};
|
||||
bool shouldCreatePlots{false};
|
||||
|
|
@ -45,7 +47,7 @@ public:
|
|||
int gradualForcedDisplacementSteps{50};
|
||||
// int desiredGradualExternalLoadsSteps{1};
|
||||
double gamma{0.8};
|
||||
double totalResidualForcesNormThreshold{1e-8};
|
||||
double totalResidualForcesNormThreshold{1e-20};
|
||||
double totalExternalForcesNormPercentageTermination{1e-5};
|
||||
std::optional<int> maxDRMIterations;
|
||||
std::optional<int> debugModeStep;
|
||||
|
|
@ -55,7 +57,6 @@ public:
|
|||
// std::optional<int> intermediateResultsSaveStep;
|
||||
std::optional<bool> saveIntermediateBestStates;
|
||||
std::optional<double> viscousDampingFactor;
|
||||
bool useKineticDamping{true};
|
||||
Settings() {}
|
||||
void save(const std::filesystem::path &jsonFilePath) const;
|
||||
bool load(const std::filesystem::path &filePath);
|
||||
|
|
@ -153,7 +154,7 @@ private:
|
|||
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices);
|
||||
|
||||
#ifdef POLYSCOPE_DEFINED
|
||||
void draw(const std::string &screenshotsFolder = {});
|
||||
void draw(const std::shared_ptr<SimulationJob> &pJob, const std::string &screenshotsFolder = {});
|
||||
#endif
|
||||
void
|
||||
updateNodalInternalForce(Vector6d &nodalInternalForce,
|
||||
|
|
@ -262,12 +263,13 @@ private:
|
|||
SimulationResults executeSimulation(const std::shared_ptr<SimulationJob> &pJob,
|
||||
const Settings &settings,
|
||||
const SimulationResults &solutionGuess = SimulationResults());
|
||||
#ifdef USE_ENSMALLEN
|
||||
double EvaluateWithGradient(const arma::mat &x, arma::mat &g);
|
||||
void setJob(const std::shared_ptr<SimulationJob> &pJob);
|
||||
SimulationMesh *getDeformedMesh(const arma::mat &x);
|
||||
|
||||
#endif
|
||||
//#ifdef USE_ENSMALLEN
|
||||
// std::shared_ptr<SimulationJob> pJob;
|
||||
// double EvaluateWithGradient(const arma::mat &x, arma::mat &g);
|
||||
// void setJob(const std::shared_ptr<SimulationJob> &pJob);
|
||||
// SimulationMesh *getDeformedMesh(const arma::mat &x, const std::shared_ptr<SimulationJob> &pJob);
|
||||
// double Evaluate(const arma::mat &x);
|
||||
//#endif
|
||||
|
||||
static void runUnitTests();
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue