virtual void onCallback(ChSharedPtr<ChBody> wheelBody, double radius, double width) { wheelBody->GetCollisionModel()->ClearModel(); wheelBody->GetCollisionModel()->AddCylinder(0.46, 0.46, width / 2); wheelBody->GetCollisionModel()->BuildModel(); wheelBody->GetMaterialSurfaceDEM()->SetFriction(mu_t); wheelBody->GetMaterialSurfaceDEM()->SetYoungModulus(Y_t); wheelBody->GetMaterialSurfaceDEM()->SetRestitution(cr_t); }
void RunTimeStep(T* mSys, const int frame) { if (!save) { Vector force = engine_anchor->Get_react_force(); Vector torque = engine_anchor->Get_react_torque(); double motor_torque = engine_anchor->Get_mot_torque(); cout << force.x << " " << force.y << " " << force.z << " " << torque.x << " " << torque.y << " " << torque.z << " " << motor_torque << " " << ANCHOR->GetPos().y << " " << ANCHOR->GetPos_dt().y << endl; ANCHOR->SetPos(ChVector<>(REFERENCE->GetPos().x, ANCHOR->GetPos().y, REFERENCE->GetPos().z)); ANCHOR->SetPos_dt(ChVector<>(REFERENCE->GetPos_dt().x, ANCHOR->GetPos_dt().y, REFERENCE->GetPos_dt().z)); ANCHOR->SetRot(REFERENCE->GetRot()); ANCHOR->SetWvel_loc(REFERENCE->GetWvel_loc()); REFERENCE->SetPos(ChVector<>(REFERENCE->GetPos().x, ANCHOR->GetPos().y, REFERENCE->GetPos().z)); REFERENCE->SetPos_dt(ChVector<>(REFERENCE->GetPos_dt().x, ANCHOR->GetPos_dt().y, REFERENCE->GetPos_dt().z)); } // real t = frame * timestep * PI * 2 * frequency; // // BLOCK->SetRot(ChQuaternion<>(1, 0, 0, 0)); // BLOCK->SetWvel_loc(ChVector<>(0, 0, 0)); // BLOCK->SetPos(ChVector<>(sin(t) * amplitude, BLOCK->GetPos().y, 0)); // BLOCK->SetPos_dt(ChVector<>(cos(t) * amplitude * 2 * PI * frequency, BLOCK->GetPos_dt().y, 0)); // // CONTAINER->SetPos(ChVector<>(sin(t) * amplitude, 0, 0)); // CONTAINER->SetPos_dt(ChVector<>(cos(t) * amplitude * 2 * PI * frequency, 0, 0)); // CONTAINER->SetWvel_loc(ChVector<>(0, 0, 0)); // CONTAINER->SetRot(ChQuaternion<>(1, 0, 0, 0)); // // // real cont_vol = (container_size.x - container_thickness * 2) * 2 * (BLOCK->GetPos().y + container_size.y - 2 * container_thickness) * (container_size.z - container_thickness * 2) * 2; // cout << layer_gen->total_volume << " " << layer_gen->total_mass << " " << cont_vol << " " << layer_gen->total_mass / cont_vol << endl; // if (save) { if (layers < 130 && frame % 80 == 0) { cout << layers << endl; layer_gen->addPerturbedVolumeMixture(R3(0, -container_size.y + container_thickness + particle_radius * 5 + frame / 14.0, 0), I3(32, 1, 32), R3(0, 0, 0), R3(0, 0, 0)); layers++; } } else { //300 - 457.2 // double time = actuator_anchor->GetChTime(); // if (ANCHOR->GetPos().y <= 300 - 457.2 && once) { // motionFunc1->Set_y0(time * -anchor_vel); // motionFunc1->Set_ang(-2); //// motionFunc2->Set_y0(time * -anchor_rot * 1 / 60.0 * 2 * CH_C_PI); //// motionFunc2->Set_ang(0); // if (ChFunction_Const* mfun = dynamic_cast<ChFunction_Const*>(engine_anchor->Get_spe_funct())) { // mfun->Set_yconst(0); // rad/s angular speed // } // once = false; // } } }
void align_spheres(ChIrrAppInterface& application) { for (unsigned int i = 0; i< mspheres.size(); ++i) { ChSharedPtr<ChBody> body = mspheres[i]; ChVector<> mpos = body->GetPos(); mpos.x = 0.5; mpos.z = 0.7; body->SetPos(mpos); body->SetRot(QUNIT); } }
// ----------------------------------------------------------------------------- // Utility for adding (visible or invisible) walls // ----------------------------------------------------------------------------- void AddWall(ChSharedPtr<ChBody>& body, const ChVector<>& dim, const ChVector<>& loc, bool visible) { body->GetCollisionModel()->AddBox(dim.x, dim.y, dim.z, loc); if (visible == true) { ChSharedPtr<ChBoxShape> box(new ChBoxShape); box->GetBoxGeometry().Size = dim; box->Pos = loc; box->SetColor(ChColor(1, 0, 0)); box->SetFading(0.6f); body->AddAsset(box); } }
int ChShaftsMotor::Initialize(ChSharedPtr<ChShaft>& mshaft1, ChSharedPtr<ChShaft>& mshaft2) { // Parent class initialize if (!ChShaftsCouple::Initialize(mshaft1, mshaft2)) return false; ChShaft* mm1 = mshaft1.get_ptr(); ChShaft* mm2 = mshaft2.get_ptr(); this->constraint.SetVariables(&mm1->Variables(), &mm2->Variables()); this->SetSystem(this->shaft1->GetSystem()); return true; }
void ChFunction_Sequence::Setup() { double basetime = this->start; double lastIy = 0; double lastIy_dt = 0; double lastIy_dtdt = 0; for (ChNode<ChFseqNode>* mnode = functions.GetHead(); mnode != NULL; mnode= mnode->next) { mnode->data->t_start = basetime; mnode->data->t_end = basetime + mnode->data->duration; mnode->data->Iy = 0; mnode->data->Iydt = 0; mnode->data->Iydtdt = 0; if (mnode->data->fx.IsType<ChFunction_Fillet3>()) // C0 C1 fillet { ChSharedPtr<ChFunction_Fillet3> mfillet = mnode->data->fx.DynamicCastTo<ChFunction_Fillet3>(); mfillet->Set_y1(lastIy); mfillet->Set_dy1(lastIy_dt); if (mnode->next) { mfillet->Set_y2(mnode->next->data->fx->Get_y(0)); mfillet->Set_dy2(mnode->next->data->fx->Get_y_dx(0)); }else { mfillet->Set_y2(0); mfillet->Set_dy2(0); } mfillet->Set_end(mnode->data->duration); mnode->data->Iy = mnode->data->Iydt = mnode->data->Iydtdt = 0; } else // generic continuity conditions { if (mnode->data->y_cont) mnode->data->Iy = lastIy - mnode->data->fx->Get_y(0); if (mnode->data->ydt_cont) mnode->data->Iydt = lastIy_dt - mnode->data->fx->Get_y_dx(0); if (mnode->data->ydtdt_cont) mnode->data->Iydtdt = lastIy_dtdt - mnode->data->fx->Get_y_dxdx(0); } lastIy = mnode->data->fx->Get_y(mnode->data->duration) + mnode->data->Iy + mnode->data->Iydt * mnode->data->duration + mnode->data->Iydtdt * mnode->data->duration * mnode->data->duration; lastIy_dt = mnode->data->fx->Get_y_dx(mnode->data->duration) + mnode->data->Iydt + mnode->data->Iydtdt * mnode->data->duration; lastIy_dtdt = mnode->data->fx->Get_y_dxdx(mnode->data->duration) + mnode->data->Iydtdt; basetime += mnode->data->duration; } }
int ChLinkDistance::Initialize(ChSharedPtr<ChBody>& mbody1, ///< first body to link ChSharedPtr<ChBody>& mbody2, ///< second body to link bool pos_are_relative,///< true: following posit. are considered relative to bodies. false: pos.are absolute ChVector<> mpos1, ///< position of distance endpoint, for 1st body (rel. or abs., see flag above) ChVector<> mpos2, ///< position of distance endpoint, for 2nd body (rel. or abs., see flag above) bool auto_distance,///< if true, initializes the imposed distance as the distance between mpos1 and mpos2 double mdistance ///< imposed distance (no need to define, if auto_distance=true.) ) { this->Body1 = mbody1.get_ptr(); this->Body2 = mbody2.get_ptr(); this->Cx.SetVariables(&this->Body1->Variables(),&this->Body2->Variables()); if (pos_are_relative) { this->pos1 = mpos1; this->pos2 = mpos2; } else { this->pos1 = this->Body1->Point_World2Body(&mpos1); this->pos2 = this->Body2->Point_World2Body(&mpos2); } ChVector<> AbsDist = Body1->Point_Body2World(&pos1)-Body2->Point_Body2World(&pos2); this->curr_dist = AbsDist.Length(); if (auto_distance) { this->distance = this->curr_dist; } else { this->distance = mdistance; } return true; }
virtual void onCallback(ChSharedPtr<ChBody> wheelBody, double radius, double width) { ChCollisionModelParallel* coll_model = (ChCollisionModelParallel*)wheelBody->GetCollisionModel(); coll_model->ClearModel(); // Assemble the tire contact from 15 segments, properly offset. // Each segment is further decomposed in convex hulls. for (int iseg = 0; iseg < 15; iseg++) { ChQuaternion<> rot = Q_from_AngAxis(iseg * 24 * CH_C_DEG_TO_RAD, VECT_Y); for (int ihull = 0; ihull < num_hulls; ihull++) { std::vector<ChVector<> > convexhull; lugged_convex.GetConvexHullResult(ihull, convexhull); coll_model->AddConvexHull(convexhull, VNULL, rot); } } // Add a cylinder to represent the wheel hub. coll_model->AddCylinder(0.223, 0.223, 0.126); coll_model->BuildModel(); wheelBody->GetMaterialSurfaceDEM()->SetFriction(mu_t); wheelBody->GetMaterialSurfaceDEM()->SetYoungModulus(Y_t); wheelBody->GetMaterialSurfaceDEM()->SetRestitution(cr_t); }
void add_fancy_items(ChSystemMPI& mySys, double prad, double pmass, double width, double g, double h, int n_batch, int n_curr_spheres) { int id_offset=10; double particle_mass =4.0; if (pmass>0.0){ particle_mass=pmass; } ChSharedPtr<ChBodyDEMMPI> mybody; double spacing = (width-8*prad)/(n_batch-1); double first = -(width-8*prad)/2; for(int jj=0; jj<n_batch; jj++) { ChVector<> particle_pos(-g+(ChRandom()*2*prad-prad), h, first+jj*spacing); if (mySys.nodeMPI->IsInto(particle_pos)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_spheres+jj); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } } }
void add_batch(ChSystemMPI& mySys, double prad, double box_dim, double pmass, int n_batch, int n_curr_spheres) { int id_offset=10; double particle_mass =4.0; if (pmass>0.0){ particle_mass=pmass; } ChSharedPtr<ChBodyDEMMPI> mybody; double boxxx=box_dim-4*prad; double spacing = (boxxx-8*prad)/((n_batch/4)-1); double first = -boxxx/2; int cid = 0; for(int ii=0; ii<n_batch/4; ii++) { ChVector<> particle_pos(boxxx/2-2*prad,box_dim/2+2*prad, first+ii*spacing+0.0001); if (mySys.nodeMPI->IsInto(particle_pos)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_spheres+cid); mybody->SetCollide(true); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mySys.Add(mybody); mybody->SetPos(particle_pos); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } cid++; } for(int ii=0; ii<n_batch/4; ii++) { ChVector<> particle_pos(boxxx/2-6*prad,box_dim/2+2*prad, first+ii*spacing+0.0001); if (mySys.nodeMPI->IsInto(particle_pos)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_spheres+cid); mybody->SetCollide(true); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mySys.Add(mybody); mybody->SetPos(particle_pos); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } cid++; } //other edge for(int ii=0; ii<n_batch/4; ii++) { ChVector<> particle_pos(first+ii*spacing+0.0001,box_dim/2+2*prad,boxxx/2-2*prad); if (mySys.nodeMPI->IsInto(particle_pos)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_spheres+cid); mybody->SetCollide(true); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mySys.Add(mybody); mybody->SetPos(particle_pos); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } cid++; } for(int ii=0; ii<n_batch/4; ii++) { ChVector<> particle_pos(first+ii*spacing+0.0001,box_dim/2+2*prad,boxxx/2-6*prad); if (mySys.nodeMPI->IsInto(particle_pos)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_spheres+cid); mybody->SetCollide(true); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mySys.Add(mybody); mybody->SetPos(particle_pos); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } cid++; } }
void create_falling_items(ChSystemMPI& mySys, double prad, int n_bodies,double box_dim, double pmass){ double particle_mass =4.0; if (pmass>0.0){ particle_mass=pmass; } ChSharedPtr<ChBodyDEMMPI> mybody; double boxxx=box_dim-2*prad; for (int ii=0; ii<n_bodies; ii++){ ChVector<> particle_pos(ChRandom()*boxxx-boxxx/2,ChRandom()*boxxx/2+boxxx/2+prad, ChRandom()*boxxx-boxxx/2); if (mySys.nodeMPI->IsInto(particle_pos)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(10+ii); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } } /* ChVector<> pp1(0.5*box_dim/2,box_dim/2,0.5*box_dim/2); if (mySys.nodeMPI->IsInto(pp1)) { mybody = ChSharedPtr<ChBodyDEMMPI>(new ChBodyDEMMPI); mybody->SetIdentifier(11); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(pp1); mybody->SetMass(particle_mass); mybody->SetInertiaXX((2.0/5.0)*particle_mass*prad*prad*ChVector<>(1.0,1.0,1.0)); } ChVector<> pp2(-0.5*box_dim/2,box_dim/2,0.5*box_dim/2); if (mySys.nodeMPI->IsInto(pp2)) { mybody = ChSharedPtr<ChBodyDEMMPI>(new ChBodyDEMMPI); mybody->SetIdentifier(22); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(pp2); mybody->SetMass(particle_mass); mybody->SetInertiaXX((2.0/5.0)*particle_mass*prad*prad*ChVector<>(1.0,1.0,1.0)); } ChVector<> pp3(0.5*box_dim/2,box_dim/2,-0.5*box_dim/2); if (mySys.nodeMPI->IsInto(pp3)) { mybody = ChSharedPtr<ChBodyDEMMPI>(new ChBodyDEMMPI); mybody->SetIdentifier(33); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(pp3); mybody->SetMass(particle_mass); mybody->SetInertiaXX((2.0/5.0)*particle_mass*prad*prad*ChVector<>(1.0,1.0,1.0)); } ChVector<> pp4(-0.5*box_dim/2,box_dim/2,-0.5*box_dim/2); if (mySys.nodeMPI->IsInto(pp4)) { mybody = ChSharedPtr<ChBodyDEMMPI>(new ChBodyDEMMPI); mybody->SetIdentifier(44); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(pp4); mybody->SetMass(particle_mass); mybody->SetInertiaXX((2.0/5.0)*particle_mass*prad*prad*ChVector<>(1.0,1.0,1.0)); } */ }
void add_other_falling_item(ChSystemMPI& mySys, double prad, double box_dim, double rho, int n_curr_bodies) { int id_offset=10; double m_s = (2/3)*CH_C_PI*pow(prad,3)*rho; double m_c = CH_C_PI*pow(prad,2)*(2*prad)*rho; double m_cube = prad*prad*prad*rho; ChVector<> pos1(0,prad,0); ChVector<> pos2(0,-prad,0); ChSharedPtr<ChBodyDEMMPI> mybody; double boxxx=box_dim-2*prad; ChVector<> particle_pos(0.8*boxxx/2,box_dim/2+2*prad, 0.6*boxxx/2); if (mySys.nodeMPI->IsInto(particle_pos)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_bodies+1); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddBox(prad,prad,prad); //mybody->GetCollisionModel()->AddSphere(prad, &pos1); //mybody->GetCollisionModel()->AddCylinder(prad,prad,prad); //mybody->GetCollisionModel()->AddSphere(prad, &pos2); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos); //mybody->SetInertiaXX(ChVector<>(((7.0/12)*m_c+4.3*m_s)*pow(prad,2),(0.5*m_c+0.8*m_s)*pow(prad,2),((7.0/12)*m_c+4.3*m_s)*pow(prad,2))); //mybody->SetMass(m_c+2*m_s); mybody->SetInertiaXX((1.0/6.0)*m_cube*pow(prad,2)*ChVector<>(1.0,1.0,1.0)); mybody->SetMass(m_cube); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } ChVector<> particle_pos2(0.8*boxxx/2,box_dim/2+2*prad, 0.2*boxxx/2); if (mySys.nodeMPI->IsInto(particle_pos2)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_bodies+2); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddBox(prad,prad,prad); //mybody->GetCollisionModel()->AddSphere(prad, &pos1); //mybody->GetCollisionModel()->AddCylinder(prad,prad,prad); //mybody->GetCollisionModel()->AddSphere(prad, &pos2); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos2); //mybody->SetInertiaXX(ChVector<>(((7.0/12)*m_c+4.3*m_s)*pow(prad,2),(0.5*m_c+0.8*m_s)*pow(prad,2),((7.0/12)*m_c+4.3*m_s)*pow(prad,2))); //mybody->SetMass(m_c+2*m_s); mybody->SetInertiaXX((1.0/6.0)*m_cube*pow(prad,2)*ChVector<>(1.0,1.0,1.0)); mybody->SetMass(m_cube); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } ChVector<> particle_pos3(0.8*boxxx/2,box_dim/2+2*prad, -0.2*boxxx/2); if (mySys.nodeMPI->IsInto(particle_pos3)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_bodies+3); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddBox(prad,prad,prad); //mybody->GetCollisionModel()->AddSphere(prad, &pos1); //mybody->GetCollisionModel()->AddCylinder(prad,prad,prad); //mybody->GetCollisionModel()->AddSphere(prad, &pos2); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos3); //mybody->SetInertiaXX(ChVector<>(((7.0/12)*m_c+4.3*m_s)*pow(prad,2),(0.5*m_c+0.8*m_s)*pow(prad,2),((7.0/12)*m_c+4.3*m_s)*pow(prad,2))); //mybody->SetMass(m_c+2*m_s); mybody->SetInertiaXX((1.0/6.0)*m_cube*pow(prad,2)*ChVector<>(1.0,1.0,1.0)); mybody->SetMass(m_cube); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } ChVector<> particle_pos4(0.8*boxxx/2,box_dim/2+2*prad, -0.6*boxxx/2); if (mySys.nodeMPI->IsInto(particle_pos4)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_bodies+4); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddBox(prad,prad,prad); //mybody->GetCollisionModel()->AddSphere(prad, &pos1); //mybody->GetCollisionModel()->AddCylinder(prad,prad,prad); //mybody->GetCollisionModel()->AddSphere(prad, &pos2); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos4); //mybody->SetInertiaXX(ChVector<>(((7.0/12)*m_c+4.3*m_s)*pow(prad,2),(0.5*m_c+0.8*m_s)*pow(prad,2),((7.0/12)*m_c+4.3*m_s)*pow(prad,2))); //mybody->SetMass(m_c+2*m_s); mybody->SetInertiaXX((1.0/6.0)*m_cube*pow(prad,2)*ChVector<>(1.0,1.0,1.0)); mybody->SetMass(m_cube); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } }
void add_falling_item(ChSystemMPI& mySys, double prad, double box_dim, double pmass, int n_curr_spheres) { int id_offset=10; double particle_mass =4.0; if (pmass>0.0){ particle_mass=pmass; } ChSharedPtr<ChBodyDEMMPI> mybody; double boxxx=box_dim-2*prad; ChVector<> particle_pos(0.8*boxxx/2,box_dim/2+2*prad, 0.6*boxxx/2); if (mySys.nodeMPI->IsInto(particle_pos)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_spheres+1); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } ChVector<> particle_pos2(0.8*boxxx/2,box_dim/2+2*prad, 0.2*boxxx/2); if (mySys.nodeMPI->IsInto(particle_pos2)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_spheres+2); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos2); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } ChVector<> particle_pos3(0.8*boxxx/2,box_dim/2+2*prad, -0.2*boxxx/2); if (mySys.nodeMPI->IsInto(particle_pos3)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_spheres+3); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos3); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } ChVector<> particle_pos4(0.8*boxxx/2,box_dim/2+2*prad, -0.6*boxxx/2); if (mySys.nodeMPI->IsInto(particle_pos4)) { ChSharedPtr<ChBodyDEMMPI> mybody(new ChBodyDEMMPI); mybody->SetIdentifier(id_offset+n_curr_spheres+4); mySys.Add(mybody); mybody->GetCollisionModel()->ClearModel(); mybody->GetCollisionModel()->AddSphere(prad); mybody->GetCollisionModel()->BuildModel(); mybody->SetCollide(true); mybody->SetPos(particle_pos4); mybody->SetInertiaXX((2.0/5.0)*particle_mass*pow(prad,2)*ChVector<>(1,1,1)); mybody->SetMass(particle_mass); mybody->GetCollisionModel()->SyncPosition(); // really necessary? mybody->Update(); // really necessary? } }
// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- int main(int argc, char* argv[]) { // Create output directories if (ChFileutils::MakeDirectory(out_dir.c_str()) < 0) { cout << "Error creating directory " << out_dir << endl; return 1; } if (ChFileutils::MakeDirectory(pov_dir.c_str()) < 0) { cout << "Error creating directory " << pov_dir << endl; return 1; } // Parameters for the system double gravity = 9.81; // m/s^2 // Parameters for the balls int ballId = 1; // first ball id const int a = 50; const int b = 10; const int c = 10; int numballs = a * b * c; // number of falling balls = (a X b X c) bool dense = false; double radius = 0.003; // m double density = 2550; // kg/m^3 double mass = density * (4.0 / 3) * CH_C_PI * radius * radius * radius; float Y = 4.0e7; // Pa float nu = 0.22f; float COR = 0.87f; float mu = 0.18f; // Parameters for containing bin, shear box, and load plate float mu_ext = 0.13f; int groundId = 0; int binId = -1; int boxId = -2; int plateId = -3; double width = 0.12; double length = 0.12; double height = 0.06; double thickness = 0.01; double shear_Area; double shear_Height; double shear_Disp; ChVector<> pos(0, 0, 0); ChQuaternion<> rot(1, 0, 0, 0); ChVector<> vel(0, 0, 0); real3 force(0, 0, 0); // Define two quaternions representing: // - a rotation of -90 degrees around x (z2y) // - a rotation of +90 degrees around y (z2x) ChQuaternion<> z2y; ChQuaternion<> z2x; z2y.Q_from_AngAxis(-CH_C_PI / 2, ChVector<>(1, 0, 0)); z2x.Q_from_AngAxis(CH_C_PI / 2, ChVector<>(0, 1, 0)); // Create the system #ifdef USE_DEM cout << "Create DEM system" << endl; const std::string title = "soft-sphere (DEM) direct shear box test"; ChBody::ContactMethod contact_method = ChBody::DEM; ChSystemParallelDEM* my_system = new ChSystemParallelDEM(); #else cout << "Create DVI system" << endl; const std::string title = "hard-sphere (DVI) direct shear box test"; ChBody::ContactMethod contact_method = ChBody::DVI; ChSystemParallelDVI* my_system = new ChSystemParallelDVI(); #endif my_system->Set_G_acc(ChVector<>(0, -gravity, 0)); // Set number of threads int max_threads = omp_get_num_procs(); if (threads > max_threads) threads = max_threads; my_system->SetParallelThreadNumber(threads); omp_set_num_threads(threads); my_system->GetSettings()->max_threads = threads; my_system->GetSettings()->perform_thread_tuning = thread_tuning; // Edit system settings my_system->GetSettings()->solver.use_full_inertia_tensor = false; my_system->GetSettings()->solver.tolerance = tolerance; my_system->GetSettings()->solver.max_iteration_bilateral = max_iteration_bilateral; my_system->GetSettings()->solver.clamp_bilaterals = clamp_bilaterals; my_system->GetSettings()->solver.bilateral_clamp_speed = bilateral_clamp_speed; #ifdef USE_DEM my_system->GetSettings()->solver.contact_force_model = HERTZ; my_system->GetSettings()->solver.tangential_displ_mode = MULTI_STEP; #else my_system->GetSettings()->solver.solver_mode = SLIDING; my_system->GetSettings()->solver.max_iteration_normal = max_iteration_normal; my_system->GetSettings()->solver.max_iteration_sliding = max_iteration_sliding; my_system->GetSettings()->solver.max_iteration_spinning = max_iteration_spinning; my_system->GetSettings()->solver.alpha = 0; my_system->GetSettings()->solver.contact_recovery_speed = contact_recovery_speed; my_system->ChangeSolverType(APGD); my_system->GetSettings()->collision.collision_envelope = 0.05 * radius; #endif my_system->GetSettings()->collision.bins_per_axis = I3(10, 10, 10); my_system->GetSettings()->collision.narrowphase_algorithm = NARROWPHASE_HYBRID_MPR; // Create a ball material (will be used by balls only) #ifdef USE_DEM ChSharedPtr<ChMaterialSurfaceDEM> material; material = ChSharedPtr<ChMaterialSurfaceDEM>(new ChMaterialSurfaceDEM); material->SetYoungModulus(Y); material->SetPoissonRatio(nu); material->SetRestitution(COR); material->SetFriction(mu); #else ChSharedPtr<ChMaterialSurface> material; material = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material->SetRestitution(COR); material->SetFriction(mu); #endif // Create a material for all objects other than balls #ifdef USE_DEM ChSharedPtr<ChMaterialSurfaceDEM> mat_ext; mat_ext = ChSharedPtr<ChMaterialSurfaceDEM>(new ChMaterialSurfaceDEM); mat_ext->SetYoungModulus(Y); mat_ext->SetPoissonRatio(nu); mat_ext->SetRestitution(COR); mat_ext->SetFriction(mu_ext); #else ChSharedPtr<ChMaterialSurface> mat_ext; mat_ext = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); mat_ext->SetRestitution(COR); mat_ext->SetFriction(mu_ext); #endif // Create lower bin ChSharedPtr<ChBody> bin(new ChBody(new ChCollisionModelParallel, contact_method)); bin->SetIdentifier(binId); bin->SetMass(1); bin->SetPos(ChVector<>(0, -height / 2, 0)); bin->SetBodyFixed(true); bin->SetCollide(true); bin->SetMaterialSurface(mat_ext); bin->GetCollisionModel()->ClearModel(); AddWall(bin, ChVector<>(width / 2, thickness / 2, length / 2), ChVector<>(0, 0, 0), true); AddWall(bin, ChVector<>(thickness / 2, height / 2, length / 2 + thickness), ChVector<>(-width / 2 - thickness / 2, 0, 0), true); AddWall(bin, ChVector<>(thickness / 2, height / 2, length / 2 + thickness), ChVector<>(width / 2 + thickness / 2, 0, 0), false); AddWall(bin, ChVector<>(width / 2 + thickness, height / 2, thickness / 2), ChVector<>(0, 0, -length / 2 - thickness / 2), true); AddWall(bin, ChVector<>(width / 2 + thickness, height / 2, thickness / 2), ChVector<>(0, 0, length / 2 + thickness / 2), true); bin->GetCollisionModel()->SetFamily(1); bin->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(2); bin->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(3); bin->GetCollisionModel()->SetFamilyMaskDoCollisionWithFamily(4); bin->GetCollisionModel()->BuildModel(); my_system->AddBody(bin); // Create upper shear box ChSharedPtr<ChBody> box(new ChBody(new ChCollisionModelParallel, contact_method)); box->SetIdentifier(boxId); box->SetMass(1); box->SetPos(ChVector<>(0, height / 2 + radius, 0)); box->SetBodyFixed(true); box->SetCollide(true); box->SetMaterialSurface(mat_ext); box->GetCollisionModel()->ClearModel(); AddWall(box, ChVector<>(thickness / 2, height / 2, length / 2 + thickness), ChVector<>(-width / 2 - thickness / 2, 0, 0), true); AddWall(box, ChVector<>(thickness / 2, height / 2, length / 2 + thickness), ChVector<>(width / 2 + thickness / 2, 0, 0), false); AddWall(box, ChVector<>(width / 2 + thickness, height / 2, thickness / 2), ChVector<>(0, 0, -length / 2 - thickness / 2), true); AddWall(box, ChVector<>(width / 2 + thickness, height / 2, thickness / 2), ChVector<>(0, 0, length / 2 + thickness / 2), true); box->GetCollisionModel()->SetFamily(2); box->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(1); box->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(3); box->GetCollisionModel()->SetFamilyMaskDoCollisionWithFamily(4); box->GetCollisionModel()->BuildModel(); my_system->AddBody(box); // Create upper load plate ChSharedPtr<ChBody> plate(new ChBody(new ChCollisionModelParallel, contact_method)); shear_Area = width * length; plate->SetIdentifier(binId); plate->SetMass(normal_pressure * shear_Area / gravity); plate->SetPos(ChVector<>(0, 2.0 * radius * float(a) + thickness, 0)); plate->SetBodyFixed(true); plate->SetCollide(true); plate->SetMaterialSurface(mat_ext); plate->GetCollisionModel()->ClearModel(); AddWall(plate, ChVector<>(width / 2, thickness / 2, length / 2), ChVector<>(0, 0, 0), true); plate->GetCollisionModel()->SetFamily(3); plate->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(1); plate->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(2); plate->GetCollisionModel()->SetFamilyMaskDoCollisionWithFamily(4); plate->GetCollisionModel()->BuildModel(); my_system->AddBody(plate); // Create (a X b X c) many falling balls int i, j, k; double ball_x, ball_y, ball_z; for (i = 0; i < a; i++) { for (j = 0; j < b; j++) { for (k = 0; k < c; k++) { ball_y = 2.0 * radius * float(i); ball_x = 4.0 * radius * (float(j - b / 2) + 0.5) + 0.99 * radius * (float(rand() % 100) / 50 - 1.0); ball_z = 4.0 * radius * (float(k - c / 2) + 0.5) + 0.99 * radius * (float(rand() % 100) / 50 - 1.0); ChSharedPtr<ChBody> ball(new ChBody(new ChCollisionModelParallel, contact_method)); ball->SetIdentifier(ballId + 6 * 6 * i + 6 * j + k); ball->SetMass(mass); ball->SetInertiaXX((2.0 / 5.0) * mass * radius * radius * ChVector<>(1, 1, 1)); ball->SetPos(ChVector<>(ball_x, ball_y, ball_z)); ball->SetBodyFixed(false); ball->SetCollide(true); ball->SetMaterialSurface(material); ball->GetCollisionModel()->ClearModel(); ball->GetCollisionModel()->AddSphere(radius); ball->GetCollisionModel()->SetFamily(4); ball->GetCollisionModel()->BuildModel(); ChSharedPtr<ChSphereShape> sphere(new ChSphereShape); sphere->GetSphereGeometry().rad = radius; sphere->SetColor(ChColor(1, 0, 1)); ball->AddAsset(sphere); my_system->AddBody(ball); } } } // Create prismatic (translational) joint between load plate and shear box. // The translational axis of a prismatic joint is along the Z axis of the // specified joint coordinate system. Here, we apply the 'z2y' rotation to // align it with the Y axis of the global reference frame. ChSharedPtr<ChLinkLockPrismatic> prismatic_plate_box(new ChLinkLockPrismatic); prismatic_plate_box->SetName("prismatic_plate_box"); prismatic_plate_box->Initialize(plate, box, ChCoordsys<>(ChVector<>(0, 0, 0), z2y)); my_system->AddLink(prismatic_plate_box); // Setup output ChStreamOutAsciiFile shearStream(shear_file.c_str()); ChStreamOutAsciiFile forceStream(force_file.c_str()); ChStreamOutAsciiFile statsStream(stats_file.c_str()); shearStream.SetNumFormat("%16.4e"); forceStream.SetNumFormat("%16.4e"); // Create the OpenGL visualization window #ifdef CHRONO_PARALLEL_HAS_OPENGL opengl::ChOpenGLWindow& gl_window = opengl::ChOpenGLWindow::getInstance(); gl_window.Initialize(800, 600, title.c_str(), my_system); gl_window.SetCamera(ChVector<>(3 * width, 0, 0), ChVector<>(0, 0, 0), ChVector<>(0, 1, 0), radius, radius); gl_window.SetRenderMode(opengl::SOLID); #endif // Begin simulation bool settling = true; bool shearing = false; int data_out_frame = 0; int visual_out_frame = 0; while (my_system->GetChTime() < end_simulation_time) { if (my_system->GetChTime() > settling_time && settling == true) { if (dense == true) material->SetFriction(0.01f); plate->SetPos(ChVector<>(0, height, 0)); plate->SetBodyFixed(false); settling = false; } if (my_system->GetChTime() > begin_shear_time && shearing == false) { if (dense == true) material->SetFriction(mu); shear_Height = plate->GetPos().y; shear_Disp = bin->GetPos().z; shearing = true; } if (shearing == true) { bin->SetPos(ChVector<>(0, -height / 2, -shear_speed * begin_shear_time + shear_speed * my_system->GetChTime())); bin->SetPos_dt(ChVector<>(0, 0, shear_speed)); // This is needed for the tangential contact displacement history model bin->SetRot(QUNIT); } else { bin->SetPos(ChVector<>(0, -height / 2, 0)); bin->SetPos_dt(ChVector<>(0, 0, 0)); bin->SetRot(QUNIT); } // Do time step #ifdef CHRONO_PARALLEL_HAS_OPENGL if (gl_window.Active()) { gl_window.DoStepDynamics(time_step); gl_window.Render(); } else break; #else my_system->DoStepDynamics(time_step); #endif TimingOutput(my_system, &statsStream); // Output to files if (my_system->GetChTime() >= data_out_frame * data_out_step) { #ifndef USE_DEM my_system->CalculateContactForces(); #endif force = my_system->GetBodyContactForce(0); forceStream << my_system->GetChTime() << "\t" << plate->GetPos().y - bin->GetPos().y << "\t" << bin->GetPos().x << "\t" << bin->GetPos().y << "\t" << bin->GetPos().z << "\t" << force.x << "\t" << force.y << "\t" << force.z << "\n"; cout << my_system->GetChTime() << "\t" << plate->GetPos().y - bin->GetPos().y << "\t" << bin->GetPos().x << "\t" << bin->GetPos().y << "\t" << bin->GetPos().z << "\t" << force.x << "\t" << force.y << "\t" << force.z << "\n"; // Output to shear data file if (shearing == true) { shearStream << (bin->GetPos().z - shear_Disp) / (2 * radius) << "\t"; shearStream << -force.z / (shear_Area * normal_pressure) << "\t"; shearStream << (plate->GetPos().y - shear_Height) / (2 * radius) << "\n"; cout << (bin->GetPos().z - shear_Disp) / (2 * radius) << "\t"; cout << -force.z / (shear_Area * normal_pressure) << "\t"; cout << (plate->GetPos().y - shear_Height) / (2 * radius) << "\n"; } data_out_frame++; } // Output to POV-Ray if (write_povray_data && my_system->GetChTime() >= visual_out_frame * visual_out_step) { char filename[100]; sprintf(filename, "%s/data_%03d.dat", pov_dir.c_str(), visual_out_frame + 1); utils::WriteShapesPovray(my_system, filename, false); visual_out_frame++; } } return 0; }
// Build and initialize the tank, creating all bodies corresponding to // the various parts and adding them to the physical system - also creating // and adding constraints to the system. MySimpleTank(ChSystem& my_system, ///< the chrono::engine physical system ISceneManager* msceneManager, ///< the Irrlicht scene manager for 3d shapes IVideoDriver* mdriver ///< the Irrlicht video driver ) { throttleL = throttleR = 0; // initially, gas throttle is 0. max_motor_speed = 10; double my = 0.5; // left back hub pos double mx = 0; double shoelength = 0.2; double shoethickness = 0.06; double shoewidth = 0.3; double shoemass = 2; double radiustrack = 0.31; double wheeldiameter = 0.280*2; int nwrap = 6; int ntiles = 7; double rlwidth = 1.20; double passo = (ntiles+1)*shoelength; ChVector<> cyl_displA(0, 0.075+0.02,0); ChVector<> cyl_displB(0, -0.075-0.02,0); double cyl_hthickness = 0.045; // --- The tank body --- IAnimatedMesh* bulldozer_bodyMesh = msceneManager->getMesh("../data/bulldozerB10.obj"); truss = (ChBodySceneNode*)addChBodySceneNode( &my_system, msceneManager, bulldozer_bodyMesh, 350.0, ChVector<>(mx + passo/2, my + radiustrack , rlwidth/2), QUNIT); truss->GetBody()->SetInertiaXX(ChVector<>(13.8, 13.5, 10)); truss->GetBody()->SetBodyFixed(false); //truss->addShadowVolumeSceneNode(); // --- Right Front suspension --- // Load a triangle mesh for wheel visualization IAnimatedMesh* irmesh_wheel_view = msceneManager->getMesh("../data/wheel_view.obj"); // ..the tank right-front wheel wheelRF = (ChBodySceneNode*) addChBodySceneNode( &my_system, msceneManager, irmesh_wheel_view, 9.0, ChVector<>(mx + passo, my+ radiustrack , 0), chrono::Q_from_AngAxis(CH_C_PI/2, VECT_X) ); wheelRF->GetBody()->GetCollisionModel()->ClearModel(); wheelRF->GetBody()->GetCollisionModel()->AddCylinder(wheeldiameter/2,wheeldiameter/2, cyl_hthickness, &cyl_displA); wheelRF->GetBody()->GetCollisionModel()->AddCylinder(wheeldiameter/2,wheeldiameter/2, cyl_hthickness, &cyl_displB); wheelRF->GetBody()->GetCollisionModel()->BuildModel(); // Creates the collision model wheelRF->GetBody()->SetCollide(true); wheelRF->GetBody()->SetInertiaXX(ChVector<>(1.2, 1.2, 1.2)); wheelRF->GetBody()->SetFriction(1.0); video::ITexture* cylinderMap = mdriver->getTexture("../data/bluwhite.png"); wheelRF->setMaterialTexture(0, cylinderMap); wheelRF->addShadowVolumeSceneNode(); // .. create the revolute joint between the wheel and the truss link_revoluteRF = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute); // right, front, upper, 1 link_revoluteRF->Initialize(wheelRF->GetBody(), truss->GetBody(), ChCoordsys<>(ChVector<>(mx + passo, my+ radiustrack , 0) , QUNIT ) ); my_system.AddLink(link_revoluteRF); // --- Left Front suspension --- // ..the tank left-front wheel wheelLF = (ChBodySceneNode*) addChBodySceneNode( &my_system, msceneManager, irmesh_wheel_view, 9.0, ChVector<>(mx + passo, my+ radiustrack , rlwidth), chrono::Q_from_AngAxis(CH_C_PI/2, VECT_X) ); wheelLF->GetBody()->GetCollisionModel()->ClearModel(); wheelLF->GetBody()->GetCollisionModel()->AddCylinder(wheeldiameter/2,wheeldiameter/2, cyl_hthickness, &cyl_displA); wheelLF->GetBody()->GetCollisionModel()->AddCylinder(wheeldiameter/2,wheeldiameter/2, cyl_hthickness, &cyl_displB); wheelLF->GetBody()->GetCollisionModel()->BuildModel(); // Creates the collision model wheelLF->GetBody()->SetCollide(true); wheelLF->GetBody()->SetInertiaXX(ChVector<>(1.2, 1.2, 1.2)); wheelLF->GetBody()->SetFriction(1.0); wheelLF->setMaterialTexture(0, cylinderMap); wheelLF->addShadowVolumeSceneNode(); // .. create the revolute joint between the wheel and the truss link_revoluteLF = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute); // left, front, upper, 1 link_revoluteLF->Initialize(wheelLF->GetBody(), truss->GetBody(), ChCoordsys<>(ChVector<>(mx + passo, my+ radiustrack , rlwidth) , QUNIT ) ); my_system.AddLink(link_revoluteLF); // --- Right Back suspension --- // ..the tank right-back wheel wheelRB = (ChBodySceneNode*) addChBodySceneNode( &my_system, msceneManager, irmesh_wheel_view, 9.0, ChVector<>(mx , my+ radiustrack , 0), chrono::Q_from_AngAxis(CH_C_PI/2, VECT_X) ); wheelRB->GetBody()->GetCollisionModel()->ClearModel(); wheelRB->GetBody()->GetCollisionModel()->AddCylinder(wheeldiameter/2,wheeldiameter/2, cyl_hthickness, &cyl_displA); wheelRB->GetBody()->GetCollisionModel()->AddCylinder(wheeldiameter/2,wheeldiameter/2, cyl_hthickness, &cyl_displB); wheelRB->GetBody()->GetCollisionModel()->BuildModel(); // Creates the collision model wheelRB->GetBody()->SetCollide(true); wheelRB->GetBody()->SetInertiaXX(ChVector<>(1.2, 1.2, 1.2)); wheelRB->GetBody()->SetFriction(1.0); cylinderMap = mdriver->getTexture("../data/bluwhite.png"); wheelRB->setMaterialTexture(0, cylinderMap); wheelRB->addShadowVolumeSceneNode(); // .. create the motor joint between the wheel and the truss (simplified motor model: just impose speed..) link_revoluteRB = ChSharedPtr<ChLinkEngine>(new ChLinkEngine); // right, back, upper, 1 link_revoluteRB->Initialize(wheelRB->GetBody(), truss->GetBody(), ChCoordsys<>(ChVector<>(mx , my+ radiustrack , 0) , QUNIT ) ); link_revoluteRB->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED); my_system.AddLink(link_revoluteRB); // --- Left Back suspension --- // ..the tank left-back wheel wheelLB = (ChBodySceneNode*) addChBodySceneNode( &my_system, msceneManager, irmesh_wheel_view, 9.0, ChVector<>(mx , my+ radiustrack , rlwidth), chrono::Q_from_AngAxis(CH_C_PI/2, VECT_X) ); wheelLB->GetBody()->GetCollisionModel()->ClearModel(); wheelLB->GetBody()->GetCollisionModel()->AddCylinder(wheeldiameter/2,wheeldiameter/2, cyl_hthickness, &cyl_displA); wheelLB->GetBody()->GetCollisionModel()->AddCylinder(wheeldiameter/2,wheeldiameter/2, cyl_hthickness, &cyl_displB); wheelLB->GetBody()->GetCollisionModel()->BuildModel(); // Creates the collision model wheelLB->GetBody()->SetCollide(true); wheelLB->GetBody()->SetInertiaXX(ChVector<>(1.2, 1.2, 1.2)); wheelLB->GetBody()->SetFriction(1.0); wheelLB->setMaterialTexture(0, cylinderMap); wheelLB->addShadowVolumeSceneNode(); // .. create the motor joint between the wheel and the truss (simplified motor model: just impose speed..) link_revoluteLB = ChSharedPtr<ChLinkEngine>(new ChLinkEngine); // left, back, upper, 1 link_revoluteLB->Initialize(wheelLB->GetBody(), truss->GetBody(), ChCoordsys<>(ChVector<>(mx , my+ radiustrack , rlwidth) , QUNIT ) ); link_revoluteLB->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED); my_system.AddLink(link_revoluteLB); //--- TRACKS --- // Load a triangle mesh for visualization IAnimatedMesh* irmesh_shoe_view = msceneManager->getMesh("../data/shoe_view.obj"); // Load a triangle mesh for collision IAnimatedMesh* irmesh_shoe_collision = msceneManager->getMesh("../data/shoe_collision.obj"); ChTriangleMeshSoup temp_trianglemesh; fillChTrimeshFromIrlichtMesh(&temp_trianglemesh, irmesh_shoe_collision->getMesh(0)); chrono::ChVector<> mesh_displacement(shoelength*0.5,0,0); // since mesh origin is not in body center of mass chrono::ChVector<> joint_displacement(-shoelength*0.5,0,0); // position of shoe-shoe constraint, relative to COG. chrono::ChVector<> position; chrono::ChQuaternion<> rotation; for (int side = 0; side <2; side ++) { mx = 0; mx += shoelength; double mz = 0; if (side == 0) mz = 0; else mz = rlwidth; position.Set(mx, my, mz); rotation = QUNIT; // Create sample body (with empty collision shape; later create the collision model by adding the coll.shapes) ChBodySceneNode* firstBodyShoe = (ChBodySceneNode*)addChBodySceneNode( &my_system, msceneManager, 0, shoemass, position, rotation); // Creates the collision model with a (simplified) mesh ChVector<> pin_displacement = mesh_displacement + ChVector<>(0,0.05,0); firstBodyShoe->GetBody()->GetCollisionModel()->SetSafeMargin(0.004); // inward safe margin firstBodyShoe->GetBody()->GetCollisionModel()->SetEnvelope(0.010); // distance of the outward "collision envelope" firstBodyShoe->GetBody()->GetCollisionModel()->ClearModel(); // ...try to use a concave (simplified) mesh plus automatic convex decomposition?? ... firstBodyShoe->GetBody()->GetCollisionModel()->AddTriangleMesh(temp_trianglemesh, false, false, &mesh_displacement); // not static, not convex // .. or rather use few 'primitive' shapes to approximate with cubes/etc?? //firstBodyShoe->GetBody()->GetCollisionModel()->AddBox(shoelength/2, shoethickness/2, shoewidth/2, &mesh_displacement); //firstBodyShoe->GetBody()->GetCollisionModel()->AddBox(0.04, 0.02, 0.02, &pin_displacement); firstBodyShoe->GetBody()->GetCollisionModel()->BuildModel(); // Creates the collision model firstBodyShoe->GetBody()->SetCollide(true); /* // alternative: use box as a collision geometry (but wheels will slip..) ChBodySceneNode* firstBodyShoe = (ChBodySceneNode*)addChBodySceneNode_easyBox( &my_system, msceneManager, shoemass, position, rotation, ChVector<>(shoelength, 0.02, 0.2) ); */ // Add a mesh for visualization purposes msceneManager->addAnimatedMeshSceneNode(irmesh_shoe_view, firstBodyShoe,-1, vector3dfCH(mesh_displacement)); // Avoid creation of contacts with neighbouring shoes, using // a collision family (=3) that does not collide with itself firstBodyShoe->GetBody()->GetCollisionModel()->SetFamily(3); firstBodyShoe->GetBody()->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(3); // Other settings firstBodyShoe->GetBody()->SetInertiaXX(ChVector<>(0.1, 0.1, 0.1)); ChBodySceneNode* previous_rigidBodyShoe = firstBodyShoe; for (int nshoe = 1; nshoe < ntiles; nshoe++) { mx += shoelength; position.Set(mx, my, mz); ChBodySceneNode* rigidBodyShoe = MakeShoe(previous_rigidBodyShoe, firstBodyShoe, position, rotation, irmesh_shoe_view, my_system, msceneManager, mdriver, mesh_displacement, joint_displacement, shoemass); previous_rigidBodyShoe = rigidBodyShoe; } for (int nshoe = 0; nshoe < nwrap; nshoe++) { double alpha = (CH_C_PI/((double)(nwrap-1.0)))*((double)nshoe); double lx = mx + shoelength + radiustrack * sin(alpha); double ly = my + radiustrack - radiustrack * cos(alpha); position.Set(lx, ly, mz); rotation = chrono::Q_from_AngAxis(alpha,ChVector<>(0,0,1)); ChBodySceneNode* rigidBodyShoe = MakeShoe(previous_rigidBodyShoe, firstBodyShoe, position, rotation, irmesh_shoe_view, my_system, msceneManager, mdriver, mesh_displacement, joint_displacement, shoemass); previous_rigidBodyShoe = rigidBodyShoe; } for (int nshoe = (ntiles-1); nshoe >= 0; nshoe--) { position.Set(mx, my+2*radiustrack, mz); ChBodySceneNode* rigidBodyShoe = MakeShoe(previous_rigidBodyShoe, firstBodyShoe, position, rotation, irmesh_shoe_view, my_system, msceneManager, mdriver, mesh_displacement, joint_displacement, shoemass); previous_rigidBodyShoe = rigidBodyShoe; mx -= shoelength; } for (int nshoe = 0; nshoe < nwrap; nshoe++) { double alpha = CH_C_PI + (CH_C_PI/((double)(nwrap-1.0)))*((double)nshoe); double lx = mx + 0 + radiustrack * sin(alpha); double ly = my + radiustrack - radiustrack * cos(alpha); position.Set(lx, ly, mz); rotation = chrono::Q_from_AngAxis(alpha,ChVector<>(0,0,1)); ChBodySceneNode* rigidBodyShoe = MakeShoe(previous_rigidBodyShoe, firstBodyShoe, position, rotation, irmesh_shoe_view, my_system, msceneManager, mdriver, mesh_displacement, joint_displacement, shoemass); previous_rigidBodyShoe = rigidBodyShoe; } // close track ChVector<> linkpos = firstBodyShoe->GetBody()->Point_Body2World(&joint_displacement); ChSharedPtr<ChLinkLockRevolute> link_revolute_shoeshoe(new ChLinkLockRevolute); link_revolute_shoeshoe->Initialize(firstBodyShoe->GetBody(), previous_rigidBodyShoe->GetBody(), ChCoordsys<>( linkpos , QUNIT) ); my_system.AddLink(link_revolute_shoeshoe); } }
int main(int argc, char* argv[]) { // Set path to ChronoVehicle data files vehicle::SetDataPath(CHRONO_VEHICLE_DATA_DIR); // -------------------------- // Create output directories. // -------------------------- if (povray_output) { if (ChFileutils::MakeDirectory(out_dir.c_str()) < 0) { cout << "Error creating directory " << out_dir << endl; return 1; } if (ChFileutils::MakeDirectory(pov_dir.c_str()) < 0) { cout << "Error creating directory " << pov_dir << endl; return 1; } } // -------------- // Create system. // -------------- ChSystemParallelDEM* system = new ChSystemParallelDEM(); system->Set_G_acc(ChVector<>(0, 0, -9.81)); // ---------------------- // Enable debug log // ---------------------- ////system->SetLoggingLevel(LOG_INFO, true); ////system->SetLoggingLevel(LOG_TRACE, true); // ---------------------- // Set number of threads. // ---------------------- int max_threads = omp_get_num_procs(); if (threads > max_threads) threads = max_threads; system->SetParallelThreadNumber(threads); omp_set_num_threads(threads); cout << "Using " << threads << " threads" << endl; system->GetSettings()->perform_thread_tuning = thread_tuning; // --------------------- // Edit system settings. // --------------------- system->GetSettings()->solver.use_full_inertia_tensor = false; system->GetSettings()->solver.tolerance = tolerance; system->GetSettings()->solver.max_iteration_bilateral = max_iteration_bilateral; system->GetSettings()->solver.contact_force_model = contact_force_model; system->GetSettings()->solver.tangential_displ_mode = tangential_displ_mode; system->GetSettings()->collision.narrowphase_algorithm = NARROWPHASE_HYBRID_MPR; system->GetSettings()->collision.bins_per_axis = I3(20, 20, 10); // ------------------- // Create the terrain. // ------------------- // Ground body ChSharedPtr<ChBody> ground = ChSharedPtr<ChBody>(new ChBody(new collision::ChCollisionModelParallel, ChBody::DEM)); ground->SetIdentifier(-1); ground->SetMass(1000); ground->SetBodyFixed(true); ground->SetCollide(true); ground->GetMaterialSurfaceDEM()->SetFriction(mu_g); ground->GetMaterialSurfaceDEM()->SetYoungModulus(Y_g); ground->GetMaterialSurfaceDEM()->SetRestitution(cr_g); ground->GetMaterialSurfaceDEM()->SetCohesion(cohesion_g); ground->GetCollisionModel()->ClearModel(); // Bottom box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hdimX, hdimY, hthick), ChVector<>(0, 0, -hthick), ChQuaternion<>(1, 0, 0, 0), true); if (terrain_type == GRANULAR) { // Front box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hthick, hdimY, hdimZ + hthick), ChVector<>(hdimX + hthick, 0, hdimZ - hthick), ChQuaternion<>(1, 0, 0, 0), visible_walls); // Rear box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hthick, hdimY, hdimZ + hthick), ChVector<>(-hdimX - hthick, 0, hdimZ - hthick), ChQuaternion<>(1, 0, 0, 0), visible_walls); // Left box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hdimX, hthick, hdimZ + hthick), ChVector<>(0, hdimY + hthick, hdimZ - hthick), ChQuaternion<>(1, 0, 0, 0), visible_walls); // Right box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hdimX, hthick, hdimZ + hthick), ChVector<>(0, -hdimY - hthick, hdimZ - hthick), ChQuaternion<>(1, 0, 0, 0), visible_walls); } ground->GetCollisionModel()->BuildModel(); system->AddBody(ground); // Create the granular material. double vertical_offset = 0; if (terrain_type == GRANULAR) { vertical_offset = CreateParticles(system); } // ----------------------------------------- // Create and initialize the vehicle system. // ----------------------------------------- utils::VehicleSystem* vehicle; utils::TireContactCallback* tire_cb; // Create the vehicle assembly and the callback object for tire contact // according to the specified type of tire/wheel. switch (wheel_type) { case CYLINDRICAL: { vehicle = new utils::VehicleSystem(system, vehicle_file_cyl, simplepowertrain_file); tire_cb = new MyCylindricalTire(); } break; case LUGGED: { vehicle = new utils::VehicleSystem(system, vehicle_file_lug, simplepowertrain_file); tire_cb = new MyLuggedTire(); } break; } vehicle->SetTireContactCallback(tire_cb); // Set the callback object for driver inputs. Pass the hold time as a delay in // generating driver inputs. MyDriverInputs driver_cb(time_hold); vehicle->SetDriverInputsCallback(&driver_cb); // Initialize the vehicle at a height above the terrain. vehicle->Initialize(initLoc + ChVector<>(0, 0, vertical_offset), initRot); // Initially, fix the chassis and wheel bodies (will be released after time_hold). vehicle->GetVehicle()->GetChassis()->SetBodyFixed(true); for (int i = 0; i < 2 * vehicle->GetVehicle()->GetNumberAxles(); i++) { vehicle->GetVehicle()->GetWheelBody(i)->SetBodyFixed(true); } // ----------------------- // Perform the simulation. // ----------------------- #ifdef CHRONO_PARALLEL_HAS_OPENGL // Initialize OpenGL opengl::ChOpenGLWindow& gl_window = opengl::ChOpenGLWindow::getInstance(); gl_window.Initialize(1280, 720, "HMMWV", system); gl_window.SetCamera(ChVector<>(0, -10, 0), ChVector<>(0, 0, 0), ChVector<>(0, 0, 1)); gl_window.SetRenderMode(opengl::WIREFRAME); #endif // Run simulation for specified time. int out_steps = std::ceil((1.0 / time_step) / out_fps); double time = 0; int sim_frame = 0; int out_frame = 0; int next_out_frame = 0; double exec_time = 0; int num_contacts = 0; while (time < time_end) { // If enabled, output data for PovRay postprocessing. if (sim_frame == next_out_frame) { cout << endl; cout << "---- Frame: " << out_frame + 1 << endl; cout << " Sim frame: " << sim_frame << endl; cout << " Time: " << time << endl; cout << " Speed: " << vehicle->GetVehicle()->GetVehicleSpeed() << endl; cout << " Avg. contacts: " << num_contacts / out_steps << endl; cout << " Execution time: " << exec_time << endl; if (povray_output) { char filename[100]; sprintf(filename, "%s/data_%03d.dat", pov_dir.c_str(), out_frame + 1); utils::WriteShapesPovray(system, filename); } out_frame++; next_out_frame += out_steps; num_contacts = 0; } // Release the vehicle chassis at the end of the hold time. if (vehicle->GetVehicle()->GetChassis()->GetBodyFixed() && time > time_hold) { cout << endl << "Release vehicle t = " << time << endl; vehicle->GetVehicle()->GetChassis()->SetBodyFixed(false); for (int i = 0; i < 2 * vehicle->GetVehicle()->GetNumberAxles(); i++) { vehicle->GetVehicle()->GetWheelBody(i)->SetBodyFixed(false); } } // Update vehicle vehicle->Update(time); // Advance dynamics. #ifdef CHRONO_PARALLEL_HAS_OPENGL if (gl_window.Active()) { gl_window.DoStepDynamics(time_step); gl_window.Render(); } else break; #else system->DoStepDynamics(time_step); #endif ////progressbar(out_steps + sim_frame - next_out_frame + 1, out_steps); TimingOutput(system); // Periodically display maximum constraint violation if (monitor_bilaterals && sim_frame % bilateral_frame_interval == 0) { std::vector<double> cvec; ////vehicle->GetVehicle()->LogConstraintViolations(); cout << " Max. violation = " << system->CalculateConstraintViolation(cvec) << endl; } // Update counters. time += time_step; sim_frame++; exec_time += system->GetTimerStep(); num_contacts += system->GetNcontacts(); } // Final stats cout << "==================================" << endl; cout << "Simulation time: " << exec_time << endl; cout << "Number of threads: " << threads << endl; delete vehicle; delete tire_cb; return 0; }
// Build and initialize the forklift, creating all bodies corresponding to // the various parts and adding them to the physical system - also creating // and adding constraints to the system. MySimpleForklift(ChIrrAppInterface* app, ChVector<> offset = ChVector<>(0,0,0)) { throttle = 0; // initially, gas throttle is 0. steer = 0; lift =0; ChVector<> COG_truss(0, 0.4, 0.5); ChVector<> COG_wheelRF( 0.566, 0.282, 1.608); ChVector<> COG_wheelLF(-0.566, 0.282, 1.608); ChVector<> COG_arm(0, 1.300, 1.855); ChVector<> COG_fork(0, 0.362, 2.100); ChVector<> COG_wheelB(0, 0.282, 0.003); ChVector<> POS_pivotarm(0, 0.150, 1.855); ChVector<> POS_prismatic(0, 0.150, 1.855); double RAD_back_wheel =0.28; double RAD_front_wheel = 0.28; forkliftTiremap = app->GetVideoDriver()->getTexture("../data/tire_truck.png"); // --- The car body --- IAnimatedMesh* forklift_bodyMesh = app->GetSceneManager()->getMesh("../data/forklift_body.obj"); truss = (ChBodySceneNode*)addChBodySceneNode( app->GetSystem(), app->GetSceneManager(), forklift_bodyMesh, 200.0, COG_truss, QUNIT); truss->GetBody()->SetInertiaXX(ChVector<>(100, 100, 100)); truss->setMaterialFlag(irr::video::EMF_NORMALIZE_NORMALS, true); truss->setMaterialTexture(0, forkliftTiremap); truss->GetChildMesh()->setPosition(-vector3df(COG_truss.x, COG_truss.y, COG_truss.z));// offset the mesh truss->addShadowVolumeSceneNode(); truss->GetBody()->GetCollisionModel()->ClearModel(); truss->GetBody()->GetCollisionModel()->AddBox(1.227/2., 1.621/2., 1.864/2., &ChVector<>(-0.003, 1.019, 0.192)); truss->GetBody()->GetCollisionModel()->AddBox(0.187/2., 0.773/2., 1.201/2., &ChVector<>( 0.486 , 0.153,-0.047)); truss->GetBody()->GetCollisionModel()->AddBox(0.187/2., 0.773/2., 1.201/2., &ChVector<>(-0.486 , 0.153,-0.047)); truss->GetBody()->GetCollisionModel()->BuildModel(); truss->GetBody()->SetCollide(true); // ..the right-front wheel IAnimatedMesh* forklift_wheelMesh = app->GetSceneManager()->getMesh("../data/wheel.obj"); wheelRF = (ChBodySceneNode*)addChBodySceneNode( app->GetSystem(), app->GetSceneManager(), forklift_wheelMesh, 20.0, COG_wheelRF, QUNIT); wheelRF->GetBody()->SetInertiaXX(ChVector<>(2, 2, 2)); wheelRF->setMaterialFlag(irr::video::EMF_NORMALIZE_NORMALS, true); wheelRF->setMaterialTexture(0, forkliftTiremap); wheelRF->GetChildMesh()->setPosition(-vector3df(COG_wheelRF.x, COG_wheelRF.y, COG_wheelRF.z));// offset the mesh // Describe the (invisible) colliding shape ChMatrix33<>Arot(chrono::Q_from_AngAxis(CH_C_PI/2, VECT_Z)); wheelRF->GetBody()->GetCollisionModel()->ClearModel(); wheelRF->GetBody()->GetCollisionModel()->AddCylinder(RAD_front_wheel,RAD_front_wheel, 0.1, &ChVector<>(0,0,0), &Arot); wheelRF->GetBody()->GetCollisionModel()->BuildModel(); wheelRF->GetBody()->SetCollide(true); // .. create the revolute joint between the wheel and the truss link_revoluteRF = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute); // right, front, upper, 1 link_revoluteRF->Initialize(wheelRF->GetBody(), truss->GetBody(), ChCoordsys<>(COG_wheelRF , chrono::Q_from_AngAxis(CH_C_PI/2, VECT_Y)) ); app->GetSystem()->AddLink(link_revoluteRF); // ..the left-front wheel wheelLF = (ChBodySceneNode*)addChBodySceneNode( app->GetSystem(), app->GetSceneManager(), forklift_wheelMesh, 20.0, COG_wheelLF, chrono::Q_from_AngAxis(CH_C_PI, VECT_Y)); // reuse RF wheel shape, flipped wheelLF->GetBody()->SetInertiaXX(ChVector<>(2, 2, 2)); wheelLF->setMaterialFlag(irr::video::EMF_NORMALIZE_NORMALS, true); wheelLF->setMaterialTexture(0, forkliftTiremap); wheelLF->GetChildMesh()->setPosition(-vector3df(COG_wheelRF.x, COG_wheelRF.y, COG_wheelRF.z));// offset the mesh (reuse RF) // Describe the (invisible) colliding shape wheelLF->GetBody()->GetCollisionModel()->ClearModel(); wheelLF->GetBody()->GetCollisionModel()->AddCylinder(RAD_front_wheel,RAD_front_wheel, 0.1, &ChVector<>(0,0,0), &Arot); wheelLF->GetBody()->GetCollisionModel()->BuildModel(); wheelLF->GetBody()->SetCollide(true); // .. create the revolute joint between the wheel and the truss link_revoluteLF = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute); // right, front, upper, 1 link_revoluteLF->Initialize(wheelLF->GetBody(), truss->GetBody(), ChCoordsys<>(COG_wheelLF , chrono::Q_from_AngAxis(CH_C_PI/2, VECT_Y)) ); app->GetSystem()->AddLink(link_revoluteLF); // ..the back steering spindle (invisible, no mesh) spindleB = (ChBodySceneNode*)addChBodySceneNode( app->GetSystem(), app->GetSceneManager(), 0, 10.0, COG_wheelB, QUNIT); spindleB->GetBody()->SetInertiaXX(ChVector<>(1, 1, 1)); spindleB->GetBody()->SetCollide(false); // .. create the vertical steering link between the spindle structure and the truss link_steer_engineB = ChSharedPtr<ChLinkEngine>(new ChLinkEngine); link_steer_engineB->Initialize(spindleB->GetBody(), truss->GetBody(), ChCoordsys<>(COG_wheelB , chrono::Q_from_AngAxis(CH_C_PI/2, VECT_X)) ); // vertical axis link_steer_engineB->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); link_steer_engineB->Set_eng_mode(ChLinkEngine::ENG_MODE_ROTATION); app->GetSystem()->AddLink(link_steer_engineB); // ..the back wheel wheelB = (ChBodySceneNode*)addChBodySceneNode( app->GetSystem(), app->GetSceneManager(), forklift_wheelMesh, 20.0, COG_wheelB, QUNIT); wheelB->GetBody()->SetInertiaXX(ChVector<>(2, 2, 2)); wheelB->setMaterialFlag(irr::video::EMF_NORMALIZE_NORMALS, true); wheelB->setMaterialTexture(0, forkliftTiremap); wheelB->GetChildMesh()->setPosition(-vector3df(COG_wheelRF.x, COG_wheelRF.y, COG_wheelRF.z));// offset the mesh (reuse RF wheel) double rescale = RAD_back_wheel/RAD_front_wheel; // Describe the (invisible) colliding shape wheelB->GetBody()->GetCollisionModel()->ClearModel(); wheelB->GetBody()->GetCollisionModel()->AddCylinder(RAD_back_wheel,RAD_back_wheel, 0.1, &ChVector<>(0,0,0), &Arot); wheelB->GetBody()->GetCollisionModel()->BuildModel(); wheelB->GetBody()->SetCollide(true); // .. create the motor between the back wheel and the steering spindle structure link_engineB = ChSharedPtr<ChLinkEngine>(new ChLinkEngine); link_engineB->Initialize(wheelB->GetBody(), spindleB->GetBody(), ChCoordsys<>(COG_wheelB , chrono::Q_from_AngAxis(CH_C_PI/2, VECT_Y)) ); link_engineB->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); link_engineB->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED); app->GetSystem()->AddLink(link_engineB); // ..the arm IAnimatedMesh* forklift_armMesh = app->GetSceneManager()->getMesh("../data/forklift_arm.obj"); arm = (ChBodySceneNode*)addChBodySceneNode( app->GetSystem(), app->GetSceneManager(), forklift_armMesh, 100.0, COG_arm, QUNIT); arm->GetBody()->SetInertiaXX(ChVector<>(30, 30, 30)); arm->setMaterialFlag(irr::video::EMF_NORMALIZE_NORMALS, true); arm->GetChildMesh()->setPosition(-vector3df(COG_arm.x, COG_arm.y, COG_arm.z));// offset the mesh // .. create the revolute joint between the arm and the truss link_engineArm = ChSharedPtr<ChLinkEngine>(new ChLinkEngine); // right, front, upper, 1 link_engineArm->Initialize(arm->GetBody(), truss->GetBody(), ChCoordsys<>(POS_pivotarm , chrono::Q_from_AngAxis(CH_C_PI/2, VECT_Y)) ); link_engineArm->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); link_engineArm->Set_eng_mode(ChLinkEngine::ENG_MODE_ROTATION); app->GetSystem()->AddLink(link_engineArm); // ..the fork IAnimatedMesh* forklift_forkMesh = app->GetSceneManager()->getMesh("../data/forklift_forks.obj"); fork = (ChBodySceneNode*)addChBodySceneNode( app->GetSystem(), app->GetSceneManager(), forklift_forkMesh, 60.0, COG_fork, QUNIT); fork->GetBody()->SetInertiaXX(ChVector<>(15, 15, 15)); //fork->GetBody()->SetCollide(false); fork->setMaterialFlag(irr::video::EMF_NORMALIZE_NORMALS, true); //fork->setMaterialTexture(0, forkliftTiremap); fork->GetChildMesh()->setPosition(-vector3df(COG_fork.x, COG_fork.y, COG_fork.z));// offset the mesh // Describe the (invisible) colliding shapes - two cubes for the two fingers, etc fork->GetBody()->GetCollisionModel()->ClearModel(); fork->GetBody()->GetCollisionModel()->AddBox(0.1/2., 0.032/2., 1.033/2., &ChVector<>(-0.352, -0.312, 0.613)); fork->GetBody()->GetCollisionModel()->AddBox(0.1/2., 0.032/2., 1.033/2., &ChVector<>( 0.352, -0.312, 0.613)); fork->GetBody()->GetCollisionModel()->AddBox(0.344/2., 1.134/2., 0.101/2., &ChVector<>(-0.000, 0.321, -0.009)); fork->GetBody()->GetCollisionModel()->BuildModel(); fork->GetBody()->SetCollide(true); // .. create the prismatic joint between the fork and arm link_prismaticFork = ChSharedPtr<ChLinkLockPrismatic>(new ChLinkLockPrismatic); link_prismaticFork->Initialize(fork->GetBody(), arm->GetBody(), ChCoordsys<>(POS_prismatic , chrono::Q_from_AngAxis(CH_C_PI/2, VECT_X)) ); // set prism as vertical (default would be aligned to z, horizontal app->GetSystem()->AddLink(link_prismaticFork); // .. create the linear actuator that pushes upward the fork link_actuatorFork = ChSharedPtr<ChLinkLinActuator>(new ChLinkLinActuator); link_actuatorFork->Initialize(fork->GetBody(), arm->GetBody(), false, ChCoordsys<>(POS_prismatic+ChVector<>(0,0.01,0) , QUNIT), ChCoordsys<>(POS_prismatic , QUNIT) ); app->GetSystem()->AddLink(link_actuatorFork); // ..a pallet IAnimatedMesh* palletMesh = app->GetSceneManager()->getMesh("../data/pallet.obj"); video::ITexture* palletmap = app->GetVideoDriver()->getTexture("../data/cubetexture.png"); ChBodySceneNode* pallet = (ChBodySceneNode*)addChBodySceneNode_easyConcaveMesh( app->GetSystem(), app->GetSceneManager(), "../data/pallet.obj", 15.0, ChVector<>(0,1,3), QUNIT); pallet->GetBody()->SetInertiaXX(ChVector<>(3, 3, 3)); pallet->setMaterialFlag(irr::video::EMF_NORMALIZE_NORMALS, true); pallet->setMaterialTexture(0, palletmap); // // Move the forklift to initial offset position // // pallet->GetBody()->Move(offset); truss->GetBody()->Move(offset); wheelRF->GetBody()->Move(offset); wheelLF->GetBody()->Move(offset); wheelB->GetBody()->Move(offset); spindleB->GetBody()->Move(offset); arm->GetBody()->Move(offset); fork->GetBody()->Move(offset); }
int main(int argc, char* argv[]) { bool visualize = true; int threads = 8; int config = 0; real gravity = -9.81; //acceleration due to gravity real timestep = .01; //step size real time_to_run = 1; //length of simulation real current_time = 0; int num_steps = time_to_run / timestep; int max_iteration = 15; int tolerance = 0; //========================================================================================================= // Create system //========================================================================================================= ChSystemParallel * system_gpu = new ChSystemParallel; //========================================================================================================= // Populate the system with bodies/constraints/forces/etc. //========================================================================================================= ChVector<> lpos(0, 0, 0); ChQuaternion<> quat(1, 0, 0, 0); real container_width = 5; //width of area with particles real container_length = 25; //length of area that roller will go over real container_thickness = .25; //thickness of container walls real container_height = 2; //height of the outer walls real particle_radius = .58; // Create a material (will be used by both objects) ChSharedPtr<ChMaterialSurface> material; material = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material->SetFriction(0.4); // Create a ball ChSharedBodyPtr ball = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); InitObject(ball, 1, // mass ChVector<>(0, 10, 0), // position ChQuaternion<>(1, 0, 0, 0), // rotation material, // material true, // collide? false, // static? -15, -15); // collision family ball->SetPos_dt(ChVector<>(0,0,10)); AddCollisionGeometry(ball, SPHERE, particle_radius, lpos, quat); FinalizeObject(ball, (ChSystemParallel *) system_gpu); // Create a bin for the ball to fall into ChSharedBodyPtr bin = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); InitObject(bin, 1, // mass ChVector<>(0, 0, 0), // position ChQuaternion<>(1, 0, 0, 0), // rotation material, // material true, // collide? true, // static? -20, -20); // collision family AddCollisionGeometry(bin, BOX, ChVector<>(container_width, container_thickness, container_length), lpos, quat); AddCollisionGeometry(bin, BOX, Vector(container_thickness, container_height, container_length), Vector(-container_width + container_thickness, container_height, 0), quat); AddCollisionGeometry(bin, BOX, Vector(container_thickness, container_height, container_length), Vector(container_width - container_thickness, container_height, 0), quat); AddCollisionGeometry(bin, BOX, Vector(container_width, container_height, container_thickness), Vector(0, container_height, -container_length + container_thickness), quat); AddCollisionGeometry(bin, BOX, Vector(container_width, container_height, container_thickness), Vector(0, container_height, container_length - container_thickness), quat); FinalizeObject(bin, (ChSystemParallel *) system_gpu); //========================================================================================================= // Edit system settings //========================================================================================================= system_gpu->SetIntegrationType(ChSystem::INT_ANITESCU); system_gpu->SetParallelThreadNumber(threads); system_gpu->SetMaxiter(max_iteration); system_gpu->SetIterLCPmaxItersSpeed(max_iteration); system_gpu->SetTol(1e-3); system_gpu->SetTolSpeeds(1e-3); system_gpu->Set_G_acc(ChVector<>(0, gravity, 0)); system_gpu->SetStep(timestep); ((ChLcpSolverParallel *) (system_gpu->GetLcpSolverSpeed()))->SetMaxIteration(max_iteration); ((ChLcpSolverParallel *) (system_gpu->GetLcpSolverSpeed()))->SetTolerance(0); ((ChLcpSolverParallel *) (system_gpu->GetLcpSolverSpeed()))->SetCompliance(0, 0, 0); ((ChLcpSolverParallel *) (system_gpu->GetLcpSolverSpeed()))->SetContactRecoverySpeed(300); ((ChLcpSolverParallel *) (system_gpu->GetLcpSolverSpeed()))->SetSolverType(ACCELERATED_PROJECTED_GRADIENT_DESCENT); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->SetCollisionEnvelope(particle_radius * .05); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBinsPerAxis(R3(10, 10, 10)); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBodyPerBin(100, 50); omp_set_num_threads(threads); //========================================================================================================= // Enter the time loop and render the simulation //========================================================================================================= if (visualize) { ChOpenGLManager * window_manager = new ChOpenGLManager(); ChOpenGL openGLView(window_manager, system_gpu, 800, 600, 0, 0, "Test_Solvers"); openGLView.render_camera->camera_pos = Vector(0, 5, -20); openGLView.render_camera->look_at = Vector(0, 0, 0); openGLView.SetCustomCallback(RunTimeStep); openGLView.StartSpinning(window_manager); window_manager->CallGlutMainLoop(); } return 0; }
int main(int argc, char* argv[]) { //omp_set_num_threads(8); if (argc == 4) { cohesion_water = atof(argv[1]); cohesion_goop = atof(argv[2]); data_folder = argv[3]; cout << cohesion_water << " " << cohesion_goop << " " << data_folder << endl; } //========================================================================================================= ChSystemParallelDVI * system_gpu = new ChSystemParallelDVI; system_gpu->SetIntegrationType(ChSystem::INT_ANITESCU); //========================================================================================================= //system_gpu->SetMaxiter(max_iter); //system_gpu->SetIterLCPmaxItersSpeed(max_iter); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationNormal(max_iter); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationSliding(max_iter); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationSpinning(0); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationBilateral(max_iter * 2); system_gpu->SetTol(.5); system_gpu->SetTolSpeeds(.5); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetTolerance(.5); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetCompliance(.0); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetContactRecoverySpeed(1); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetSolverType(APGDRS); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetWarmStart(false); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->SetCollisionEnvelope(particle_radius * .05); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBinsPerAxis(I3(100, 100, 100)); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBodyPerBin(200, 100); system_gpu->Set_G_acc(ChVector<>(0, gravity, 0)); system_gpu->SetStep(timestep); //((ChSystemParallel*) system_gpu)->SetAABB(R3(-6, -6, -6), R3(6, 6, 6)); ChSharedBodyPtr L = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr R = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr F = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr B = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr Bottom = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr Top = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr Float = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedPtr<ChMaterialSurface> material; material = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material->SetFriction(container_friction); //material->SetRollingFriction(.5); //material->SetSpinningFriction(.5); material->SetCompliance(0); material->SetCohesion(-1000); InitObject(L, 100000, Vector(-container_size.x + container_thickness, container_height - container_thickness, 0), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(R, 100000, Vector(container_size.x - container_thickness, container_height - container_thickness, 0), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(F, 100000, Vector(0, container_height - container_thickness, -container_size.z + container_thickness), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(B, 100000, Vector(0, container_height - container_thickness, container_size.z - container_thickness), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(Bottom, 100000, Vector(0, container_height - container_size.y, 0), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(Top, 100000, Vector(0, container_height + container_size.y, 0), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); Quaternion qqq; qqq.Q_from_AngZ(15); InitObject(Float, 100000, Vector(0, -3, 0), qqq, material, true, true, -20, -20); AddCollisionGeometry(L, BOX, Vector(container_thickness, container_size.y, container_size.z), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(R, BOX, Vector(container_thickness, container_size.y, container_size.z), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(F, BOX, Vector(container_size.x, container_size.y, container_thickness), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(B, BOX, Vector(container_size.x, container_size.y, container_thickness), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Bottom, BOX, Vector(container_size.x, container_thickness, container_size.z), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); //AddCollisionGeometry(Top, BOX, Vector(container_size.x, container_thickness, container_size.z), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); //AddCollisionGeometry(Float, BOX, Vector(1, 1, 1), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); FinalizeObject(L, (ChSystemParallel *) system_gpu); FinalizeObject(R, (ChSystemParallel *) system_gpu); FinalizeObject(F, (ChSystemParallel *) system_gpu); FinalizeObject(B, (ChSystemParallel *) system_gpu); FinalizeObject(Bottom, (ChSystemParallel *) system_gpu); //FinalizeObject(Float, (ChSystemParallel *) system_gpu); Quaternion quat; quat.Q_from_AngAxis(90, Vector(0, 1, 0)); ChSharedPtr<ChMaterialSurface> material_spout; material_spout = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material_spout->SetFriction(0); //material->SetRollingFriction(.5); //material->SetSpinningFriction(.5); material_spout->SetCompliance(0); material_spout->SetCohesion(-1000); ChSharedBodyPtr Spout = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); InitObject(Spout, 100000, Vector(0, 0, 8), Quaternion(1, 0, 0, 0), material_spout, true, true, -20, -20); real width = 1; real thick = .1; real depth = 2; real height = .5; AddCollisionGeometry(Spout, BOX, Vector(width, thick, depth), Vector(0, height, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Spout, BOX, Vector(width, thick, depth), Vector(0, -height, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Spout, BOX, Vector(thick, height, depth), Vector(width, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Spout, BOX, Vector(thick, height, depth), Vector(-width, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Spout, BOX, Vector(width, height, thick), Vector(0, 0, depth), Quaternion(1, 0, 0, 0)); FinalizeObject(Spout, (ChSystemParallel *) system_gpu); real wheel_rad = 3; real paddle_len = .5; real thickness = .05; real wheel_width = 1; Wheel = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); InitObject(Wheel, 100, Vector(0, -6, 4), Quaternion(1, 0, 0, 0), material, true, false, -20, -20); AddCollisionGeometry(Wheel, CYLINDER, Vector(wheel_rad, wheel_width, wheel_rad), Vector(0, 0, 0), chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Z)); AddCollisionGeometry(Wheel, CYLINDER, Vector(wheel_rad + paddle_len * 2, thickness, wheel_rad + paddle_len * 2), Vector(-wheel_width, 0, 0), chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Z)); AddCollisionGeometry(Wheel, CYLINDER, Vector(wheel_rad + paddle_len * 2, thickness, wheel_rad + paddle_len * 2), Vector(wheel_width, 0, 0), chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Z)); for (int i = 0; i < 360; i += 30) { real angle = i * PI / 180.0; real x = cos(angle) * (wheel_rad + paddle_len); real z = sin(angle) * (wheel_rad + paddle_len); Quaternion q; q.Q_from_AngAxis(-angle, Vector(1, 0, 0)); AddCollisionGeometry(Wheel, BOX, Vector(wheel_width, thickness, paddle_len), Vector(0, z, x), q); } FinalizeObject(Wheel, (ChSystemParallel *) system_gpu); ChSharedPtr<ChLinkLockRevolute> my_link1(new ChLinkLockRevolute); my_link1->Initialize(Bottom, Wheel, ChCoordsys<>(Vector(0, -6, 4), chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Y))); system_gpu->AddLink(my_link1); water_generator = new ParticleGenerator<ChSystemParallel>((ChSystemParallel *) system_gpu); water_generator->SetDensity(1000); water_generator->SetRadius(R3(particle_radius, particle_radius, particle_radius)); water_generator->material->SetFriction(particle_friction); water_generator->material->SetCohesion(cohesion_water); water_generator->material->SetRollingFriction(0); water_generator->material->SetSpinningFriction(0); water_generator->material->SetCompliance(0); water_generator->AddMixtureType(MIX_SPHERE); //========================================================================================================= ////Rendering specific stuff: // ChOpenGLManager * window_manager = new ChOpenGLManager(); // ChOpenGL openGLView(window_manager, system_gpu, 800, 600, 0, 0, "Test_Solvers"); // //openGLView.render_camera->camera_position = glm::vec3(0, -5, -10); // //openGLView.render_camera->camera_look_at = glm::vec3(0, -5, 0); // //openGLView.render_camera->camera_scale = .4; // openGLView.SetCustomCallback(RunTimeStep); // openGLView.StartSpinning(window_manager); // window_manager->CallGlutMainLoop(); //========================================================================================================= int file = 0; for (int i = 0; i < num_steps; i++) { system_gpu->DoStepDynamics(timestep); double TIME = system_gpu->GetChTime(); double STEP = system_gpu->GetTimerStep(); double BROD = system_gpu->GetTimerCollisionBroad(); double NARR = system_gpu->GetTimerCollisionNarrow(); double LCP = system_gpu->GetTimerLcp(); double UPDT = system_gpu->GetTimerUpdate(); double RESID = ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->GetResidual(); int BODS = system_gpu->GetNbodies(); int CNTC = system_gpu->GetNcontacts(); int REQ_ITS = ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->GetTotalIterations(); printf("%7.4f|%7.4f|%7.4f|%7.4f|%7.4f|%7.4f|%7d|%7d|%7d|%7.4f\n", TIME, STEP, BROD, NARR, LCP, UPDT, BODS, CNTC, REQ_ITS, RESID); int save_every = 1.0 / timestep / 60.0; //save data every n steps if (i % save_every == 0) { stringstream ss; cout << "Frame: " << file << endl; ss << data_folder << "/" << file << ".txt"; DumpAllObjectsWithGeometryPovray(system_gpu, ss.str()); file++; } RunTimeStep(system_gpu, i); } //DumpObjects(system_gpu, "diagonal_impact_settled.txt", "\t"); }
void create_items(ChIrrAppInterface& application) { // Create some spheres in a vertical stack bool do_wall = false; bool do_stack = true; bool do_oddmass = true; bool do_spheres = true; bool do_heavyonside = true; double sphrad = 0.2; double dens= 1000; double sphmass = dens * (4./3.) * CH_C_PI * pow(sphrad,3); double sphinertia = (2./5.) * sphmass * pow(sphrad,2); if (do_stack) { int nbodies = 15; double totmass= 0; double level = 0; double sphrad_base = 0.2; double oddfactor = 100; for (int bi = 0; bi < nbodies; bi++) // N. of vert. bricks { double sphrad = sphrad_base; if (do_oddmass && bi==(nbodies-1)) sphrad = sphrad*pow(oddfactor, 1./3.); double dens= 1000; ChSharedPtr<ChBody> mrigidBody; if (do_spheres) { mrigidBody = ChSharedPtr<ChBodyEasySphere>(new ChBodyEasySphere( sphrad, // radius dens, // density true, // collide enable? true)); // visualization? mrigidBody->SetPos(ChVector<>(0.5, sphrad+level, 0.7)); mrigidBody->AddAsset(ChSharedPtr<ChTexture>(new ChTexture(GetChronoDataFile("bluwhite.png")))); application.GetSystem()->Add(mrigidBody); } else { mrigidBody = ChSharedPtr<ChBodyEasyBox>(new ChBodyEasyBox( sphrad,sphrad,sphrad, // x,y,z size dens, // density true, // collide enable? true)); // visualization? mrigidBody->SetPos(ChVector<>(0.5, sphrad+level, 0.7)); mrigidBody->AddAsset(ChSharedPtr<ChTexture>(new ChTexture(GetChronoDataFile("cubetexture_bluwhite.png")))); application.GetSystem()->Add(mrigidBody); } mrigidBody->GetMaterialSurface()->SetFriction(0.5f); mrigidBody->GetMaterialSurface()->SetRestitution(0.0f); mspheres.push_back(mrigidBody); level +=sphrad*2; totmass +=mrigidBody->GetMass(); } GetLog() << "Expected contact force at bottom F=" << (totmass *application.GetSystem()->Get_G_acc().y) << "\n"; } if (do_wall) for (int ai = 0; ai < 1; ai++) // N. of walls { for (int bi = 0; bi < 10; bi++) // N. of vert. bricks { for (int ui = 0; ui < 15; ui++) // N. of hor. bricks { ChSharedPtr<ChBodyEasyBox> mrigidWall (new ChBodyEasyBox( 3.96,2,4, // radius dens, // density true, // collide enable? true)); // visualization? mrigidWall->SetPos(ChVector<>(-8+ui*4.0+2*(bi%2), 1.0+bi*2.0, -5+ ai*6)); mrigidWall->GetMaterialSurface()->SetFriction(0.4f); mrigidWall->AddAsset(ChSharedPtr<ChTexture>(new ChTexture(GetChronoDataFile("cubetexture_bluwhite.png")))); application.GetSystem()->Add(mrigidWall); } } } if (do_heavyonside) { double sphrad = 0.2; double dens= 1000; double hfactor = 100; ChSharedPtr<ChBodyEasySphere> mrigidHeavy(new ChBodyEasySphere( sphrad, // radius dens*hfactor,// density true, // collide enable? true)); // visualization? mrigidHeavy->SetPos(ChVector<>(0.5, sphrad+0.1, -1)); mrigidHeavy->AddAsset(ChSharedPtr<ChTexture>(new ChTexture(GetChronoDataFile("pinkwhite.png")))); application.GetSystem()->Add(mrigidHeavy); GetLog() << "Expected contact deformation at side sphere=" << (mrigidHeavy->GetMass() *application.GetSystem()->Get_G_acc().y)*STATIC_COMPLIANCE << "\n"; } // Create the floor using a fixed rigid body of 'box' type: ChSharedPtr<ChBodyEasyBox> mrigidFloor (new ChBodyEasyBox( 50,4,50, // radius dens, // density true, // collide enable? true)); // visualization? mrigidFloor->SetPos( ChVector<>(0,-2,0) ); mrigidFloor->SetBodyFixed(true); mrigidFloor->GetMaterialSurface()->SetFriction(0.6f); mrigidFloor->AddAsset(ChSharedPtr<ChTexture>(new ChTexture(GetChronoDataFile("concrete.jpg")))); application.GetSystem()->Add(mrigidFloor); }
int main(int argc, char* argv[]) { int threads = 8; if (argc > 1) { threads = (atoi(argv[1])); } omp_set_num_threads(threads); //========================================================================================================= ChSystemParallelDVI * system_gpu = new ChSystemParallelDVI; system_gpu->SetIntegrationType(ChSystem::INT_ANITESCU); //========================================================================================================= system_gpu->SetParallelThreadNumber(threads); system_gpu->SetMaxiter(max_iter); system_gpu->SetIterLCPmaxItersSpeed(max_iter); ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationNormal(10); ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationSliding(10); ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationSpinning(0); ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationBilateral(10); system_gpu->SetTol(.0001); system_gpu->SetTolSpeeds(.0001); system_gpu->SetMaxPenetrationRecoverySpeed(100); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetTolerance(.0001); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetCompliance( 0); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetContactRecoverySpeed(1); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetSolverType(APGDRS); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->SetCollisionEnvelope(particle_radius * .01); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBinsPerAxis(I3(50, 50, 50)); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBodyPerBin(100, 50); system_gpu->Set_G_acc(ChVector<>(0, gravity, 0)); system_gpu->SetStep(timestep); ((ChSystemParallel*) system_gpu)->SetAABB(R3(-6, -3, -12), R3(6, 6, 12)); //========================================================================================================= //cout << num_per_dir.x << " " << num_per_dir.y << " " << num_per_dir.z << " " << num_per_dir.x * num_per_dir.y * num_per_dir.z << endl; //addPerturbedLayer(R3(0, -5 +container_thickness-particle_radius.y, 0), ELLIPSOID, particle_radius, num_per_dir, R3(.01, .01, .01), 10, 1, system_gpu); //addHCPCube(num_per_dir.x, num_per_dir.y, num_per_dir.z, 1, particle_radius.x, 1, true, 0, -6 +container_thickness+particle_radius.y, 0, 0, system_gpu); //========================================================================================================= ChSharedBodyPtr L = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr R = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr F = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr B = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr Bottom = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr Top = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedBodyPtr Tube = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); ChSharedPtr<ChMaterialSurface> material; material = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material->SetFriction(.1); material->SetRollingFriction(0); material->SetSpinningFriction(0); material->SetCompliance(0); material->SetCohesion(-100); Quaternion q; q.Q_from_AngX(-.1); InitObject(L, 100000, Vector(-container_size.x + container_thickness, container_height - container_thickness, 0), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(R, 100000, Vector(container_size.x - container_thickness, container_height - container_thickness, 0), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(F, 100000, Vector(0, container_height - container_thickness, -container_size.z + container_thickness), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(B, 100000, Vector(0, container_height - container_thickness, container_size.z - container_thickness), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(Bottom, 100000, Vector(0, container_height - container_size.y, 0), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); InitObject(Top, 100000, Vector(0, container_height + container_size.y, 0), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); ChSharedPtr<ChMaterialSurface> material_tube; material_tube = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material_tube->SetFriction(0); material_tube->SetRollingFriction(0); material_tube->SetSpinningFriction(0); material_tube->SetCompliance(0); material_tube->SetCohesion(-100); InitObject(Tube, 100000, Vector(0, 0, 0), Quaternion(1, 0, 0, 0), material_tube, true, true, -20, -20); AddCollisionGeometry(L, BOX, Vector(container_thickness, container_size.y, container_size.z), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(R, BOX, Vector(container_thickness, container_size.y, container_size.z), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(F, BOX, Vector(container_size.x, container_size.y, container_thickness), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(B, BOX, Vector(container_size.x, container_size.y, container_thickness), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Bottom, BOX, Vector(container_size.x, container_thickness, container_size.z), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Top, BOX, Vector(container_size.x, container_thickness, container_size.z), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); real tube_size = .03; AddCollisionGeometry(Tube, BOX, Vector(tube_size * 5, container_thickness / 6.0, tube_size), Vector(0, tube_size, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Tube, BOX, Vector(tube_size * 5, container_thickness / 6.0, tube_size), Vector(0, -tube_size, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Tube, BOX, Vector(tube_size * 5, tube_size, container_thickness / 6.0), Vector(0, 0, -tube_size), Quaternion(1, 0, 0, 0)); AddCollisionGeometry(Tube, BOX, Vector(tube_size * 5, tube_size, container_thickness / 6.0), Vector(0, 0, tube_size), Quaternion(1, 0, 0, 0)); FinalizeObject(L, (ChSystemParallel *) system_gpu); FinalizeObject(R, (ChSystemParallel *) system_gpu); FinalizeObject(F, (ChSystemParallel *) system_gpu); FinalizeObject(B, (ChSystemParallel *) system_gpu); FinalizeObject(Bottom, (ChSystemParallel *) system_gpu); //FinalizeObject(Top, (ChSystemParallel *) system_gpu); //FinalizeObject(Tube, (ChSystemParallel *) system_gpu); material_fiber = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material_fiber->SetFriction(.4); material_fiber->SetRollingFriction(.8); material_fiber->SetSpinningFriction(.8); material_fiber->SetCompliance(0); material_fiber->SetCohesion(0); layer_gen = new ParticleGenerator<ChSystemParallel>((ChSystemParallel *) system_gpu); layer_gen->SetDensity(1000); layer_gen->SetRadius(R3(particle_radius)); layer_gen->material->SetFriction(.1); layer_gen->material->SetCohesion(.1); layer_gen->material->SetSpinningFriction(0); layer_gen->material->SetRollingFriction(0); //layer_gen->SetCylinderRadius(4.5); //layer_gen->SetNormalDistribution(particle_radius, .002); layer_gen->AddMixtureType(MIX_SPHERE); //layer_gen->addPerturbedVolumeMixture(R3(0,-1,0), I3(80,40,80),R3(.1,.1,.1),R3(0,0,0),0); //========================================================================================================= //Rendering specific stuff: ChOpenGLManager * window_manager = new ChOpenGLManager(); ChOpenGL openGLView(window_manager, system_gpu, 800, 600, 0, 0, "Test_Solvers"); //openGLView.render_camera->camera_position = glm::vec3(0, -5, -10); //openGLView.render_camera->camera_look_at = glm::vec3(0, -5, 0); openGLView.render_camera->camera_scale = .1; openGLView.SetCustomCallback(RunTimeStep); openGLView.StartSpinning(window_manager); window_manager->CallGlutMainLoop(); //========================================================================================================= int file = 0; for (int i = 0; i < num_steps; i++) { system_gpu->DoStepDynamics(timestep); double TIME = system_gpu->GetChTime(); double STEP = system_gpu->GetTimerStep(); double BROD = system_gpu->GetTimerCollisionBroad(); double NARR = system_gpu->GetTimerCollisionNarrow(); double LCP = system_gpu->GetTimerLcp(); double UPDT = system_gpu->GetTimerUpdate(); double RESID = ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->GetResidual(); int BODS = system_gpu->GetNbodies(); int CNTC = system_gpu->GetNcontacts(); int REQ_ITS = ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->GetTotalIterations(); printf("%7.4f|%7.4f|%7.4f|%7.4f|%7.4f|%7.4f|%7d|%7d|%7d|%7.4f\n", TIME, STEP, BROD, NARR, LCP, UPDT, BODS, CNTC, REQ_ITS, RESID); int save_every = 1.0 / timestep / 60.0; //save data every n steps if (i % save_every == 0) { stringstream ss; cout << "Frame: " << file << endl; ss << "data/string/" << "/" << file << ".txt"; //DumpAllObjects(system_gpu, ss.str(), ",", true); DumpAllObjectsWithGeometryPovray(system_gpu, ss.str()); //output.ExportData(ss.str()); file++; } RunTimeStep(system_gpu, i); } //DumpObjects(system_gpu, "diagonal_impact_settled.txt", "\t"); }
int main(int argc, char* argv[]) { save = atoi(argv[1]); cout << save << endl; if (save) { seconds_to_simulate = 5; num_steps = seconds_to_simulate / timestep; } else { seconds_to_simulate = 300; num_steps = seconds_to_simulate / timestep; } if (argc > 2) { particle_slide_friction = atof(argv[2]); particle_roll_friction = atof(argv[3]); particle_cohesion = atof(argv[4]); data_folder = argv[5]; cout << particle_slide_friction << " " << particle_roll_friction << " " << particle_roll_friction << endl; } //========================================================================================================= ChSystemParallelDVI * system_gpu = new ChSystemParallelDVI; //========================================================================================================= //system_gpu->SetMinThreads(32); //system_gpu->SetMaxiter(max_iter); //system_gpu->SetIterLCPmaxItersSpeed(max_iter); ((ChSystemParallelDVI*) system_gpu)->DoThreadTuning(true); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationNormal(max_iter); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationSliding(max_iter); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationSpinning(max_iter); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationBilateral(0); system_gpu->SetTol(tolerance); system_gpu->SetTolSpeeds(tolerance); system_gpu->SetMaxPenetrationRecoverySpeed(1e9); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetTolerance(tolerance); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetCompliance(0); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetContactRecoverySpeed(100); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetSolverType(APGDRS); //((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->DoStabilization(true); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->SetCollisionEnvelope(particle_radius * .05); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBinsPerAxis(I3(30, 60, 30)); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBodyPerBin(100, 50); system_gpu->Set_G_acc(ChVector<>(0, gravity, 0)); system_gpu->SetStep(timestep); ((ChSystemParallel*) system_gpu)->SetAABB(R3(-250, -600, -250), R3(250, 600, 250)); //========================================================================================================= ChSharedPtr<ChMaterialSurface> material; material = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material->SetFriction(container_friction); material->SetRollingFriction(container_friction); material->SetSpinningFriction(container_friction); material->SetCompliance(0); material->SetCohesion(-100); CONTAINER = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); InitObject(CONTAINER, 100000, Vector(0, 0, 0), Quaternion(1, 0, 0, 0), material, true, true, -20, -20); if (save) { AddCollisionGeometry( CONTAINER, BOX, Vector(container_thickness, container_size.y, container_size.z), Vector(-container_size.x + container_thickness, container_height - container_thickness, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry( CONTAINER, BOX, Vector(container_thickness, container_size.y, container_size.z), Vector(container_size.x - container_thickness, container_height - container_thickness, 0), Quaternion(1, 0, 0, 0)); AddCollisionGeometry( CONTAINER, BOX, Vector(container_size.x, container_size.y, container_thickness), Vector(0, container_height - container_thickness, -container_size.z + container_thickness), Quaternion(1, 0, 0, 0)); AddCollisionGeometry( CONTAINER, BOX, Vector(container_size.x, container_size.y, container_thickness), Vector(0, container_height - container_thickness, container_size.z - container_thickness), Quaternion(1, 0, 0, 0)); AddCollisionGeometry( CONTAINER, BOX, Vector(container_size.x, container_thickness, container_size.z), Vector(0, container_height - container_size.y, 0), Quaternion(1, 0, 0, 0)); //AddCollisionGeometry(CONTAINER, BOX, Vector(container_size.x, container_thickness, container_size.z), Vector(0, container_height + container_size.y, 0), Quaternion(1, 0, 0, 0)); } CONTAINER->GetMaterialSurface()->SetCohesion(container_cohesion); FinalizeObject(CONTAINER, (ChSystemParallel *) system_gpu); if (save == false) { real anchor_length = 100; real anchor_r = 35 / 2.0; real anchor_R = 150 / 4.0; real anchor_h = 50; real anchor_thickness = 6 / 2.0; real anchor_blade_width = 8; ChVector<> p1(0, 0, 0); ChVector<> p2(0, anchor_length, 0); real anchor_mass = 6208; real number_sections = 30; REFERENCE = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); InitObject(REFERENCE, anchor_mass, Vector(0, 200, 0), Quaternion(1, 0, 0, 0), material, false, false, -15, -15); // AddCollisionGeometry(REFERENCE, SPHERE, ChVector<>(anchor_r, 0, 0), p1, Quaternion(1, 0, 0, 0)); // AddCollisionGeometry(REFERENCE, CYLINDER, Vector(anchor_r, anchor_length, anchor_r), p2, Quaternion(1, 0, 0, 0)); // for (int i = 0; i < number_sections; i++) { // ChQuaternion<> quat, quat2; // quat.Q_from_AngAxis(i / number_sections * 2 * PI, ChVector<>(0, 1, 0)); // quat2.Q_from_AngAxis(6.5 * 2 * PI / 360.0, ChVector<>(0, 0, 1)); // quat = quat % quat2; // ChVector<> pos(sin(i / number_sections * 2 * PI) * anchor_R, i / number_sections * anchor_h, cos(i / number_sections * 2 * PI) * anchor_R); // //ChMatrix33<> mat(quat); // AddCollisionGeometry(REFERENCE, BOX, ChVector<>(anchor_blade_width, anchor_thickness, anchor_R), pos, quat); // } ANCHOR = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); InitObject(ANCHOR, anchor_mass, Vector(0, 200, 0), Quaternion(1, 0, 0, 0), material, true, false, -15, -15); AddCollisionGeometry(ANCHOR, SPHERE, ChVector<>(anchor_r, 0, 0), p1, Quaternion(1, 0, 0, 0)); AddCollisionGeometry(ANCHOR, CYLINDER, Vector(anchor_r, anchor_length, anchor_r), p2, Quaternion(1, 0, 0, 0)); // for (int i = 0; i < number_sections; i++) { ChQuaternion<> quat, quat2; quat.Q_from_AngAxis(i / number_sections * 2 * PI, ChVector<>(0, 1, 0)); quat2.Q_from_AngAxis(6.5 * 2 * PI / 360.0, ChVector<>(0, 0, 1)); quat = quat % quat2; ChVector<> pos(sin(i / number_sections * 2 * PI) * anchor_R, i / number_sections * anchor_h, cos(i / number_sections * 2 * PI) * anchor_R); //ChMatrix33<> mat(quat); AddCollisionGeometry(ANCHOR, BOX, ChVector<>(anchor_blade_width, anchor_thickness, anchor_R), pos, quat); } FinalizeObject(ANCHOR, (ChSystemParallel *) system_gpu); FinalizeObject(REFERENCE, (ChSystemParallel *) system_gpu); // real vol = ((ChCollisionModelParallel *) ANCHOR->GetCollisionModel())->getVolume(); // real den = .00785; // anchor_mass = den*vol; // cout<<vol<<" "<<anchor_mass<<endl; // ANCHOR->SetMass(anchor_mass); ANCHOR->SetInertiaXX(ChVector<>(12668786.72, 5637598.31, 12682519.69)); REFERENCE->SetInertiaXX(ChVector<>(12668786.72, 5637598.31, 12682519.69)); // ANCHOR->SetInertiaXX( // ChVector<>( // 1 / 12.0 * anchor_mass * (1 * 1 + anchor_R * anchor_R), // 1 / 12.0 * anchor_mass * (anchor_R * anchor_R + anchor_R * anchor_R), // 1 / 12.0 * anchor_mass * (anchor_R * anchor_R + 1 * 1))); //BLOCK = ChSharedBodyPtr(new ChBody(new ChCollisionModelParallel)); //InitObject(BLOCK, anchor_mass/2, Vector(0, 300, 0), Quaternion(1, 0, 0, 0), material, false, false, -20, -20); //AddCollisionGeometry(BLOCK, BOX, ChVector<>(1, 1, 1), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); //FinalizeObject(BLOCK, (ChSystemParallel *) system_gpu); //actuator_anchor = ChSharedPtr<ChLinkLockLock>(new ChLinkLockLock()); //actuator_anchor->Initialize(CONTAINER, BLOCK, ChCoordsys<>(ChVector<>(0, 0, 0), QUNIT)); //system_gpu->AddLink(actuator_anchor); // apply motion //motionFunc1 = new ChFunction_Ramp(0, -anchor_vel); //actuator_anchor->SetMotion_Y(motionFunc1); //actuator_anchor->SetMotion_axis(ChVector<>(0, 1, 0)); engine_anchor = ChSharedPtr<ChLinkEngine>(new ChLinkEngine); engine_anchor->Initialize(CONTAINER, ANCHOR, ChCoordsys<>(ANCHOR->GetPos(), chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_X))); engine_anchor->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_PRISM); // also works as revolute support engine_anchor->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED); system_gpu->AddLink(engine_anchor); reference_engine = ChSharedPtr<ChLinkEngine>(new ChLinkEngine); reference_engine->Initialize(CONTAINER, REFERENCE, ChCoordsys<>(REFERENCE->GetPos(), chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_X))); reference_engine->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_PRISM); // also works as revolute support reference_engine->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED); system_gpu->AddLink(reference_engine); if (ChFunction_Const* mfun = dynamic_cast<ChFunction_Const*>(engine_anchor->Get_spe_funct())) { mfun->Set_yconst(anchor_rot * 1 / 60.0 * 2 * CH_C_PI); // rad/s angular speed } if (ChFunction_Const* mfun = dynamic_cast<ChFunction_Const*>(reference_engine->Get_spe_funct())) { mfun->Set_yconst(anchor_rot * 1 / 60.0 * 2 * CH_C_PI); // rad/s angular speed } ReadAllObjectsWithGeometryChrono(system_gpu, "data/anchor/anchor.dat"); ChSharedPtr<ChMaterialSurface> material_read; material_read = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material_read->SetFriction(particle_slide_friction); material_read->SetRollingFriction(particle_roll_friction); material_read->SetSpinningFriction(particle_roll_friction); material_read->SetCompliance(0); material_read->SetCohesion(particle_cohesion * timestep); for (int i = 0; i < system_gpu->Get_bodylist()->size(); i++) { system_gpu->Get_bodylist()->at(i)->SetMaterialSurface(material_read); } } else { layer_gen = new ParticleGenerator<ChSystemParallelDVI>((ChSystemParallelDVI *) system_gpu); layer_gen->SetDensity(particle_density); layer_gen->SetRadius(R3(particle_radius, particle_radius * .5, particle_radius)); layer_gen->SetNormalDistribution(particle_radius, particle_std_dev, 1); layer_gen->material->SetFriction(particle_slide_friction); layer_gen->material->SetCohesion(particle_cohesion); layer_gen->material->SetRollingFriction(0); layer_gen->material->SetSpinningFriction(0); layer_gen->AddMixtureType(MIX_SPHERE); } //layer_gen->AddMixtureType(MIX_ELLIPSOID); //layer_gen->AddMixtureType(MIX_DOUBLESPHERE); //layer_gen->addPerturbedVolumeMixture(R3(0, 0, 0), I3(64, 1, 64), R3(0, 0, 0), R3(0, 0, 0)); //========================================================================================================= //Rendering specific stuff: // ChOpenGLManager * window_manager = new ChOpenGLManager(); // ChOpenGL openGLView(window_manager, system_gpu, 800, 600, 0, 0, "Test_Solvers"); // openGLView.render_camera->camera_position = glm::vec3(0, -5, -10); // openGLView.render_camera->camera_look_at = glm::vec3(0, 0, 0); // openGLView.render_camera->camera_scale = 2; // openGLView.SetCustomCallback(RunTimeStep); // openGLView.StartSpinning(window_manager); // window_manager->CallGlutMainLoop(); //========================================================================================================= int file = 0; ofstream reactionfile; if (save == false) { stringstream ss; ss << data_folder << "reactions.txt"; reactionfile.open(ss.str()); } for (int i = 0; i < num_steps; i++) { system_gpu->DoStepDynamics(timestep); double TIME = system_gpu->GetChTime(); double STEP = system_gpu->GetTimerStep(); double BROD = system_gpu->GetTimerCollisionBroad(); double NARR = system_gpu->GetTimerCollisionNarrow(); double LCP = system_gpu->GetTimerLcp(); double SHUR = ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->solver.time_shurcompliment; double UPDT = system_gpu->GetTimerUpdate(); double RESID = ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->GetResidual(); int BODS = system_gpu->GetNbodies(); int CNTC = system_gpu->GetNcontacts(); int REQ_ITS = ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->GetTotalIterations(); printf("%7.4f|%7.4f|%7.4f|%7.4f|%7.4f|%7.4f|%7.4f|%7d|%7d|%7d|%7.4f\n", TIME, STEP, BROD, NARR, LCP, SHUR, UPDT, BODS, CNTC, REQ_ITS, RESID); system_gpu->gpu_data_manager->system_timer.PrintReport(); int save_every = 1.0 / timestep / 60.0; //save data every n steps if (i % save_every == 0) { stringstream ss; cout << "Frame: " << file << endl; ss << data_folder << "/" << file << ".txt"; if (save) { DumpAllObjectsWithGeometryChrono(system_gpu, "data/anchor/anchor.dat"); } else { DumpAllObjectsWithGeometryPovray(system_gpu, ss.str()); } file++; } if (save == false) { Vector force = engine_anchor->Get_react_force(); Vector torque = engine_anchor->Get_react_torque(); double motor_torque = engine_anchor->Get_mot_torque(); reactionfile << force.x << " " << force.y << " " << force.z << " " << torque.x << " " << torque.y << " " << torque.z << " " << motor_torque << " " << ANCHOR->GetPos().y << " " << ANCHOR->GetPos_dt().y << endl; } RunTimeStep(system_gpu, i); } if (save == false) { reactionfile.close(); } }
int main(int argc, char* argv[]) { //int threads = 8; string solver = "APGD"; if (argc > 1) { solver = argv[1]; max_particles = atoi(argv[2]); data_folder = argv[3]; //threads = (atoi(argv[1])); } if (argc == 5) { particle_radius = atof(argv[4]); } omp_set_num_threads(1); //========================================================================================================= ch_system * system_gpu = new ch_system; system_gpu->SetIntegrationType(ChSystem::INT_ANITESCU); #ifndef USEGPU if (solver == "APGD") { system_gpu->SetLcpSolverType(ChSystem::LCP_ITERATIVE_APGD); } else if (solver == "JACOBI") { system_gpu->SetLcpSolverType(ChSystem::LCP_ITERATIVE_JACOBI); //((ChLcpIterativeSolver*) system_gpu->GetLcpSolverSpeed())->SetOmega(.5); //((ChLcpIterativeSolver*) system_gpu->GetLcpSolverSpeed())->SetSharpnessLambda(.5); } else if (solver == "SOR") { system_gpu->SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR); } #endif ((ChLcpIterativeSolver*) system_gpu->GetLcpSolverSpeed())->SetRecordViolation(true); //========================================================================================================= system_gpu->SetParallelThreadNumber(1); system_gpu->SetMaxiter(max_iter); system_gpu->SetIterLCPmaxItersSpeed(max_iter); system_gpu->SetTol(tolerance); system_gpu->SetTolSpeeds(tolerance); system_gpu->SetMaxPenetrationRecoverySpeed(30); #ifdef USEGPU //((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->SetMaxIteration(max_iteration); ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationNormal(max_iter/2); ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationSliding(max_iter/2); ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationSpinning(0); ((ChLcpSolverParallelDVI*) (system_gpu->GetLcpSolverSpeed()))->SetMaxIterationBilateral(0); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetTolerance(tolerance); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetCompliance( 0); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetContactRecoverySpeed(5); ((ChLcpSolverParallelDVI *) (system_gpu->GetLcpSolverSpeed()))->SetSolverType(APGDRS); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->SetCollisionEnvelope(particle_radius * .01); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBinsPerAxis(I3(30, 30, 30)); ((ChCollisionSystemParallel *) (system_gpu->GetCollisionSystem()))->setBodyPerBin(100, 50); ((ch_system*) system_gpu)->SetAABB(R3(-6, -6, -6), R3(6, 6, 6)); #endif system_gpu->Set_G_acc(ChVector<>(0, gravity, 0)); system_gpu->SetStep(timestep); //========================================================================================================= ChSharedBodyPtr L = ChSharedBodyPtr(new ch_body); ChSharedBodyPtr R = ChSharedBodyPtr(new ch_body); ChSharedBodyPtr F = ChSharedBodyPtr(new ch_body); ChSharedBodyPtr B = ChSharedBodyPtr(new ch_body); ChSharedBodyPtr Bottom = ChSharedBodyPtr(new ch_body); ChSharedBodyPtr Top = ChSharedBodyPtr(new ch_body); ChSharedBodyPtr Tube = ChSharedBodyPtr(new ch_body); ChSharedPtr<ChMaterialSurface> material; material = ChSharedPtr<ChMaterialSurface>(new ChMaterialSurface); material->SetFriction(.4); material->SetRollingFriction(0); material->SetSpinningFriction(0); material->SetCompliance(0); material->SetCohesion(0); InitObject(Bottom, 100000, Vector(0, container_height - container_size.y, 0), Quaternion(1, 0, 0, 0), material, true, true, 1, 1); AddCollisionGeometry(Bottom, BOX, Vector(container_size.x, container_thickness, container_size.z), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); FinalizeObject(Bottom, (ch_system *) system_gpu); ChSharedBodyPtr Ring; for (int i = 0; i < 360; i += 5) { real angle = i * PI / 180.0; real x = cos(angle) * 5; real z = sin(angle) * 5; Quaternion q; q.Q_from_AngAxis(-angle, Vector(0, 1, 0)); Ring = ChSharedBodyPtr(new ch_body); InitObject(Ring, 100000, Vector(x, container_height - 3, z), q, material, true, true, 1, 1); AddCollisionGeometry(Ring, BOX, Vector(.25, 3, .25), Vector(0, 0, 0), Quaternion(1, 0, 0, 0)); FinalizeObject(Ring, (ch_system *) system_gpu); } spinner = ChSharedBodyPtr(new ch_body); InitObject(spinner, 100000, Vector(0, container_height - container_size.y + 2, 0), Quaternion(1, 0, 0, 0), material, true, false, 1, 1); real spinner_h = .5; AddCollisionGeometry(spinner, CYLINDER, Vector(.5, .4, .5), Vector(0, 0, 0), chrono::Q_from_AngAxis(0, ChVector<>(0, 0, 1))); AddCollisionGeometry(spinner, BOX, Vector(container_thickness / 15.0, spinner_h, 1.5), Vector(0, 0, 1.75), chrono::Q_from_AngAxis(CH_C_PI / 4.0, ChVector<>(0, 0, 1))); AddCollisionGeometry(spinner, BOX, Vector(container_thickness / 15.0, spinner_h, 1.5), Vector(0, 0, -1.75), chrono::Q_from_AngAxis(-CH_C_PI / 4.0, ChVector<>(0, 0, 1))); AddCollisionGeometry(spinner, BOX, Vector(1.5, spinner_h, container_thickness / 15.0), Vector(1.75, 0, 0), chrono::Q_from_AngAxis(CH_C_PI / 4.0, ChVector<>(1, 0, 0))); AddCollisionGeometry(spinner, BOX, Vector(1.5, spinner_h, container_thickness / 15.0), Vector(-1.75, 0, 0), chrono::Q_from_AngAxis(-CH_C_PI / 4.0, ChVector<>(1, 0, 0))); FinalizeObject(spinner, (ch_system *) system_gpu); #ifdef USEGPU layer_gen = new ParticleGenerator<ch_system>((ch_system *) system_gpu, true); #else layer_gen = new ParticleGenerator<ch_system>((ch_system *) system_gpu, false); #endif layer_gen->SetDensity(1000); layer_gen->SetRadius(R3(particle_radius)); layer_gen->material->SetFriction(.5); layer_gen->material->SetCohesion(particle_cohesion); #ifdef USEGPU layer_gen->material->SetCompliance(0); #else layer_gen->material->SetCompliance(0); #endif layer_gen->material->SetSpinningFriction(0); layer_gen->material->SetRollingFriction(0); layer_gen->SetRadius(R3(particle_radius, particle_radius * 1.1, particle_radius)); layer_gen->SetCylinderRadius(4.5); layer_gen->SetNormalDistribution(particle_radius, .01); layer_gen->AddMixtureType(MIX_SPHERE); layer_gen->AddMixtureType(MIX_ELLIPSOID); //layer_gen->AddMixtureType(MIX_CYLINDER); layer_gen->AddMixtureType(MIX_CUBE); //layer_gen->AddMixtureType(MIX_CONE); //========================================================================================================= ////Rendering specific stuff: // ChOpenGLManager * window_manager = new ChOpenGLManager(); // ChOpenGL openGLView(window_manager, system_gpu, 800, 600, 0, 0, "Test_Solvers"); // // //openGLView.render_camera->camera_position = glm::vec3(0, -5, -10); // // openGLView.render_camera->camera_look_at = glm::vec3(0, -5, 0); // // openGLView.render_camera->camera_scale = .1; // openGLView.SetCustomCallback(RunTimeStep); // openGLView.StartSpinning(window_manager); // window_manager->CallGlutMainLoop(); //========================================================================================================= stringstream s1; s1 << data_folder << "/residual.txt"; CSVGen csv_output; csv_output.OpenFile(s1.str().c_str()); int file = 0; for (int i = 0; i < num_steps; i++) { system_gpu->DoStepDynamics(timestep); double TIME = system_gpu->GetChTime(); double STEP = system_gpu->GetTimerStep(); double BROD = system_gpu->GetTimerCollisionBroad(); double NARR = system_gpu->GetTimerCollisionNarrow(); double LCP = system_gpu->GetTimerLcp(); double UPDT = system_gpu->GetTimerUpdate(); std::vector<double> violation = ((ChLcpIterativeSolver*) system_gpu->GetLcpSolverSpeed())->GetViolationHistory(); int REQ_ITS = violation.size(); double RESID = 0; if (REQ_ITS != 0) { RESID = violation.at(violation.size() - 1); } int BODS = system_gpu->GetNbodies(); int CNTC = system_gpu->GetNcontacts(); printf("%7.4f|%7.4f|%7.4f|%7.4f|%7.4f|%7.4f|%7d|%7d|%7d|%7.4f\n", TIME, STEP, BROD, NARR, LCP, UPDT, BODS, CNTC, REQ_ITS, RESID); int save_every = 1.0 / timestep / 60.0; //save data every n steps // if (i % save_every == 0) { // stringstream ss; // cout << "Frame: " << file << endl; // ss << data_folder << "/" << file << ".txt"; // //DumpAllObjects(system_gpu, ss.str(), ",", true); // DumpAllObjectsWithGeometryPovray(system_gpu, ss.str()); // file++; // // } csv_output << TIME; csv_output << STEP; csv_output << BROD; csv_output << NARR; csv_output << LCP; csv_output << UPDT; csv_output << BODS; csv_output << CNTC; csv_output << REQ_ITS; csv_output << RESID; csv_output.Endline(); RunTimeStep(system_gpu, i); } csv_output.CloseFile(); }
int main(int argc, char* argv[]) { // Create output directories. if (ChFileutils::MakeDirectory(out_dir.c_str()) < 0) { cout << "Error creating directory " << out_dir << endl; return 1; } if (ChFileutils::MakeDirectory(pov_dir.c_str()) < 0) { cout << "Error creating directory " << pov_dir << endl; return 1; } // ------------- // Create system // ------------- #ifdef USE_DEM cout << "Create DEM system" << endl; ChSystemParallelDEM* msystem = new ChSystemParallelDEM(); #else cout << "Create DVI system" << endl; ChSystemParallelDVI* msystem = new ChSystemParallelDVI(); #endif msystem->Set_G_acc(ChVector<>(0, 0, -gravity)); // Set number of threads. int max_threads = omp_get_num_procs(); if (threads > max_threads) threads = max_threads; msystem->SetParallelThreadNumber(threads); omp_set_num_threads(threads); cout << "Using " << threads << " threads" << endl; msystem->GetSettings()->max_threads = threads; msystem->GetSettings()->perform_thread_tuning = thread_tuning; // Edit system settings msystem->GetSettings()->solver.use_full_inertia_tensor = false; msystem->GetSettings()->solver.tolerance = tolerance; msystem->GetSettings()->solver.max_iteration_bilateral = max_iteration_bilateral; msystem->GetSettings()->solver.clamp_bilaterals = clamp_bilaterals; msystem->GetSettings()->solver.bilateral_clamp_speed = bilateral_clamp_speed; #ifdef USE_DEM msystem->GetSettings()->collision.narrowphase_algorithm = NARROWPHASE_R; msystem->GetSettings()->solver.contact_force_model = contact_force_model; msystem->GetSettings()->solver.tangential_displ_mode = tangential_displ_mode; #else msystem->GetSettings()->solver.solver_mode = SLIDING; msystem->GetSettings()->solver.max_iteration_normal = max_iteration_normal; msystem->GetSettings()->solver.max_iteration_sliding = max_iteration_sliding; msystem->GetSettings()->solver.max_iteration_spinning = max_iteration_spinning; msystem->GetSettings()->solver.alpha = 0; msystem->GetSettings()->solver.contact_recovery_speed = contact_recovery_speed; msystem->SetMaxPenetrationRecoverySpeed(contact_recovery_speed); msystem->ChangeSolverType(APGDREF); msystem->GetSettings()->collision.collision_envelope = 0.05 * r_g; #endif msystem->GetSettings()->collision.bins_per_axis = I3(10, 10, 10); // -------------- // Problem set up // -------------- // Depending on problem type: // - Select end simulation time // - Select output FPS // - Create / load objects double time_min = 0; double time_end; int out_fps; ChSharedPtr<ChBody> ground; ChSharedPtr<ChBody> loadPlate; ChSharedPtr<ChLinkLockPrismatic> prismatic; ChSharedPtr<ChLinkLinActuator> actuator; switch (problem) { case SETTLING: { time_min = time_settling_min; time_end = time_settling_max; out_fps = out_fps_settling; // Create the mechanism bodies (all fixed). CreateMechanismBodies(msystem); // Grab handles to mechanism bodies (must increase ref counts) ground = ChSharedPtr<ChBody>(msystem->Get_bodylist()->at(0)); loadPlate = ChSharedPtr<ChBody>(msystem->Get_bodylist()->at(1)); msystem->Get_bodylist()->at(0)->AddRef(); msystem->Get_bodylist()->at(1)->AddRef(); // Create granular material. int num_particles = CreateGranularMaterial(msystem); cout << "Granular material: " << num_particles << " particles" << endl; break; } case PRESSING: { time_min = time_pressing_min; time_end = time_pressing_max; out_fps = out_fps_pressing; // Create bodies from checkpoint file. cout << "Read checkpoint data from " << settled_ckpnt_file; utils::ReadCheckpoint(msystem, settled_ckpnt_file); cout << " done. Read " << msystem->Get_bodylist()->size() << " bodies." << endl; // Grab handles to mechanism bodies (must increase ref counts) ground = ChSharedPtr<ChBody>(msystem->Get_bodylist()->at(0)); loadPlate = ChSharedPtr<ChBody>(msystem->Get_bodylist()->at(1)); msystem->Get_bodylist()->at(0)->AddRef(); msystem->Get_bodylist()->at(1)->AddRef(); // Move the load plate just above the granular material. double highest, lowest; FindHeightRange(msystem, lowest, highest); ChVector<> pos = loadPlate->GetPos(); double z_new = highest + 1.01 * r_g; loadPlate->SetPos(ChVector<>(pos.x, pos.y, z_new)); // Add collision geometry to plate loadPlate->GetCollisionModel()->ClearModel(); utils::AddBoxGeometry(loadPlate.get_ptr(), ChVector<>(hdimX_p, hdimY_p, hdimZ_p), ChVector<>(0, 0, hdimZ_p)); loadPlate->GetCollisionModel()->BuildModel(); // If using an actuator, connect the load plate and get a handle to the actuator. if (use_actuator) { ConnectLoadPlate(msystem, ground, loadPlate); prismatic = msystem->SearchLink("prismatic").StaticCastTo<ChLinkLockPrismatic>(); actuator = msystem->SearchLink("actuator").StaticCastTo<ChLinkLinActuator>(); } // Release the load plate. loadPlate->SetBodyFixed(!use_actuator); break; } case TESTING: { time_end = time_testing; out_fps = out_fps_testing; // For TESTING only, increse shearing velocity. desiredVelocity = 0.5; // Create the mechanism bodies (all fixed). CreateMechanismBodies(msystem); // Create the test ball. CreateBall(msystem); // Grab handles to mechanism bodies (must increase ref counts) ground = ChSharedPtr<ChBody>(msystem->Get_bodylist()->at(0)); loadPlate = ChSharedPtr<ChBody>(msystem->Get_bodylist()->at(1)); msystem->Get_bodylist()->at(0)->AddRef(); msystem->Get_bodylist()->at(1)->AddRef(); // Move the load plate just above the test ball. ChVector<> pos = loadPlate->GetPos(); double z_new = 2.1 * radius_ball; loadPlate->SetPos(ChVector<>(pos.x, pos.y, z_new)); // Add collision geometry to plate loadPlate->GetCollisionModel()->ClearModel(); utils::AddBoxGeometry(loadPlate.get_ptr(), ChVector<>(hdimX_p, hdimY_p, hdimZ_p), ChVector<>(0, 0, hdimZ_p)); loadPlate->GetCollisionModel()->BuildModel(); // If using an actuator, connect the shear box and get a handle to the actuator. if (use_actuator) { ConnectLoadPlate(msystem, ground, loadPlate); actuator = msystem->SearchLink("actuator").StaticCastTo<ChLinkLinActuator>(); } // Release the shear box when using an actuator. loadPlate->SetBodyFixed(!use_actuator); break; } } // ---------------------- // Perform the simulation // ---------------------- // Set number of simulation steps and steps between successive output int num_steps = (int)std::ceil(time_end / time_step); int out_steps = (int)std::ceil((1.0 / time_step) / out_fps); int write_steps = (int)std::ceil((1.0 / time_step) / write_fps); // Initialize counters double time = 0; int sim_frame = 0; int out_frame = 0; int next_out_frame = 0; double exec_time = 0; int num_contacts = 0; double max_cnstr_viol[2] = {0, 0}; // Circular buffer with highest particle location // (only used for SETTLING or PRESSING) int buffer_size = std::ceil(time_min / time_step); std::valarray<double> hdata(0.0, buffer_size); // Create output files ChStreamOutAsciiFile statsStream(stats_file.c_str()); ChStreamOutAsciiFile sinkageStream(sinkage_file.c_str()); sinkageStream.SetNumFormat("%16.4e"); #ifdef CHRONO_PARALLEL_HAS_OPENGL opengl::ChOpenGLWindow& gl_window = opengl::ChOpenGLWindow::getInstance(); gl_window.Initialize(1280, 720, "Pressure Sinkage Test", msystem); gl_window.SetCamera(ChVector<>(0, -10 * hdimY, hdimZ), ChVector<>(0, 0, hdimZ), ChVector<>(0, 0, 1)); gl_window.SetRenderMode(opengl::WIREFRAME); #endif // Loop until reaching the end time... while (time < time_end) { // Current position and velocity of the shear box ChVector<> pos_old = loadPlate->GetPos(); ChVector<> vel_old = loadPlate->GetPos_dt(); // Calculate minimum and maximum particle heights double highest, lowest; FindHeightRange(msystem, lowest, highest); // If at an output frame, write PovRay file and print info if (sim_frame == next_out_frame) { cout << "------------ Output frame: " << out_frame + 1 << endl; cout << " Sim frame: " << sim_frame << endl; cout << " Time: " << time << endl; cout << " Load plate pos: " << pos_old.z << endl; cout << " Lowest point: " << lowest << endl; cout << " Highest point: " << highest << endl; cout << " Execution time: " << exec_time << endl; // Save PovRay post-processing data. if (write_povray_data) { char filename[100]; sprintf(filename, "%s/data_%03d.dat", pov_dir.c_str(), out_frame + 1); utils::WriteShapesPovray(msystem, filename, false); } // Create a checkpoint from the current state. if (problem == SETTLING || problem == PRESSING) { cout << " Write checkpoint data " << flush; if (problem == SETTLING) utils::WriteCheckpoint(msystem, settled_ckpnt_file); else utils::WriteCheckpoint(msystem, pressed_ckpnt_file); cout << msystem->Get_bodylist()->size() << " bodies" << endl; } // Increment counters out_frame++; next_out_frame += out_steps; } // Check for early termination of a settling phase. if (problem == SETTLING) { // Store maximum particle height in circular buffer hdata[sim_frame % buffer_size] = highest; // Check variance of data in circular buffer if (time > time_min) { double mean_height = hdata.sum() / buffer_size; std::valarray<double> x = hdata - mean_height; double var = std::sqrt((x * x).sum() / buffer_size); // Consider the material settled when the variance is below the // specified fraction of a particle radius if (var < settling_tol * r_g) { cout << "Granular material settled... time = " << time << endl; break; } } } // Advance simulation by one step #ifdef CHRONO_PARALLEL_HAS_OPENGL if (gl_window.Active()) { gl_window.DoStepDynamics(time_step); gl_window.Render(); } else break; #else msystem->DoStepDynamics(time_step); #endif TimingOutput(msystem); // Record stats about the simulation if (sim_frame % write_steps == 0) { // write stat info int numIters = msystem->data_manager->measures.solver.maxd_hist.size(); double residual = 0; if (numIters) residual = msystem->data_manager->measures.solver.residual; statsStream << time << ", " << exec_time << ", " << num_contacts / write_steps << ", " << numIters << ", " << residual << ", " << max_cnstr_viol[0] << ", " << max_cnstr_viol[1] << ", \n"; statsStream.GetFstream().flush(); num_contacts = 0; max_cnstr_viol[0] = 0; max_cnstr_viol[1] = 0; } if (problem == PRESSING || problem == TESTING) { // Get the current reaction force or impose load plate position double cnstr_force = 0; if (use_actuator) { cnstr_force = actuator->Get_react_force().x; } else { double zpos_new = pos_old.z + desiredVelocity * time_step; loadPlate->SetPos(ChVector<>(pos_old.x, pos_old.y, zpos_new)); loadPlate->SetPos_dt(ChVector<>(0, 0, desiredVelocity)); } if (sim_frame % write_steps == 0) { // std::cout << time << ", " << loadPlate->GetPos().z << ", " << cnstr_force << ", \n"; sinkageStream << time << ", " << loadPlate->GetPos().z << ", " << cnstr_force << ", \n"; sinkageStream.GetFstream().flush(); } } // Find maximum constraint violation if (!prismatic.IsNull()) { ChMatrix<>* C = prismatic->GetC(); for (int i = 0; i < 5; i++) max_cnstr_viol[0] = std::max(max_cnstr_viol[0], std::abs(C->GetElement(i, 0))); } if (!actuator.IsNull()) { ChMatrix<>* C = actuator->GetC(); max_cnstr_viol[1] = std::max(max_cnstr_viol[2], std::abs(C->GetElement(0, 0))); } // Increment counters time += time_step; sim_frame++; exec_time += msystem->GetTimerStep(); num_contacts += msystem->GetNcontacts(); // If requested, output detailed timing information for this step if (sim_frame == timing_frame) msystem->PrintStepStats(); } // ---------------- // Final processing // ---------------- // Create a checkpoint from the last state if (problem == SETTLING || problem == PRESSING) { cout << " Write checkpoint data " << flush; if (problem == SETTLING) utils::WriteCheckpoint(msystem, settled_ckpnt_file); else utils::WriteCheckpoint(msystem, pressed_ckpnt_file); cout << msystem->Get_bodylist()->size() << " bodies" << endl; } // Final stats cout << "==================================" << endl; cout << "Number of bodies: " << msystem->Get_bodylist()->size() << endl; cout << "Simulation time: " << exec_time << endl; cout << "Number of threads: " << threads << endl; return 0; }