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