seaice-experiments

sea ice experiments using Granular.jl
git clone git://src.adamsgaard.dk/seaice-experiments # fast
git clone https://src.adamsgaard.dk/seaice-experiments.git # slow
Log | Files | Refs | README | LICENSE Back to index

ridging_bulk_simulation.jl (9545B)


      1 #/usr/bin/env julia
      2 ENV["MPLBACKEND"] = "Agg"
      3 import Granular
      4 import PyPlot
      5 import ArgParse
      6 using Random
      7 import DelimitedFiles
      8 
      9 let
     10 render = false
     11 
     12 function parse_command_line()
     13     s = ArgParse.ArgParseSettings()
     14     ArgParse.@add_arg_table s begin
     15         "--E"
     16             help = "Young's modulus [Pa]"
     17             arg_type = Float64
     18             default = 2e7
     19         "--nu"
     20             help = "Poisson's ratio [-]"
     21             arg_type = Float64
     22             default = 0.285
     23         "--mu_d"
     24             help = "dynamic friction coefficient [-]"
     25             arg_type = Float64
     26             default = 0.3
     27         "--tensile_strength"
     28             help = "the maximum tensile strength [Pa]"
     29             arg_type = Float64
     30             default = 400e3
     31         "--tensile_strength_std_dev"
     32             help = "standard deviation of the maximum tensile strength [Pa]"
     33             arg_type = Float64
     34             default = 0.0
     35         "--shear_strength"
     36             help = "the maximum shear strength [Pa]"
     37             arg_type = Float64
     38             default = 200e3
     39         "--fracture_toughness"
     40             help = "fracture toughness [Pa*m^{1/2}]"
     41             arg_type = Float64
     42             default = 1285e3
     43         "--r_min"
     44             help = "min. grain radius [m]"
     45             arg_type = Float64
     46             default = 20.0
     47         "--r_max"
     48             help = "max. grain radius [m]"
     49             arg_type = Float64
     50             default = 200.0
     51         "--thickness"
     52             help = "grain thickness [m]"
     53             arg_type = Float64
     54             default = 1.
     55         "--rotating"
     56             help = "allow the grains to rotate"
     57             arg_type = Bool
     58             default = true
     59         "--compressive_velocity"
     60             help = "compressive velocity [m/s]"
     61             arg_type = Float64
     62             default = 0.1
     63         "--seed"
     64             help = "seed for the pseudo RNG"
     65             arg_type = Int
     66             default = 1
     67         "id"
     68             help = "simulation id"
     69             required = true
     70     end
     71     return ArgParse.parse_args(s)
     72 end
     73 
     74 function report_args(parsed_args)
     75     println("Parsed args:")
     76     for (arg,val) in parsed_args
     77         println("  $arg  =>  $val")
     78     end
     79 end
     80 
     81 function run_simulation(id::String,
     82                         E::Float64,
     83                         nu::Float64,
     84                         mu_d::Float64,
     85                         tensile_strength::Float64,
     86                         tensile_strength_std_dev::Float64,
     87                         shear_strength::Float64,
     88                         fracture_toughness::Float64,
     89                         r_min::Float64,
     90                         r_max::Float64,
     91                         thickness::Float64,
     92                         rotating::Bool,
     93                         compressive_velocity::Float64,
     94                         seed::Int)
     95 
     96     ############################################################################
     97     #### SIMULATION PARAMETERS
     98     ############################################################################
     99 
    100     # Common simulation identifier
    101     id_prefix = id
    102 
    103     # Grain mechanical properties
    104     youngs_modulus = E              # Elastic modulus [Pa]
    105     poissons_ratio = nu             # Shear-stiffness ratio [-]
    106     contact_dynamic_friction = mu_d # Coulomb-frictional coefficient [-]
    107 
    108     # Simulation duration [s]
    109     t_total = 60.0 * 60.0
    110 
    111     # Temporal interval between output files
    112     file_dt = t_total/200
    113 
    114     # Misc parameters
    115     water_density = 1000.
    116 
    117     # World size [m]
    118     L = [1e3, 1e3, 10.0]
    119 
    120     Random.seed!(seed)
    121 
    122     ############################################################################
    123     #### Create ice floes
    124     ############################################################################
    125     sim = Granular.createSimulation("$(id_prefix)")
    126     Granular.removeSimulationFiles(sim)
    127 
    128     # Create box edges of ice floes with r_min radius, moving inward
    129     r_walls = r_min
    130     #= for x in LinRange(0.0, L[1] - r_walls, Int(ceil(L[1]/(r_walls*2)))) =#
    131     #=     Granular.addGrainCylindrical!(sim, [x, r_min], =# 
    132     #=                                  r_walls, thickness, fixed=true, =#
    133     #=                                  lin_vel=[0.0, compressive_velocity/2.], =#
    134     #=                                  verbose=false) =#
    135     #=     Granular.addGrainCylindrical!(sim, [x, L[2] - r_min], =#
    136     #=                                  r_walls, thickness, fixed=true, =#
    137     #=                                  lin_vel=[0.0, -compressive_velocity/2.], =#
    138     #=                                  verbose=false) =#
    139     #= end =#
    140     for y in LinRange(r_walls, L[2] - r_walls, Int(ceil(L[2]/(r_walls*2))))
    141         Granular.addGrainCylindrical!(sim, [r_min, y], 
    142                                      r_walls, thickness, fixed=true,
    143                                      #lin_vel=[compressive_velocity/2., 0.0],
    144                                      verbose=false)
    145         Granular.addGrainCylindrical!(sim, [L[1] - r_min, y], 
    146                                      r_walls, thickness, fixed=true,
    147                                      lin_vel=[-compressive_velocity/2., 0.0],
    148                                      verbose=false)
    149     end
    150 
    151     # Create a grid for contact searching spanning the extent of the grains
    152     n = [Int(ceil(L[1]/r_max/2)), Int(ceil(L[2]/r_max/2)), 2]
    153     sim.ocean = Granular.createRegularOceanGrid(n, L)
    154     Granular.setGridBoundaryConditions!(sim.ocean, "inactive", "-x +x")
    155     Granular.setGridBoundaryConditions!(sim.ocean, "periodic", "-y +y")
    156 
    157     # Add unconstrained ice floes
    158     #= Granular.regularPacking!(sim, =#
    159     #=                          n, =#
    160     #=                          r_min, r_max, =#
    161     #=                          seed=seed) =#
    162     Granular.irregularPacking!(sim,
    163                                radius_max=r_max, radius_min=r_min,
    164                                thickness=thickness,
    165                                #binary_radius_search=true,
    166                                seed=seed)
    167 
    168     # Set grain mechanical properties
    169     for grain in sim.grains
    170         grain.youngs_modulus = youngs_modulus
    171         grain.poissons_ratio = poissons_ratio
    172         grain.tensile_strength = abs(tensile_strength +
    173                                      randn()*tensile_strength_std_dev)
    174         grain.shear_strength = abs(shear_strength +
    175                                    randn()*tensile_strength_std_dev)
    176         grain.contact_static_friction = contact_dynamic_friction  # mu_s = mu_d
    177         grain.contact_dynamic_friction = contact_dynamic_friction
    178         grain.fracture_toughness = fracture_toughness
    179         grain.rotating = rotating
    180         grain.ocean_drag_coeff_horiz = 0.0 # don't include drag on ends
    181     end
    182 
    183     # Create GSD plot to signify that simulation is complete
    184     Granular.writeSimulation(sim)
    185     render && Granular.plotGrainSizeDistribution(sim)
    186 
    187     Granular.setTimeStep!(sim)
    188     Granular.setTotalTime!(sim, t_total)
    189     Granular.setOutputFileInterval!(sim, file_dt)
    190     render && Granular.plotGrains(sim, verbose=true)
    191 
    192 
    193     ############################################################################
    194     #### RUN THE SIMULATION
    195     ############################################################################
    196     #= theta = 0.0; submerged_volume = 0.0 =#
    197     time = Float64[]
    198     N = Float64[]  # normal stress on leftmost fixed particles
    199     τ = Float64[]  # shear stress on leftmost fixed particles
    200     A = sim.grains[1].thickness * L[2]
    201     while sim.time < sim.time_total
    202 
    203         append!(time, sim.time)
    204 
    205         # Record cumulative force on fixed particles at the +x boundary
    206         normal_force = 0.0
    207         tangential_force = 0.0
    208         for grain in sim.grains
    209             if grain.fixed && grain.lin_pos[1] > 0.2*L[1]
    210                 normal_force += grain.force[1]
    211                 tangential_force += grain.force[2]
    212             end
    213         end
    214         append!(N, normal_force/A) # compressive = positive
    215         append!(τ, tangential_force/A)
    216 
    217         # Run for 100 time steps before measuring bulk forces
    218         for i=1:100
    219             Granular.run!(sim, single_step=true)
    220         end
    221 
    222     end
    223 
    224     # Plot normal stress and shear stress vs time
    225     DelimitedFiles.writedlm(id_prefix * "-data.txt", [time, N, τ])
    226     PyPlot.subplot(211)
    227     PyPlot.subplots_adjust(hspace=0.0)
    228     ax1 = PyPlot.gca()
    229     PyPlot.setp(ax1[:get_xticklabels](),visible=false) # Disable x labels
    230     PyPlot.plot(time, N/1e3)
    231     PyPlot.ylabel("Compressive stress [kPa]")
    232     PyPlot.subplot(212, sharex=ax1)
    233     PyPlot.plot(time, τ/1e3)
    234     PyPlot.xlabel("Time [s]")
    235     PyPlot.ylabel("Shear stress [kPa]")
    236     PyPlot.tight_layout()
    237     PyPlot.savefig(sim.id * "-time_vs_stress.pdf")
    238     PyPlot.clf()
    239 
    240     render && Granular.render(sim, trim=false, animation=true)
    241 end
    242 
    243 function main()
    244     parsed_args = parse_command_line()
    245     report_args(parsed_args)
    246 
    247     seed = parsed_args["seed"]
    248     run_simulation(parsed_args["id"] * "-seed" * string(seed),
    249                    parsed_args["E"],
    250                    parsed_args["nu"],
    251                    parsed_args["mu_d"],
    252                    parsed_args["tensile_strength"],
    253                    parsed_args["tensile_strength_std_dev"],
    254                    parsed_args["shear_strength"],
    255                    parsed_args["fracture_toughness"],
    256                    parsed_args["r_min"],
    257                    parsed_args["r_max"],
    258                    parsed_args["thickness"],
    259                    parsed_args["rotating"],
    260                    parsed_args["compressive_velocity"],
    261                    seed)
    262 end
    263 
    264 main()
    265 end