Skip to content

Heterarchical Granular Dynamics

A python package for simulating the motion of a granular material as a result of the motion of voids. In particular, it (currently) models non-inertial problems quite well. In particular, segregation is well modelled for several systems.

Code style: black

Installation

  1. Download and unzip (or clone) this repository
  2. Install python 3.11 or newer
  3. Install the required python packages with pip install -e .
  4. Set up your pre-commit hooks (so that when you make changes things are kept nice and clean) by running pre-commit install
  5. Run the code with python HGD/main.py json/collapse.json5. The parameters for this specific case are stored in json/collapse.json5. Change that file name to a different json5 file to use those values instead.

Documentation

You can read the docs here.

Authors

Usage

The code is run by calling python void_migration/main.py <json5 file>. The parameters for the simulation are stored in the json5 file. The default parameters, contained in defaults.json5 are as follows:

{
    // resolution
    nx : 10, // number of cells horizontally
    ny : 10, // number of cells vertically
    nm : 10,  // number of cells in internal direction
    P_stab : 0.5, // maximum probability to allow for stability


    // geometry
    H : 1, // physical height of the system (m)
    theta : 0, // angle of gravity (0 is vertical, degrees)
    g : 9.81, // gravitational acceleration (m/s^2)
    boundaries : [], // "central_outlet", "multiple_outlets", "slope", "mara" or "pour"
    masks: [], // list of masks to be used in the simulation
    internal_geometry : false, // true if internal geometry is present, currently defined only for a single case
    cyclic_BC : false, // true if cyclic BCs are used horizontally
    cyclic_BC_y_angle : 0, // angle of the cyclic BCs (degrees)
    refill : false, // should the particles come back in the top if they leave the bottom
    outlet_rate : 1.0, // proportion of each timestep that the outlet is open
    outlet_nu : 0, // solid fraction of the particles in the outlet
    wall_motion : false, // should the walls move

    // void migration model parameters
    diag : 0,
    lagrangian : false,
    close_voids : false, // should the voids be closed after some time
    max_diff_swap_length : 1, // maximum length of a diffusion swap
    slope_stability_model : 'gradient', // 'stress' or 'gradient'

    // material properties
    repose_angle : 30, // (degrees)
    gsd_mode : 'bi', // 'mono', 'bi' or 'poly'
    large_concentration: 0.5, // concentration of large particles for bidisperse case
    s_m : 0.0005, // minimum particle size (m)
    nu_cs : 0.5, // critical state solid volume fraction
    alpha : 4, // diffusivity parameter

    // initial condition
    fill_ratio : 0.25, // ratio of the domain that is filled with particles
    nu_fill : 0.5, // solid fraction of the particles in the initial condition
    IC_mode : "column", // where should the initial particles be, "column", "random", "top", "full" or "empty"

    // temperature
    calculate_temperature : false, // should the temperature be calculated
    T_init : 20, // initial temperature (C)

    // stress
    calculate_stress : false, // should the stress be calculated
    stress_mode : 'active', // 'isotropic', 'active', 'passive', 'K_0' or 'anisotropic'
    solid_density : 2700, // density of the solid particles (kg/m^3/m)
    wall_friction_angle : 30, // friction coefficient between the walls and the particles

    // saving
    folderName : "output/", // name of the folder to save the data in
    save_inc : 1, // how often to save the state of the system (timesteps)
    t_f : 5,  // final time to end the simulation (s)
    plot : ['nu', 's'], // which variables to plot. Should at least include the ones to make videos.
    videos : ['nu','s'], // which variables to save videos of.
    save : [], // which variables to save. By default none.
    mask_s_bar : false, // should the images of s_bar be masked to hide areas of low density
    plot_colorbar : false, // should the colorbar be plotted

    // density pressure model
    nu_cs_mode : 'constant', // 'dynamic' or 'constant'
    lambda_nu : 10, // rate of change of nu_cs
    nu_1 : 0.5, // value of nu_cs at (or below) 1 kPa
    point_load : false,
    pad_width : 0.05, // width of the pad (m)

    // parallel code
    max_workers : 5, // max number of workers to run simultaneously. Default value is actually set void_migration.py

    motion_model : 'd2q4_array_v2', // 'd2q4_slow', 'd2q4_array' or 'd2q9_slow'
    advection_model : 'freefall', // 'average_size', 'freefall' or 'stress'
    inertia : false, // should the inertia term be included

    // cycles
    cycles : [], // list of dicts that define any cycles
    inlet : 0, // amount of material added this cycle
    outlet : 0, // amount of material removed this cycle
    cycle_forever : false, // should the cycles be repeated indefinitely
    charge_rate : 1, // rate of charge zone filling (kg/s)
    sigma_charge : 0.1, // relative width of charge zone
    elutriation : false, // should elutriation be used

    // stopping
    stop_event : null, // this is None in Python, but null in JavaScript
    stop_after : 100, // number of timesteps to run with nothing happening before stopping
    stopped_times : 0, // number of times the system has stopped

    // diagnostics
    show_optimal_resolution : false, // should the optimal resolution be shown on the screen at runtime

    gui : null, // this is None in Python, but null in JavaScript
    queue: null,
    queue2: null,
}