diff --git a/CHANGELOG.md b/CHANGELOG.md index fcabaa8..ff5a51b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,8 @@ ### Added -- `Fluid` now has a new parameter `InteractionGroup`, - which controls which static particles (`Boundary`s) can interact with it. +- `Fluid` and `Boundary`s now have a new property `interaction_groups`, + which controls which other particles can interact with it. ### Changed diff --git a/examples2d/layers2.rs b/examples2d/layers2.rs index c7c9d34..20155aa 100644 --- a/examples2d/layers2.rs +++ b/examples2d/layers2.rs @@ -78,7 +78,12 @@ pub fn init_world(testbed: &mut Testbed) { plugin.set_fluid_color(fluid_handle, Point3::new(1.0, 0.4, 0.6)); let viscosity = ArtificialViscosity::new(0.5, 0.0); - let mut fluid = Fluid::new(points3, PARTICLE_RADIUS, 1.0, InteractionGroups::none()); + let mut fluid = Fluid::new( + points3, + PARTICLE_RADIUS, + 1.0, + InteractionGroups::new(Group::GROUP_2, Group::GROUP_2), + ); fluid.nonpressure_forces.push(Box::new(viscosity.clone())); let fluid_handle = fluids_pipeline.liquid_world.add_fluid(fluid); plugin.set_fluid_color(fluid_handle, Point3::new(0.6, 0.8, 0.5)); diff --git a/src/geometry/contacts.rs b/src/geometry/contacts.rs index ce6b5fa..a4d0964 100644 --- a/src/geometry/contacts.rs +++ b/src/geometry/contacts.rs @@ -273,7 +273,9 @@ fn compute_contacts_for_pair_of_cells( HGridEntry::BoundaryParticle(boundary_j, particle_j) => { let bi = &boundaries[*boundary_i]; let bj = &boundaries[*boundary_j]; - if !bi.fluid_interaction.test(bj.fluid_interaction) { + if *boundary_i != *boundary_j + && !bi.interaction_groups.test(bj.interaction_groups) + { continue; } @@ -311,7 +313,7 @@ fn compute_contacts_for_pair_of_cells( } let bi = &boundaries[*boundary_i]; let fj = &fluids[*fluid_j]; - if !bi.fluid_interaction.test(fj.boundary_interaction) { + if !bi.interaction_groups.test(fj.interaction_groups) { continue; } let pi = &boundaries[*boundary_i].positions[*particle_i]; @@ -343,13 +345,21 @@ fn compute_contacts_for_pair_of_cells( let pj = if is_boundary_j { let bj = &boundaries[fluid_j]; if !fluids[*fluid_i] - .boundary_interaction - .test(bj.fluid_interaction) + .interaction_groups + .test(bj.interaction_groups) { continue; } boundaries[fluid_j].positions[particle_j] } else { + if *fluid_i != fluid_j { + let groups_i = &fluids[*fluid_i].interaction_groups; + let groups_j = &fluids[fluid_j].interaction_groups; + + if !groups_i.test(*groups_j) { + continue; + } + } fluids[fluid_j].positions[particle_j] }; diff --git a/src/object/boundary.rs b/src/object/boundary.rs index 76a5c06..006bf95 100644 --- a/src/object/boundary.rs +++ b/src/object/boundary.rs @@ -19,13 +19,16 @@ pub struct Boundary { /// If this is set to `None` (which is the default), the boundary won't receive any /// force for fluids. pub forces: Option>>>, - /// Determines which fluids this boundary is allowed to interact with. - pub fluid_interaction: InteractionGroups, + /// Determines which other particles is allowed to interact with. + pub interaction_groups: InteractionGroups, } impl Boundary { /// Initialize a boundary object with the given particles. - pub fn new(particle_positions: Vec>, fluid_interaction: InteractionGroups) -> Self { + pub fn new( + particle_positions: Vec>, + interaction_groups: InteractionGroups, + ) -> Self { let num_particles = particle_positions.len(); let velocities = std::iter::repeat(Vector::zeros()) .take(num_particles) @@ -39,7 +42,7 @@ impl Boundary { velocities, volumes, forces: None, - fluid_interaction, + interaction_groups, } } diff --git a/src/object/fluid.rs b/src/object/fluid.rs index 5583547..69bb356 100644 --- a/src/object/fluid.rs +++ b/src/object/fluid.rs @@ -28,8 +28,9 @@ pub struct Fluid { num_deleted_particles: usize, /// The particles radius. particle_radius: Real, - /// The groups controlling which static particles ([`Boundary`]) can interact with this fluid. - pub boundary_interaction: InteractionGroups, + /// The groups controlling which other particles can interact with this fluid. + /// A fluid always interacts with itself. + pub interaction_groups: InteractionGroups, } impl Fluid { @@ -40,7 +41,7 @@ impl Fluid { particle_positions: Vec>, particle_radius: Real, // XXX: remove this parameter since it is already defined by the liquid world. density0: Real, - boundary_interaction: InteractionGroups, + interaction_groups: InteractionGroups, ) -> Self { let num_particles = particle_positions.len(); let velocities: Vec<_> = std::iter::repeat(Vector::zeros()) @@ -58,7 +59,7 @@ impl Fluid { volumes: std::iter::repeat(particle_volume) .take(num_particles) .collect(), - boundary_interaction, + interaction_groups, deleted_particles: std::iter::repeat(false).take(num_particles).collect(), num_deleted_particles: 0, density0,