Granular.jl

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

commit 7fe5b27334a798544f5a5ae76b8c259026d37e65
parent b4856096f45707589baa494ad735de2128f7ec35
Author: Anders Damsgaard <andersd@riseup.net>
Date:   Wed, 24 May 2017 15:09:43 -0400

Use Young's modulus and Poisson's ratio by default for contact mechanics

Diffstat:
Msrc/icefloe.jl | 5+++--
Msrc/interaction.jl | 70++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/temporal.jl | 19+++++++++++++++----
Mtest/collision-2floes-oblique.jl | 22++++++++++++----------
Mtest/vtk.jl | 2+-
5 files changed, 77 insertions(+), 41 deletions(-)

diff --git a/src/icefloe.jl b/src/icefloe.jl @@ -21,13 +21,14 @@ function addIceFloeCylindrical(simulation::Simulation, ang_acc::float = 0., torque::float = 0., density::float = 934., - contact_stiffness_normal::float = 1.e6, + contact_stiffness_normal::float = 1e7, contact_stiffness_tangential::float = 0., contact_viscosity_normal::float = 0., contact_viscosity_tangential::float = 0., contact_static_friction::float = 0.4, contact_dynamic_friction::float = 0.4, - youngs_modulus::float = 2e9, # Hopkins 2004 + youngs_modulus::float = 2e7, + #youngs_modulus::float = 2e9, # Hopkins 2004 poissons_ratio::float = 0.185, # Hopkins 2004 tensile_strength::float = 500e3, # Hopkins 2004 compressive_strength_prefactor::float = 1285e3, diff --git a/src/interaction.jl b/src/interaction.jl @@ -33,9 +33,14 @@ end export interactIceFloes! """ + interactIceFloes!(simulation::Simulation, i::Int, j::Int, ic::Int) + Resolve an grain-to-grain interaction using a prescibed contact law. This function adds the compressive force of the interaction to the ice floe `pressure` field of mean compressive stress on the ice floe sides. + +The function uses the macroscopic contact parameterization based on Young's +modulus and Poisson's ratio if Young's modulus is a positive value. """ function interactIceFloes!(simulation::Simulation, i::Int, j::Int, ic::Int) @@ -80,19 +85,37 @@ function interactIceFloes!(simulation::Simulation, i::Int, j::Int, ic::Int) abs(delta_n)/2. # Contact mechanical parameters - k_n_harmonic_mean = - harmonicMean(simulation.ice_floes[i].contact_stiffness_normal, - simulation.ice_floes[j].contact_stiffness_normal) - - k_t_harmonic_mean = - harmonicMean(simulation.ice_floes[i].contact_stiffness_tangential, - simulation.ice_floes[j].contact_stiffness_tangential) + if simulation.ice_floes[i].youngs_modulus > 0. && + simulation.ice_floes[j].youngs_modulus > 0. + + E = harmonicMean(simulation.ice_floes[i].youngs_modulus, + simulation.ice_floes[j].youngs_modulus) + ν = harmonicMean(simulation.ice_floes[i].poissons_ratio, + simulation.ice_floes[j].poissons_ratio) + + # Contact area + A_ij = R_ij*min(simulation.ice_floes[i].thickness, + simulation.ice_floes[j].thickness) + + # Effective normal and tangential stiffness + k_n = E*A_ij/R_ij + #k_t = k_n*ν # Kneib et al 2016 + k_t = k_n*2.*(1. - ν^2.)/((2. - ν)*(1. + ν)) # Obermayr et al 2011 + + else # Micromechanical parameterization: k_n and k_t set explicitly + k_n = harmonicMean(simulation.ice_floes[i].contact_stiffness_normal, + simulation.ice_floes[j].contact_stiffness_normal) + + k_t = + harmonicMean(simulation.ice_floes[i].contact_stiffness_tangential, + simulation.ice_floes[j].contact_stiffness_tangential) + end - gamma_n_harmonic_mean = harmonicMean( + gamma_n = harmonicMean( simulation.ice_floes[i].contact_viscosity_normal, simulation.ice_floes[j].contact_viscosity_normal) - gamma_t_harmonic_mean = harmonicMean( + gamma_t = harmonicMean( simulation.ice_floes[i].contact_viscosity_tangential, simulation.ice_floes[j].contact_viscosity_tangential) @@ -100,28 +123,28 @@ function interactIceFloes!(simulation::Simulation, i::Int, j::Int, ic::Int) simulation.ice_floes[j].contact_dynamic_friction) # Determine contact forces - if k_n_harmonic_mean ≈ 0. && gamma_n_harmonic_mean ≈ 0. + if k_n ≈ 0. && gamma_n ≈ 0. force_n = 0. - elseif k_n_harmonic_mean > 0. && gamma_n_harmonic_mean ≈ 0. - force_n = -k_n_harmonic_mean*delta_n + elseif k_n > 0. && gamma_n ≈ 0. + force_n = -k_n*delta_n - elseif k_n_harmonic_mean > 0. && gamma_n_harmonic_mean > 0. - force_n = -k_n_harmonic_mean*delta_n - gamma_n_harmonic_mean*vel_n + elseif k_n > 0. && gamma_n > 0. + force_n = -k_n*delta_n - gamma_n*vel_n if force_n < 0. force_n = 0. end else - error("unknown contact_normal_rheology (k_n = $k_n_harmonic_mean," * - " gamma_n = $gamma_n_harmonic_mean") + error("unknown contact_normal_rheology (k_n = $k_n," * + " gamma_n = $gamma_n") end - if k_t_harmonic_mean ≈ 0. && gamma_t_harmonic_mean ≈ 0. + if k_t ≈ 0. && gamma_t ≈ 0. # do nothing - elseif k_t_harmonic_mean ≈ 0. && gamma_t_harmonic_mean > 0. - force_t = abs(gamma_t_harmonic_mean * vel_t) + elseif k_t ≈ 0. && gamma_t > 0. + force_t = abs(gamma_t * vel_t) if force_t > mu_d_minimum*abs(force_n) force_t = mu_d_minimum*abs(force_n) end @@ -129,19 +152,18 @@ function interactIceFloes!(simulation::Simulation, i::Int, j::Int, ic::Int) force_t = -force_t end - elseif k_t_harmonic_mean > 0. + elseif k_t > 0. - force_t = -k_t_harmonic_mean*delta_t - gamma_t_harmonic_mean*vel_t + force_t = -k_t*delta_t - gamma_t*vel_t if abs(force_t) > mu_d_minimum*abs(force_n) force_t = mu_d_minimum*abs(force_n)*force_t/abs(force_t) - delta_t = (-force_t - gamma_t_harmonic_mean*vel_t)/ - k_t_harmonic_mean + delta_t = (-force_t - gamma_t*vel_t)/k_t end else error("unknown contact_tangential_rheology (k_t = " * - "$k_t_harmonic_mean, gamma_t = $gamma_t_harmonic_mean") + "$k_t, gamma_t = $gamma_t") end end simulation.ice_floes[i].contact_parallel_displacement[ic] = delta_t*t diff --git a/src/temporal.jl b/src/temporal.jl @@ -99,13 +99,24 @@ function findLargestIceFloeStiffness(simulation::Simulation) i_n_max = -1 i_t_max = -1 for i in length(simulation.ice_floes) + icefloe = simulation.ice_floes[i] - if icefloe.contact_stiffness_normal > k_n_max - k_n_max = icefloe.contact_stiffness_normal + + if icefloe.youngs_modulus > 0. + k_n = icefloe.youngs_modulus*icefloe.thickness # A = h*r + k_t = k_n*2.*(1. - icefloe.poissons_ratio^2.)/ + ((2. - icefloe.poissons_ratio)*(1. + icefloe.poissons_ratio)) + else + k_n = icefloe.contact_stiffness_normal + k_t = icefloe.contact_stiffness_tangential + end + + if k_n > k_n_max + k_n_max = k_n i_n_max = i end - if icefloe.contact_stiffness_tangential > k_t_max - k_t_max = icefloe.contact_stiffness_tangential + if k_t > k_t_max + k_t_max = k_t i_t_max = i end end diff --git a/test/collision-2floes-oblique.jl b/test/collision-2floes-oblique.jl @@ -13,6 +13,8 @@ sim = SeaIce.createSimulation(id="test") SeaIce.addIceFloeCylindrical(sim, [0., 10.], 10., 1., verbose=verbose) SeaIce.addIceFloeCylindrical(sim, [19., 0.], 10., 1., verbose=verbose) sim.ice_floes[1].lin_vel[1] = 0.1 +sim.ice_floes[1].contact_dynamic_friction = 0. +sim.ice_floes[2].contact_dynamic_friction = 0. sim.ice_floes[2].fixed = true E_kin_lin_init = SeaIce.totalIceFloeKineticTranslationalEnergy(sim) @@ -68,6 +70,8 @@ sim = SeaIce.createSimulation(id="test") SeaIce.addIceFloeCylindrical(sim, [0., 10.], 10., 1., verbose=verbose) SeaIce.addIceFloeCylindrical(sim, [19.0, 0.], 10., 1., verbose=verbose) sim.ice_floes[1].lin_vel[1] = 0.1 +sim.ice_floes[1].contact_dynamic_friction = 0. +sim.ice_floes[2].contact_dynamic_friction = 0. E_kin_lin_init = SeaIce.totalIceFloeKineticTranslationalEnergy(sim) E_kin_rot_init = SeaIce.totalIceFloeKineticRotationalEnergy(sim) @@ -229,7 +233,7 @@ E_kin_rot_final = SeaIce.totalIceFloeKineticRotationalEnergy(sim) info("Testing kinetic energy conservation with Two-term Taylor scheme") sim = deepcopy(sim_init) SeaIce.setTimeStep!(sim, epsilon=0.007) -tol = 0.02 +tol = 0.04 info("Relative tolerance: $(tol*100.)%") SeaIce.run!(sim, temporal_integration_method="Two-term Taylor", verbose=verbose) @@ -242,7 +246,7 @@ E_kin_rot_final = SeaIce.totalIceFloeKineticRotationalEnergy(sim) info("Testing kinetic energy conservation with Three-term Taylor scheme") sim = deepcopy(sim_init) SeaIce.setTimeStep!(sim, epsilon=0.07) -tol = 0.02 +tol = 0.04 info("Relative tolerance: $(tol*100.)% with time step: $(sim.time_step)") SeaIce.run!(sim, temporal_integration_method="Three-term Taylor", verbose=verbose) @@ -292,7 +296,7 @@ E_kin_rot_final = SeaIce.totalIceFloeKineticRotationalEnergy(sim) info("Testing kinetic energy conservation with Two-term Taylor scheme") sim = deepcopy(sim_init) SeaIce.setTimeStep!(sim, epsilon=0.007) -tol = 0.02 +tol = 0.04 info("Relative tolerance: $(tol*100.)%") SeaIce.run!(sim, temporal_integration_method="Two-term Taylor", verbose=verbose) @@ -305,7 +309,7 @@ E_kin_rot_final = SeaIce.totalIceFloeKineticRotationalEnergy(sim) info("Testing kinetic energy conservation with Three-term Taylor scheme") sim = deepcopy(sim_init) SeaIce.setTimeStep!(sim, epsilon=0.07) -tol = 0.02 +tol = 0.04 info("Relative tolerance: $(tol*100.)% with time step: $(sim.time_step)") SeaIce.run!(sim, temporal_integration_method="Three-term Taylor", verbose=verbose) @@ -325,8 +329,6 @@ sim = SeaIce.createSimulation(id="test") SeaIce.addIceFloeCylindrical(sim, [0., 0.], 10., 1., verbose=verbose) SeaIce.addIceFloeCylindrical(sim, [19.0, -10.], 10., 1., verbose=verbose) sim.ice_floes[2].lin_vel[1] = -0.1 -sim.ice_floes[1].contact_viscosity_tangential = 1e4 -sim.ice_floes[2].contact_viscosity_tangential = 1e4 E_kin_lin_init = SeaIce.totalIceFloeKineticTranslationalEnergy(sim) E_kin_rot_init = SeaIce.totalIceFloeKineticRotationalEnergy(sim) @@ -355,7 +357,7 @@ E_kin_rot_final = SeaIce.totalIceFloeKineticRotationalEnergy(sim) info("Testing kinetic energy conservation with Two-term Taylor scheme") sim = deepcopy(sim_init) SeaIce.setTimeStep!(sim, epsilon=0.007) -tol = 0.02 +tol = 0.04 info("Relative tolerance: $(tol*100.)%") SeaIce.run!(sim, temporal_integration_method="Two-term Taylor", verbose=verbose) @@ -368,7 +370,7 @@ E_kin_rot_final = SeaIce.totalIceFloeKineticRotationalEnergy(sim) info("Testing kinetic energy conservation with Three-term Taylor scheme") sim = deepcopy(sim_init) SeaIce.setTimeStep!(sim, epsilon=0.07) -tol = 0.02 +tol = 0.04 info("Relative tolerance: $(tol*100.)% with time step: $(sim.time_step)") SeaIce.run!(sim, temporal_integration_method="Three-term Taylor", verbose=verbose) @@ -424,7 +426,7 @@ E_kin_rot_final = SeaIce.totalIceFloeKineticRotationalEnergy(sim) info("Testing kinetic energy conservation with Two-term Taylor scheme") sim = deepcopy(sim_init) SeaIce.setTimeStep!(sim, epsilon=0.007) -tol = 0.02 +tol = 0.04 info("Relative tolerance: $(tol*100.)%") SeaIce.run!(sim, temporal_integration_method="Two-term Taylor", verbose=verbose) @@ -437,7 +439,7 @@ E_kin_rot_final = SeaIce.totalIceFloeKineticRotationalEnergy(sim) info("Testing kinetic energy conservation with Three-term Taylor scheme") sim = deepcopy(sim_init) SeaIce.setTimeStep!(sim, epsilon=0.07) -tol = 0.03 +tol = 0.04 info("Relative tolerance: $(tol*100.)% with time step: $(sim.time_step)") SeaIce.run!(sim, temporal_integration_method="Three-term Taylor", verbose=verbose) diff --git a/test/vtk.jl b/test/vtk.jl @@ -26,7 +26,7 @@ else end icefloechecksum = -"4885bc7c0eccc5e43a77d370295841fae710465c8bcc120a13681a0947ffbd53 " * +"de1ee347a6a15c665d3fa122c73092b3aa200bf8180007303f43f71396094d8d " * "test.icefloes.1.vtu\n" oceanchecksum =