tAdd function to produce rasterized map of grain coverage - Granular.jl - Julia package for granular dynamics simulation
 (HTM) git clone git://src.adamsgaard.dk/Granular.jl
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit bcc9daa32ee17a31b2576133f546cb19890c539e
 (DIR) parent f7da3ebd8db4dbfa61ca5c0ae22391cff43e8644
 (HTM) Author: Anders Damsgaard <andersd@riseup.net>
       Date:   Wed, 24 Jan 2018 11:03:42 -0500
       
       Add function to produce rasterized map of grain coverage
       
       Diffstat:
         M src/packing.jl                      |      65 +++++++++++++++++++++++++++++++
         M test/packing.jl                     |      43 ++++++++++++++++++++++++++++++
       
       2 files changed, 108 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/src/packing.jl b/src/packing.jl
       t@@ -307,3 +307,68 @@ function irregularPacking!(simulation::Simulation;
                info("Generated $(length(simulation.grains) - np_init) points")
            end
        end
       +
       +"""
       +    rasterMap(sim, dx)
       +
       +Returns a rasterized map of grain extent in the domain with length `L` and a
       +pixel size of `dx`. The function will return a map of `Bool` type with size
       +`floor.(L./dx)`.
       +
       +* Arguments
       +- `sim::Simulation`: simulation object containing the grains.
       +- `dx::Real`: pixel size to use for the raster map.
       +
       +"""
       +function rasterMap(sim::Simulation, dx::Real)
       +
       +    # Use existing `grid` (ocean or atmosphere) for contact search
       +    if typeof(sim.ocean.input_file) != Bool
       +        grid = sim.ocean
       +    elseif typeof(sim.atmosphere.input_file) != Bool
       +        grid = sim.atmosphere
       +    else
       +        error("rasterMap(...) requires an ocean or atmosphere grid")
       +    end
       +    # save grid boundaries
       +    if grid.regular_grid
       +        L = grid.L[1:2]
       +        origo = grid.origo
       +    else
       +        sw, se, ne, nw = getGridCornerCoordinates(grid.xq, grid.yq)
       +        L = [se[1] - sw[1], nw[2] - sw[2]]
       +        origo = [sw[1], sw[2]]
       +    end
       +    const dims = floor.(L./dx)
       +    occupied = zeros(Bool, dims[1], dims[2])
       +
       +    # Loop over existing grains and mark their extent in the `occupied` array
       +    i = 0; j = 0
       +    min_i = 0; min_j = 0
       +    max_i = 0; max_j = 0
       +    cell_mid_point = zeros(2)
       +    for grain in sim.grains
       +        
       +        # Find center position in `occupied` grid
       +        #i, j = Int.(floor.((grain.lin_pos - origo) ./ dx)) + [1,1]
       +
       +        # Find corner indexes for box spanning the grain
       +        min_i, min_j = Int.(floor.((grain.lin_pos - origo -
       +                                    grain.contact_radius) ./ dx)) + [1,1]
       +        max_i, max_j = Int.(floor.((grain.lin_pos - origo +
       +                                    grain.contact_radius) ./ dx)) + [1,1]
       +
       +        # For each cell in box, check if the grain is contained
       +        for i = min_i:max_i
       +            for j = min_j:max_j
       +                cell_mid_point = dx .* Vector{Float64}([i,j]) - 0.5 * dx
       +
       +                if (norm(cell_mid_point - grain.lin_pos) -
       +                    grain.contact_radius < 0.5*dx)
       +                    occupied[i,j] = true
       +                end
       +            end
       +        end
       +    end
       +    return occupied
       +end
 (DIR) diff --git a/test/packing.jl b/test/packing.jl
       t@@ -82,3 +82,46 @@ Granular.irregularPacking!(sim,
                                   plot_during_packing=plot_packings,
                                   verbose=verbose)
        @test length(sim.grains) > 280
       +
       +
       +info("Testing raster-based packing algorithm")
       +sim = Granular.createSimulation("raster-packing1")
       +sim.ocean = Granular.createRegularOceanGrid([1, 1, 1], [1., 1., 1.])
       +Granular.addGrainCylindrical!(sim, [0.5, 0.5], 0.4, 1.0)
       +occupied = Granular.rasterMap(sim, 0.08)
       +occupied_ans = Array{Bool}([
       +0 0 0 0 0 0 0 0 0 0 0 0;
       +0 0 0 1 1 1 1 1 1 0 0 0;
       +0 0 1 1 1 1 1 1 1 1 0 0;
       +0 1 1 1 1 1 1 1 1 1 1 0;
       +0 1 1 1 1 1 1 1 1 1 1 0;
       +0 1 1 1 1 1 1 1 1 1 1 1;
       +0 1 1 1 1 1 1 1 1 1 1 1;
       +0 1 1 1 1 1 1 1 1 1 1 1;
       +0 1 1 1 1 1 1 1 1 1 1 0;
       +0 0 1 1 1 1 1 1 1 1 1 0;
       +0 0 0 1 1 1 1 1 1 1 0 0;
       +0 0 0 0 0 1 1 1 0 0 0 0])
       +@test occupied == occupied_ans
       +Granular.addGrainCylindrical!(sim, [0.03, 0.03], 0.02, 1.0)
       +occupied = Granular.rasterMap(sim, 0.08)
       +occupied_ans = Array{Bool}([
       +1 0 0 0 0 0 0 0 0 0 0 0;
       +0 0 0 1 1 1 1 1 1 0 0 0;
       +0 0 1 1 1 1 1 1 1 1 0 0;
       +0 1 1 1 1 1 1 1 1 1 1 0;
       +0 1 1 1 1 1 1 1 1 1 1 0;
       +0 1 1 1 1 1 1 1 1 1 1 1;
       +0 1 1 1 1 1 1 1 1 1 1 1;
       +0 1 1 1 1 1 1 1 1 1 1 1;
       +0 1 1 1 1 1 1 1 1 1 1 0;
       +0 0 1 1 1 1 1 1 1 1 1 0;
       +0 0 0 1 1 1 1 1 1 1 0 0;
       +0 0 0 0 0 1 1 1 0 0 0 0])
       +@test occupied == occupied_ans
       +
       +#Granular.rasterPacking!(sim,
       +                           #radius_max=.01,
       +                           #radius_min=.01,
       +                           #verbose=verbose)
       +