Using quadratic reset. Unit tests 2120 ,3333,9268 iterations

This commit is contained in:
iasonmanolas 2022-07-26 20:04:07 +03:00
parent 76fb1b8609
commit 90551e5485
4 changed files with 209 additions and 185 deletions

View File

@ -45,10 +45,11 @@ void DRMSimulationModel::runUnitTests()
Settings settings;
settings.Dtini = 0.1;
settings.xi = 0.9969;
settings.maxDRMIterations = 0;
formFinder.mSettings.totalResidualForcesNormThreshold = 1;
settings.totalResidualForcesNormThreshold = 1;
settings.shouldDraw = false;
settings.beVerbose = true;
// settings.debugModeStep = 1000;
// settings.shouldDraw = true;
settings.shouldCreatePlots = true;
SimulationResults simpleBeam_simulationResults
= formFinder.executeSimulation(std::make_shared<SimulationJob>(beamSimulationJob), settings);
@ -104,10 +105,11 @@ void DRMSimulationModel::runUnitTests()
shortSpanGridshellSimulationJob.pMesh->setBeamMaterial(0.3, 200 * 1e9);
assert(typeid(CrossSectionType) == typeid(CylindricalBeamDimensions));
shortSpanGridshellSimulationJob.pMesh->setBeamCrossSection(CrossSectionType{0.03, 0.026});
DRMSimulationModel formFinder2;
SimulationResults shortSpanGridshellSimulationResults
= formFinder.executeSimulation(std::make_shared<SimulationJob>(
shortSpanGridshellSimulationJob),
settings);
= formFinder2.executeSimulation(std::make_shared<SimulationJob>(
shortSpanGridshellSimulationJob),
settings);
shortSpanGridshellSimulationResults.save();
const std::string groundOfTruthBinaryFilename
@ -183,10 +185,11 @@ void DRMSimulationModel::runUnitTests()
}
longSpanGridshell_simulationJob.pMesh->setBeamCrossSection(CrossSectionType{0.03, 0.026});
DRMSimulationModel formFinder3;
SimulationResults longSpanGridshell_simulationResults
= formFinder.executeSimulation(std::make_shared<SimulationJob>(
longSpanGridshell_simulationJob),
settings);
= formFinder3.executeSimulation(std::make_shared<SimulationJob>(
longSpanGridshell_simulationJob),
settings);
longSpanGridshell_simulationResults.save();
const std::string longSpan_groundOfTruthBinaryFilename
@ -217,22 +220,14 @@ void DRMSimulationModel::runUnitTests()
// polyscope::show();
}
void DRMSimulationModel::reset(const std::shared_ptr<SimulationJob> &pJob)
{
mCurrentSimulationStep = 0;
history.clear();
history.label = pJob->pMesh->getLabel() + "_" + pJob->getLabel();
plotYValues.clear();
plotHandle.reset();
checkedForMaximumMoment = false;
externalMomentsNorm = 0;
Dt = mSettings.Dtini;
numOfDampings = 0;
shouldTemporarilyDampForces = false;
externalLoadStep = 1;
isVertexConstrained.clear();
minTotalResidualForcesNorm = std::numeric_limits<double>::max();
//#ifdef USE_ENSMALLEN
// this->pJob = pJob;
//#endif
pMesh.reset();
pMesh = std::make_unique<SimulationMesh>(*pJob->pMesh);
vcg::tri::UpdateBounding<SimulationMesh>::Box(*pMesh);
constrainedVertices.clear();
constrainedVertices = pJob->constrainedVertices;
@ -247,6 +242,26 @@ void DRMSimulationModel::reset(const std::shared_ptr<SimulationJob> &pJob)
for (auto fixedVertex : constrainedVertices) {
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
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(),
pMesh->getEigenVertices(),
pMesh->getEigenEdges())
->setRadius(pMesh->elements[0].dimensions.getDrawingRadius());
->setRadius(0.002);
// registerWorldAxes();
}
#endif
// if (!pJob->nodalForcedDisplacements.empty() && pJob->nodalExternalForces.empty()) {
// shouldApplyInitialDistortion = true;
// }
if (!pJob->nodalForcedDisplacements.empty() && pJob->nodalExternalForces.empty()) {
shouldApplyInitialDistortion = true;
}
updateElementalFrames();
}
@ -1414,7 +1429,6 @@ void DRMSimulationModel::updateResidualForces()
void DRMSimulationModel::computeRigidSupports()
{
assert(pMesh != nullptr);
isRigidSupport.clear();
isRigidSupport.resize(pMesh->VN(), false);
for (const VertexType &v : pMesh->vert) {
@ -1625,6 +1639,7 @@ void DRMSimulationModel::updateNodalVelocities()
for (VertexType &v : pMesh->vert) {
const VertexIndex vi = pMesh->getIndex(v);
Node &node = pMesh->nodes[v];
node.previousVelocity = node.velocity;
if (mSettings.viscousDampingFactor.has_value()) {
const Vector6d massOverDt = node.mass_6d / Dt;
// const Vector6d visciousDampingFactor(viscuousDampingConstant / 2);
@ -1777,11 +1792,17 @@ void DRMSimulationModel::updateNodeNormal(
void DRMSimulationModel::applyDisplacements(
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices)
{
for (VertexType &v : pMesh->vert) {
updateNodePosition(v, fixedVertices);
updateNodeNormal(v, fixedVertices);
updateNodeNr(v);
}
std::for_each(
#ifdef ENABLE_PARALLEL_DRM
std::execution::par_unseq,
#endif
pMesh->vert.begin(),
pMesh->vert.end(),
[&](auto &v) {
updateNodePosition(v, fixedVertices);
updateNodeNormal(v, fixedVertices);
updateNodeNr(v);
});
updateElementalFrames();
if (mSettings.shouldDraw) {
pMesh->updateEigenEdgeAndVertices();
@ -1847,8 +1868,12 @@ void DRMSimulationModel::applyForcedNormals(
// NOTE: Is this correct? Should the kinetic energy be computed like that?
void DRMSimulationModel::updateKineticEnergy()
{
pMesh->pre_previousTotalKineticEnergy = pMesh->previousTotalKineticEnergy;
pMesh->pre_previousTotalTranslationalKineticEnergy
= pMesh->previousTotalTranslationalKineticEnergy;
pMesh->pre_previousTotalRotationalKineticEnergy = pMesh->previousTotalRotationalKineticEnergy;
pMesh->previousTotalKineticEnergy = pMesh->currentTotalKineticEnergy;
pMesh->previousTranslationalKineticEnergy = pMesh->currentTotalTranslationalKineticEnergy;
pMesh->previousTotalTranslationalKineticEnergy = pMesh->currentTotalTranslationalKineticEnergy;
pMesh->previousTotalRotationalKineticEnergy = pMesh->currentTotalRotationalKineticEnergy;
pMesh->currentTotalKineticEnergy = 0;
pMesh->currentTotalTranslationalKineticEnergy = 0;
@ -1889,7 +1914,14 @@ void DRMSimulationModel::resetVelocities()
// // reset
// // current to 0 or this?
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();
}
@ -1960,6 +1992,7 @@ void DRMSimulationModel::updatePositionsOnTheFly(
for (VertexType &v : pMesh->vert) {
Node &node = pMesh->nodes[v];
node.previousVelocity = node.velocity;
node.velocity = node.velocity + node.acceleration * Dt;
}
updateKineticEnergy();
@ -2564,15 +2597,26 @@ void DRMSimulationModel::applyKineticDamping(const std::shared_ptr<SimulationJob
{
// if (!mSettings.viscousDampingFactor.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) {
Node &node = pMesh->nodes[v];
Vector6d stepDisplacement = node.velocity * 0.5 * Dt;
// Vector6d stepDisplacement = node.velocity * 0.5 * Dt;
// if (shouldCapDisplacements
// && stepDisplacement.getTranslation().norm() > mSettings.displacementCap) {
// stepDisplacement = stepDisplacement
// * (*mSettings.displacementCap
// / stepDisplacement.getTranslation().norm());
// }
// Vector6d stepDisplacement = node.velocity * 0.5 * Dt;
Vector6d stepDisplacement = node.velocity * Dt + node.previousVelocity * bitaDt;
node.displacements = node.displacements - stepDisplacement;
}
applyDisplacements(constrainedVertices);
@ -2598,51 +2642,38 @@ void DRMSimulationModel::applyKineticDamping(const std::shared_ptr<SimulationJob
++numOfDampings;
}
void DRMSimulationModel::updateDerivatives()
{
updateNormalDerivatives();
updateT1Derivatives();
updateRDerivatives();
updateT2Derivatives();
updateT3Derivatives();
}
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();
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);
if (!pJob->nodalExternalForces.empty()) {
if (!pJob->nodalExternalForces.empty()
&& !mSettings.totalResidualForcesNormThreshold.has_value()) {
mSettings.totalResidualForcesNormThreshold
= mSettings.totalExternalForcesNormPercentageTermination
* pMesh->totalExternalForcesNorm;
} else {
} /*else {
mSettings.totalResidualForcesNormThreshold = 1e-3;
std::cout << "No forces setted default residual forces norm threshold" << std::endl;
}
if (mSettings.beVerbose) {
std::cout << "totalResidualForcesNormThreshold:"
<< mSettings.totalResidualForcesNormThreshold << std::endl;
if (mSettings.averageResidualForcesCriterionThreshold.has_value()) {
std::cout << "average/extNorm threshold:"
<< *mSettings.averageResidualForcesCriterionThreshold << std::endl;
}
}*/
if (mSettings.beVerbose) {
// std::cout << "totalResidualForcesNormThreshold:"
// << mSettings.totalResidualForcesNormThreshold << std::endl;
if (mSettings.averageResidualForcesCriterionThreshold.has_value()) {
std::cout << "average/extNorm threshold:"
<< *mSettings.averageResidualForcesCriterionThreshold << std::endl;
}
}
if (mSettings.beVerbose) {
std::cout << "Executing simulation for mesh with:" << pMesh->VN() << " nodes and "
@ -2655,25 +2686,7 @@ 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)) {
// 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++;
}
updateDerivatives();
updateResidualForcesOnTheFly(constrainedVertices);
// TODO: write parallel function for updating positions
@ -2690,9 +2703,6 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
pJob->nodalForcedDisplacements);
}
// if (!pJob->nodalForcedNormals.empty()) {
// applyForcedNormals(pJob->nodalForcedNormals);
// }
updateElementalLengths();
mCurrentSimulationStep++;
if (std::isnan(pMesh->currentTotalKineticEnergy)) {
@ -2790,8 +2800,8 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
// << std::endl;
}
history.stepPulse(*pMesh);
percentageOfConvergence.push_back(100 * mSettings.totalResidualForcesNormThreshold
/ pMesh->totalResidualForcesNorm);
// percentageOfConvergence.push_back(100 * mSettings.totalResidualForcesNormThreshold
// / pMesh->totalResidualForcesNorm);
}
if (mSettings.shouldCreatePlots && mSettings.debugModeStep.has_value()
@ -2880,15 +2890,19 @@ currentSimulationStep > maxDRMIterations*/
// std::cout << "Residual forces norm:" << mesh.totalResidualForcesNorm
// << std::endl;
const bool fullfillsResidualForcesNormTerminationCriterion
= !mSettings.averageResidualForcesCriterionThreshold.has_value()
= mSettings.averageResidualForcesCriterionThreshold.has_value()
&& pMesh->totalResidualForcesNorm / pMesh->totalExternalForcesNorm
< mSettings.totalExternalForcesNormPercentageTermination;
const bool fullfillsAverageResidualForcesNormTerminationCriterion
= mSettings.averageResidualForcesCriterionThreshold.has_value()
&& (pMesh->totalResidualForcesNorm / pMesh->VN()) / pMesh->totalExternalForcesNorm
< mSettings.averageResidualForcesCriterionThreshold.value();
const bool fullfillsResidualForcesNormThreshold
= mSettings.totalResidualForcesNormThreshold.has_value()
&& pMesh->totalResidualForcesNorm < mSettings.totalResidualForcesNormThreshold;
if ((fullfillsAverageResidualForcesNormTerminationCriterion
|| fullfillsResidualForcesNormTerminationCriterion)
|| fullfillsResidualForcesNormTerminationCriterion
|| fullfillsResidualForcesNormThreshold)
&& numOfDampings > 0
&& (pJob->nodalForcedDisplacements.empty()
|| mCurrentSimulationStep > mSettings.gradualForcedDisplacementSteps)) {
@ -2906,12 +2920,15 @@ currentSimulationStep > maxDRMIterations*/
break;
}
const bool isKineticEnergyPeak = (mSettings.useTotalRotationalKineticEnergyForKineticDamping
&& pMesh->previousTotalRotationalKineticEnergy
> pMesh->currentTotalRotationalKineticEnergy)
|| (mSettings.useTranslationalKineticEnergyForKineticDamping
&& pMesh->previousTranslationalKineticEnergy
> pMesh->currentTotalTranslationalKineticEnergy);
const bool isKineticEnergyPeak
= /* pMesh->previousTotalKineticEnergy > pMesh->currentTotalKineticEnergy
||*/
(mSettings.useTotalRotationalKineticEnergyForKineticDamping
&& pMesh->previousTotalRotationalKineticEnergy
> pMesh->currentTotalRotationalKineticEnergy)
|| (mSettings.useTranslationalKineticEnergyForKineticDamping
&& pMesh->previousTotalTranslationalKineticEnergy
> pMesh->currentTotalTranslationalKineticEnergy);
if (isKineticEnergyPeak) {
const bool fullfillsKineticEnergyTerminationCriterion
= mSettings.totalTranslationalKineticEnergyThreshold.has_value()
@ -2964,13 +2981,13 @@ currentSimulationStep > maxDRMIterations*/
// }
}
if (mSettings.useTranslationalKineticEnergyForKineticDamping) {
applyKineticDamping(pJob);
if (mSettings.shouldCreatePlots) {
history.redMarks.push_back(mCurrentSimulationStep);
}
}
// if (mSettings.useTranslationalKineticEnergyForKineticDamping) {
applyKineticDamping(pJob);
Dt *= mSettings.xi;
if (mSettings.shouldCreatePlots) {
history.redMarks.push_back(mCurrentSimulationStep);
}
// }
// if (mSettings.isDebugMode) {
// std::cout << Dt << std::endl;
// }
@ -3002,11 +3019,9 @@ currentSimulationStep > maxDRMIterations*/
void DRMSimulationModel::setStructure(const std::shared_ptr<SimulationMesh> &pMesh)
{
this->pMesh.reset();
this->pMesh = std::make_unique<SimulationMesh>(*pMesh);
vcg::tri::UpdateBounding<SimulationMesh>::Box(*pMesh);
// assert(false);
// std::terminate();
std::cout << "This function is currently not implemented" << std::endl;
assert(false);
std::terminate();
}
SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<SimulationJob> &pJob,
@ -3014,8 +3029,7 @@ SimulationResults DRMSimulationModel::executeSimulation(const std::shared_ptr<Si
const SimulationResults &solutionGuess)
{
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
mSettings = settings;
setStructure(pJob->pMesh);
reset(pJob, settings);
assert(pJob->pMesh != nullptr);
if (!solutionGuess.displacements.empty()) {

View File

@ -47,8 +47,8 @@ public:
int gradualForcedDisplacementSteps{50};
// int desiredGradualExternalLoadsSteps{1};
double gamma{0.8};
double totalResidualForcesNormThreshold{1e-20};
double totalExternalForcesNormPercentageTermination{1e-3};
std::optional<double> totalResidualForcesNormThreshold;
double totalExternalForcesNormPercentageTermination{1e-5};
std::optional<int> maxDRMIterations;
std::optional<int> debugModeStep;
std::optional<double> totalTranslationalKineticEnergyThreshold;
@ -104,10 +104,11 @@ private:
SimulationHistory history;
// Eigen::Tensor<double, 4> theta3Derivatives;
// std::unordered_map<MyKeyType, double, key_hash> theta3Derivatives;
bool shouldApplyInitialDistortion = false;
bool shouldApplyInitialDistortion{false};
//#ifdef USE_ENSMALLEN
// std::shared_ptr<SimulationJob> pJob;
//#endif
void reset(const std::shared_ptr<SimulationJob> &pJob, const Settings &settings);
void updateNodalInternalForces(
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices);
void updateNodalExternalForces(
@ -259,6 +260,8 @@ private:
std::vector<std::array<Vector6d, 4>> computeInternalForces(
const std::unordered_map<VertexIndex, std::unordered_set<DoFType>> &fixedVertices);
void updateDerivatives();
public:
DRMSimulationModel();
SimulationResults executeSimulation(const std::shared_ptr<SimulationJob> &pJob,

View File

@ -268,12 +268,12 @@ void SimulationMesh::unregister() const
}
#endif
void SimulationMesh::setBeamCrossSection(
const CrossSectionType &beamDimensions) {
for (size_t ei = 0; ei < EN(); ei++) {
elements[ei].dimensions = beamDimensions;
elements[ei].updateRigidity();
}
void SimulationMesh::setBeamCrossSection(const CrossSectionType &beamDimensions)
{
for (size_t ei = 0; ei < EN(); ei++) {
elements[ei].dimensions = beamDimensions;
elements[ei].updateRigidity();
}
}
void SimulationMesh::setBeamMaterial(const double &pr, const double &ym) {

View File

@ -8,8 +8,8 @@
//extern bool drawGlobal;
struct Element;
struct Node;
using CrossSectionType = RectangularBeamDimensions;
//using CrossSectionType = CylindricalBeamDimensions;
//using CrossSectionType = RectangularBeamDimensions;
using CrossSectionType = CylindricalBeamDimensions;
class SimulationMesh : public VCGEdgeMesh {
private:
@ -38,8 +38,11 @@ public:
std::vector<CrossSectionType> getBeamDimensions();
std::vector<ElementMaterial> getBeamMaterial();
double pre_previousTotalKineticEnergy{0};
double pre_previousTotalTranslationalKineticEnergy{0};
double pre_previousTotalRotationalKineticEnergy{0};
double previousTotalKineticEnergy{0};
double previousTranslationalKineticEnergy{0};
double previousTotalTranslationalKineticEnergy{0};
double previousTotalRotationalKineticEnergy{0};
double previousTotalResidualForcesNorm{0};
double currentTotalKineticEnergy{0};
@ -68,73 +71,76 @@ public:
#endif
};
struct Element {
struct Element
{
CrossSectionType dimensions;
ElementMaterial material;
CrossSectionType dimensions;
ElementMaterial material;
void computeMaterialProperties(const ElementMaterial &material);
// void computeDimensionsProperties(const RectangularBeamDimensions &dimensions);
// void computeDimensionsProperties(const CylindricalBeamDimensions &dimensions);
void setDimensions(const CrossSectionType &dimensions);
void setMaterial(const ElementMaterial &material);
double getMass(const double &matrialDensity);
void computeMaterialProperties(const ElementMaterial &material);
// void computeDimensionsProperties(const RectangularBeamDimensions &dimensions);
// void computeDimensionsProperties(const CylindricalBeamDimensions &dimensions);
void setDimensions(const CrossSectionType &dimensions);
void setMaterial(const ElementMaterial &material);
double getMass(const double &matrialDensity);
struct LocalFrame
{
VectorType t1;
VectorType t2;
VectorType t3;
};
struct LocalFrame {
VectorType t1;
VectorType t2;
VectorType t3;
};
EdgeIndex ei;
double length{0};
double initialLength;
LocalFrame frame;
EdgeIndex ei;
double length{0};
double initialLength;
LocalFrame frame;
struct Rigidity
{
double axial;
double torsional;
double firstBending;
double secondBending;
std::string toString() const
{
return std::string("Rigidity:") + std::string("\nAxial=") + std::to_string(axial)
+ std::string("\nTorsional=") + std::to_string(torsional)
+ std::string("\nFirstBending=") + std::to_string(firstBending)
+ std::string("\nSecondBending=") + std::to_string(secondBending);
}
};
Rigidity rigidity;
void updateRigidity();
struct Rigidity {
double axial;
double torsional;
double firstBending;
double secondBending;
std::string toString() const {
return std::string("Rigidity:") + std::string("\nAxial=") +
std::to_string(axial) + std::string("\nTorsional=") +
std::to_string(torsional) + std::string("\nFirstBending=") +
std::to_string(firstBending) + std::string("\nSecondBending=") +
std::to_string(secondBending);
}
};
Rigidity rigidity;
void updateRigidity();
VectorType f1_j;
VectorType f1_jplus1;
VectorType f2_j;
VectorType f2_jplus1;
VectorType f3_j;
VectorType f3_jplus1;
double cosRotationAngle_j;
double cosRotationAngle_jplus1;
double sinRotationAngle_j;
double sinRotationAngle_jplus1;
std::vector<std::vector<VectorType>> derivativeT1;
std::vector<std::vector<VectorType>> derivativeT2;
std::vector<std::vector<VectorType>> derivativeT3;
std::vector<VectorType> derivativeT1_j;
std::vector<VectorType> derivativeT1_jplus1;
std::vector<VectorType> derivativeT2_j;
std::vector<VectorType> derivativeT2_jplus1;
std::vector<VectorType> derivativeT3_j;
std::vector<VectorType> derivativeT3_jplus1;
std::vector<VectorType> derivativeR_j;
std::vector<VectorType> derivativeR_jplus1;
struct RotationalDisplacements
{
double theta1{0}, theta2{0}, theta3{0};
};
RotationalDisplacements rotationalDisplacements_j;
RotationalDisplacements rotationalDisplacements_jplus1;
VectorType f1_j;
VectorType f1_jplus1;
VectorType f2_j;
VectorType f2_jplus1;
VectorType f3_j;
VectorType f3_jplus1;
double cosRotationAngle_j;
double cosRotationAngle_jplus1;
double sinRotationAngle_j;
double sinRotationAngle_jplus1;
std::vector<std::vector<VectorType>> derivativeT1;
std::vector<std::vector<VectorType>> derivativeT2;
std::vector<std::vector<VectorType>> derivativeT3;
std::vector<VectorType> derivativeT1_j;
std::vector<VectorType> derivativeT1_jplus1;
std::vector<VectorType> derivativeT2_j;
std::vector<VectorType> derivativeT2_jplus1;
std::vector<VectorType> derivativeT3_j;
std::vector<VectorType> derivativeT3_jplus1;
std::vector<VectorType> derivativeR_j;
std::vector<VectorType> derivativeR_jplus1;
struct RotationalDisplacements {
double theta1{0}, theta2{0}, theta3{0};
};
RotationalDisplacements rotationalDisplacements_j;
RotationalDisplacements rotationalDisplacements_jplus1;
static void computeCrossSectionArea(const RectangularBeamDimensions &dimensions, double &A);
static void computeCrossSectionArea(const RectangularBeamDimensions &dimensions, double &A);
};
struct Node {
@ -164,6 +170,7 @@ struct Node {
CoordType initialNormal;
Vector6d acceleration{0};
Forces force;
Vector6d previousVelocity{0};
Vector6d velocity{0};
double kineticEnergy{0};
Vector6d displacements{0};