Granular.jl

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

commit 6c9c0d321169a8fa21b710f65950bdc82c0b5946
parent 342a88008ca72de30d15bd12570db7e180f928af
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:
Msrc/simulation.jl | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/contact-search-and-geometry.jl | 23+++++++++++++++++++++++
2 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/src/simulation.jl b/src/simulation.jl @@ -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 diff --git a/test/contact-search-and-geometry.jl b/test/contact-search-and-geometry.jl @@ -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