### Integrate FluidsPipeline with Rapier Physics Source: https://context7.com/dimforge/salva/llms.txt Demonstrates how to initialize a FluidsPipeline, create a Rapier collider for a boundary, and register the coupling between the rigid body and the fluid simulation. This setup enables two-way interaction between fluid particles and physical rigid bodies. ```rust use salva3d::integrations::rapier::{FluidsPipeline, ColliderSampling, FluidsTestbedPlugin}; use salva3d::object::Boundary; use salva3d::object::interaction_groups::InteractionGroups; use rapier3d::dynamics::{RigidBodyBuilder, RigidBodySet}; use rapier3d::geometry::{ColliderBuilder, ColliderSet, SharedShape}; use nalgebra::{Vector3, Point3}; let mut bodies = RigidBodySet::new(); let mut colliders = ColliderSet::new(); let particle_radius = 0.05; let smoothing_factor = 2.0; let mut fluids_pipeline = FluidsPipeline::new(particle_radius, smoothing_factor); let wall_shape = SharedShape::cuboid(0.2, 0.7, 2.5); let rigid_body = RigidBodyBuilder::fixed().build(); let body_handle = bodies.insert(rigid_body); let collider = ColliderBuilder::new(wall_shape.clone()).build(); let collider_handle = colliders.insert_with_parent(collider, body_handle, &mut bodies); let samples = salva3d::sampling::shape_surface_ray_sample(&*wall_shape, particle_radius).unwrap(); let boundary_handle = fluids_pipeline.liquid_world.add_boundary( Boundary::new(Vec::new(), InteractionGroups::default()) ); fluids_pipeline.coupling.register_coupling( boundary_handle, collider_handle, ColliderSampling::StaticSampling(samples) ); let gravity = Vector3::new(0.0, -9.81, 0.0); let dt = 1.0 / 200.0; fluids_pipeline.step(&gravity, dt, &colliders, &mut bodies); ``` -------------------------------- ### Complete 3D Fluid Simulation with Rigid Body Coupling in Rust Source: https://context7.com/dimforge/salva/llms.txt A full example of a 3D fluid simulation using Salva3D, integrated with Rapier for rigid body dynamics. It showcases fluid initialization, viscosity, boundary handling, and a simulation loop. Dependencies include `nalgebra`, `rapier3d`, and `salva3d`. ```Rust use nalgebra::{Isometry3, Point3, Vector3}; use rapier3d::dynamics::{ImpulseJointSet, MultibodyJointSet, RigidBodyBuilder, RigidBodySet}; use rapier3d::geometry::{ColliderBuilder, ColliderSet, SharedShape}; use salva3d::integrations::rapier::{ColliderSampling, FluidsPipeline}; use salva3d::object::interaction_groups::InteractionGroups; use salva3d::object::{Boundary, Fluid}; use salva3d::solver::ArtificialViscosity; fn main() { // Simulation parameters let particle_radius: f32 = 0.05; let smoothing_factor: f32 = 2.0; let gravity = Vector3::y() * -9.81; let dt = 1.0 / 200.0; // Initialize physics world let mut bodies = RigidBodySet::new(); let mut colliders = ColliderSet::new(); let mut fluids_pipeline = FluidsPipeline::new(particle_radius, smoothing_factor); // Create fluid cube let nparticles = 15; let mut points = Vec::new(); let half_extents = Vector3::new(nparticles as f32, nparticles as f32, nparticles as f32) * particle_radius; for i in 0..nparticles { for j in 0..nparticles { for k in 0..nparticles { let x = (i as f32) * particle_radius * 2.0; let y = (j as f32) * particle_radius * 2.0; let z = (k as f32) * particle_radius * 2.0; points.push(Point3::new(x, y, z) + Vector3::repeat(particle_radius) - half_extents); } } } let mut fluid = Fluid::new(points, particle_radius, 1000.0, InteractionGroups::default()); fluid.transform_by(&Isometry3::translation(0.0, 1.0, 0.0)); // Add viscosity let viscosity = ArtificialViscosity::new(1.0, 0.0); fluid.nonpressure_forces.push(Box::new(viscosity)); let _fluid_handle = fluids_pipeline.liquid_world.add_fluid(fluid); // Create ground let ground_shape = SharedShape::cuboid(2.5, 0.2, 2.5); let ground_body = RigidBodyBuilder::fixed().build(); let ground_handle = bodies.insert(ground_body); let ground_collider = ColliderBuilder::new(ground_shape.clone()).build(); let ground_co_handle = colliders.insert_with_parent(ground_collider, ground_handle, &mut bodies); // Sample ground and register coupling let ground_samples = salva3d::sampling::shape_surface_ray_sample(&*ground_shape, particle_radius).unwrap(); let ground_boundary = fluids_pipeline.liquid_world.add_boundary( Boundary::new(Vec::new(), InteractionGroups::default()) ); fluids_pipeline.coupling.register_coupling( ground_boundary, ground_co_handle, ColliderSampling::StaticSampling(ground_samples) ); // Simulation loop for _step in 0..1000 { // Step fluids simulation (also applies forces to rigid bodies) fluids_pipeline.step(&gravity, dt, &colliders, &mut bodies); // Access fluid state let fluid = &fluids_pipeline.liquid_world.fluids().get_from_contiguous_index(0); if let Some((fluid, _handle)) = fluid { println!("Particle 0 position: {:?}", fluid.positions[0]); println!("Particle 0 velocity: {:?}", fluid.velocities[0]); } } } ``` -------------------------------- ### Initialize LiquidWorld Simulation Source: https://context7.com/dimforge/salva/llms.txt Demonstrates how to instantiate a LiquidWorld with a DFSPH solver, define simulation parameters like gravity, and advance the simulation by a specific timestep. ```rust use salva3d::LiquidWorld; use salva3d::solver::DFSPHSolver; use nalgebra::Vector3; let particle_radius = 0.05; let smoothing_factor = 2.0; let solver = DFSPHSolver::new(); let mut liquid_world = LiquidWorld::new(solver, particle_radius, smoothing_factor); let gravity = Vector3::new(0.0, -9.81, 0.0); let dt = 1.0 / 200.0; liquid_world.step(dt, &gravity); let kernel_radius = liquid_world.h(); let radius = liquid_world.particle_radius(); ``` -------------------------------- ### Shape Sampling: Surface and Volume Ray Sampling in Rust Source: https://context7.com/dimforge/salva/llms.txt Demonstrates how to use `shape_surface_ray_sample` and `shape_volume_ray_sample` from Salva3D to generate particle distributions on the surface or within the volume of various geometric shapes. This is useful for boundary initialization or fluid seeding. It requires the `salva3d` and `rapier3d` crates. ```Rust use salva3d::sampling::{shape_surface_ray_sample, shape_volume_ray_sample}; use rapier3d::geometry::SharedShape; use nalgebra::Point3; let particle_radius = 0.05; // Create a sphere shape let sphere = SharedShape::ball(1.0); // Sample the surface (for boundaries) let surface_points: Vec> = shape_surface_ray_sample(&*sphere, particle_radius).unwrap(); // Returns points distributed on the sphere surface // Sample the volume (for fluid initialization) let volume_points: Vec> = shape_volume_ray_sample(&*sphere, particle_radius).unwrap(); // Returns points filling the sphere interior // Works with various shapes let cuboid = SharedShape::cuboid(1.0, 0.5, 2.0); let capsule = SharedShape::capsule_y(0.5, 1.0); let cylinder = SharedShape::cylinder(1.0, 0.5); let cuboid_surface = shape_surface_ray_sample(&*cuboid, particle_radius).unwrap(); let capsule_surface = shape_surface_ray_sample(&*capsule, particle_radius).unwrap(); let cylinder_volume = shape_volume_ray_sample(&*cylinder, particle_radius).unwrap(); ``` -------------------------------- ### Configure DFSPHSolver for Liquid Simulation Source: https://context7.com/dimforge/salva/llms.txt Initializes and configures the Divergence-Free Smoothed Particle Hydrodynamics solver. It allows setting iteration limits and error tolerances for both pressure and divergence calculations. ```rust use salva3d::solver::DFSPHSolver; use salva3d::LiquidWorld; let mut solver = DFSPHSolver::new(); solver.min_pressure_iter = 1; solver.max_pressure_iter = 50; solver.max_density_error = 0.05; solver.min_divergence_iter = 1; solver.max_divergence_iter = 50; solver.max_divergence_error = 0.1; let particle_radius = 0.05; let smoothing_factor = 2.0; let liquid_world = LiquidWorld::new(solver, particle_radius, smoothing_factor); ``` -------------------------------- ### Configure Boundary Objects Source: https://context7.com/dimforge/salva/llms.txt Explains how to define static or coupled boundary particles, enable force feedback for physics interactions, and apply spatial transformations. ```rust use salva3d::object::Boundary; use salva3d::object::interaction_groups::InteractionGroups; use nalgebra::{Point3, Vector3, Isometry3}; use std::sync::RwLock; let particle_positions: Vec> = vec![ Point3::new(0.0, 0.0, 0.0), Point3::new(0.1, 0.0, 0.0), Point3::new(0.2, 0.0, 0.0) ]; let mut boundary = Boundary::new(particle_positions, InteractionGroups::default()); boundary.forces = Some(RwLock::new(Vec::new())); boundary.clear_forces(true); boundary.transform_by(&Isometry3::translation(1.0, 0.0, 0.0)); let num_boundary_particles = boundary.num_particles(); ``` -------------------------------- ### Manage Fluid Particle Objects Source: https://context7.com/dimforge/salva/llms.txt Shows how to create a fluid object from particle positions, perform transformations, add particles dynamically, and query physical properties. ```rust use salva3d::object::Fluid; use salva3d::object::interaction_groups::InteractionGroups; use nalgebra::{Point3, Vector3, Isometry3}; let particle_radius = 0.05; let density = 1000.0; let mut points = Vec::new(); for i in 0..15 { for j in 0..15 { for k in 0..15 { let x = (i as f32) * particle_radius * 2.0; let y = (j as f32) * particle_radius * 2.0; let z = (k as f32) * particle_radius * 2.0; points.push(Point3::new(x, y, z)); } } } let mut fluid = Fluid::new(points, particle_radius, density, InteractionGroups::default()); fluid.transform_by(&Isometry3::translation(0.0, 1.0, 0.0)); let new_positions = vec![Point3::new(0.0, 2.0, 0.0), Point3::new(0.1, 2.0, 0.0)]; let new_velocities = vec![Vector3::new(0.0, -1.0, 0.0), Vector3::new(0.0, -1.0, 0.0)]; fluid.add_particles(&new_positions, Some(&new_velocities)); let num_particles = fluid.num_particles(); fluid.delete_particle_at_next_timestep(0); ``` -------------------------------- ### Implement ColliderSampling for Boundary Particles Source: https://context7.com/dimforge/salva/llms.txt Explains the two methods for converting collider shapes into boundary particles: StaticSampling for pre-computed geometry and DynamicContactSampling for runtime interaction. ```rust use salva3d::integrations::rapier::{FluidsPipeline, ColliderSampling}; use salva3d::object::Boundary; use salva3d::object::interaction_groups::InteractionGroups; use rapier3d::geometry::SharedShape; use nalgebra::Point3; let particle_radius = 0.05; let mut fluids_pipeline = FluidsPipeline::new(particle_radius, 2.0); let ground_shape = SharedShape::cuboid(2.5, 0.2, 2.5); let samples = salva3d::sampling::shape_surface_ray_sample(&*ground_shape, particle_radius).unwrap(); let boundary_handle = fluids_pipeline.liquid_world.add_boundary( Boundary::new(Vec::new(), InteractionGroups::default()) ); ``` -------------------------------- ### Configure InteractionGroups for Particle Filtering Source: https://context7.com/dimforge/salva/llms.txt Shows how to use bit-mask-based filtering to define which fluid types interact with each other. This is essential for multiphase simulations where different fluids have specific collision rules. ```rust use salva3d::object::interaction_groups::{InteractionGroups, Group}; use salva3d::object::Fluid; use nalgebra::Point3; let oil_groups = InteractionGroups::new(Group::GROUP_1, Group::GROUP_1 | Group::GROUP_2); let water_groups = InteractionGroups::new(Group::GROUP_2, Group::GROUP_1 | Group::GROUP_2); let oil_points: Vec> = vec![]; let water_points: Vec> = vec![]; let oil_fluid = Fluid::new(oil_points, 0.05, 800.0, oil_groups); let water_fluid = Fluid::new(water_points, 0.05, 1000.0, water_groups); let allows_interaction = oil_groups.test(water_groups); ``` -------------------------------- ### Apply XSPHViscosity to Fluid Source: https://context7.com/dimforge/salva/llms.txt Implements the XSPH viscosity model to achieve smoother velocity fields and reduced particle disorder. It requires fluid and boundary viscosity parameters. ```rust use salva3d::solver::XSPHViscosity; use salva3d::object::Fluid; use salva3d::object::interaction_groups::InteractionGroups; use nalgebra::Point3; let points: Vec> = vec![]; let mut fluid = Fluid::new(points, 0.05, 1000.0, InteractionGroups::default()); let fluid_viscosity = 0.5; let boundary_viscosity = 1.0; let viscosity = XSPHViscosity::new(fluid_viscosity, boundary_viscosity); fluid.nonpressure_forces.push(Box::new(viscosity)); ``` -------------------------------- ### Apply ArtificialViscosity to Fluid Source: https://context7.com/dimforge/salva/llms.txt Implements a basic viscosity model by defining fluid-fluid and fluid-boundary interaction coefficients. This force is added to the fluid's non-pressure forces collection. ```rust use salva3d::solver::ArtificialViscosity; use salva3d::object::Fluid; use salva3d::object::interaction_groups::InteractionGroups; use nalgebra::Point3; let points: Vec> = vec![]; let mut fluid = Fluid::new(points, 0.05, 1000.0, InteractionGroups::default()); let fluid_viscosity_coefficient = 1.0; let boundary_viscosity_coefficient = 0.0; let viscosity = ArtificialViscosity::new(fluid_viscosity_coefficient, boundary_viscosity_coefficient); fluid.nonpressure_forces.push(Box::new(viscosity)); ``` -------------------------------- ### Apply Akinci2013SurfaceTension to Fluid Source: https://context7.com/dimforge/salva/llms.txt Adds surface tension and adhesion forces to a fluid object. This model uses cohesion and curvature minimization to simulate surface effects. ```rust use salva3d::solver::Akinci2013SurfaceTension; use salva3d::object::Fluid; use salva3d::object::interaction_groups::InteractionGroups; use nalgebra::Point3; let points: Vec> = vec![]; let mut fluid = Fluid::new(points, 0.05, 1000.0, InteractionGroups::default()); let fluid_tension_coefficient = 0.5; let boundary_adhesion_coefficient = 0.3; let surface_tension = Akinci2013SurfaceTension::new(fluid_tension_coefficient, boundary_adhesion_coefficient); fluid.nonpressure_forces.push(Box::new(surface_tension)); ``` -------------------------------- ### Fluid Simulation Pipeline Source: https://context7.com/dimforge/salva/llms.txt API for managing the fluid simulation pipeline, including fluid creation, boundary coupling, and simulation stepping. ```APIDOC ## POST /pipeline/step ### Description Advances the fluid simulation by one time step, calculating forces and updating particle positions and velocities, including interaction with rigid bodies. ### Method POST ### Endpoint /pipeline/step ### Parameters #### Request Body - **gravity** (Vector3) - Required - The gravity vector applied to the simulation. - **dt** (f32) - Required - The time step duration. - **colliders** (ColliderSet) - Required - The set of colliders in the physics world. - **bodies** (RigidBodySet) - Required - The set of rigid bodies in the physics world. ### Response #### Success Response (200) - **status** (String) - Confirmation of simulation step completion. ``` -------------------------------- ### Shape Sampling API Source: https://context7.com/dimforge/salva/llms.txt Endpoints for converting geometric shapes into particle distributions for boundary or fluid initialization. ```APIDOC ## POST /sampling/surface ### Description Generates a set of points distributed on the surface of a given geometric shape using ray-based sampling. ### Method POST ### Endpoint /sampling/surface ### Parameters #### Request Body - **shape** (SharedShape) - Required - The geometric shape (ball, cuboid, capsule, etc.) to sample. - **particle_radius** (f32) - Required - The radius of the particles to be generated. ### Response #### Success Response (200) - **points** (Vec>) - A collection of points representing the surface distribution. --- ## POST /sampling/volume ### Description Generates a set of points filling the interior volume of a given geometric shape. ### Method POST ### Endpoint /sampling/volume ### Parameters #### Request Body - **shape** (SharedShape) - Required - The geometric shape to fill. - **particle_radius** (f32) - Required - The radius of the particles to be generated. ### Response #### Success Response (200) - **points** (Vec>) - A collection of points representing the volume distribution. ``` -------------------------------- ### Apply Becker2009Elasticity to Fluid Source: https://context7.com/dimforge/salva/llms.txt Enables elastic material behavior in fluids using the corotated SPH elasticity model. Configurable via Young's modulus and Poisson ratio. ```rust use salva3d::solver::Becker2009Elasticity; use salva3d::object::Fluid; use salva3d::object::interaction_groups::InteractionGroups; use nalgebra::Point3; let points: Vec> = vec![]; let mut fluid = Fluid::new(points, 0.05, 1.0, InteractionGroups::default()); let young_modulus = 1000.0; let poisson_ratio = 0.3; let nonlinear_strain = true; let elasticity = Becker2009Elasticity::new(young_modulus, poisson_ratio, nonlinear_strain); fluid.nonpressure_forces.push(Box::new(elasticity)); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.