tlinearly increase cohesion with contact time until hard limit, remove contacts within interaction function - 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 6250a89c16baa8c912f836f2586cc9dc8e9537b6
 (DIR) parent 2e88c8f814b4838ec6ec179feb6a565d46a7b155
 (HTM) Author: Anders Damsgaard <andersd@riseup.net>
       Date:   Thu, 25 May 2017 14:03:42 -0400
       
       linearly increase cohesion with contact time until hard limit, remove contacts within interaction function
       
       Diffstat:
         M src/contact_search.jl               |       1 +
         M src/datatypes.jl                    |       1 +
         M src/icefloe.jl                      |      10 ++++++----
         M src/interaction.jl                  |      37 ++++++++++++++++++++++++-------
         A test/cohesion.jl                    |      22 ++++++++++++++++++++++
         M test/runtests.jl                    |       1 +
       
       6 files changed, 60 insertions(+), 12 deletions(-)
       ---
 (DIR) diff --git a/src/contact_search.jl b/src/contact_search.jl
       t@@ -149,6 +149,7 @@ function checkAndAddContact!(sim::Simulation, i::Int, j::Int)
                                sim.ice_floes[i].contacts[ic] = j
                                sim.ice_floes[i].contact_parallel_displacement[ic] =
                                    zeros(2)
       +                        sim.ice_floes[i].contact_age[ic] = 0.
                                break
                            end
                        end
 (DIR) diff --git a/src/datatypes.jl b/src/datatypes.jl
       t@@ -61,6 +61,7 @@ type IceFloeCylindrical
            ocean_grid_pos::Array{Int, 1}
            contacts::Array{Int, 1}
            contact_parallel_displacement::Array{Array{Float64, 1}, 1}
       +    contact_age::Array{Float64, 1}
        end
        
        # Type for gathering data from ice floe objects into single arrays
 (DIR) diff --git a/src/icefloe.jl b/src/icefloe.jl
       t@@ -46,9 +46,10 @@ function addIceFloeCylindrical(simulation::Simulation,
                                       n_contacts::Int = 0,
                                       contacts::Array{Int, 1} = zeros(Int, Nc_max),
                                       contact_parallel_displacement::
       -                                   Array{Array{Float64, 1}, 1}
       -                                   =
       -                                   Array{Array{Float64, 1}, 1}(Nc_max))
       +                                   Array{Array{Float64, 1}, 1} =
       +                                   Array{Array{Float64, 1}, 1}(Nc_max),
       +                               contact_age::Array{Float64, 1} =
       +                                   zeros(Float64, Nc_max))
        
            # Check input values
            if length(lin_pos) != 2
       t@@ -126,7 +127,8 @@ function addIceFloeCylindrical(simulation::Simulation,
                                         n_contacts,
                                         ocean_grid_pos,
                                         contacts,
       -                                 contact_parallel_displacement
       +                                 contact_parallel_displacement,
       +                                 contact_age
                                        )
        
            # Overwrite previous placeholder values
 (DIR) diff --git a/src/interaction.jl b/src/interaction.jl
       t@@ -16,6 +16,7 @@ function interact!(simulation::Simulation)
                        continue
                    end
        
       +            """
                    if norm(simulation.ice_floes[i].lin_pos - 
                            simulation.ice_floes[j].lin_pos) - 
                        (simulation.ice_floes[i].contact_radius + 
       t@@ -25,8 +26,9 @@ function interact!(simulation::Simulation)
                        simulation.ice_floes[i].n_contacts -= 1
                        simulation.ice_floes[j].n_contacts -= 1
                    else
       -                interactIceFloes!(simulation, i, j, ic)
       -            end
       +            """
       +            interactIceFloes!(simulation, i, j, ic)
       +            #end
                end
            end
        end
       t@@ -76,6 +78,9 @@ function interactIceFloes!(simulation::Simulation, i::Int, j::Int, ic::Int)
            # Effective radius
            R_ij = harmonicMean(simulation.ice_floes[i].contact_radius,
                                simulation.ice_floes[j].contact_radius) - abs(δ_n)/2.
       +    # Contact area
       +    A_ij = R_ij*min(simulation.ice_floes[i].thickness, 
       +                    simulation.ice_floes[j].thickness)
        
            # Contact mechanical parameters
            if simulation.ice_floes[i].youngs_modulus > 0. &&
       t@@ -86,10 +91,6 @@ function interactIceFloes!(simulation::Simulation, i::Int, j::Int, ic::Int)
                ν = 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
       t@@ -126,8 +127,27 @@ function interactIceFloes!(simulation::Simulation, i::Int, j::Int, ic::Int)
                end
        
            else
       -        error("unknown contact_normal_rheology (k_n = $k_n," *
       -              " γ_n = $γ_n")
       +        error("unknown contact_normal_rheology (k_n = $k_n, γ_n = $γ_n")
       +    end
       +
       +    # Contact tensile strength increases linearly with contact age until tensile 
       +    # stress exceeds tensile strength
       +    if δ_n > 0.
       +
       +        # linearly increase tensile strength with time until max. value
       +        tensile_strength = min(simulation.ice_floes[i].contact_age[ic]/
       +                               (60.*60.*24.), 1.)*
       +                               simulation.ice_floes[i].tensile_strength*
       +                               simulation.ice_floes[i].thickness
       +
       +        # break bond
       +        if abs(force_n) > tensile_strength*A_ij
       +            force_n = 0.
       +            force_t = 0.
       +            simulation.ice_floes[i].contacts[ic] = 0  # remove contact
       +            simulation.ice_floes[i].n_contacts -= 1
       +            simulation.ice_floes[j].n_contacts -= 1
       +        end
            end
        
            if k_t ≈ 0. && γ_t ≈ 0.
       t@@ -156,6 +176,7 @@ function interactIceFloes!(simulation::Simulation, i::Int, j::Int, ic::Int)
            end
        
            simulation.ice_floes[i].contact_parallel_displacement[ic] = δ_t*t
       +    simulation.ice_floes[i].contact_age[ic] += simulation.time_step
        
            simulation.ice_floes[i].force += force_n*n + force_t*t;
            simulation.ice_floes[j].force -= force_n*n + force_t*t;
 (DIR) diff --git a/test/cohesion.jl b/test/cohesion.jl
       t@@ -0,0 +1,22 @@
       +#!/usr/bin/env julia
       +
       +# Check for conservation of kinetic energy (=momentum) during a normal collision 
       +# between two ice cylindrical ice floes 
       +
       +info("#### $(basename(@__FILE__)) ####")
       +
       +verbose=false
       +
       +sim_init = SeaIce.createSimulation(id="test")
       +SeaIce.addIceFloeCylindrical(sim_init, [0., 0.], 10., 1., verbose=verbose)
       +SeaIce.addIceFloeCylindrical(sim_init, [18., 0.], 10., 1., verbose=verbose)
       +sim_init.ice_floes[1].youngs_modulus = 1e-5  # repulsion is negligible
       +sim_init.ice_floes[2].youngs_modulus = 1e-5  # repulsion is negligible
       +SeaIce.setTimeStep!(sim_init, verbose=verbose)
       +
       +info("# Check contact age scheme")
       +sim = deepcopy(sim_init)
       +SeaIce.setTotalTime!(sim, 10.)
       +sim.time_step = 1.
       +SeaIce.run!(sim, verbose=verbose)
       +@test sim.ice_floes[1].contact_age[1] ≈ sim.time
 (DIR) diff --git a/test/runtests.jl b/test/runtests.jl
       t@@ -7,6 +7,7 @@ include("contact-search-and-geometry.jl")
        include("collision-2floes-normal.jl")
        include("collision-5floes-normal.jl")
        include("collision-2floes-oblique.jl")
       +include("cohesion.jl")
        include("netcdf.jl")
        include("vtk.jl")
        include("grid.jl")