Restitution - ChSystemMulticoreNSC

48 views
Skip to first unread message

Samuele Vaghi

unread,
Jul 27, 2026, 9:59:24 AM (2 days ago) Jul 27
to ProjectChrono
Hi,

I'm having a problem with collisions when using the ChSystemMulticoreNSC.  Basically if I try to make two simple box shapes collide, there seems to be no restitution, and the bodies stick together. On the other hand, with ChSystemNSC, the bodies collide correctly according to the input CoR. Is restitution implemented in ChSystemMulticoreNSC?
I attach a code snippet for more clarity.

Thanks!

Samuele
//========== CREATE CHRONO PHYSICAL SYSTEM ========================// ChSystemMulticoreNSC sys; //======================== NUMERICAL SOLVER ======================// // Set solver parameters sys.SetCollisionSystemType(ChCollisionSystem::Type::MULTICORE);  /* sys.GetSettings()->solver.max_iteration_bilateral = max_iteration; sys.GetSettings()->solver.tolerance = tolerance; // sys.GetSettings()->collision.narrowphase_algorithm = ChNarrowphase::Algorithm::HYBRID; //this is default sys.GetSettings()->collision.bins_per_axis = vec3(10, 10, 10); sys.GetSettings()->collision.broadphase_grid = ChBroadphase::GridType::FIXED_DENSITY; sys.GetSettings()->collision.grid_density = 1; // Solver type sys.GetSettings()->solver.solver_type = SolverType::MINIMUM_RESIDUAL; std::cout << "Solver is Minimum Residual" << std::endl; //sys.SetNumThreads(21); // Set number of threads. int threads = 40; threads = std::min(threads, ChOMP::GetNumProcs()); sys.SetNumThreads(threads); std::cout << "Max. threads available " << ChOMP::GetNumProcs() << "\n"; std::cout << "Using " << threads << " threads" << "\n"; #pragma omp parallel { printf("thread %d\n", omp_get_thread_num()); } */ ///// === COMPUTE DERIVED QUANTITIES === //////// // ============= SET LOCAL GRAVITY ================// sys.SetGravitationalAcceleration(ChVector3d(gx_local, gy_local, gz_local)); // ============= CREATE CONTACT MATERIAL ==========// // === Lander material properties === // auto terrain_mat = chrono_types::make_shared<ChContactMaterialNSC>(); terrain_mat->SetRestitution(CoR_terrain); // === Container material properties === // auto container_mat = chrono_types::make_shared<ChContactMaterialNSC>(); container_mat->SetRestitution(CoR_wall); container_mat->SetStaticFriction(0.1); // === Ground material properties === // auto lander_mat = chrono_types::make_shared<ChContactMaterialNSC>(); lander_mat->SetRestitution(CoR_lander); //lander_mat->SetStaticFriction(0.1); // ============ CREATE BODIES ==================// // Container auto cdim = ChVector3<>(cdimX, cdimY, cdimZ); // half-dims auto cpos = ChVector3<>(cposX, cposY, cposZ); auto bin = chrono_types::make_shared<ChBody>(); bin->SetMass(1); cpos.x() = 0; cpos.z() = -cdim.z(); bin->SetPos(cpos); bin->SetRot(ChQuaternion<>(1, 0, 0, 0)); bin->EnableCollision(true); bin->SetFixed(true); // floor chrono::utils::AddBoxGeometry(bin.get(), container_mat, ChVector3<>(cdim.x(), cdim.y(), tw) * 2.0, ChVector3<>(0, 0, -tw), ChQuaternion<>(1, 0, 0, 0), true); // left wall chrono::utils::AddBoxGeometry(bin.get(), container_mat, ChVector3<>(tw, cdim.y(), cdim.z() + tw) * 2.0, ChVector3<>(-cdim.x() - tw, 0, cdim.z() - tw), ChQuaternion<>(1, 0, 0, 0), false); // right wall chrono::utils::AddBoxGeometry(bin.get(), container_mat, ChVector3<>(tw, cdim.y(), cdim.z() + tw) * 2.0, ChVector3<>(cdim.x() + tw, 0, cdim.z() - tw), ChQuaternion<>(1, 0, 0, 0), false); // front wall chrono::utils::AddBoxGeometry(bin.get(), container_mat, ChVector3<>(cdim.x(), tw, cdim.z() + tw) * 2.0, ChVector3<>(0, -cdim.y() - tw, cdim.z() - tw), ChQuaternion<>(1, 0, 0, 0), true); // rear wall chrono::utils::AddBoxGeometry(bin.get(), container_mat, ChVector3<>(cdim.x(), tw, cdim.z() + tw) * 2.0, ChVector3<>(0, cdim.y() + tw, cdim.z() - tw), ChQuaternion<>(1, 0, 0, 0), false); sys.AddBody(bin); std::cout << "Container position is: " << bin->GetPos().x() << " " << bin->GetPos().y() << " " << bin->GetPos().z() << "\n"; // Create lander (cube) auto lander = std::make_shared<ChBody>(); ChCoordsys<> mcoord; // local coordinates system mcoord.pos = ChVector3<>(px_lander, py_lander, pz_lander); //double halfAngle = (Ry / 2.0) * (3.14159265358979311 / 180.); mcoord.rot = ChQuaternion<>(q0_lander, q1_lander, q2_lander, q3_lander); lander->SetCoordsys(mcoord); lander->SetPosDt(ChVector3<>(vx_lander, vy_lander, vz_lander)); lander->SetPosDt2(ChVector3<>(0, 0, 0)); lander->SetMass(mass_lander); lander->EnableCollision(true); utils::AddBoxGeometry(lander.get(), lander_mat, ChVector3<>(lx_lander, ly_lander, lz_lander), ChVector3<>(0, 0, 0), ChQuaternion<>(1, 0, 0, 0), true); sys.AddBody(lander);

