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:
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")