#ifndef ELEMENTALMESH_HPP #define ELEMENTALMESH_HPP #include "Eigen/Dense" #include "edgemesh.hpp" #include "flatpattern.hpp" struct Element; struct Node; class SimulationMesh : public VCGEdgeMesh { private: void computeElementalProperties(); void initializeNodes(); void initializeElements(); EdgePointer getReferenceElement(const VertexType &v); public: PerEdgeAttributeHandle elements; PerVertexAttributeHandle nodes; SimulationMesh(FlatPattern &pattern); SimulationMesh(ConstVCGEdgeMesh &edgeMesh); SimulationMesh(SimulationMesh &elementalMesh); void updateElementalLengths(); std::vector getIncidentElements(const VCGEdgeMesh::VertexType &v); double previousTotalKineticEnergy{0}; double previousTotalResidualForcesNorm{0}; double currentTotalKineticEnergy{0}; double totalResidualForcesNorm{0}; double totalPotentialEnergykN{0}; }; struct Element { struct Properties { double E{0}; // youngs modulus in pascal double G{0}; // shear modulus double A{0}; // cross sectional area double I2{0}; // second moment of inertia double I3{0}; // third moment of inertia double J{0}; // torsional constant (polar moment of inertia) void computeMaterialProperties(const ElementMaterial &material) { E = material.youngsModulusGPascal * std::pow(10, 9); G = E / (2 * (1 + material.poissonsRatio)); } void computeDimensionsProperties(const RectangularBeamDimensions &dimensions) { A = (dimensions.b * dimensions.h); I2 = dimensions.b * std::pow(dimensions.h, 3) / 12; I3 = dimensions.h * std::pow(dimensions.b, 3) / 12; } void computeDimensionsProperties( const CylindricalElementDimensions &dimensions) { A = M_PI * (std::pow(dimensions.od / 2, 2) - std::pow(dimensions.id / 2, 2)); I2 = M_PI * (std::pow(dimensions.od, 4) - std::pow(dimensions.id, 4)) / 64; I3 = I2; } Properties(const RectangularBeamDimensions &dimensions, const ElementMaterial &material) { computeDimensionsProperties(dimensions); computeMaterialProperties(material); J = I2 + I3; } Properties(const CylindricalElementDimensions &dimensions, const ElementMaterial &material) { computeDimensionsProperties(dimensions); computeMaterialProperties(material); J = I2 + I3; } Properties() {} }; struct LocalFrame { VectorType t1; VectorType t2; VectorType t3; }; EdgeIndex ei; double length{0}; Properties properties; double initialLength; LocalFrame frame; double axialConstFactor; double torsionConstFactor; double firstBendingConstFactor; double secondBendingConstFactor; 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> derivativeT1; std::vector> derivativeT2; std::vector> derivativeT3; std::vector derivativeT1_j; std::vector derivativeT1_jplus1; std::vector derivativeT2_j; std::vector derivativeT2_jplus1; std::vector derivativeT3_j; std::vector derivativeT3_jplus1; std::vector derivativeR_j; std::vector derivativeR_jplus1; struct RotationalDisplacements { double theta1{0}, theta2{0}, theta3{0}; }; RotationalDisplacements rotationalDisplacements_j; RotationalDisplacements rotationalDisplacements_jplus1; }; struct Node { struct Forces { Vector6d external{0}; Vector6d internal{0}; Vector6d residual{0}; Vector6d internalAxial{0}; Vector6d internalFirstBending{0}; Vector6d internalSecondBending{0}; bool hasExternalForce() const { return external.isZero(); } }; VertexIndex vi; CoordType initialLocation; CoordType previousLocation; CoordType initialNormal; double translationalMass; double rotationalMass_I2; double rotationalMass_I3; double rotationalMass_J; Vector6d acceleration{0}; Forces force; Vector6d velocity{0}; double kineticEnergy{0}; Vector6d displacements{0}; double nR{0}; std::unordered_map alphaAngles; // contains the initial angles between the first star element // incident to this node and the other elements of the star // has size equal to the valence of the vertex std::vector incidentElements; std::vector derivativeOfNormal; SimulationMesh::EdgePointer referenceElement; }; Element::LocalFrame computeElementFrame(const CoordType &p0, const CoordType &p1, const VectorType &elementNormal); VectorType computeT1Vector(const ::SimulationMesh::EdgeType &e); VectorType computeT1Vector(const CoordType &p0, const CoordType &p1); double computeAngle(const VectorType &vector0, const VectorType &vector1, const VectorType &normalVector); #endif // ELEMENTALMESH_HPP