Refactoring
This commit is contained in:
parent
3e3d32399b
commit
a58414892c
|
@ -794,7 +794,7 @@ void DRMSimulationModel::updateResidualForcesOnTheFly(
|
|||
// omp_lock_t writelock;
|
||||
// omp_init_lock(&writelock);
|
||||
#ifdef ENABLE_OPENMP
|
||||
#pragma omp parallel for schedule(static) num_threads(8)
|
||||
#pragma omp parallel for schedule(static) num_threads(6)
|
||||
#endif
|
||||
for (int ei = 0; ei < pMesh->EN(); ei++) {
|
||||
const EdgeType &e = pMesh->edge[ei];
|
||||
|
@ -1151,6 +1151,9 @@ void DRMSimulationModel::updateNodalMasses()
|
|||
if (shouldTemporarilyDampForces && mCurrentSimulationStep < untilStep) {
|
||||
gamma *= 1e6 * (1 - static_cast<double>(mCurrentSimulationStep) / untilStep);
|
||||
}
|
||||
if (mCurrentSimulationStep == untilStep && shouldTemporarilyDampForces) {
|
||||
Dt = mSettings.Dtini * 0.95;
|
||||
}
|
||||
for (VertexType &v : pMesh->vert) {
|
||||
const size_t vi = pMesh->getIndex(v);
|
||||
double translationalSumSk = 0;
|
||||
|
@ -2037,6 +2040,7 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
|
||||
applySolutionGuess(solutionGuess, pJob);
|
||||
shouldTemporarilyDampForces = true;
|
||||
// Dt = mSettings.Dtini * 0.9;
|
||||
}
|
||||
|
||||
updateNodalMasses();
|
||||
|
@ -2047,6 +2051,14 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
|
||||
double residualForcesMovingAverageDerivativeMax = 0;
|
||||
while (settings.maxDRMIterations == 0 || mCurrentSimulationStep < settings.maxDRMIterations) {
|
||||
if ((mSettings.isDebugMode && mCurrentSimulationStep == 50000)) {
|
||||
// std::filesystem::create_directory("./PatternOptimizationNonConv");
|
||||
// pJob->save("./PatternOptimizationNonConv");
|
||||
// Dt = mSettings.Dtini;
|
||||
}
|
||||
if (mCurrentSimulationStep == 500 && shouldTemporarilyDampForces) {
|
||||
Dt = mSettings.Dtini;
|
||||
}
|
||||
// while (true) {
|
||||
updateNormalDerivatives();
|
||||
updateT1Derivatives();
|
||||
|
@ -2144,6 +2156,42 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
|||
break;
|
||||
}
|
||||
|
||||
if (mSettings.shouldCreatePlots && mSettings.isDebugMode
|
||||
&& mCurrentSimulationStep % mSettings.debugModeStep == 0) {
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Residual Forces mov aver deriv",
|
||||
// movingAveragesDerivatives_norm);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Residual Forces mov aver",
|
||||
// history.residualForcesMovingAverage);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Log of Residual Forces",
|
||||
// history.logResidualForces,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Log of Kinetic energy",
|
||||
// history.kineticEnergy,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
SimulationResultsReporter reporter;
|
||||
reporter.reportHistory(history, "IntermediateResults", pJob->pMesh->getLabel());
|
||||
// SimulationResultsReporter::createPlot("Number of Iterations",
|
||||
// "Sum of normalized displacement norms",
|
||||
// history.sumOfNormalizedDisplacementNorms /*,
|
||||
// std::filesystem::path("./")
|
||||
// .append("SumOfNormalizedDisplacementNorms_" + graphSuffix + ".png")
|
||||
// .string()*/
|
||||
// ,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Percentage of convergence",
|
||||
// percentageOfConvergence,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
}
|
||||
|
||||
#ifdef POLYSCOPE_DEFINED
|
||||
if (mSettings.shouldDraw && mSettings.isDebugMode
|
||||
&& mCurrentSimulationStep % mSettings.drawingStep == 0) /* &&
|
||||
|
@ -2163,40 +2211,19 @@ currentSimulationStep > maxDRMIterations*/
|
|||
// shouldUseKineticEnergyThreshold = true;
|
||||
}
|
||||
#endif
|
||||
if (mSettings.shouldCreatePlots && mSettings.isDebugMode
|
||||
&& mCurrentSimulationStep % mSettings.debugModeStep == 0) {
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Residual Forces mov aver deriv",
|
||||
// movingAveragesDerivatives_norm);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Residual Forces mov aver",
|
||||
// history.residualForcesMovingAverage);
|
||||
SimulationResultsReporter::createPlot("Number of Steps",
|
||||
"Log of Residual Forces",
|
||||
history.logResidualForces,
|
||||
{},
|
||||
history.redMarks);
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Log of Kinetic energy",
|
||||
// history.kineticEnergy);
|
||||
// SimulationResultsReporter reporter;
|
||||
// reporter.reportHistory(history, "Results");
|
||||
// SimulationResultsReporter::createPlot("Number of Steps",
|
||||
// "Percentage of convergence",
|
||||
// percentageOfConvergence,
|
||||
// {},
|
||||
// history.redMarks);
|
||||
}
|
||||
|
||||
// t = t + Dt;
|
||||
// std::cout << "Kinetic energy:" << mesh.currentTotalKineticEnergy
|
||||
// << std::endl;
|
||||
// std::cout << "Residual forces norm:" << mesh.totalResidualForcesNorm
|
||||
// << std::endl;
|
||||
// Residual forces norm convergence
|
||||
if (pMesh->previousTotalKineticEnergy > pMesh->currentTotalKineticEnergy
|
||||
&& mCurrentSimulationStep > movingAverageSampleSize
|
||||
if ((pMesh->previousTotalKineticEnergy > pMesh->currentTotalKineticEnergy
|
||||
// && mCurrentSimulationStep > movingAverageSampleSize
|
||||
&& (pJob->nodalForcedDisplacements.empty()
|
||||
|| mCurrentSimulationStep > mSettings.gradualForcedDisplacementSteps)
|
||||
|| mCurrentSimulationStep > mSettings.gradualForcedDisplacementSteps))
|
||||
/* || (pMesh->totalResidualForcesNorm / mSettings.totalResidualForcesNormThreshold <= 1
|
||||
&& mCurrentSimulationStep > 1)*/
|
||||
/*||
|
||||
mesh->previousTotalPotentialEnergykN >
|
||||
mesh->currentTotalPotentialEnergykN*/
|
||||
|
@ -2221,7 +2248,7 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
// || fullfillsMovingAverageDerivativeNormTerminationCriterion
|
||||
|| fullfillsResidualForcesNormTerminationCriterion;
|
||||
if (shouldTerminate) {
|
||||
if (mSettings.beVerbose) {
|
||||
if (mSettings.beVerbose && !mSettings.isDebugMode) {
|
||||
std::cout << "Simulation converged." << std::endl;
|
||||
printCurrentState();
|
||||
if (fullfillsResidualForcesNormTerminationCriterion) {
|
||||
|
@ -2232,7 +2259,8 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
" used as a convergence criterion"
|
||||
<< std::endl;
|
||||
} else if (fullfillsMovingAverageNormTerminationCriterion) {
|
||||
std::cout << "Converged using residual forces moving average derivative norm "
|
||||
std::cout
|
||||
<< "Converged using residual forces moving average derivative norm "
|
||||
"threshold criterion"
|
||||
<< std::endl;
|
||||
}
|
||||
|
@ -2241,9 +2269,6 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
// }
|
||||
}
|
||||
|
||||
// if (mSettings.beVerbose) {
|
||||
// printCurrentState();
|
||||
// }
|
||||
// const bool shouldCapDisplacements = mSettings.displacementCap.has_value();
|
||||
// for (VertexType &v : pMesh->vert) {
|
||||
// Node &node = pMesh->nodes[v];
|
||||
|
@ -2264,8 +2289,8 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
// }
|
||||
// updateElementalLengths();
|
||||
|
||||
// const double triggerPercentage = 0.001;
|
||||
// const double xi_min = 0.85;
|
||||
// const double triggerPercentage = 0.01;
|
||||
// const double xi_min = 0.55;
|
||||
// const double xi_init = 0.9969;
|
||||
// if (mSettings.totalResidualForcesNormThreshold / pMesh->totalResidualForcesNorm
|
||||
// > triggerPercentage) {
|
||||
|
@ -2276,6 +2301,9 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
// / (1 - triggerPercentage);
|
||||
// }
|
||||
Dt *= mSettings.xi;
|
||||
// if (mSettings.isDebugMode) {
|
||||
// std::cout << Dt << std::endl;
|
||||
// }
|
||||
resetVelocities();
|
||||
++numOfDampings;
|
||||
if (mSettings.shouldCreatePlots) {
|
||||
|
@ -2289,33 +2317,25 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
SimulationResults results = computeResults(pJob);
|
||||
|
||||
if (mCurrentSimulationStep == settings.maxDRMIterations && mCurrentSimulationStep != 0) {
|
||||
if (mSettings.beVerbose) {
|
||||
std::cout << "Did not reach equilibrium before reaching the maximum number "
|
||||
"of DRM steps ("
|
||||
<< settings.maxDRMIterations << "). Breaking simulation" << std::endl;
|
||||
}
|
||||
results.converged = false;
|
||||
} else if (std::isnan(pMesh->currentTotalKineticEnergy)) {
|
||||
if (mSettings.beVerbose) {
|
||||
std::cerr << "Simulation did not converge due to infinite kinetic energy." << std::endl;
|
||||
}
|
||||
results.converged = false;
|
||||
|
||||
} else if (mSettings.beVerbose) {
|
||||
auto t2 = std::chrono::high_resolution_clock::now();
|
||||
double simulationDuration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1)
|
||||
.count();
|
||||
simulationDuration /= 1000;
|
||||
std::cout << "Simulation converged after " << simulationDuration << "s" << std::endl;
|
||||
std::cout << "Time/(node*iteration) "
|
||||
<< simulationDuration / (static_cast<double>(mCurrentSimulationStep) * pMesh->VN())
|
||||
<< "s" << std::endl;
|
||||
std::cout << "Number of dampings:" << numOfDampings << endl;
|
||||
std::cout << "Number of steps:" << mCurrentSimulationStep << endl;
|
||||
}
|
||||
// mesh.printVertexCoordinates(mesh.VN() / 2);
|
||||
#ifdef POLYSCOPE_DEFINED
|
||||
if (settings.shouldDraw) {
|
||||
if (mSettings.shouldDraw && !mSettings.isDebugMode) {
|
||||
draw();
|
||||
}
|
||||
#endif
|
||||
if (results.converged) {
|
||||
if (!std::isnan(pMesh->currentTotalKineticEnergy)) {
|
||||
results.debug_drmDisplacements = results.displacements;
|
||||
results.internalPotentialEnergy = computeTotalInternalPotentialEnergy();
|
||||
|
||||
|
@ -2325,7 +2345,8 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
results.debug_q_nr.resize(pMesh->VN());
|
||||
for (int vi = 0; vi < pMesh->VN(); vi++) {
|
||||
const Node &node = pMesh->nodes[vi];
|
||||
const Eigen::Vector3d nInitial_eigen = node.initialNormal.ToEigenVector<Eigen::Vector3d>();
|
||||
const Eigen::Vector3d nInitial_eigen = node.initialNormal
|
||||
.ToEigenVector<Eigen::Vector3d>();
|
||||
const Eigen::Vector3d nDeformed_eigen
|
||||
= pMesh->vert[vi].cN().ToEigenVector<Eigen::Vector3d>();
|
||||
|
||||
|
@ -2347,9 +2368,9 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
assert(pMesh->nodes[vi].nR - nr_debug < 1e-6);
|
||||
VectorType referenceT1_deformed = pMesh->elements[node.referenceElement].frame.t1;
|
||||
const VectorType &nDeformed = pMesh->vert[vi].cN();
|
||||
const VectorType referenceF1_deformed = (referenceT1_deformed
|
||||
- (node.initialNormal
|
||||
* (referenceT1_deformed * node.initialNormal)))
|
||||
const VectorType referenceF1_deformed
|
||||
= (referenceT1_deformed
|
||||
- (node.initialNormal * (referenceT1_deformed * node.initialNormal)))
|
||||
.Normalize();
|
||||
|
||||
const VectorType referenceT1_initial
|
||||
|
@ -2368,9 +2389,12 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
// const VectorType &n_initial = node.initialNormal;
|
||||
const VectorType referenceF1_initial_def
|
||||
= (referenceT1_initial - (nDeformed * (referenceT1_initial * nDeformed))).Normalize();
|
||||
const VectorType referenceF1_deformed_def
|
||||
= (referenceT1_deformed - (nDeformed * (referenceT1_deformed * nDeformed))).Normalize();
|
||||
q_f1_nDeformed.setFromTwoVectors(referenceF1_initial_def.ToEigenVector<Eigen::Vector3d>(),
|
||||
const VectorType referenceF1_deformed_def = (referenceT1_deformed
|
||||
- (nDeformed
|
||||
* (referenceT1_deformed * nDeformed)))
|
||||
.Normalize();
|
||||
q_f1_nDeformed
|
||||
.setFromTwoVectors(referenceF1_initial_def.ToEigenVector<Eigen::Vector3d>(),
|
||||
referenceF1_deformed_def.ToEigenVector<Eigen::Vector3d>());
|
||||
const auto debug_qf1_nDef = (q_f1_nDeformed * q_nr_nDeformed) * nDeformed_eigen;
|
||||
const auto debug_qf1_nInit = (q_f1_nInit * q_nr_nInit) * nInitial_eigen;
|
||||
|
@ -2386,10 +2410,12 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
results.debug_q_normal[vi] = q_normal;
|
||||
results.debug_q_nr[vi] = q_nr_nInit;
|
||||
results.rotationalDisplacementQuaternion[vi]
|
||||
= (q_normal * (q_f1_nInit * q_nr_nInit)); //q_f1_nDeformed * q_nr_nDeformed * q_normal;
|
||||
= (q_normal
|
||||
* (q_f1_nInit * q_nr_nInit)); //q_f1_nDeformed * q_nr_nDeformed * q_normal;
|
||||
//Update the displacement vector to contain the euler angles
|
||||
const Eigen::Vector3d eulerAngles
|
||||
= results.rotationalDisplacementQuaternion[vi].toRotationMatrix().eulerAngles(0, 1, 2);
|
||||
const Eigen::Vector3d eulerAngles = results.rotationalDisplacementQuaternion[vi]
|
||||
.toRotationMatrix()
|
||||
.eulerAngles(0, 1, 2);
|
||||
results.displacements[vi][3] = eulerAngles[0];
|
||||
results.displacements[vi][4] = eulerAngles[1];
|
||||
results.displacements[vi][5] = eulerAngles[2];
|
||||
|
@ -2406,7 +2432,7 @@ mesh->currentTotalPotentialEnergykN*/
|
|||
}
|
||||
}
|
||||
|
||||
if (mSettings.shouldCreatePlots && results.converged) {
|
||||
if (!mSettings.isDebugMode && mSettings.shouldCreatePlots) {
|
||||
SimulationResultsReporter reporter;
|
||||
reporter.reportResults({results}, "Results", pJob->pMesh->getLabel());
|
||||
}
|
||||
|
|
|
@ -31,8 +31,7 @@ public:
|
|||
bool beVerbose{false};
|
||||
bool shouldCreatePlots{false};
|
||||
int drawingStep{1};
|
||||
double totalTranslationalKineticEnergyThreshold{1e-10};
|
||||
double totalExternalForcesNormPercentageTermination{1e-3};
|
||||
double totalTranslationalKineticEnergyThreshold{1e-8};
|
||||
double residualForcesMovingAverageDerivativeNormThreshold{1e-8};
|
||||
double residualForcesMovingAverageNormThreshold{1e-8};
|
||||
double Dtini{0.1};
|
||||
|
|
|
@ -254,7 +254,8 @@ struct Colors
|
|||
{
|
||||
std::string label{"EmptyLabel"};
|
||||
double time{-1};
|
||||
int numberOfSimulationCrashes{0};
|
||||
bool wasSuccessful{true};
|
||||
// int numberOfSimulationCrashes{0};
|
||||
Settings settings;
|
||||
struct ObjectiveValues
|
||||
{
|
||||
|
@ -273,6 +274,7 @@ struct Colors
|
|||
|
||||
PatternGeometry baseTriangleFullPattern; //non-fanned,non-tiled full pattern
|
||||
vcg::Triangle3<double> baseTriangle;
|
||||
std::string notes;
|
||||
|
||||
struct JsonKeys
|
||||
{
|
||||
|
@ -294,15 +296,19 @@ struct Colors
|
|||
//Save optimal X
|
||||
nlohmann::json json_optimizationResults;
|
||||
json_optimizationResults[JsonKeys::Label] = label;
|
||||
if (wasSuccessful) {
|
||||
std::string jsonValue_optimizationVariables;
|
||||
for (const auto &optimalXNameValuePair : optimalXNameValuePairs) {
|
||||
jsonValue_optimizationVariables.append(optimalXNameValuePair.first + ",");
|
||||
}
|
||||
jsonValue_optimizationVariables.pop_back(); // for deleting the last comma
|
||||
json_optimizationResults[JsonKeys::optimizationVariables] = jsonValue_optimizationVariables;
|
||||
json_optimizationResults[JsonKeys::optimizationVariables]
|
||||
= jsonValue_optimizationVariables;
|
||||
|
||||
for (const auto &optimalXNameValuePair : optimalXNameValuePairs) {
|
||||
json_optimizationResults[optimalXNameValuePair.first] = optimalXNameValuePair.second;
|
||||
json_optimizationResults[optimalXNameValuePair.first] = optimalXNameValuePair
|
||||
.second;
|
||||
}
|
||||
}
|
||||
//base triangle
|
||||
json_optimizationResults[JsonKeys::baseTriangle]
|
||||
|
@ -650,7 +656,8 @@ struct Colors
|
|||
os << nameValuePair.first;
|
||||
}
|
||||
os << "Time(s)";
|
||||
os << "#Crashes";
|
||||
// os << "#Crashes";
|
||||
// os << "notes";
|
||||
}
|
||||
|
||||
void writeResultsTo(const Settings &settings_optimization, csvFile &os) const
|
||||
|
@ -669,11 +676,12 @@ struct Colors
|
|||
}
|
||||
|
||||
os << time;
|
||||
if (numberOfSimulationCrashes == 0) {
|
||||
os << "-";
|
||||
} else {
|
||||
os << numberOfSimulationCrashes;
|
||||
}
|
||||
// if (numberOfSimulationCrashes == 0) {
|
||||
// os << "-";
|
||||
// } else {
|
||||
// os << numberOfSimulationCrashes;
|
||||
// }
|
||||
// os << notes;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ struct SimulationResultsReporter {
|
|||
const std::string &graphSuffix = std::string())
|
||||
{
|
||||
const auto simulationResultPath = std::filesystem::path(reportFolderPath).append(history.label);
|
||||
std::filesystem::create_directory(simulationResultPath);
|
||||
std::filesystem::create_directories(simulationResultPath);
|
||||
createPlots(history, simulationResultPath, graphSuffix);
|
||||
}
|
||||
|
||||
|
|
|
@ -177,8 +177,13 @@ void TopologyEnumerator::computeValidPatterns(const std::vector<size_t> &reduced
|
|||
auto perEdgeResultPath = std::filesystem::path(resultsPath)
|
||||
.append(std::to_string(numberOfEdges));
|
||||
if (std::filesystem::exists(perEdgeResultPath)) {
|
||||
if (debugIsOn) {
|
||||
std::filesystem::remove_all(perEdgeResultPath);
|
||||
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
std::filesystem::create_directory(perEdgeResultPath);
|
||||
computeValidPatterns(numberOfNodesPerSlot,
|
||||
numberOfEdges,
|
||||
|
@ -517,8 +522,7 @@ void TopologyEnumerator::computeValidPatterns(
|
|||
// Check dangling edges with vcg method
|
||||
// const bool vcg_tiledPatternHasDangling =
|
||||
// tiledPatternGeometry.hasUntiledDanglingEdges();
|
||||
if (tiledPatternHasDanglingEdges /*&& !hasFloatingComponents &&
|
||||
!hasArticulationPoints*/) {
|
||||
if (tiledPatternHasDanglingEdges && !hasFloatingComponents /*&& !hasArticulationPoints*/) {
|
||||
statistics.numberOfPatternsWithADanglingEdgeOrNode++;
|
||||
if (debugIsOn) {
|
||||
if (savePlyFiles) {
|
||||
|
@ -539,8 +543,7 @@ void TopologyEnumerator::computeValidPatterns(
|
|||
}
|
||||
}
|
||||
|
||||
if (hasFloatingComponents /*&& !hasArticulationPoints &&
|
||||
!tiledPatternHasDanglingEdges*/) {
|
||||
if (hasFloatingComponents && !hasArticulationPoints && !tiledPatternHasDanglingEdges) {
|
||||
statistics.numberOfPatternsWithMoreThanASingleCC++;
|
||||
if (debugIsOn) {
|
||||
if (savePlyFiles) {
|
||||
|
|
|
@ -15,12 +15,12 @@ bool VCGTriMesh::load(const std::string &filename) {
|
|||
mask |= nanoply::NanoPlyWrapper<VCGTriMesh>::IO_EDGEINDEX;
|
||||
mask |= nanoply::NanoPlyWrapper<VCGTriMesh>::IO_FACEINDEX;
|
||||
|
||||
if (nanoply::NanoPlyWrapper<VCGTriMesh>::LoadModel(
|
||||
std::filesystem::absolute(filename).string().c_str(), *this, mask)
|
||||
!= 0) {
|
||||
// if (vcg::tri::io::Importer<VCGTriMesh>::Open(*this,
|
||||
// std::filesystem::absolute(filename).string().c_str())
|
||||
// if (nanoply::NanoPlyWrapper<VCGTriMesh>::LoadModel(
|
||||
// std::filesystem::absolute(filename).string().c_str(), *this, mask)
|
||||
// != 0) {
|
||||
if (vcg::tri::io::Importer<VCGTriMesh>::Open(*this,
|
||||
std::filesystem::absolute(filename).string().c_str())
|
||||
!= 0) {
|
||||
std::cout << "Could not load tri mesh" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue