Hi! I have a problem when importing a .obj mesh into Chrono with BSTShellFromObjFile. For some reason, when I apply a pressure to the mesh, a set of nodes stays fixed while the rest of the nodes move. I have not written any code to fix these nodes. Does anyone know what the problem might be? The .obj file is a simple circular mesh, and both my code and the file are attached.
-- You received this message because you are subscribed to the Google Groups "ProjectChrono" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/projectchrono/8a52ff91-9ece-44a5-8bb4-d9291873a2e0n%40googlegroups.com.
circle.obj
Description: Binary data
// =============================================================================
// PROJECT CHRONO
//==============================================================================
#include "chrono/physics/ChBodyEasy.h"
#include "chrono/physics/ChLinkMate.h"
#include "chrono/physics/ChSystemNSC.h"
#include "chrono/physics/ChLoaderUV.h"
#include "chrono/solver/ChIterativeSolverLS.h"
#include "chrono/timestepper/ChTimestepper.h"
#include "chrono/fea/ChElementShellBST.h"
#include "chrono/fea/ChLinkPointFrame.h"
#include "chrono/fea/ChMesh.h"
#include "chrono/fea/ChMeshFileLoader.h"
#include "chrono/fea/ChContactSurfaceMesh.h"
#include "chrono/fea/ChContactSurfaceNodeCloud.h"
#include "chrono/fea/ChLoadContactSurfaceMesh.h"
#include "chrono/assets/ChVisualShapeFEA.h"
#include "chrono_irrlicht/ChVisualSystemIrrlicht.h"
#include "chrono/solver/ChIterativeSolverLS.h"
#include "chrono/physics/ChLoadContainer.h"
#include "chrono/physics/ChLoadsBody.h"
#include "chrono_postprocess/ChGnuPlot.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <map>
#include <cmath>
using namespace chrono;
using namespace chrono::fea;
using namespace chrono::geometry;
using namespace chrono::irrlicht;
class MyChLoaderPressure : public ChLoaderUVdistributed {
private:
double pressure;
bool is_stiff;
int num_integration_points;
double frequency; // frequency of the sinusoidal wave
double time; // current time
public:
MyChLoaderPressure(std::shared_ptr<ChLoadableUV> mloadable)
: ChLoaderUVdistributed(mloadable), is_stiff(false), num_integration_points(1), time(0.0), frequency(1.0) {}
virtual void ComputeF(const double U, ///< parametric coordinate in surface
const double V, ///< parametric coordinate in surface
ChVectorDynamic<>& F, ///< Result F vector here, size must be = n.field coords.of loadable
ChVectorDynamic<>* state_x, ///< if != 0, update state (pos. part) to this, then evaluate F
ChVectorDynamic<>* state_w ///< if != 0, update state (speed part) to this, then evaluate F
) override {
ChVector<> mnorm = this->loadable->ComputeNormal(U, V);
double pressure_time = pressure * sin(2 * CH_C_PI * frequency * time);
F.segment(0, 3) = -pressure_time * mnorm.eigen();
}
void SetPressure(double mpressure) { pressure = mpressure; }
double GetPressure() { return pressure; }
void SetFrequency(double mfreq) { frequency = mfreq; }
double GetFrequency() { return frequency; }
void SetTime(double mtime) { time = mtime; } // setter for time
double GetTime() { return time; } // getter for time
void SetIntegrationPoints(int val) { num_integration_points = val; }
virtual int GetIntegrationPointsU() override { return num_integration_points; }
virtual int GetIntegrationPointsV() override { return num_integration_points; }
void SetStiff(bool val) { is_stiff = val; }
virtual bool IsStiff() override { return is_stiff; }
};
int main(int argc, char* argv[]) {
// Create a Chrono::Engine physical system + collision system
ChSystemNSC sys;
//sys.Set_G_acc(ChVector<>(0, 0, 0));
SetChronoDataPath(CHRONO_DATA_DIR);
ChCollisionModel::SetDefaultSuggestedEnvelope(0.0025);
ChCollisionModel::SetDefaultSuggestedMargin(0.0025);
sys.SetCollisionSystemType(ChCollisionSystem::Type::BULLET);
/*
//create surface material
auto surfacemat = chrono_types::make_shared<ChMaterialSurfaceNSC>();
auto floorBody = chrono_types::make_shared<ChBodyEasyBox>(10, 0, 10, // x, y, z dimensions
3000, // density
true, // create visualization asset
true, // collision geometry
surfacemat // surface material
);
floorBody->SetPos(ChVector<>(0, 0, 0));
floorBody->SetBodyFixed(true);
floorBody->GetVisualShape(0)->SetTexture(GetChronoDataFile("textures/blue.png"));
//sys.Add(floorBody);
*/
auto mesh = chrono_types::make_shared<ChMesh>();
double density = 100;
// Create a material
auto elasticity = chrono_types::make_shared<ChElasticityKirchhoffIsothropic>(500, 0.33);
auto material = chrono_types::make_shared<ChMaterialShellKirchhoff>(elasticity);
material->SetDensity(density);
ChMeshFileLoader::BSTShellFromObjFile(mesh, "/Users/weizhiwang/workspace/circle.obj", material, 0.01);
/*
if (auto mnode = std::dynamic_pointer_cast<ChNodeFEAxyz>(mesh->GetNode(0))) {
mnode->SetFixed(true);
}
*/
sys.Add(mesh);
// Iterate over all nodes in the mesh
for (int i = 0; i < mesh->GetNnodes(); i++) {
if (auto node = std::dynamic_pointer_cast<ChNodeFEAxyz>(mesh->GetNode(i))) {
// Get the position of the node
ChVector<> pos = node->GetPos();
// Print the position
std::cout << "Node " << i << ": " << pos.x() << ", " << pos.y() << ", " << pos.z() << std::endl;
}
}
auto loadcontainer = chrono_types::make_shared<ChLoadContainer>();
// Set the pressure value
double pressureValue = -100.0; // replace with your actual pressure value
// Iterate over all elements in the mesh
for (int i = 0; i < mesh->GetNelements(); i++) {
if (auto el = std::dynamic_pointer_cast<ChElementShellBST>(mesh->GetElement(i))) {
// Create a ChLoaderPressure for the element
auto pressure_load = chrono_types::make_shared<ChLoad<MyChLoaderPressure>>(el);
pressure_load->loader.SetPressure(pressureValue);
pressure_load->loader.SetStiff(true);
pressure_load->loader.SetIntegrationPoints(2);
pressure_load->loader.SetFrequency(1.0);
pressure_load->loader.SetTime(sys.GetChTime());
loadcontainer->Add(pressure_load);
}
}
sys.Add(loadcontainer);
// Visualization of the FEM mesh.
auto vis_shell_mesh = chrono_types::make_shared<ChVisualShapeFEA>(mesh);
vis_shell_mesh->SetFEMdataType(ChVisualShapeFEA::DataType::SURFACE);
vis_shell_mesh->SetWireframe(true);
vis_shell_mesh->SetShellResolution(2);
vis_shell_mesh->SetBackfaceCull(true);
mesh->AddVisualShapeFEA(vis_shell_mesh);
auto vis_shell_speed = chrono_types::make_shared<ChVisualShapeFEA>(mesh);
vis_shell_speed->SetFEMdataType(ChVisualShapeFEA::DataType::NODE_SPEED_NORM);
vis_shell_speed->SetColorscaleMinMax(0.0, 5.0);
vis_shell_speed->SetWireframe(false);
vis_shell_speed->SetShellResolution(3);
mesh->AddVisualShapeFEA(vis_shell_speed);
auto vis_shell_nodes = chrono_types::make_shared<ChVisualShapeFEA>(mesh);
vis_shell_nodes->SetFEMdataType(ChVisualShapeFEA::DataType::NONE);
vis_shell_nodes->SetFEMglyphType(ChVisualShapeFEA::GlyphType::NODE_DOT_POS);
vis_shell_nodes->SetSymbolsThickness(0.006);
mesh->AddVisualShapeFEA(vis_shell_nodes);
// Create the Irrlicht visualization system
auto vis = chrono_types::make_shared<ChVisualSystemIrrlicht>();
vis->AttachSystem(&sys);
vis->SetWindowSize(800, 600);
vis->SetWindowTitle("Obj-tri Mesh Simulation");
vis->Initialize();
vis->AddLogo();
vis->AddSkyBox();
vis->AddCamera(ChVector<>(0, 0.5, -1));
vis->AddTypicalLights();
//MINRES solver
auto solver = chrono_types::make_shared<ChSolverMINRES>();
sys.SetSolver(solver);
solver->SetMaxIterations(100);
solver->SetTolerance(1e-10);
solver->EnableDiagonalPreconditioner(true);
// Simulation loop
while (vis->Run()) {
for (auto& load : loadcontainer->GetLoadList()) {
if (auto pressure_load = std::dynamic_pointer_cast<ChLoad<MyChLoaderPressure>>(load)) {
pressure_load->loader.SetTime(sys.GetChTime());
}
}
vis->BeginScene(true, true, ChColor(0.55f, 0.63f, 0.75f));
vis->Render();
vis->EndScene();
sys.DoStepDynamics(0.005);
}
return 0;
}