Khai S

unread,
Jul 27, 2026, 6:17:57 PM (2 days ago) Jul 27
to ProjectChrono
Hey!

I just went digging around through the source code. From what I can see, no, restitution is not implemented in ChSystemMulticoreNSC.

Based on the code snippet, I think ChSystemNSC will be sufficient for your use case. 

~Khai

Samuele Vaghi

unread,
Jul 28, 2026, 4:36:06 AM (22 hours ago) Jul 28
to ProjectChrono
Hi Khai, thanks!

Actually I didn't include it in the snippet, but my simulation requires also to add a granular terrain composed of more than 10k convex hulls, so using the MULTICORE option would be great in terms of computational performance. Is there an alternative, or is it planned to implement resitution in the ChSystemMulticoreNSC in the future?

Samuele

Radu Serban

unread,
Jul 28, 2026, 5:24:09 AM (21 hours ago) Jul 28
to ProjectChrono

Hi Samuele,

 

There’s ongoing work on a refactoring of the Chrono::Multicore module (low-level implementation details that will not affect user code). Once that is done, I will look into adding support for coefficient of restitution.

 

Is there a particular reason why you want to use NSC (non-smooth contact formulation)? The SMC option (ChSystemMulticoreSMC) has support for restitution; see for example this test program.

 

As an alternative for granular dynamics, you can use one of the GPU codes: either the Chrono::DEM module (single-GPU, monodisperse granular material) or the DEME code (optionally dual-GPU, polydisperse granular material with possibility of clumps). Using either of these has the following consequences:

  • They both only support SMC (smooth contact, aka “penalty-based”)
  • They require setting up the coupled multibody-DEM problem as a co-simulation problem
  • They obviously require (at least) one GPU
    - in the current code on the ‘main’ branch, Chrono::DEM works with either NVIDIA or AMD GPUs
    - DEME support for AMD GPUs is not yet available

 

Best,
Radu

--
You received this message because you are subscribed to the Google Groups "ProjectChrono" group.
To unsubscribe from this group and stop receiving emails from it, send an email to projectchron...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/projectchrono/f9373cd1-47f0-4241-b3b5-743e364b6f6bn%40googlegroups.com.

Samuele Vaghi

unread,
Jul 28, 2026, 5:58:17 AM (21 hours ago) Jul 28
to ProjectChrono

Hi Radu,

thanks for your answer. 

  • The main reason we would like to use NSC model over SMC is because of the limitation on time step coming from the penalty-based approach. But restitution is fundamental for our application, so the current version of ChSystemMulticoreNSC is not suited for us.
  • We also would like to use convex hulls and not spheres or clumps, so we haven't considered the DEM(E) modules so far
  • we also have a further doubt about using SMC with convex hulls: is the "effective radius" necessary for contact force computation actually computed, or a default value is used?

Samuele
Reply all
Reply to author
Forward
0 new messages