tAdd method to change the maximum number of contacts with reallocation - 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 6c9c0d321169a8fa21b710f65950bdc82c0b5946
 (DIR) parent 342a88008ca72de30d15bd12570db7e180f928af
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Wed,  8 Aug 2018 16:36:49 +0200
       
       Add method to change the maximum number of contacts with reallocation
       
       Diffstat:
         M src/simulation.jl                   |      59 +++++++++++++++++++++++++++++++
         M test/contact-search-and-geometry.jl |      23 +++++++++++++++++++++++
       
       2 files changed, 82 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/src/simulation.jl b/src/simulation.jl
       t@@ -347,3 +347,62 @@ function reportMemory(variable, head::String, tail::String="")
            @printf("%-20s %s %s\n", head, size_str, tail)
            nothing
        end
       +
       +export setMaximumNumberOfContactsPerGrain!
       +"""
       +    setMaximumNumberOfContactsPerGrain!(simulation, number_of_contacts)
       +
       +Change the maximum number of contacts per grain, which changes simulation.Nc_max
       +and reallocates memory for each grain. Larger values require more memory, but
       +allow simulation of wider grain-size distributions. The default value is a
       +maximum of 32 contacts per grain, which is sufficient for most practical
       +purposes.
       +
       +# Arguments
       +* `simulation::Simulation`: the Simulation object to modify
       +* `number_of_contacts::Int`: the maximum number of contacts per grain to allow.
       +"""
       +function setMaximumNumberOfContactsPerGrain!(sim::Simulation,
       +                                             number_of_contacts::Int)
       +
       +    if number_of_contacts < 1
       +        error("the parameter number_of_contacts must be a positive integer, " *
       +              "but has the value '$number_of_contacts'")
       +    end
       +    if number_of_contacts == sim.Nc_max
       +        error("number_of_contacts equals the current number of contacts " *
       +              "sim.Nc_max = $(sim.Nc_max)")
       +    end
       +
       +    Nc_max_orig = sim.Nc_max
       +    sim.Nc_max = number_of_contacts
       +    diff = sim.Nc_max - Nc_max_orig
       +
       +    for grain in sim.grains
       +
       +        if diff > 0
       +            # push values to the end of contact arrays if Nc_max > Nc_max_orig
       +            for i=1:diff
       +                push!(grain.contacts, 0)
       +                push!(grain.position_vector, zeros(Float64, 3))
       +                push!(grain.contact_parallel_displacement, zeros(Float64, 3))
       +                push!(grain.contact_rotation, zeros(Float64, 3))
       +                push!(grain.contact_age, 0.0)
       +                push!(grain.contact_area, 0.0)
       +                push!(grain.compressive_failure, false)
       +            end
       +
       +        else
       +            # pop values from the end of contact arrays if Nc_max < Nc_max_orig
       +            for i=1:abs(diff)
       +                pop!(grain.contacts)
       +                pop!(grain.position_vector)
       +                pop!(grain.contact_parallel_displacement)
       +                pop!(grain.contact_rotation)
       +                pop!(grain.contact_age)
       +                pop!(grain.contact_area)
       +                pop!(grain.compressive_failure)
       +            end
       +        end
       +    end
       +end
 (DIR) diff --git a/test/contact-search-and-geometry.jl b/test/contact-search-and-geometry.jl
       t@@ -300,3 +300,26 @@ for j=2:(ny-1)
                @test sim.grains[idx].n_contacts == 4
            end
        end
       +
       +Compat.@info "Test changes to the max. number of contacts"
       +sim = Granular.createSimulation()
       +nx = 60; ny = 50
       +Granular.regularPacking!(sim, [nx, ny], 1., 1., padding_factor=0,
       +                         tiling="square")
       +@test 32 == sim.Nc_max
       +@test_throws ErrorException Granular.setMaximumNumberOfContactsPerGrain!(sim, 0)
       +@test_throws ErrorException Granular.setMaximumNumberOfContactsPerGrain!(sim,-1)
       +@test_throws ErrorException Granular.setMaximumNumberOfContactsPerGrain!(sim,32)
       +
       +for Nc_max in [4, 32, 33, 100, 1]
       +    info("Nc_max = $Nc_max")
       +    Granular.setMaximumNumberOfContactsPerGrain!(sim, Nc_max)
       +    for grain in sim.grains
       +        @test length(grain.contacts) == Nc_max
       +        @test length(grain.position_vector) == Nc_max
       +        @test length(grain.contact_rotation) == Nc_max
       +        @test length(grain.contact_age) == Nc_max
       +        @test length(grain.contact_area) == Nc_max
       +        @test length(grain.compressive_failure) == Nc_max
       +    end
       +end