Granular.jl

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

commit 2ab3e5cc94c45a4baff6d1e5ca769c3eeebe0309
parent c0fa76fc348cd9d1285191817827717f951e26cb
Author: Anders Damsgaard <andersd@riseup.net>
Date:   Thu, 22 Feb 2018 15:40:28 -0500

Add additional bond tests and fix bond problems

Diffstat:
Msrc/interaction.jl | 13++++++++-----
Mtest/cohesion.jl | 143++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 142 insertions(+), 14 deletions(-)

diff --git a/src/interaction.jl b/src/interaction.jl @@ -238,12 +238,12 @@ function interactGrains!(simulation::Simulation, i::Int, j::Int, ic::Int) if tensile_strength > 0.0 # Determine bending momentum on contact [N*m], # (converting k_n to E to bar(k_n)) - M_t = -(k_n*R_ij/(A_ij*(simulation.grains[i].contact_radius + - simulation.grains[j].contact_radius)))*I_ij*θ_t + M_t = (k_n*R_ij/(A_ij*(simulation.grains[i].contact_radius + + simulation.grains[j].contact_radius)))*I_ij*θ_t end # Reset contact age (breaking bond) if bond strength is exceeded - if δ_n > 0.0 && abs(force_n)/A_ij + abs(M_t)*R_ij/I_ij > tensile_strength + if δ_n >= 0.0 && abs(force_n)/A_ij + abs(M_t)*R_ij/I_ij > tensile_strength force_n = 0. force_t = 0. simulation.grains[i].contacts[ic] = 0 # remove contact @@ -252,7 +252,7 @@ function interactGrains!(simulation::Simulation, i::Int, j::Int, ic::Int) end # Limit compressive stress if the prefactor is set to a positive value - if δ_n < 0.0 && compressive_strength > 0. && + if δ_n <= 0.0 && compressive_strength > 0. && abs(force_n) >= compressive_strength # Determine the overlap distance where yeild stress is reached @@ -311,7 +311,10 @@ function interactGrains!(simulation::Simulation, i::Int, j::Int, ic::Int) error("unknown contact_tangential_rheology (k_t = $k_t, γ_t = $γ_t") end - if shear_strength > 0.0 && abs(force_t)/A > shear_strength + # Break bond under extension through bending failure + if δ_n < 0.0 && tensile_strength > 0.0 && shear_strength > 0.0 && + abs(force_t)/A_ij > shear_strength + force_n = 0. force_t = 0. simulation.grains[i].contacts[ic] = 0 # remove contact diff --git a/test/cohesion.jl b/test/cohesion.jl @@ -38,17 +38,142 @@ Granular.run!(sim, verbose=verbose) @test sim.grains[1].ang_vel ≈ 0. @test sim.grains[2].ang_vel ≈ 0. -info("# Add shear strength") +info("# Add shear strength and test bending resistance (one grain rotating)") sim = Granular.createSimulation(id="cohesion") -Granular.addGrainCylindrical!(sim, [0., 0.], 10., 1., tensile_strength=500e3) -Granular.addGrainCylindrical!(sim, [20.1, 0.], 10., 1., tensile_strength=500e3) -sim.grains[1].lin_vel[1] = 0.1 +Granular.addGrainCylindrical!(sim, [0., 0.], 10.1, 1., tensile_strength=500e3, + shear_strength=500e3) +Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, + shear_strength=500e3) +sim.grains[1].ang_vel = 0.1 +Granular.findContacts!(sim) # make sure contact is registered +sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression +E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(sim) Granular.setTimeStep!(sim) -Granular.setTotalTime!(sim, 10.) +Granular.setTotalTime!(sim, 5.) +#Granular.setOutputFileInterval!(sim, 0.1) Granular.run!(sim, verbose=verbose) -@test sim.grains[1].lin_vel[1] > 0. +@test sim.grains[1].lin_vel[1] ≈ 0. @test sim.grains[1].lin_vel[2] ≈ 0. -@test sim.grains[2].lin_vel[1] > 0. +@test sim.grains[2].lin_vel[1] ≈ 0. @test sim.grains[2].lin_vel[2] ≈ 0. -@test sim.grains[1].ang_vel ≈ 0. -@test sim.grains[2].ang_vel ≈ 0. +@test sim.grains[1].ang_vel != 0. +@test sim.grains[2].ang_vel != 0. +E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) +E_therm_final = Granular.totalGrainThermalEnergy(sim) +@test E_kin_lin_init ≈ E_kin_lin_final +@test E_kin_rot_init > E_kin_rot_final + E_therm_final + +info("# Add shear strength and test bending resistance (one grain rotating)") +sim = Granular.createSimulation(id="cohesion") +Granular.addGrainCylindrical!(sim, [0., 0.], 10.1, 1., tensile_strength=500e3, + shear_strength=500e3) +Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, + shear_strength=500e3) +sim.grains[2].ang_vel = 0.1 +Granular.findContacts!(sim) # make sure contact is registered +sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression +E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(sim) +Granular.setTimeStep!(sim) +Granular.setTotalTime!(sim, 5.) +#Granular.setOutputFileInterval!(sim, 0.1) +Granular.run!(sim, verbose=verbose) +@test sim.grains[1].lin_vel[1] ≈ 0. +@test sim.grains[1].lin_vel[2] ≈ 0. +@test sim.grains[2].lin_vel[1] ≈ 0. +@test sim.grains[2].lin_vel[2] ≈ 0. +@test sim.grains[1].ang_vel != 0. +@test sim.grains[2].ang_vel != 0. +E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) +E_therm_final = Granular.totalGrainThermalEnergy(sim) +@test E_kin_lin_init ≈ E_kin_lin_final +@test E_kin_rot_init > E_kin_rot_final + E_therm_final + +info("# Add shear strength and test bending resistance (both grains rotating)") +sim = Granular.createSimulation(id="cohesion") +Granular.addGrainCylindrical!(sim, [0., 0.], 10.0000001, 1., tensile_strength=500e3, + shear_strength=500e3) +Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, + shear_strength=500e3) +sim.grains[1].ang_vel = 0.1 +sim.grains[2].ang_vel = -0.1 +Granular.findContacts!(sim) # make sure contact is registered +sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression +E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(sim) +Granular.setTimeStep!(sim) +Granular.setTotalTime!(sim, 5.) +#Granular.setOutputFileInterval!(sim, 0.1) +Granular.run!(sim, verbose=verbose) +@test sim.grains[1].lin_vel[1] ≈ 0. +@test sim.grains[1].lin_vel[2] ≈ 0. +@test sim.grains[2].lin_vel[1] ≈ 0. +@test sim.grains[2].lin_vel[2] ≈ 0. +@test sim.grains[1].ang_vel != 0. +@test sim.grains[2].ang_vel != 0. +E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) +E_therm_final = Granular.totalGrainThermalEnergy(sim) +@test E_kin_lin_init ≈ E_kin_lin_final +@test E_kin_rot_init > E_kin_rot_final + E_therm_final + +info("# Break bond through bending I") +sim = Granular.createSimulation(id="cohesion") +Granular.addGrainCylindrical!(sim, [0., 0.], 10.0000001, 1., tensile_strength=500e3, + shear_strength=500e3) +Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, + shear_strength=500e3) +sim.grains[1].ang_vel = 100 +sim.grains[2].ang_vel = -100 +Granular.findContacts!(sim) # make sure contact is registered +sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression +E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(sim) +Granular.setTimeStep!(sim) +Granular.setTotalTime!(sim, 5.) +#Granular.setOutputFileInterval!(sim, 0.1) +Granular.run!(sim, verbose=verbose) +@test sim.grains[1].lin_vel[1] ≈ 0. +@test sim.grains[1].lin_vel[2] ≈ 0. +@test sim.grains[2].lin_vel[1] ≈ 0. +@test sim.grains[2].lin_vel[2] ≈ 0. +@test sim.grains[1].ang_vel != 0. +@test sim.grains[2].ang_vel != 0. +E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) +E_therm_final = Granular.totalGrainThermalEnergy(sim) +@test E_kin_lin_init ≈ E_kin_lin_final +@test sim.grains[1].n_contacts == 0 +@test sim.grains[2].n_contacts == 0 + +info("# Break bond through bending II") +sim = Granular.createSimulation(id="cohesion") +Granular.addGrainCylindrical!(sim, [0., 0.], 10.1, 1., tensile_strength=500e3, + shear_strength=50e3) +Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, + shear_strength=50e3) +sim.grains[1].ang_vel = 100 +sim.grains[2].ang_vel = 0.0 +Granular.findContacts!(sim) # make sure contact is registered +sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression +E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(sim) +Granular.setTimeStep!(sim) +Granular.setTotalTime!(sim, 5.) +#Granular.setOutputFileInterval!(sim, 0.1) +Granular.run!(sim, verbose=verbose) +@test sim.grains[1].lin_vel[1] ≈ 0. +@test sim.grains[1].lin_vel[2] ≈ 0. +@test sim.grains[2].lin_vel[1] ≈ 0. +@test sim.grains[2].lin_vel[2] ≈ 0. +@test sim.grains[1].ang_vel != 0. +@test sim.grains[2].ang_vel != 0. +E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) +E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) +E_therm_final = Granular.totalGrainThermalEnergy(sim) +@test E_kin_lin_init ≈ E_kin_lin_final +@test sim.grains[1].n_contacts == 0 +@test sim.grains[2].n_contacts == 0