Using quadratic reset. Unit tests 2120 ,3333,9268 iterations
This commit is contained in:
parent
76fb1b8609
commit
90551e5485
|
|
@ -45,10 +45,11 @@ void DRMSimulationModel::runUnitTests()
|
||||||
Settings settings;
|
Settings settings;
|
||||||
settings.Dtini = 0.1;
|
settings.Dtini = 0.1;
|
||||||
settings.xi = 0.9969;
|
settings.xi = 0.9969;
|
||||||
settings.maxDRMIterations = 0;
|
settings.totalResidualForcesNormThreshold = 1;
|
||||||
formFinder.mSettings.totalResidualForcesNormThreshold = 1;
|
|
||||||
settings.shouldDraw = false;
|
settings.shouldDraw = false;
|
||||||
settings.beVerbose = true;
|
settings.beVerbose = true;
|
||||||
|
// settings.debugModeStep = 1000;
|
||||||
|
// settings.shouldDraw = true;
|
||||||
settings.shouldCreatePlots = true;
|
settings.shouldCreatePlots = true;
|
||||||
SimulationResults simpleBeam_simulationResults
|
SimulationResults simpleBeam_simulationResults
|
||||||
= formFinder.executeSimulation(std::make_shared<SimulationJob>(beamSimulationJob), settings);
|
= formFinder.executeSimulation(std::make_shared<SimulationJob>(beamSimulationJob), settings);
|
||||||
|
|
@ -104,8 +105,9 @@ void DRMSimulationModel::runUnitTests()
|
||||||
shortSpanGridshellSimulationJob.pMesh->setBeamMaterial(0.3, 200 * 1e9);
|
shortSpanGridshellSimulationJob.pMesh->setBeamMaterial(0.3, 200 * 1e9);
|
||||||
assert(typeid(CrossSectionType) == typeid(CylindricalBeamDimensions));
|
assert(typeid(CrossSectionType) == typeid(CylindricalBeamDimensions));
|
||||||
shortSpanGridshellSimulationJob.pMesh->setBeamCrossSection(CrossSectionType{0.03, 0.026});
|
shortSpanGridshellSimulationJob.pMesh->setBeamCrossSection(CrossSectionType{0.03, 0.026});
|
||||||
|
DRMSimulationModel formFinder2;
|
||||||
SimulationResults shortSpanGridshellSimulationResults
|
SimulationResults shortSpanGridshellSimulationResults
|
||||||
= formFinder.executeSimulation(std::make_shared<SimulationJob>(
|
= formFinder2.executeSimulation(std::make_shared<SimulationJob>(
|
||||||
shortSpanGridshellSimulationJob),
|
shortSpanGridshellSimulationJob),
|
||||||
settings);
|
settings);
|
||||||
shortSpanGridshellSimulationResults.save();
|
shortSpanGridshellSimulationResults.save();
|
||||||
|
|
@ -183,8 +185,9 @@ void DRMSimulationModel::runUnitTests()
|
||||||
}
|
}
|
||||||
longSpanGridshell_simulationJob.pMesh->setBeamCrossSection(CrossSectionType{0.03, 0.026});
|
longSpanGridshell_simulationJob.pMesh->setBeamCrossSection(CrossSectionType{0.03, 0.026});
|
||||||
|
|
||||||
|
DRMSimulationModel formFinder3;
|
||||||
SimulationResults longSpanGridshell_simulationResults
|
SimulationResults longSpanGridshell_simulationResults
|
||||||
= formFinder.executeSimulation(std::make_shared<SimulationJob>(
|
= formFinder3.executeSimulation(std::make_shared<SimulationJob>(
|
||||||
longSpanGridshell_simulationJob),
|
longSpanGridshell_simulationJob),
|
||||||
settings);
|
settings);
|
||||||
longSpanGridshell_simulationResults.save();
|
longSpanGridshell_simulationResults.save();
|
||||||
|
|
@ -217,22 +220,14 @@ void DRMSimulationModel::runUnitTests()
|
||||||
|
|
||||||
// polyscope::show();
|
// polyscope::show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DRMSimulationModel::reset(const std::shared_ptr<SimulationJob> &pJob)
|
void DRMSimulationModel::reset(const std::shared_ptr<SimulationJob> &pJob)
|
||||||
{
|
{
|
||||||
mCurrentSimulationStep = 0;
|
//#ifdef USE_ENSMALLEN
|
||||||
history.clear();
|
// this->pJob = pJob;
|
||||||
history.label = pJob->pMesh->getLabel() + "_" + pJob->getLabel();
|
//#endif
|
||||||
plotYValues.clear();
|
pMesh.reset();
|
||||||
plotHandle.reset();
|
pMesh = std::make_unique<SimulationMesh>(*pJob->pMesh);
|
||||||
checkedForMaximumMoment = false;
|
vcg::tri::UpdateBounding<SimulationMesh>::Box(*pMesh);
|
||||||
externalMomentsNorm = 0;
|
|
||||||
Dt = mSettings.Dtini;
|
|
||||||
numOfDampings = 0;
|
|
||||||
shouldTemporarilyDampForces = false;
|
|
||||||
externalLoadStep = 1;
|
|
||||||
isVertexConstrained.clear();
|
|
||||||
minTotalResidualForcesNorm = std::numeric_limits<double>::max();
|
|
||||||
|
|
||||||
constrainedVertices.clear();
|
constrainedVertices.clear();
|
||||||
constrainedVertices = pJob->constrainedVertices;
|
constrainedVertices = pJob->constrainedVertices;
|
||||||
|
|
@ -247,6 +242,26 @@ void DRMSimulationModel::reset(const std::shared_ptr<SimulationJob> &pJob)
|
||||||
for (auto fixedVertex : constrainedVertices) {
|
for (auto fixedVertex : constrainedVertices) {
|
||||||
isVertexConstrained[fixedVertex.first] = true;
|
isVertexConstrained[fixedVertex.first] = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRMSimulationModel::reset(const std::shared_ptr<SimulationJob> &pJob, const Settings &settings)
|
||||||
|
{
|
||||||
|
mSettings = settings;
|
||||||
|
mCurrentSimulationStep = 0;
|
||||||
|
history.clear();
|
||||||
|
history.label = pJob->pMesh->getLabel() + "_" + pJob->getLabel();
|
||||||
|
plotYValues.clear();
|
||||||
|
plotHandle.reset();
|
||||||
|
checkedForMaximumMoment = false;
|
||||||
|
externalMomentsNorm = 0;
|
||||||
|
Dt = settings.Dtini;
|
||||||
|
numOfDampings = 0;
|
||||||
|
shouldTemporarilyDampForces = false;
|
||||||
|
externalLoadStep = 1;
|
||||||
|
isVertexConstrained.clear();
|
||||||
|
minTotalResidualForcesNorm = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
|
reset(pJob);
|
||||||
|
|
||||||
#ifdef POLYSCOPE_DEFINED
|
#ifdef POLYSCOPE_DEFINED
|
||||||
if (mSettings.shouldDraw || mSettings.debugModeStep.has_value()) {
|
if (mSettings.shouldDraw || mSettings.debugModeStep.has_value()) {
|
||||||
|
|
@ -257,14 +272,14 @@ void DRMSimulationModel::reset(const std::shared_ptr<SimulationJob> &pJob)
|
||||||
polyscope::registerCurveNetwork("Initial_" + meshPolyscopeLabel + "_" + pMesh->getLabel(),
|
polyscope::registerCurveNetwork("Initial_" + meshPolyscopeLabel + "_" + pMesh->getLabel(),
|
||||||
pMesh->getEigenVertices(),
|
pMesh->getEigenVertices(),
|
||||||
pMesh->getEigenEdges())
|
pMesh->getEigenEdges())
|
||||||
->setRadius(pMesh->elements[0].dimensions.getDrawingRadius());
|
->setRadius(0.002);
|
||||||
// registerWorldAxes();
|
// registerWorldAxes();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// if (!pJob->nodalForcedDisplacements.empty() && pJob->nodalExternalForces.empty()) {
|
if (!pJob->nodalForcedDisplacements.empty() && pJob->nodalExternalForces.empty()) {
|
||||||
// shouldApplyInitialDistortion = true;
|
shouldApplyInitialDistortion = true;
|
||||||
// }
|
}
|
||||||
updateElementalFrames();
|
updateElementalFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1414,7 +1429,6 @@ void DRMSimulationModel::updateResidualForces()
|
||||||
|
|
||||||
void DRMSimulationModel::computeRigidSupports()
|
void DRMSimulationModel::computeRigidSupports()
|
||||||
{
|
{
|
||||||
assert(pMesh != nullptr);
|
|
||||||
isRigidSupport.clear();
|
isRigidSupport.clear();
|
||||||
isRigidSupport.resize(pMesh->VN(), false);
|
isRigidSupport.resize(pMesh->VN(), false);
|
||||||
for (const VertexType &v : pMesh->vert) {
|
for (const VertexType &v : pMesh->vert) {
|
||||||
|
|
@ -1625,6 +1639,7 @@ 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.previousVelocity = node.velocity;
|
||||||
if (mSettings.viscousDampingFactor.has_value()) {
|
if (mSettings.viscousDampingFactor.has_value()) {
|
||||||
const Vector6d massOverDt = node.mass_6d / Dt;
|
const Vector6d massOverDt = node.mass_6d / Dt;
|
||||||
// const Vector6d visciousDampingFactor(viscuousDampingConstant / 2);
|
// const Vector6d visciousDampingFactor(viscuousDampingConstant / 2);
|
||||||
|
|
@ -1777,11 +1792,17 @@ void DRMSimulationModel::updateNodeNormal(
|
||||||
void DRMSimulationModel::applyDisplacements(
|
void DRMSimulationModel::applyDisplacements(
|
||||||
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices)
|
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices)
|
||||||
{
|
{
|
||||||
for (VertexType &v : pMesh->vert) {
|
std::for_each(
|
||||||
|
#ifdef ENABLE_PARALLEL_DRM
|
||||||
|
std::execution::par_unseq,
|
||||||
|
#endif
|
||||||
|
pMesh->vert.begin(),
|
||||||
|
pMesh->vert.end(),
|
||||||
|
[&](auto &v) {
|
||||||
updateNodePosition(v, fixedVertices);
|
updateNodePosition(v, fixedVertices);
|
||||||
updateNodeNormal(v, fixedVertices);
|
updateNodeNormal(v, fixedVertices);
|
||||||
updateNodeNr(v);
|
updateNodeNr(v);
|
||||||
}
|
});
|
||||||
updateElementalFrames();
|
updateElementalFrames();
|
||||||
if (mSettings.shouldDraw) {
|
if (mSettings.shouldDraw) {
|
||||||
pMesh->updateEigenEdgeAndVertices();
|
pMesh->updateEigenEdgeAndVertices();
|
||||||
|
|
@ -1847,8 +1868,12 @@ void DRMSimulationModel::applyForcedNormals(
|
||||||
// NOTE: Is this correct? Should the kinetic energy be computed like that?
|
// NOTE: Is this correct? Should the kinetic energy be computed like that?
|
||||||
void DRMSimulationModel::updateKineticEnergy()
|
void DRMSimulationModel::updateKineticEnergy()
|
||||||
{
|
{
|
||||||
|
pMesh->pre_previousTotalKineticEnergy = pMesh->previousTotalKineticEnergy;
|
||||||
|
pMesh->pre_previousTotalTranslationalKineticEnergy
|
||||||
|
= pMesh->previousTotalTranslationalKineticEnergy;
|
||||||
|
pMesh->pre_previousTotalRotationalKineticEnergy = pMesh->previousTotalRotationalKineticEnergy;
|
||||||
pMesh->previousTotalKineticEnergy = pMesh->currentTotalKineticEnergy;
|
pMesh->previousTotalKineticEnergy = pMesh->currentTotalKineticEnergy;
|
||||||
pMesh->previousTranslationalKineticEnergy = pMesh->currentTotalTranslationalKineticEnergy;
|
pMesh->previousTotalTranslationalKineticEnergy = pMesh->currentTotalTranslationalKineticEnergy;
|
||||||
pMesh->previousTotalRotationalKineticEnergy = pMesh->currentTotalRotationalKineticEnergy;
|
pMesh->previousTotalRotationalKineticEnergy = pMesh->currentTotalRotationalKineticEnergy;
|
||||||
pMesh->currentTotalKineticEnergy = 0;
|
pMesh->currentTotalKineticEnergy = 0;
|
||||||
pMesh->currentTotalTranslationalKineticEnergy = 0;
|
pMesh->currentTotalTranslationalKineticEnergy = 0;
|
||||||
|
|
@ -1889,7 +1914,14 @@ void DRMSimulationModel::resetVelocities()
|
||||||
// // reset
|
// // reset
|
||||||
// // current to 0 or this?
|
// // current to 0 or this?
|
||||||
0;
|
0;
|
||||||
|
pMesh->nodes[v].previousVelocity = 0;
|
||||||
}
|
}
|
||||||
|
pMesh->pre_previousTotalKineticEnergy = 0;
|
||||||
|
pMesh->pre_previousTotalTranslationalKineticEnergy = 0;
|
||||||
|
pMesh->pre_previousTotalRotationalKineticEnergy = 0;
|
||||||
|
pMesh->previousTotalKineticEnergy = 0;
|
||||||
|
pMesh->previousTotalTranslationalKineticEnergy = 0;
|
||||||
|
pMesh->previousTotalRotationalKineticEnergy = 0;
|
||||||
updateKineticEnergy();
|
updateKineticEnergy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1960,6 +1992,7 @@ void DRMSimulationModel::updatePositionsOnTheFly(
|
||||||
|
|
||||||
for (VertexType &v : pMesh->vert) {
|
for (VertexType &v : pMesh->vert) {
|
||||||
Node &node = pMesh->nodes[v];
|
Node &node = pMesh->nodes[v];
|
||||||
|
node.previousVelocity = node.velocity;
|
||||||
node.velocity = node.velocity + node.acceleration * Dt;
|
node.velocity = node.velocity + node.acceleration * Dt;
|
||||||
}
|
}
|
||||||
updateKineticEnergy();
|
updateKineticEnergy();
|
||||||
|
|
@ -2564,15 +2597,26 @@ void DRMSimulationModel::applyKineticDamping(const std::shared_ptr<SimulationJob
|
||||||
{
|
{
|
||||||
// if (!mSettings.viscousDampingFactor.has_value()) {
|
// if (!mSettings.viscousDampingFactor.has_value()) {
|
||||||
// const bool shouldCapDisplacements = mSettings.displacementCap.has_value();
|
// const bool shouldCapDisplacements = mSettings.displacementCap.has_value();
|
||||||
|
// const double &KE1 = pMesh->pre_previousTotalKineticEnergy;
|
||||||
|
// const double &KE2 = pMesh->previousTotalKineticEnergy;
|
||||||
|
// const double &KE3 = pMesh->currentTotalKineticEnergy;
|
||||||
|
const double &KE1 = pMesh->pre_previousTotalTranslationalKineticEnergy;
|
||||||
|
const double &KE2 = pMesh->previousTotalTranslationalKineticEnergy;
|
||||||
|
const double &KE3 = pMesh->currentTotalTranslationalKineticEnergy;
|
||||||
|
const double bitaDt = 0.5 * Dt * (3 + (-3 * KE1 + 4 * KE2 - KE3) / (KE1 - 2 * KE2 + KE3));
|
||||||
for (VertexType &v : pMesh->vert) {
|
for (VertexType &v : pMesh->vert) {
|
||||||
Node &node = pMesh->nodes[v];
|
Node &node = pMesh->nodes[v];
|
||||||
Vector6d stepDisplacement = node.velocity * 0.5 * Dt;
|
// Vector6d stepDisplacement = node.velocity * 0.5 * 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());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// Vector6d stepDisplacement = node.velocity * 0.5 * Dt;
|
||||||
|
Vector6d stepDisplacement = node.velocity * Dt + node.previousVelocity * bitaDt;
|
||||||
|
|
||||||
node.displacements = node.displacements - stepDisplacement;
|
node.displacements = node.displacements - stepDisplacement;
|
||||||
}
|
}
|
||||||
applyDisplacements(constrainedVertices);
|
applyDisplacements(constrainedVertices);
|
||||||
|
|
@ -2598,46 +2642,33 @@ void DRMSimulationModel::applyKineticDamping(const std::shared_ptr<SimulationJob
|
||||||
++numOfDampings;
|
++numOfDampings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DRMSimulationModel::updateDerivatives()
|
||||||
|
{
|
||||||
|
updateNormalDerivatives();
|
||||||
|
updateT1Derivatives();
|
||||||
|
updateRDerivatives();
|
||||||
|
updateT2Derivatives();
|
||||||
|
updateT3Derivatives();
|
||||||
|
}
|
||||||
|
|
||||||
SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<SimulationJob> &pJob)
|
SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<SimulationJob> &pJob)
|
||||||
{
|
{
|
||||||
assert(pMesh != nullptr && pMesh->VN() == pJob->pMesh->VN() && pMesh->EN() == pJob->pMesh->EN());
|
|
||||||
reset(pJob);
|
|
||||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
updateNodalMasses();
|
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);
|
|
||||||
// for (auto &nodalForce : nodalExternalForces) {
|
|
||||||
// const double percentageOfExternalLoads = double(externalLoadStep)
|
|
||||||
// / mSettings.desiredGradualExternalLoadsSteps;
|
|
||||||
// nodalForce.second = nodalForce.second * percentageOfExternalLoads;
|
|
||||||
// totalExternalForcesNorm += nodalForce.second.norm();
|
|
||||||
// // sumOfExternalForces = sumOfExternalForces + nodalForce.second;
|
|
||||||
// }
|
|
||||||
updateNodalExternalForces(pJob->nodalExternalForces, constrainedVertices);
|
updateNodalExternalForces(pJob->nodalExternalForces, constrainedVertices);
|
||||||
if (!pJob->nodalExternalForces.empty()) {
|
if (!pJob->nodalExternalForces.empty()
|
||||||
|
&& !mSettings.totalResidualForcesNormThreshold.has_value()) {
|
||||||
mSettings.totalResidualForcesNormThreshold
|
mSettings.totalResidualForcesNormThreshold
|
||||||
= mSettings.totalExternalForcesNormPercentageTermination
|
= mSettings.totalExternalForcesNormPercentageTermination
|
||||||
* pMesh->totalExternalForcesNorm;
|
* pMesh->totalExternalForcesNorm;
|
||||||
} 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;
|
||||||
}
|
}*/
|
||||||
if (mSettings.beVerbose) {
|
if (mSettings.beVerbose) {
|
||||||
std::cout << "totalResidualForcesNormThreshold:"
|
// std::cout << "totalResidualForcesNormThreshold:"
|
||||||
<< mSettings.totalResidualForcesNormThreshold << std::endl;
|
// << mSettings.totalResidualForcesNormThreshold << std::endl;
|
||||||
if (mSettings.averageResidualForcesCriterionThreshold.has_value()) {
|
if (mSettings.averageResidualForcesCriterionThreshold.has_value()) {
|
||||||
std::cout << "average/extNorm threshold:"
|
std::cout << "average/extNorm threshold:"
|
||||||
<< *mSettings.averageResidualForcesCriterionThreshold << std::endl;
|
<< *mSettings.averageResidualForcesCriterionThreshold << std::endl;
|
||||||
|
|
@ -2655,25 +2686,7 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
||||||
// double residualForcesMovingAverageDerivativeMax = 0;
|
// double residualForcesMovingAverageDerivativeMax = 0;
|
||||||
while (!mSettings.maxDRMIterations.has_value()
|
while (!mSettings.maxDRMIterations.has_value()
|
||||||
|| mCurrentSimulationStep < mSettings.maxDRMIterations.value()) {
|
|| mCurrentSimulationStep < mSettings.maxDRMIterations.value()) {
|
||||||
// if ((mSettings.debugModeStep.has_value() && mCurrentSimulationStep == 50000)) {
|
updateDerivatives();
|
||||||
// std::filesystem::create_directory("./PatternOptimizationNonConv");
|
|
||||||
// pJob->save("./PatternOptimizationNonConv");
|
|
||||||
// Dt = mSettings.Dtini;
|
|
||||||
// }
|
|
||||||
// if (mCurrentSimulationStep == 500 && shouldTemporarilyDampForces) {
|
|
||||||
// Dt = mSettings.Dtini;
|
|
||||||
// }
|
|
||||||
// while (true) {
|
|
||||||
updateNormalDerivatives();
|
|
||||||
updateT1Derivatives();
|
|
||||||
updateRDerivatives();
|
|
||||||
updateT2Derivatives();
|
|
||||||
updateT3Derivatives();
|
|
||||||
const bool shouldBreak = mCurrentSimulationStep == 3935;
|
|
||||||
if (shouldBreak) {
|
|
||||||
int i = 0;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
updateResidualForcesOnTheFly(constrainedVertices);
|
updateResidualForcesOnTheFly(constrainedVertices);
|
||||||
|
|
||||||
// TODO: write parallel function for updating positions
|
// TODO: write parallel function for updating positions
|
||||||
|
|
@ -2690,9 +2703,6 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
||||||
|
|
||||||
pJob->nodalForcedDisplacements);
|
pJob->nodalForcedDisplacements);
|
||||||
}
|
}
|
||||||
// if (!pJob->nodalForcedNormals.empty()) {
|
|
||||||
// applyForcedNormals(pJob->nodalForcedNormals);
|
|
||||||
// }
|
|
||||||
updateElementalLengths();
|
updateElementalLengths();
|
||||||
mCurrentSimulationStep++;
|
mCurrentSimulationStep++;
|
||||||
if (std::isnan(pMesh->currentTotalKineticEnergy)) {
|
if (std::isnan(pMesh->currentTotalKineticEnergy)) {
|
||||||
|
|
@ -2790,8 +2800,8 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
||||||
// << std::endl;
|
// << std::endl;
|
||||||
}
|
}
|
||||||
history.stepPulse(*pMesh);
|
history.stepPulse(*pMesh);
|
||||||
percentageOfConvergence.push_back(100 * mSettings.totalResidualForcesNormThreshold
|
// percentageOfConvergence.push_back(100 * mSettings.totalResidualForcesNormThreshold
|
||||||
/ pMesh->totalResidualForcesNorm);
|
// / pMesh->totalResidualForcesNorm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSettings.shouldCreatePlots && mSettings.debugModeStep.has_value()
|
if (mSettings.shouldCreatePlots && mSettings.debugModeStep.has_value()
|
||||||
|
|
@ -2880,15 +2890,19 @@ currentSimulationStep > maxDRMIterations*/
|
||||||
// std::cout << "Residual forces norm:" << mesh.totalResidualForcesNorm
|
// std::cout << "Residual forces norm:" << mesh.totalResidualForcesNorm
|
||||||
// << std::endl;
|
// << std::endl;
|
||||||
const bool fullfillsResidualForcesNormTerminationCriterion
|
const bool fullfillsResidualForcesNormTerminationCriterion
|
||||||
= !mSettings.averageResidualForcesCriterionThreshold.has_value()
|
= mSettings.averageResidualForcesCriterionThreshold.has_value()
|
||||||
&& pMesh->totalResidualForcesNorm / pMesh->totalExternalForcesNorm
|
&& pMesh->totalResidualForcesNorm / pMesh->totalExternalForcesNorm
|
||||||
< mSettings.totalExternalForcesNormPercentageTermination;
|
< mSettings.totalExternalForcesNormPercentageTermination;
|
||||||
const bool fullfillsAverageResidualForcesNormTerminationCriterion
|
const bool fullfillsAverageResidualForcesNormTerminationCriterion
|
||||||
= mSettings.averageResidualForcesCriterionThreshold.has_value()
|
= mSettings.averageResidualForcesCriterionThreshold.has_value()
|
||||||
&& (pMesh->totalResidualForcesNorm / pMesh->VN()) / pMesh->totalExternalForcesNorm
|
&& (pMesh->totalResidualForcesNorm / pMesh->VN()) / pMesh->totalExternalForcesNorm
|
||||||
< mSettings.averageResidualForcesCriterionThreshold.value();
|
< mSettings.averageResidualForcesCriterionThreshold.value();
|
||||||
|
const bool fullfillsResidualForcesNormThreshold
|
||||||
|
= mSettings.totalResidualForcesNormThreshold.has_value()
|
||||||
|
&& pMesh->totalResidualForcesNorm < mSettings.totalResidualForcesNormThreshold;
|
||||||
if ((fullfillsAverageResidualForcesNormTerminationCriterion
|
if ((fullfillsAverageResidualForcesNormTerminationCriterion
|
||||||
|| fullfillsResidualForcesNormTerminationCriterion)
|
|| fullfillsResidualForcesNormTerminationCriterion
|
||||||
|
|| fullfillsResidualForcesNormThreshold)
|
||||||
&& numOfDampings > 0
|
&& numOfDampings > 0
|
||||||
&& (pJob->nodalForcedDisplacements.empty()
|
&& (pJob->nodalForcedDisplacements.empty()
|
||||||
|| mCurrentSimulationStep > mSettings.gradualForcedDisplacementSteps)) {
|
|| mCurrentSimulationStep > mSettings.gradualForcedDisplacementSteps)) {
|
||||||
|
|
@ -2906,11 +2920,14 @@ currentSimulationStep > maxDRMIterations*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isKineticEnergyPeak = (mSettings.useTotalRotationalKineticEnergyForKineticDamping
|
const bool isKineticEnergyPeak
|
||||||
|
= /* pMesh->previousTotalKineticEnergy > pMesh->currentTotalKineticEnergy
|
||||||
|
||*/
|
||||||
|
(mSettings.useTotalRotationalKineticEnergyForKineticDamping
|
||||||
&& pMesh->previousTotalRotationalKineticEnergy
|
&& pMesh->previousTotalRotationalKineticEnergy
|
||||||
> pMesh->currentTotalRotationalKineticEnergy)
|
> pMesh->currentTotalRotationalKineticEnergy)
|
||||||
|| (mSettings.useTranslationalKineticEnergyForKineticDamping
|
|| (mSettings.useTranslationalKineticEnergyForKineticDamping
|
||||||
&& pMesh->previousTranslationalKineticEnergy
|
&& pMesh->previousTotalTranslationalKineticEnergy
|
||||||
> pMesh->currentTotalTranslationalKineticEnergy);
|
> pMesh->currentTotalTranslationalKineticEnergy);
|
||||||
if (isKineticEnergyPeak) {
|
if (isKineticEnergyPeak) {
|
||||||
const bool fullfillsKineticEnergyTerminationCriterion
|
const bool fullfillsKineticEnergyTerminationCriterion
|
||||||
|
|
@ -2964,13 +2981,13 @@ currentSimulationStep > maxDRMIterations*/
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSettings.useTranslationalKineticEnergyForKineticDamping) {
|
// if (mSettings.useTranslationalKineticEnergyForKineticDamping) {
|
||||||
applyKineticDamping(pJob);
|
applyKineticDamping(pJob);
|
||||||
|
Dt *= mSettings.xi;
|
||||||
if (mSettings.shouldCreatePlots) {
|
if (mSettings.shouldCreatePlots) {
|
||||||
history.redMarks.push_back(mCurrentSimulationStep);
|
history.redMarks.push_back(mCurrentSimulationStep);
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
Dt *= mSettings.xi;
|
|
||||||
// if (mSettings.isDebugMode) {
|
// if (mSettings.isDebugMode) {
|
||||||
// std::cout << Dt << std::endl;
|
// std::cout << Dt << std::endl;
|
||||||
// }
|
// }
|
||||||
|
|
@ -3002,11 +3019,9 @@ currentSimulationStep > maxDRMIterations*/
|
||||||
|
|
||||||
void DRMSimulationModel::setStructure(const std::shared_ptr<SimulationMesh> &pMesh)
|
void DRMSimulationModel::setStructure(const std::shared_ptr<SimulationMesh> &pMesh)
|
||||||
{
|
{
|
||||||
this->pMesh.reset();
|
std::cout << "This function is currently not implemented" << std::endl;
|
||||||
this->pMesh = std::make_unique<SimulationMesh>(*pMesh);
|
assert(false);
|
||||||
vcg::tri::UpdateBounding<SimulationMesh>::Box(*pMesh);
|
std::terminate();
|
||||||
// assert(false);
|
|
||||||
// std::terminate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<SimulationJob> &pJob,
|
SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<SimulationJob> &pJob,
|
||||||
|
|
@ -3014,8 +3029,7 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
|
||||||
const SimulationResults &solutionGuess)
|
const SimulationResults &solutionGuess)
|
||||||
{
|
{
|
||||||
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
|
||||||
mSettings = settings;
|
reset(pJob, settings);
|
||||||
setStructure(pJob->pMesh);
|
|
||||||
assert(pJob->pMesh != nullptr);
|
assert(pJob->pMesh != nullptr);
|
||||||
|
|
||||||
if (!solutionGuess.displacements.empty()) {
|
if (!solutionGuess.displacements.empty()) {
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,8 @@ public:
|
||||||
int gradualForcedDisplacementSteps{50};
|
int gradualForcedDisplacementSteps{50};
|
||||||
// int desiredGradualExternalLoadsSteps{1};
|
// int desiredGradualExternalLoadsSteps{1};
|
||||||
double gamma{0.8};
|
double gamma{0.8};
|
||||||
double totalResidualForcesNormThreshold{1e-20};
|
std::optional<double> totalResidualForcesNormThreshold;
|
||||||
double totalExternalForcesNormPercentageTermination{1e-3};
|
double totalExternalForcesNormPercentageTermination{1e-5};
|
||||||
std::optional<int> maxDRMIterations;
|
std::optional<int> maxDRMIterations;
|
||||||
std::optional<int> debugModeStep;
|
std::optional<int> debugModeStep;
|
||||||
std::optional<double> totalTranslationalKineticEnergyThreshold;
|
std::optional<double> totalTranslationalKineticEnergyThreshold;
|
||||||
|
|
@ -104,10 +104,11 @@ private:
|
||||||
SimulationHistory history;
|
SimulationHistory history;
|
||||||
// Eigen::Tensor<double, 4> theta3Derivatives;
|
// Eigen::Tensor<double, 4> theta3Derivatives;
|
||||||
// std::unordered_map<MyKeyType, double, key_hash> theta3Derivatives;
|
// std::unordered_map<MyKeyType, double, key_hash> theta3Derivatives;
|
||||||
bool shouldApplyInitialDistortion = false;
|
bool shouldApplyInitialDistortion{false};
|
||||||
//#ifdef USE_ENSMALLEN
|
//#ifdef USE_ENSMALLEN
|
||||||
// std::shared_ptr<SimulationJob> pJob;
|
// std::shared_ptr<SimulationJob> pJob;
|
||||||
//#endif
|
//#endif
|
||||||
|
void reset(const std::shared_ptr<SimulationJob> &pJob, const Settings &settings);
|
||||||
void updateNodalInternalForces(
|
void updateNodalInternalForces(
|
||||||
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices);
|
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices);
|
||||||
void updateNodalExternalForces(
|
void updateNodalExternalForces(
|
||||||
|
|
@ -259,6 +260,8 @@ private:
|
||||||
std::vector<std::array<Vector6d, 4>> computeInternalForces(
|
std::vector<std::array<Vector6d, 4>> computeInternalForces(
|
||||||
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices);
|
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices);
|
||||||
|
|
||||||
|
void updateDerivatives();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DRMSimulationModel();
|
DRMSimulationModel();
|
||||||
SimulationResults executeSimulation(const std::shared_ptr<SimulationJob> &pJob,
|
SimulationResults executeSimulation(const std::shared_ptr<SimulationJob> &pJob,
|
||||||
|
|
|
||||||
|
|
@ -268,8 +268,8 @@ void SimulationMesh::unregister() const
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void SimulationMesh::setBeamCrossSection(
|
void SimulationMesh::setBeamCrossSection(const CrossSectionType &beamDimensions)
|
||||||
const CrossSectionType &beamDimensions) {
|
{
|
||||||
for (size_t ei = 0; ei < EN(); ei++) {
|
for (size_t ei = 0; ei < EN(); ei++) {
|
||||||
elements[ei].dimensions = beamDimensions;
|
elements[ei].dimensions = beamDimensions;
|
||||||
elements[ei].updateRigidity();
|
elements[ei].updateRigidity();
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
//extern bool drawGlobal;
|
//extern bool drawGlobal;
|
||||||
struct Element;
|
struct Element;
|
||||||
struct Node;
|
struct Node;
|
||||||
using CrossSectionType = RectangularBeamDimensions;
|
//using CrossSectionType = RectangularBeamDimensions;
|
||||||
//using CrossSectionType = CylindricalBeamDimensions;
|
using CrossSectionType = CylindricalBeamDimensions;
|
||||||
|
|
||||||
class SimulationMesh : public VCGEdgeMesh {
|
class SimulationMesh : public VCGEdgeMesh {
|
||||||
private:
|
private:
|
||||||
|
|
@ -38,8 +38,11 @@ public:
|
||||||
std::vector<CrossSectionType> getBeamDimensions();
|
std::vector<CrossSectionType> getBeamDimensions();
|
||||||
std::vector<ElementMaterial> getBeamMaterial();
|
std::vector<ElementMaterial> getBeamMaterial();
|
||||||
|
|
||||||
|
double pre_previousTotalKineticEnergy{0};
|
||||||
|
double pre_previousTotalTranslationalKineticEnergy{0};
|
||||||
|
double pre_previousTotalRotationalKineticEnergy{0};
|
||||||
double previousTotalKineticEnergy{0};
|
double previousTotalKineticEnergy{0};
|
||||||
double previousTranslationalKineticEnergy{0};
|
double previousTotalTranslationalKineticEnergy{0};
|
||||||
double previousTotalRotationalKineticEnergy{0};
|
double previousTotalRotationalKineticEnergy{0};
|
||||||
double previousTotalResidualForcesNorm{0};
|
double previousTotalResidualForcesNorm{0};
|
||||||
double currentTotalKineticEnergy{0};
|
double currentTotalKineticEnergy{0};
|
||||||
|
|
@ -68,8 +71,8 @@ public:
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Element {
|
struct Element
|
||||||
|
{
|
||||||
CrossSectionType dimensions;
|
CrossSectionType dimensions;
|
||||||
ElementMaterial material;
|
ElementMaterial material;
|
||||||
|
|
||||||
|
|
@ -80,7 +83,8 @@ struct Element {
|
||||||
void setMaterial(const ElementMaterial &material);
|
void setMaterial(const ElementMaterial &material);
|
||||||
double getMass(const double &matrialDensity);
|
double getMass(const double &matrialDensity);
|
||||||
|
|
||||||
struct LocalFrame {
|
struct LocalFrame
|
||||||
|
{
|
||||||
VectorType t1;
|
VectorType t1;
|
||||||
VectorType t2;
|
VectorType t2;
|
||||||
VectorType t3;
|
VectorType t3;
|
||||||
|
|
@ -91,17 +95,18 @@ struct Element {
|
||||||
double initialLength;
|
double initialLength;
|
||||||
LocalFrame frame;
|
LocalFrame frame;
|
||||||
|
|
||||||
struct Rigidity {
|
struct Rigidity
|
||||||
|
{
|
||||||
double axial;
|
double axial;
|
||||||
double torsional;
|
double torsional;
|
||||||
double firstBending;
|
double firstBending;
|
||||||
double secondBending;
|
double secondBending;
|
||||||
std::string toString() const {
|
std::string toString() const
|
||||||
return std::string("Rigidity:") + std::string("\nAxial=") +
|
{
|
||||||
std::to_string(axial) + std::string("\nTorsional=") +
|
return std::string("Rigidity:") + std::string("\nAxial=") + std::to_string(axial)
|
||||||
std::to_string(torsional) + std::string("\nFirstBending=") +
|
+ std::string("\nTorsional=") + std::to_string(torsional)
|
||||||
std::to_string(firstBending) + std::string("\nSecondBending=") +
|
+ std::string("\nFirstBending=") + std::to_string(firstBending)
|
||||||
std::to_string(secondBending);
|
+ std::string("\nSecondBending=") + std::to_string(secondBending);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Rigidity rigidity;
|
Rigidity rigidity;
|
||||||
|
|
@ -128,7 +133,8 @@ struct Element {
|
||||||
std::vector<VectorType> derivativeT3_jplus1;
|
std::vector<VectorType> derivativeT3_jplus1;
|
||||||
std::vector<VectorType> derivativeR_j;
|
std::vector<VectorType> derivativeR_j;
|
||||||
std::vector<VectorType> derivativeR_jplus1;
|
std::vector<VectorType> derivativeR_jplus1;
|
||||||
struct RotationalDisplacements {
|
struct RotationalDisplacements
|
||||||
|
{
|
||||||
double theta1{0}, theta2{0}, theta3{0};
|
double theta1{0}, theta2{0}, theta3{0};
|
||||||
};
|
};
|
||||||
RotationalDisplacements rotationalDisplacements_j;
|
RotationalDisplacements rotationalDisplacements_j;
|
||||||
|
|
@ -164,6 +170,7 @@ struct Node {
|
||||||
CoordType initialNormal;
|
CoordType initialNormal;
|
||||||
Vector6d acceleration{0};
|
Vector6d acceleration{0};
|
||||||
Forces force;
|
Forces force;
|
||||||
|
Vector6d previousVelocity{0};
|
||||||
Vector6d velocity{0};
|
Vector6d velocity{0};
|
||||||
double kineticEnergy{0};
|
double kineticEnergy{0};
|
||||||
Vector6d displacements{0};
|
Vector6d displacements{0};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue