Granular.jl

Julia package for granular dynamics simulation
git clone git://src.adamsgaard.dk/Granular.jl
Log | Files | Refs | README | LICENSE

commit 73163a169378401d89a8448e07ff893b2dbefc18
parent a3cf4e735204a99d2e485473926aa46b4d0c4730
Author: Anders Damsgaard <anders@adamsgaard.dk>
Date:   Mon,  7 May 2018 12:47:19 -0400

Fix irregular packing generation across periodic boundaries

Diffstat:
Msrc/contact_search.jl | 36++++++++++++++++++------------------
Msrc/packing.jl | 2+-
Mtest/packing.jl | 32++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 19 deletions(-)

diff --git a/src/contact_search.jl b/src/contact_search.jl @@ -128,8 +128,8 @@ function findContactsInGrid!(simulation::Simulation, grid::Any) for j=(grid_pos[2] - 1):(grid_pos[2] + 1) # correct indexes if necessary - i_corrected, j_corrected = periodicBoundaryCorrection!(grid, - i, j, distance_modifier) + i_corrected, j_corrected, distance_modifier = + periodicBoundaryCorrection!(grid, i, j) # skip iteration if target still falls outside grid after # periodicity correction @@ -155,14 +155,17 @@ export checkForContacts Perform an O(n*log(n)) cell-based contact search between a candidate grain with position `position` and `radius`, against all grains registered in the `grid`. -Returns the number of contacts that were found as an `Integer` value. +Returns the number of contacts that were found as an `Integer` value, unless +`return_when_overlap_found` is `true`. # Arguments * `simulation::Simulation`: Simulation object containing grain positions. * `grid::Any`: `Ocean` or `Atmosphere` grid containing sorted particles. -* `position::Vector{Float64}`: Candidate center position to probe for contacts - with existing grains [m]. -* `radius::Float64`: Candidate radius [m]. +* `x_candidate::Vector{Float64}`: Candidate center position to probe for + contacts with existing grains [m]. +* `r_candidate::Float64`: Candidate radius [m]. +* `return_when_overlap_found::Bool` (default: `false`): Return `true` if no + contacts are found, or return `false` as soon as a contact is found. """ function checkForContacts(simulation::Simulation, grid::Any, @@ -181,8 +184,8 @@ function checkForContacts(simulation::Simulation, for iy_=(iy - 1):(iy + 1) # correct indexes if necessary - ix_corrected, iy_corrected = - periodicBoundaryCorrection!(grid, ix_, iy_, distance_modifier) + ix_corrected, iy_corrected, distance_modifier = + periodicBoundaryCorrection!(grid, ix_, iy_) # skip iteration if target still falls outside grid after # periodicity correction @@ -192,10 +195,9 @@ function checkForContacts(simulation::Simulation, end @inbounds for idx in grid.grain_list[ix_corrected, iy_corrected] - if norm(simulation.grains[idx].lin_pos - x_candidate + - distance_modifier) - - (simulation.grains[idx].contact_radius + - r_candidate) < 0. + if norm(x_candidate - simulation.grains[idx].lin_pos + + distance_modifier) - + (simulation.grains[idx].contact_radius + r_candidate) < 0.0 if return_when_overlap_found return false @@ -214,18 +216,16 @@ end """ periodicBoundaryCorrection!(grid::Any, i::Integer, j::Integer, - i_corrected::Integer, j_corrected::Integer, - distance_modifier::Vector{Float64}) + i_corrected::Integer, j_corrected::Integer) Determine the geometric correction and grid-index adjustment required across periodic boundaries. """ -function periodicBoundaryCorrection!(grid::Any, i::Integer, j::Integer, - distance_modifier::Vector{Float64}) +function periodicBoundaryCorrection!(grid::Any, i::Integer, j::Integer) # vector for correcting inter-particle distance in case of # boundary periodicity - distance_modifier .= [0., 0.] + distance_modifier = zeros(2) # i and j are not corrected for periodic boundaries i_corrected = i @@ -252,7 +252,7 @@ function periodicBoundaryCorrection!(grid::Any, i::Integer, j::Integer, end end - return i_corrected, j_corrected + return i_corrected, j_corrected, distance_modifier end export checkAndAddContact! diff --git a/src/packing.jl b/src/packing.jl @@ -256,7 +256,7 @@ function irregularPacking!(simulation::Simulation; x_candidate = getPositionDistancedFromPoint(T, x_active, r_active + r_candidate) else - if j <= 2 + if j <= 2 # generate large grains during the first two samples x_candidate, r_candidate = generateNeighboringPoint( x_active, r_active, diff --git a/test/packing.jl b/test/packing.jl @@ -86,6 +86,38 @@ Granular.irregularPacking!(sim, verbose=verbose) @test length(sim.grains) > 280 +Compat.@info "Testing irregular packing with inactive boundaries" +sim = Granular.createSimulation("poisson-inactive") +sim.ocean = Granular.createRegularOceanGrid([5, 5, 1], [1., 1., 1.]) +Granular.setGridBoundaryConditions!(sim.ocean, "inactive", verbose=verbose) +Granular.irregularPacking!(sim, + radius_max=.05, + radius_min=.1, + padding_factor=0., + plot_during_packing=plot_packings, + verbose=verbose) +Granular.findContacts!(sim, method="ocean grid") +plot && Granular.plotGrains(sim, filetype="poisson-inactive.png", show_figure=false) +for grain in sim.grains + @test grain.n_contacts == 0 +end + +Compat.@info "Testing irregular packing with periodic boundaries" +sim = Granular.createSimulation("poisson-periodic") +sim.ocean = Granular.createRegularOceanGrid([5, 5, 1], [1., 1., 1.]) +Granular.setGridBoundaryConditions!(sim.ocean, "periodic", verbose=verbose) +Granular.irregularPacking!(sim, + radius_max=.05, + radius_min=.1, + padding_factor=0., + plot_during_packing=plot_packings, + verbose=verbose) +plot && Granular.plotGrains(sim, filetype="poisson-periodic.png", show_figure=false) +Granular.findContacts!(sim, method="ocean grid") +for grain in sim.grains + @test grain.n_contacts == 0 +end + Compat.@info "Testing raster-based mapping algorithm" sim = Granular.createSimulation("raster-packing1")