Skip to content

dineshadepu/simple_shapes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Create simple shapes in particle methods

Table of Contents

What is this?

This library is used to generate simple geometries made of particles, for example tank, a particles block. It is heavily used in prestige.

Examples

Stack of cylinders collapsing

Figure ref:fig:cylinders_collapse is taken from cite:zhang-2009-simul-solid. The geometry we are trying to simulate is

./figures/cylinders_collapse.png

We need to create a total of six layers of cylinders with five or six cylinders in each row. We will number layers from bottom. The bottom row is one, then two and so on.

First we will create the bottom layer, then the second layer, then copy the bottom layer and increase its y coordinate such that it is on top of second layer. Write these functions in src/benchmarks.rs so that it can be reused.

use crate::{tank_2d, circle_2d};
/// Create stack of cylinders as in the benchmark of Zhang
pub fn create_cylinders_zhang(spacing: f32) -> (Vec<f32>, Vec<f32>, Vec<usize>) {
    // We follow three steps while creating the geometry
    // - Create bottom layer
    // - Create bottom second layer
    // - Create bottom third layer

    // ---------------------------------------
    // Create bottom layer
    // create a cylinder in 2d (that would be a circle),
    let diameter = 0.01; // in meters
    let (xc1, yc1) = circle_2d(
        (diameter / 2. + spacing, diameter / 2. + spacing),
        diameter / 2.,
        spacing,
    );

    // get the number of particles in cylinder to compute the body id later
    let no_of_particles = xc1.len();

    let xc2: Vec<_> = xc1.iter().map(|&i| i + diameter + spacing / 2.).collect();
    let yc2 = yc1.clone();
    let xc3: Vec<_> = xc2.iter().map(|&i| i + diameter + spacing / 2.).collect();
    let yc3 = yc1.clone();
    let xc4: Vec<_> = xc3.iter().map(|&i| i + diameter + spacing / 2.).collect();
    let yc4 = yc1.clone();
    let xc5: Vec<_> = xc4.iter().map(|&i| i + diameter + spacing / 2.).collect();
    let yc5 = yc1.clone();
    let xc6: Vec<_> = xc5.iter().map(|&i| i + diameter + spacing / 2.).collect();
    let yc6 = yc1.clone();
    let x_layer_1 = [&xc1[..], &xc2[..], &xc3[..], &xc4[..], &xc5[..], &xc6[..]].concat();
    let y_layer_1 = [&yc1[..], &yc2[..], &yc3[..], &yc4[..], &yc5[..], &yc6[..]].concat();
    // ---------------------------------------

    // ---------------------------------------
    // Create second bottom layer
    let (xc1, yc1) = circle_2d(
        (diameter + spacing, 1.5 * diameter + spacing),
        diameter / 2.,
        spacing,
    );
    let xc2: Vec<_> = xc1.iter().map(|&i| i + diameter + spacing / 2.).collect();
    let yc2 = yc1.clone();
    let xc3: Vec<_> = xc2.iter().map(|&i| i + diameter + spacing / 2.).collect();
    let yc3 = yc1.clone();
    let xc4: Vec<_> = xc3.iter().map(|&i| i + diameter + spacing / 2.).collect();
    let yc4 = yc1.clone();
    let xc5: Vec<_> = xc4.iter().map(|&i| i + diameter + spacing / 2.).collect();
    let yc5 = yc1.clone();
    let x_layer_2 = [&xc1[..], &xc2[..], &xc3[..], &xc4[..], &xc5[..]].concat();
    let y_layer_2 = [&yc1[..], &yc2[..], &yc3[..], &yc4[..], &yc5[..]].concat();

    // ---------------------------------------
    // Create third bottom layer
    let x_layer_3 = x_layer_1.clone();
    let y_layer_3 = y_layer_1
        .iter()
        .map(|&i| i + 2. * diameter + spacing / 2.)
        .collect::<Vec<_>>();

    // ---------------------------------------
    // ---------------------------------------
    // Create fourth bottom layer
    let x_layer_4 = x_layer_2.clone();
    let y_layer_4 = y_layer_2
        .iter()
        .map(|&i| i + 2. * diameter + spacing / 2.)
        .collect::<Vec<_>>();

    // Create fifth bottom layer
    let x_layer_5 = x_layer_3.clone();
    let y_layer_5 = y_layer_3
        .iter()
        .map(|&i| i + 2. * diameter + spacing / 2.)
        .collect::<Vec<_>>();

    // Create sixth bottom layer
    let x_layer_6 = x_layer_4.clone();
    let y_layer_6 = y_layer_4
        .iter()
        .map(|&i| i + 2. * diameter + spacing / 2.)
        .collect::<Vec<_>>();

    let x_all = [
        &x_layer_1[..],
        &x_layer_2[..],
        &x_layer_3[..],
        &x_layer_4[..],
        &x_layer_5[..],
        &x_layer_6[..],
    ]
        .concat();
    let y_all = [
        &y_layer_1[..],
        &y_layer_2[..],
        &y_layer_3[..],
        &y_layer_4[..],
        &y_layer_5[..],
        &y_layer_6[..],
    ]
        .concat();

    // create body id of each cylinder
    let no_of_cylinders = 3 * 6 + 3 * 5;
    let mut b_id = vec![];

    for i in 0..no_of_cylinders{
        b_id.extend_from_slice(&vec![i; no_of_particles]);
    }

    (x_all, y_all, b_id)
}

/// Create geometry as in the benchmark of Zhang solid bodies
pub fn create_zhang_geometry(spacing: f32) -> (Vec<f32>, Vec<f32>, Vec<usize>, Vec<f32>, Vec<f32>){
    // get the x, y and body id vectors
    let (xc, yc, bid) = create_cylinders_zhang(spacing);
    // create the tank
    let layers = 3;
    // create a tank with 26 cm length, 26 cm height
    let (xt, yt) = tank_2d(
        0.0, 0.26 + spacing / 2., spacing, 0.0,
        0.26 + spacing / 2., spacing, layers, true);

    (xc, yc, bid, xt, yt)
}

using these functions, we can visualize by creating an example. The code looks like

extern crate simple_shapes;
extern crate vtkio;

use simple_shapes::{create_zhang_geometry, Entity};

fn main() {
    let spacing = 0.001;

    let (xc, yc, _, xt, yt) = create_zhang_geometry(spacing);

    let tank = Entity::from_xyz_rad(
        xt.clone(),
        yt,
        vec![0.; xt.len()],
        vec![spacing / 2.; xt.len()],
    );
    let circle = Entity::from_xyz_rad(
        xc.clone(),
        yc,
        vec![0.; xc.len()],
        vec![spacing / 2.; xc.len()],
    );

    circle.write_vtk("zhang_circles.vtk");
    tank.write_vtk("zhang_tank.vtk");
}

Run the example by

cargo --release --example zhang_collapsing_cylinders

Which will generate two files in the root directory with names zhang_circles.vtk and zhang_tank.vtk. Visualize them in paraview or your favorite visualizer. (The format of the vtk file is unstructured).

About

No description, website, or topics provided.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages