Esempio n. 1
0
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?
		}
	}
}
Esempio n. 2
0
  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);
  }
Esempio n. 3
0
// -----------------------------------------------------------------------------
// 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);
    }
}
Esempio n. 4
0
  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);
  }
Esempio n. 5
0
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));
	}
	*/

}
Esempio n. 6
0
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++;
	}
}
Esempio n. 7
0
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?
	}
}
Esempio n. 8
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?
	}
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}