Added linear and non linear chronos euler simulation model classes in order to be able to out-of-the-box use them with a factory class
This commit is contained in:
parent
9fd536ccf3
commit
68d5655214
|
|
@ -1,5 +1,4 @@
|
||||||
#include "chronoseulersimulationmodel.hpp"
|
#include "chronoseulersimulationmodel.hpp"
|
||||||
#include "chrono/physics/ChLoadContainer.h"
|
|
||||||
#include <chrono/fea/ChBeamSectionEuler.h>
|
#include <chrono/fea/ChBeamSectionEuler.h>
|
||||||
#include <chrono/fea/ChBuilderBeam.h>
|
#include <chrono/fea/ChBuilderBeam.h>
|
||||||
#include <chrono/fea/ChLoadsBeam.h>
|
#include <chrono/fea/ChLoadsBeam.h>
|
||||||
|
|
@ -8,6 +7,7 @@
|
||||||
#include <chrono/physics/ChBody.h>
|
#include <chrono/physics/ChBody.h>
|
||||||
#include <chrono/physics/ChSystemSMC.h>
|
#include <chrono/physics/ChSystemSMC.h>
|
||||||
#include <chrono/solver/ChIterativeSolverLS.h>
|
#include <chrono/solver/ChIterativeSolverLS.h>
|
||||||
|
#include "chrono/physics/ChLoadContainer.h"
|
||||||
|
|
||||||
#include <chrono/assets/ChVisualization.h>
|
#include <chrono/assets/ChVisualization.h>
|
||||||
#include <chrono/fea/ChElementBeamEuler.h>
|
#include <chrono/fea/ChElementBeamEuler.h>
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
using namespace chrono;
|
using namespace chrono;
|
||||||
using namespace chrono::fea;
|
using namespace chrono::fea;
|
||||||
std::shared_ptr<ChMesh> ChronosEulerSimulationModel::convertToChronosMesh_Euler(
|
std::shared_ptr<ChMesh> ChronosEulerSimulationModel::convertToChronosMesh_Euler(
|
||||||
const std::shared_ptr<SimulationMesh> &pMesh,
|
const std::shared_ptr<SimulationEdgeMesh>& pMesh,
|
||||||
std::vector<std::shared_ptr<ChNodeFEAxyzrot>> &edgeMeshVertsToChronosNodes)
|
std::vector<std::shared_ptr<ChNodeFEAxyzrot>>&
|
||||||
{
|
edgeMeshVertsToChronosNodes) {
|
||||||
auto mesh_chronos = chrono_types::make_shared<ChMesh>();
|
auto mesh_chronos = chrono_types::make_shared<ChMesh>();
|
||||||
edgeMeshVertsToChronosNodes.clear();
|
edgeMeshVertsToChronosNodes.clear();
|
||||||
edgeMeshVertsToChronosNodes.resize(pMesh->VN(), nullptr);
|
edgeMeshVertsToChronosNodes.resize(pMesh->VN(), nullptr);
|
||||||
|
|
@ -27,14 +27,14 @@ std::shared_ptr<ChMesh> ChronosEulerSimulationModel::convertToChronosMesh_Euler(
|
||||||
for (int vi = 0; vi < pMesh->VN(); vi++) {
|
for (int vi = 0; vi < pMesh->VN(); vi++) {
|
||||||
const auto& vertex = pMesh->vert[vi];
|
const auto& vertex = pMesh->vert[vi];
|
||||||
ChVector<> vertexPos(vertex.cP()[0], vertex.cP()[1], vertex.cP()[2]);
|
ChVector<> vertexPos(vertex.cP()[0], vertex.cP()[1], vertex.cP()[2]);
|
||||||
edgeMeshVertsToChronosNodes[vi] = chrono_types::make_shared<ChNodeFEAxyzrot>(
|
edgeMeshVertsToChronosNodes[vi] =
|
||||||
ChFrame<>(vertexPos));
|
chrono_types::make_shared<ChNodeFEAxyzrot>(ChFrame<>(vertexPos));
|
||||||
mesh_chronos->AddNode(edgeMeshVertsToChronosNodes[vi]);
|
mesh_chronos->AddNode(edgeMeshVertsToChronosNodes[vi]);
|
||||||
}
|
}
|
||||||
// add elements
|
// add elements
|
||||||
ChBuilderBeamEuler builder;
|
ChBuilderBeamEuler builder;
|
||||||
for (int ei = 0; ei < pMesh->EN(); ei++) {
|
for (int ei = 0; ei < pMesh->EN(); ei++) {
|
||||||
const SimulationMesh::EdgeType &edge = pMesh->edge[ei];
|
const SimulationEdgeMesh::EdgeType& edge = pMesh->edge[ei];
|
||||||
// define end-points
|
// define end-points
|
||||||
const auto vi0 = pMesh->getIndex(edge.cV(0));
|
const auto vi0 = pMesh->getIndex(edge.cV(0));
|
||||||
const auto vi1 = pMesh->getIndex(edge.cV(1));
|
const auto vi1 = pMesh->getIndex(edge.cV(1));
|
||||||
|
|
@ -46,20 +46,29 @@ std::shared_ptr<ChMesh> ChronosEulerSimulationModel::convertToChronosMesh_Euler(
|
||||||
// const double poisson = element.material.poissonsRatio;
|
// const double poisson = element.material.poissonsRatio;
|
||||||
const double density = 1e0;
|
const double density = 1e0;
|
||||||
|
|
||||||
// auto msection = chrono_types::make_shared<ChBeamSectionEulerAdvanced>();
|
// auto msection =
|
||||||
auto msection = chrono_types::make_shared<ChBeamSectionEulerEasyRectangular>(
|
// chrono_types::make_shared<ChBeamSectionEulerAdvanced>();
|
||||||
|
auto msection =
|
||||||
|
chrono_types::make_shared<ChBeamSectionEulerEasyRectangular>(
|
||||||
beam_wy, beam_wz, E, element.material.G, density);
|
beam_wy, beam_wz, E, element.material.G, density);
|
||||||
|
msection->SetArea(element.dimensions.A);
|
||||||
|
msection->SetIyy(element.dimensions.inertia.I2);
|
||||||
|
msection->SetIzz(element.dimensions.inertia.I3);
|
||||||
|
msection->SetJ(element.dimensions.inertia.J);
|
||||||
// msection->SetDensity(density);
|
// msection->SetDensity(density);
|
||||||
// msection->SetYoungModulus(E);
|
// msection->SetYoungModulus(E);
|
||||||
// msection->SetGwithPoissonRatio(poisson);
|
// msection->SetGwithPoissonRatio(poisson);
|
||||||
// // msection->SetBeamRaleyghDamping(0.0);
|
// // msection->SetBeamRaleyghDamping(0.0);
|
||||||
// msection->SetAsRectangularSection(beam_wy, beam_wz);
|
// msection->SetAsRectangularSection(beam_wy, beam_wz);
|
||||||
builder
|
builder.BuildBeam(
|
||||||
.BuildBeam(mesh_chronos, // the mesh where to put the created nodes and elements
|
mesh_chronos, // the mesh where to put the created nodes and elements
|
||||||
msection, // the ChBeamSectionEuler to use for the ChElementBeamEuler elements
|
msection, // the ChBeamSectionEuler to use for the ChElementBeamEuler
|
||||||
|
// elements
|
||||||
1, // the number of ChElementBeamEuler to create
|
1, // the number of ChElementBeamEuler to create
|
||||||
edgeMeshVertsToChronosNodes[vi0], // the 'A' point in space (beginning of beam)
|
edgeMeshVertsToChronosNodes[vi0], // the 'A' point in space (beginning
|
||||||
edgeMeshVertsToChronosNodes[vi1], // the 'B' point in space (end of beam)
|
// of beam)
|
||||||
|
edgeMeshVertsToChronosNodes[vi1], // the 'B' point in space (end of
|
||||||
|
// beam)
|
||||||
ChVector<>(0, 0, 1)
|
ChVector<>(0, 0, 1)
|
||||||
// ChVector<>(0, cos(rot_rad), sin(rot_rad))
|
// ChVector<>(0, cos(rot_rad), sin(rot_rad))
|
||||||
); // the 'Y' up direction of the section for the beam
|
); // the 'Y' up direction of the section for the beam
|
||||||
|
|
@ -74,51 +83,52 @@ ChronosEulerSimulationModel::ChronosEulerSimulationModel() {}
|
||||||
// const std::shared_ptr<SimulationJob> &pJob)
|
// const std::shared_ptr<SimulationJob> &pJob)
|
||||||
//{}
|
//{}
|
||||||
|
|
||||||
//chrono::ChSystemSMC convertToChronosSystem(const std::shared_ptr<SimulationJob> &pJob)
|
// chrono::ChSystemSMC convertToChronosSystem(const
|
||||||
|
// std::shared_ptr<SimulationJob> &pJob)
|
||||||
//{
|
//{
|
||||||
// chrono::ChSystemSMC my_system;
|
// chrono::ChSystemSMC my_system;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void ChronosEulerSimulationModel::parseForces(
|
void ChronosEulerSimulationModel::parseForces(
|
||||||
const std::shared_ptr<chrono::fea::ChMesh>& mesh_chronos,
|
const std::shared_ptr<chrono::fea::ChMesh>& mesh_chronos,
|
||||||
const std::vector<std::shared_ptr<chrono::fea::ChNodeFEAxyzrot>> &edgeMeshVertsToChronoNodes,
|
const std::vector<std::shared_ptr<chrono::fea::ChNodeFEAxyzrot>>&
|
||||||
const std::unordered_map<VertexIndex, Vector6d> &nodalExternalForces)
|
edgeMeshVertsToChronoNodes,
|
||||||
{
|
const std::unordered_map<VertexIndex, Vector6d>& nodalExternalForces) {
|
||||||
mesh_chronos->SetAutomaticGravity(false);
|
mesh_chronos->SetAutomaticGravity(false);
|
||||||
for (const std::pair<VertexIndex, Vector6d> &externalForce : nodalExternalForces) {
|
for (const std::pair<VertexIndex, Vector6d>& externalForce :
|
||||||
|
nodalExternalForces) {
|
||||||
const int& forceVi = externalForce.first;
|
const int& forceVi = externalForce.first;
|
||||||
const Vector6d& force = externalForce.second;
|
const Vector6d& force = externalForce.second;
|
||||||
edgeMeshVertsToChronoNodes[forceVi]->SetForce(ChVector<>(force[0], force[1], force[2]));
|
edgeMeshVertsToChronoNodes[forceVi]->SetForce(
|
||||||
edgeMeshVertsToChronoNodes[forceVi]->SetTorque(ChVector<>(force[3], force[4], force[5]));
|
ChVector<>(force[0], force[1], force[2]));
|
||||||
|
edgeMeshVertsToChronoNodes[forceVi]->SetTorque(
|
||||||
|
ChVector<>(force[3], force[4], force[5]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChronosEulerSimulationModel::parseConstrainedVertices(
|
void ChronosEulerSimulationModel::parseConstrainedVertices(
|
||||||
const std::shared_ptr<const SimulationJob>& pJob,
|
const std::shared_ptr<const SimulationJob>& pJob,
|
||||||
const std::vector<std::shared_ptr<chrono::fea::ChNodeFEAxyzrot>> &edgeMeshVertsToChronoNodes,
|
const std::vector<std::shared_ptr<chrono::fea::ChNodeFEAxyzrot>>&
|
||||||
chrono::ChSystemSMC &my_system)
|
edgeMeshVertsToChronoNodes,
|
||||||
{
|
chrono::ChSystemSMC& my_system) {
|
||||||
assert(!edgeMeshVertsToChronoNodes.empty());
|
assert(!edgeMeshVertsToChronoNodes.empty());
|
||||||
for (const std::pair<VertexIndex, std::unordered_set<int>> &constrainedVertex :
|
for (const std::pair<VertexIndex, std::unordered_set<int>>&
|
||||||
pJob->constrainedVertices) {
|
constrainedVertex : pJob->constrainedVertices) {
|
||||||
const int& constrainedVi = constrainedVertex.first;
|
const int& constrainedVi = constrainedVertex.first;
|
||||||
const std::unordered_set<int>& constrainedDoF = constrainedVertex.second;
|
const std::unordered_set<int>& constrainedDoF = constrainedVertex.second;
|
||||||
// Create a truss
|
// Create a truss
|
||||||
auto truss = chrono_types::make_shared<ChBody>();
|
auto truss = chrono_types::make_shared<ChBody>();
|
||||||
truss->SetBodyFixed(true);
|
truss->SetBodyFixed(true);
|
||||||
my_system.Add(truss);
|
my_system.Add(truss);
|
||||||
const auto &constrainedChronoNode = edgeMeshVertsToChronoNodes[constrainedVi];
|
const auto& constrainedChronoNode =
|
||||||
|
edgeMeshVertsToChronoNodes[constrainedVi];
|
||||||
// Create a constraint at the end of the beam
|
// Create a constraint at the end of the beam
|
||||||
auto constr_a = chrono_types::make_shared<ChLinkMateGeneric>();
|
auto constr_a = chrono_types::make_shared<ChLinkMateGeneric>();
|
||||||
constr_a->SetConstrainedCoords(constrainedDoF.contains(0),
|
constr_a->SetConstrainedCoords(
|
||||||
constrainedDoF.contains(1),
|
constrainedDoF.contains(0), constrainedDoF.contains(1),
|
||||||
constrainedDoF.contains(2),
|
constrainedDoF.contains(2), constrainedDoF.contains(3),
|
||||||
constrainedDoF.contains(3),
|
constrainedDoF.contains(4), constrainedDoF.contains(5));
|
||||||
constrainedDoF.contains(4),
|
constr_a->Initialize(constrainedChronoNode, truss, false,
|
||||||
constrainedDoF.contains(5));
|
|
||||||
constr_a->Initialize(constrainedChronoNode,
|
|
||||||
truss,
|
|
||||||
false,
|
|
||||||
constrainedChronoNode->Frame(),
|
constrainedChronoNode->Frame(),
|
||||||
constrainedChronoNode->Frame());
|
constrainedChronoNode->Frame());
|
||||||
// const auto frameNode = constrainedChronoNode->Frame();
|
// const auto frameNode = constrainedChronoNode->Frame();
|
||||||
|
|
@ -127,7 +137,8 @@ void ChronosEulerSimulationModel::parseConstrainedVertices(
|
||||||
// edgeMeshVertsToChronoNodes[constrainedVi]->SetFixed(true);
|
// edgeMeshVertsToChronoNodes[constrainedVi]->SetFixed(true);
|
||||||
// if (vertexIsFullyConstrained) {
|
// if (vertexIsFullyConstrained) {
|
||||||
// } else {
|
// } else {
|
||||||
// std::cerr << "Currently only rigid vertices are handled." << std::endl;
|
// std::cerr << "Currently only rigid vertices are handled." <<
|
||||||
|
// std::endl;
|
||||||
// // SimulationResults simulationResults;
|
// // SimulationResults simulationResults;
|
||||||
// // simulationResults.converged = false;
|
// // simulationResults.converged = false;
|
||||||
// // assert(false);
|
// // assert(false);
|
||||||
|
|
@ -137,40 +148,44 @@ void ChronosEulerSimulationModel::parseConstrainedVertices(
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulationResults ChronosEulerSimulationModel::executeSimulation(
|
SimulationResults ChronosEulerSimulationModel::executeSimulation(
|
||||||
const std::shared_ptr<SimulationJob> &pJob)
|
const std::shared_ptr<SimulationJob>& pJob) {
|
||||||
{
|
assert(pJob->pMesh->VN() != 0);
|
||||||
// assert(pJob->pMesh->VN() != 0);
|
|
||||||
// const bool structureInitialized = mesh_chronos != nullptr;
|
// const bool structureInitialized = mesh_chronos != nullptr;
|
||||||
// const bool wasInitializedWithDifferentStructure = structureInitialized
|
// const bool wasInitializedWithDifferentStructure =
|
||||||
// && (pJob->pMesh->EN()
|
// structureInitialized &&
|
||||||
// != mesh_chronos->GetNelements()
|
// (pJob->pMesh->EN() != mesh_chronos->GetNelements() ||
|
||||||
// || pJob->pMesh->VN()
|
// pJob->pMesh->VN() != mesh_chronos->GetNnodes());
|
||||||
// != mesh_chronos->GetNnodes());
|
|
||||||
// if (!structureInitialized || wasInitializedWithDifferentStructure) {
|
// if (!structureInitialized || wasInitializedWithDifferentStructure) {
|
||||||
setStructure(pJob->pMesh);
|
setStructure(pJob->pMesh);
|
||||||
// }
|
// }
|
||||||
chrono::ChSystemSMC my_system;
|
chrono::ChSystemSMC my_system;
|
||||||
// chrono::irrlicht::ChIrrApp application(&my_system,
|
// chrono::irrlicht::ChIrrApp application(&my_system,
|
||||||
// L"Irrlicht FEM visualization",
|
// L"Irrlicht FEM visualization",
|
||||||
// irr::core::dimension2d<irr::u32>(800, 600),
|
// irr::core::dimension2d<irr::u32>(800,
|
||||||
|
// 600),
|
||||||
// chrono::irrlicht::VerticalDir::Z,
|
// chrono::irrlicht::VerticalDir::Z,
|
||||||
// false,
|
// false,
|
||||||
// true);
|
// true);
|
||||||
// const std::string chronoDataFolderPath = "/home/iason/Coding/build/external "
|
// const std::string chronoDataFolderPath =
|
||||||
|
// "/home/iason/Coding/build/external "
|
||||||
// "dependencies/CHRONO-src/data/";
|
// "dependencies/CHRONO-src/data/";
|
||||||
// application.AddTypicalLogo(chronoDataFolderPath + "logo_chronoengine_alpha.png");
|
// application.AddTypicalLogo(chronoDataFolderPath +
|
||||||
|
// "logo_chronoengine_alpha.png");
|
||||||
// application.AddTypicalSky(chronoDataFolderPath + "skybox/");
|
// application.AddTypicalSky(chronoDataFolderPath + "skybox/");
|
||||||
// application.AddTypicalLights();
|
// application.AddTypicalLights();
|
||||||
// application.AddTypicalCamera(irr::core::vector3df(0, (irr::f32) 0.6, -1));
|
// application.AddTypicalCamera(irr::core::vector3df(0, (irr::f32) 0.6,
|
||||||
|
// -1));
|
||||||
// my_system.SetTimestepperType(chrono::ChTimestepper::Type::EULER_IMPLICIT_LINEARIZED);
|
// my_system.SetTimestepperType(chrono::ChTimestepper::Type::EULER_IMPLICIT_LINEARIZED);
|
||||||
// parse forces
|
// parse forces
|
||||||
parseForces(mesh_chronos, edgeMeshVertsToChronoNodes, pJob->nodalExternalForces);
|
parseForces(mesh_chronos, edgeMeshVertsToChronoNodes,
|
||||||
|
pJob->nodalExternalForces);
|
||||||
// parse constrained vertices
|
// parse constrained vertices
|
||||||
parseConstrainedVertices(pJob, edgeMeshVertsToChronoNodes, my_system);
|
parseConstrainedVertices(pJob, edgeMeshVertsToChronoNodes, my_system);
|
||||||
// std::dynamic_pointer_cast<std::shared_ptr<ChNodeFEAxyzrot>>(mesh_chronos->GetNode(1))
|
// std::dynamic_pointer_cast<std::shared_ptr<ChNodeFEAxyzrot>>(mesh_chronos->GetNode(1))
|
||||||
// ->SetFixed(true);
|
// ->SetFixed(true);
|
||||||
// and load containers must be added to your system
|
// and load containers must be added to your system
|
||||||
// auto mvisualizemesh = chrono_types::make_shared<ChVisualizationFEAmesh>(*(mesh_chronos.get()));
|
// auto mvisualizemesh =
|
||||||
|
// chrono_types::make_shared<ChVisualizationFEAmesh>(*(mesh_chronos.get()));
|
||||||
// mvisualizemesh->SetFEMdataType(ChVisualizationFEAmesh::E_PLOT_NODE_DISP_NORM);
|
// mvisualizemesh->SetFEMdataType(ChVisualizationFEAmesh::E_PLOT_NODE_DISP_NORM);
|
||||||
// mvisualizemesh->SetColorscaleMinMax(0.0, 5.50);
|
// mvisualizemesh->SetColorscaleMinMax(0.0, 5.50);
|
||||||
// mvisualizemesh->SetShrinkElements(false, 0.85);
|
// mvisualizemesh->SetShrinkElements(false, 0.85);
|
||||||
|
|
@ -183,16 +198,20 @@ SimulationResults ChronosEulerSimulationModel::executeSimulation(
|
||||||
|
|
||||||
auto solver = chrono_types::make_shared<ChSolverMINRES>();
|
auto solver = chrono_types::make_shared<ChSolverMINRES>();
|
||||||
my_system.SetSolver(solver);
|
my_system.SetSolver(solver);
|
||||||
solver->SetMaxIterations(1e5);
|
// solver->SetMaxIterations(1e5);
|
||||||
// solver->SetTolerance(1e-12);
|
// solver->SetTolerance(1e-12);
|
||||||
solver->EnableWarmStart(true); // IMPORTANT for convergence when using EULER_IMPLICIT_LINEARIZED
|
solver->EnableWarmStart(
|
||||||
|
true); // IMPORTANT for convergence when using EULER_IMPLICIT_LINEARIZED
|
||||||
solver->EnableDiagonalPreconditioner(true);
|
solver->EnableDiagonalPreconditioner(true);
|
||||||
my_system.SetSolverForceTolerance(1e-9);
|
my_system.SetSolverForceTolerance(1e-9);
|
||||||
solver->SetVerbose(false);
|
solver->SetVerbose(false);
|
||||||
|
|
||||||
SimulationResults simulationResults;
|
SimulationResults simulationResults;
|
||||||
|
if (settings.analysisType == Settings::AnalysisType::Linear) {
|
||||||
|
simulationResults.converged = my_system.DoStaticLinear();
|
||||||
|
} else {
|
||||||
simulationResults.converged = my_system.DoStaticNonlinear();
|
simulationResults.converged = my_system.DoStaticNonlinear();
|
||||||
// simulationResults.converged = my_system.DoStaticLinear();
|
}
|
||||||
if (!simulationResults.converged) {
|
if (!simulationResults.converged) {
|
||||||
std::cerr << "Simulation failed" << std::endl;
|
std::cerr << "Simulation failed" << std::endl;
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -212,20 +231,26 @@ SimulationResults ChronosEulerSimulationModel::executeSimulation(
|
||||||
simulationResults.rotationalDisplacementQuaternion.resize(pJob->pMesh->VN());
|
simulationResults.rotationalDisplacementQuaternion.resize(pJob->pMesh->VN());
|
||||||
for (size_t vi = 0; vi < pJob->pMesh->VN(); vi++) {
|
for (size_t vi = 0; vi < pJob->pMesh->VN(); vi++) {
|
||||||
const auto node_chronos = edgeMeshVertsToChronoNodes[vi];
|
const auto node_chronos = edgeMeshVertsToChronoNodes[vi];
|
||||||
const auto posDisplacement = node_chronos->Frame().GetPos()
|
const auto posDisplacement =
|
||||||
- node_chronos->GetX0().GetPos();
|
node_chronos->Frame().GetPos() - node_chronos->GetX0().GetPos();
|
||||||
// std::cout << "Node " << vi << " coordinate x= " << node_chronos->Frame().GetPos().x()
|
// std::cout << "Node " << vi << " coordinate x= " <<
|
||||||
|
// node_chronos->Frame().GetPos().x()
|
||||||
// << " y=" << node_chronos->Frame().GetPos().y()
|
// << " y=" << node_chronos->Frame().GetPos().y()
|
||||||
// << " z=" << node_chronos->Frame().GetPos().z() << "\n";
|
// << " z=" << node_chronos->Frame().GetPos().z() <<
|
||||||
|
// "\n";
|
||||||
// Translations
|
// Translations
|
||||||
simulationResults.displacements[vi][0] = posDisplacement[0];
|
simulationResults.displacements[vi][0] = posDisplacement[0];
|
||||||
simulationResults.displacements[vi][1] = posDisplacement[1];
|
simulationResults.displacements[vi][1] = posDisplacement[1];
|
||||||
simulationResults.displacements[vi][2] = posDisplacement[2];
|
simulationResults.displacements[vi][2] = posDisplacement[2];
|
||||||
// Rotations
|
// Rotations
|
||||||
chrono::ChQuaternion<double> rotQuat = node_chronos->GetRot();
|
chrono::ChQuaternion<double> rotQuat = node_chronos->GetRot();
|
||||||
|
simulationResults.rotationalDisplacementQuaternion[vi] =
|
||||||
|
Eigen::Quaternion<double>(rotQuat.e0(), rotQuat.e1(), rotQuat.e2(),
|
||||||
|
rotQuat.e3());
|
||||||
|
const Eigen::Vector3d eulerAngles =
|
||||||
simulationResults.rotationalDisplacementQuaternion[vi]
|
simulationResults.rotationalDisplacementQuaternion[vi]
|
||||||
= Eigen::Quaternion<double>(rotQuat.e0(), rotQuat.e1(), rotQuat.e2(), rotQuat.e3());
|
.toRotationMatrix()
|
||||||
const ChVector<double> eulerAngles = rotQuat.Q_to_Euler123();
|
.eulerAngles(0, 1, 2);
|
||||||
// std::cout << "Euler angles:" << eulerAngles << std::endl;
|
// std::cout << "Euler angles:" << eulerAngles << std::endl;
|
||||||
simulationResults.displacements[vi][3] = eulerAngles[0];
|
simulationResults.displacements[vi][3] = eulerAngles[0];
|
||||||
simulationResults.displacements[vi][4] = eulerAngles[1];
|
simulationResults.displacements[vi][4] = eulerAngles[1];
|
||||||
|
|
@ -238,8 +263,9 @@ SimulationResults ChronosEulerSimulationModel::executeSimulation(
|
||||||
// VCGEdgeMesh deformedMesh;
|
// VCGEdgeMesh deformedMesh;
|
||||||
// deformedMesh.copy(*(pJob->pMesh));
|
// deformedMesh.copy(*(pJob->pMesh));
|
||||||
// for (size_t vi = 0; vi < pJob->pMesh->VN(); vi++) {
|
// for (size_t vi = 0; vi < pJob->pMesh->VN(); vi++) {
|
||||||
// const std::shared_ptr<ChNodeFEAxyzrot> node_chronos = edgeMeshVertsToChronosNodes[vi];
|
// const std::shared_ptr<ChNodeFEAxyzrot> node_chronos =
|
||||||
// deformedMesh.vert[vi].P() = CoordType(node_chronos->GetPos()[0],
|
// edgeMeshVertsToChronosNodes[vi]; deformedMesh.vert[vi].P() =
|
||||||
|
// CoordType(node_chronos->GetPos()[0],
|
||||||
// node_chronos->GetPos()[1],
|
// node_chronos->GetPos()[1],
|
||||||
// node_chronos->GetPos()[2]);
|
// node_chronos->GetPos()[2]);
|
||||||
// }
|
// }
|
||||||
|
|
@ -251,7 +277,7 @@ SimulationResults ChronosEulerSimulationModel::executeSimulation(
|
||||||
// return simulationResults;
|
// return simulationResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChronosEulerSimulationModel::setStructure(const std::shared_ptr<SimulationMesh> &pMesh)
|
void ChronosEulerSimulationModel::setStructure(
|
||||||
{
|
const std::shared_ptr<SimulationEdgeMesh>& pMesh) {
|
||||||
mesh_chronos = convertToChronosMesh_Euler(pMesh, edgeMeshVertsToChronoNodes);
|
mesh_chronos = convertToChronosMesh_Euler(pMesh, edgeMeshVertsToChronoNodes);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,19 @@ class ChronosEulerSimulationModel : public SimulationModel
|
||||||
public:
|
public:
|
||||||
ChronosEulerSimulationModel();
|
ChronosEulerSimulationModel();
|
||||||
SimulationResults executeSimulation(const std::shared_ptr<SimulationJob> &pJob) override;
|
SimulationResults executeSimulation(const std::shared_ptr<SimulationJob> &pJob) override;
|
||||||
void setStructure(const std::shared_ptr<SimulationMesh> &pMesh) override;
|
void setStructure(const std::shared_ptr<SimulationEdgeMesh> &pMesh) override;
|
||||||
static std::shared_ptr<chrono::fea::ChMesh> convertToChronosMesh_Euler(
|
static std::shared_ptr<chrono::fea::ChMesh> convertToChronosMesh_Euler(
|
||||||
const std::shared_ptr<SimulationMesh> &pMesh,
|
const std::shared_ptr<SimulationEdgeMesh> &pMesh,
|
||||||
std::vector<std::shared_ptr<chrono::fea::ChNodeFEAxyzrot>> &edgeMeshVertsToChronosNodes);
|
std::vector<std::shared_ptr<chrono::fea::ChNodeFEAxyzrot>> &edgeMeshVertsToChronosNodes);
|
||||||
|
|
||||||
inline const static std::string label{"Chronos_nonLinear_Euler"};
|
inline const static std::string label{"Chronos_Euler"};
|
||||||
|
|
||||||
|
struct Settings
|
||||||
|
{
|
||||||
|
enum AnalysisType { Linear = 0, NonLinear };
|
||||||
|
AnalysisType analysisType{NonLinear};
|
||||||
|
};
|
||||||
|
Settings settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHRONOSEULERSIMULATIONMODEL_HPP
|
#endif // CHRONOSEULERSIMULATIONMODEL_HPP
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
using namespace chrono;
|
using namespace chrono;
|
||||||
using namespace chrono::fea;
|
using namespace chrono::fea;
|
||||||
std::shared_ptr<ChMesh> ChronosIGASimulationModel::convertToChronosMesh_IGA(
|
std::shared_ptr<ChMesh> ChronosIGASimulationModel::convertToChronosMesh_IGA(
|
||||||
const std::shared_ptr<SimulationMesh> &pMesh,
|
const std::shared_ptr<SimulationEdgeMesh> &pMesh,
|
||||||
std::vector<std::shared_ptr<ChNodeFEAxyzrot>> &edgeMeshVertsToChronosNodes)
|
std::vector<std::shared_ptr<ChNodeFEAxyzrot>> &edgeMeshVertsToChronosNodes)
|
||||||
{
|
{
|
||||||
auto mesh_chronos = chrono_types::make_shared<ChMesh>();
|
auto mesh_chronos = chrono_types::make_shared<ChMesh>();
|
||||||
|
|
@ -34,7 +34,7 @@ std::shared_ptr<ChMesh> ChronosIGASimulationModel::convertToChronosMesh_IGA(
|
||||||
//add elements
|
//add elements
|
||||||
ChBuilderBeamIGA builder;
|
ChBuilderBeamIGA builder;
|
||||||
for (int ei = 0; ei < pMesh->EN(); ei++) {
|
for (int ei = 0; ei < pMesh->EN(); ei++) {
|
||||||
const SimulationMesh::EdgeType &edge = pMesh->edge[ei];
|
const SimulationEdgeMesh::EdgeType &edge = pMesh->edge[ei];
|
||||||
//define end-points
|
//define end-points
|
||||||
const auto vi0 = pMesh->getIndex(edge.cV(0));
|
const auto vi0 = pMesh->getIndex(edge.cV(0));
|
||||||
const auto vi1 = pMesh->getIndex(edge.cV(1));
|
const auto vi1 = pMesh->getIndex(edge.cV(1));
|
||||||
|
|
@ -54,13 +54,14 @@ std::shared_ptr<ChMesh> ChronosIGASimulationModel::convertToChronosMesh_IGA(
|
||||||
// msection->SetGwithPoissonRatio(poisson);
|
// msection->SetGwithPoissonRatio(poisson);
|
||||||
// // msection->SetBeamRaleyghDamping(0.0);
|
// // msection->SetBeamRaleyghDamping(0.0);
|
||||||
// msection->SetAsRectangularSection(beam_wy, beam_wz);
|
// msection->SetAsRectangularSection(beam_wy, beam_wz);
|
||||||
builder.BuildBeam(
|
builder
|
||||||
mesh_chronos, // the mesh where to put the created nodes and elements
|
.BuildBeam(mesh_chronos, // the mesh where to put the created nodes and elements
|
||||||
msection, // the ChBeamSectionEuler to use for the ChElementBeamEuler elements
|
msection, // the ChBeamSectionEuler to use for the ChElementBeamEuler elements
|
||||||
4, // the number of ChElementBeamEuler to create
|
1, // the number of ChElementBeamEuler to create
|
||||||
edgeMeshVertsToChronosNodes[vi0]->GetPos(), // the 'A' point in space (beginning of beam)
|
edgeMeshVertsToChronosNodes[vi0], // the 'A' point in space (beginning of beam)
|
||||||
edgeMeshVertsToChronosNodes[vi1]->GetPos(), // the 'B' point in space (end of beam)
|
edgeMeshVertsToChronosNodes[vi1], // the 'B' point in space (end of beam)
|
||||||
ChVector<>(0, 0, 1)
|
ChVector<>(0, 0, 1),
|
||||||
|
3
|
||||||
// ChVector<>(0, cos(rot_rad), sin(rot_rad))
|
// ChVector<>(0, cos(rot_rad), sin(rot_rad))
|
||||||
); // the 'Y' up direction of the section for the beam
|
); // the 'Y' up direction of the section for the beam
|
||||||
const auto lastBeamNodesVector = builder.GetLastBeamNodes();
|
const auto lastBeamNodesVector = builder.GetLastBeamNodes();
|
||||||
|
|
@ -195,7 +196,8 @@ SimulationResults ChronosIGASimulationModel::executeSimulation(
|
||||||
//parse constrained vertices
|
//parse constrained vertices
|
||||||
// std::cout << node_0->GetCoord().pos[0] << " " << node_0->GetCoord().pos[1] << " "
|
// std::cout << node_0->GetCoord().pos[0] << " " << node_0->GetCoord().pos[1] << " "
|
||||||
// << node_0->GetCoord().pos[2] << std::endl;
|
// << node_0->GetCoord().pos[2] << std::endl;
|
||||||
parseConstrainedVertices(pJob, edgeMeshVertsToChronoNodes, my_system);
|
// parseConstrainedVertices(pJob, edgeMeshVertsToChronoNodes, my_system);
|
||||||
|
|
||||||
// std::cout << node_0->GetCoord().pos[0] << " " << node_0->GetCoord().pos[1] << " "
|
// std::cout << node_0->GetCoord().pos[0] << " " << node_0->GetCoord().pos[1] << " "
|
||||||
// << node_0->GetCoord().pos[2] << std::endl;
|
// << node_0->GetCoord().pos[2] << std::endl;
|
||||||
// std::dynamic_pointer_cast<std::shared_ptr<ChNodeFEAxyzrot>>(mesh_chronos->GetNode(1))
|
// std::dynamic_pointer_cast<std::shared_ptr<ChNodeFEAxyzrot>>(mesh_chronos->GetNode(1))
|
||||||
|
|
@ -290,7 +292,7 @@ SimulationResults ChronosIGASimulationModel::executeSimulation(
|
||||||
// return simulationResults;
|
// return simulationResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChronosIGASimulationModel::setStructure(const std::shared_ptr<SimulationMesh> &pMesh)
|
void ChronosIGASimulationModel::setStructure(const std::shared_ptr<SimulationEdgeMesh> &pMesh)
|
||||||
{
|
{
|
||||||
mesh_chronos = convertToChronosMesh_IGA(pMesh, edgeMeshVertsToChronoNodes);
|
mesh_chronos = convertToChronosMesh_IGA(pMesh, edgeMeshVertsToChronoNodes);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ class ChronosIGASimulationModel : public SimulationModel
|
||||||
public:
|
public:
|
||||||
ChronosIGASimulationModel();
|
ChronosIGASimulationModel();
|
||||||
SimulationResults executeSimulation(const std::shared_ptr<SimulationJob> &pJob) override;
|
SimulationResults executeSimulation(const std::shared_ptr<SimulationJob> &pJob) override;
|
||||||
void setStructure(const std::shared_ptr<SimulationMesh> &pMesh) override;
|
void setStructure(const std::shared_ptr<SimulationEdgeMesh> &pMesh) override;
|
||||||
static std::shared_ptr<chrono::fea::ChMesh> convertToChronosMesh_IGA(
|
static std::shared_ptr<chrono::fea::ChMesh> convertToChronosMesh_IGA(
|
||||||
const std::shared_ptr<SimulationMesh> &pMesh,
|
const std::shared_ptr<SimulationEdgeMesh> &pMesh,
|
||||||
std::vector<std::shared_ptr<chrono::fea::ChNodeFEAxyzrot>> &edgeMeshVertsToChronosNodes);
|
std::vector<std::shared_ptr<chrono::fea::ChNodeFEAxyzrot>> &edgeMeshVertsToChronosNodes);
|
||||||
|
|
||||||
inline const static std::string label{"Chronos_linear_IGA"};
|
inline const static std::string label{"Chronos_linear_IGA"};
|
||||||
|
|
|
||||||
|
|
@ -4210,7 +4210,7 @@ Eigen::Vector3d DER_leimer::getPerpendicularVector(const Eigen::Vector3d &t) con
|
||||||
}
|
}
|
||||||
|
|
||||||
DER_leimer::RodConfig *DER_leimer::readRodGrid(
|
DER_leimer::RodConfig *DER_leimer::readRodGrid(
|
||||||
const std::shared_ptr<SimulationMesh> &pMesh,
|
const std::shared_ptr<SimulationEdgeMesh> &pMesh,
|
||||||
const std::vector<int> &numVertsPerRod,
|
const std::vector<int> &numVertsPerRod,
|
||||||
const std::vector<int> &
|
const std::vector<int> &
|
||||||
vInd, //index after the physVerts in the verts vector? Contains "global" indices of all centerline vertices eg at intersections all endpoints vertices get the same "global" index. Do interior centerline vertices get a global index?
|
vInd, //index after the physVerts in the verts vector? Contains "global" indices of all centerline vertices eg at intersections all endpoints vertices get the same "global" index. Do interior centerline vertices get a global index?
|
||||||
|
|
@ -4837,7 +4837,7 @@ int DER_leimer::RodConfig::getNumDoF() const
|
||||||
return ndofs;
|
return ndofs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DER_leimer::setStructure(const std::shared_ptr<SimulationMesh> &pMesh)
|
void DER_leimer::setStructure(const std::shared_ptr<SimulationEdgeMesh> &pMesh)
|
||||||
{
|
{
|
||||||
std::cout << "This function is currently not implemented" << std::endl;
|
std::cout << "This function is currently not implemented" << std::endl;
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ public:
|
||||||
int getNumDoF() const;
|
int getNumDoF() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void setStructure(const std::shared_ptr<SimulationMesh> &pMesh) override;
|
void setStructure(const std::shared_ptr<SimulationEdgeMesh> &pMesh) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool simulateOneStepGrid(RodConfig *config);
|
bool simulateOneStepGrid(RodConfig *config);
|
||||||
|
|
@ -159,7 +159,7 @@ private:
|
||||||
std::vector<Eigen::Triplet<int>> *Hu_index = NULL,
|
std::vector<Eigen::Triplet<int>> *Hu_index = NULL,
|
||||||
std::vector<double> *Hu_value = NULL);
|
std::vector<double> *Hu_value = NULL);
|
||||||
|
|
||||||
RodConfig *readRodGrid(const std::shared_ptr<SimulationMesh> &pMesh,
|
RodConfig *readRodGrid(const std::shared_ptr<SimulationEdgeMesh> &pMesh,
|
||||||
const std::vector<int> &numVertsPerRod,
|
const std::vector<int> &numVertsPerRod,
|
||||||
const std::vector<int> &vInd,
|
const std::vector<int> &vInd,
|
||||||
const std::vector<Eigen::Vector3d> &verts,
|
const std::vector<Eigen::Vector3d> &verts,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue