Granular.jl

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

commit de89698ecd7d60173f5cfbf8e30b455452b8951c
parent f8e0e4db6963a0e5775539a65d8f85add7af9565
Author: Anders Damsgaard <andersd@riseup.net>
Date:   Fri, 17 Nov 2017 22:48:10 -0500

move GSD plotting to io.jl, add grain-plotting function

Diffstat:
Msrc/grain.jl | 105-------------------------------------------------------------------------------
Msrc/io.jl | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 187 insertions(+), 105 deletions(-)

diff --git a/src/grain.jl b/src/grain.jl @@ -2,15 +2,6 @@ using Compat.Test -# load Homebrew/WinRPM for gnuplot and imagemagick -if is_apple() - using Homebrew -end - -if is_windows() - using WinRPM -end - export addGrainCylindrical! """ function addGrainCylindrical!(simulation, lin_pos, contact_radius, @@ -725,102 +716,6 @@ function compareGrains(if1::GrainCylindrical, if2::GrainCylindrical) nothing end -export plotGrainSizeDistribution -""" - plotGrainSizeDistribution(simulation, [filename_postfix], [nbins], - [size_type], [figsize], [filetype]) - -Plot the grain size distribution as a histogram and save it to the disk. The -plot is saved accoring to the simulation id, the optional `filename_postfix` -string, and the `filetype`, and is written to the current folder. - -# Arguments -* `simulation::Simulation`: the simulation object containing the grains. -* `filename_postfix::String`: optional string for the output filename. -* `nbins::Int`: number of bins in the histogram (default = 12). -* `size_type::String`: specify whether to use the `contact` or `areal` radius - for the grain size. The default is `contact`. -* `figsize::Tuple`: the output figure size in inches (default = (6,4). -* `filetype::String`: the output file type (default = "png"). -* `verbose::String`: show output file as info message in stdout (default = - true). -* `skip_fixed::Bool`: ommit grains that are fixed in space from the size - distribution (default = true). -* `log_y::Bool`: plot y-axis in log scale. -* `show_plot::Bool`: show plot in pop-up window in addition to writing to disk. -""" -function plotGrainSizeDistribution(simulation::Simulation; - filename_postfix::String = "", - nbins::Int=12, - size_type::String = "contact", - figsize::Tuple = (6,4), - filetype::String = "png", - gnuplot_terminal::String = "png", - verbose::Bool = true, - skip_fixed::Bool = true, - log_y::Bool = false, - show_plot::Bool = false) - - diameters = Float64[] - for i=1:length(simulation.grains) - if simulation.grains[i].fixed && skip_fixed - continue - end - if size_type == "contact" - push!(diameters, simulation.grains[i].contact_radius*2.) - elseif size_type == "areal" - push!(diameters, simulation.grains[i].areal_radius*2.) - else - error("size_type '$size_type' not understood") - end - end - - filename = string(simulation.id * filename_postfix * - "-grain-size-distribution." * filetype) - - # write data to temporary file on disk - datafile = Base.Filesystem.tempname() - writedlm(datafile, diameters) - gnuplotscript = Base.Filesystem.tempname() - - #if maximum(diameters) ≈ minimum(diameters) - #info("Overriding `nbins = $nbins` -> `nbins = 1`.") - #nbins = 1 - #end - - open(gnuplotscript, "w") do f - - write(f, """#!/usr/bin/env gnuplot - set term $gnuplot_terminal - set out "$(filename)"\n""") - if log_y - write(f, "set logscale y\n") - end - write(f, """set xlabel "Diameter [m]" - set ylabel "Count [-]" - binwidth = $((maximum(diameters) - minimum(diameters)+1e-7)/nbins) - binstart = $(minimum(diameters)) - set boxwidth 1.0*binwidth - set style fill solid 0.5 - set key off - hist = 'u (binwidth*(floor((\$1-binstart)/binwidth)+0.5)+binstart):(1.0) smooth freq w boxes' - plot "$(datafile)" i 0 @hist ls 1 - """) - end - - try - run(`gnuplot $gnuplotscript`) - catch return_signal - if isa(return_signal, Base.UVError) - error("Could not launch external gnuplot process") - end - end - - if verbose - info(filename) - end -end - export enableOceanDrag! """ enableOceanDrag!(grain) diff --git a/src/io.jl b/src/io.jl @@ -7,6 +7,15 @@ if typeof(Pkg.installed("JLD")) == VersionNumber end using Compat.DelimitedFiles +# load Homebrew/WinRPM for gnuplot and imagemagick +if is_apple() + using Homebrew +end + +if is_windows() + using WinRPM +end + ## IO functions export writeSimulation @@ -1057,3 +1066,181 @@ function removeSimulationFiles(simulation::Simulation; folder::String=".") run(`bash -c "rm -rf $(folder)"`) nothing end + +export plotGrainSizeDistribution +""" + plotGrainSizeDistribution(simulation, [filename_postfix, nbins, + size_type, filetype, gnuplot_terminal, + skip_fixed, log_y, verbose) + +Plot the grain size distribution as a histogram and save it to the disk. The +plot is saved accoring to the simulation id, the optional `filename_postfix` +string, and the `filetype`, and is written to the current folder. + +# Arguments +* `simulation::Simulation`: the simulation object containing the grains. +* `filename_postfix::String`: optional string for the output filename. +* `nbins::Int`: number of bins in the histogram (default = 12). +* `size_type::String`: specify whether to use the `contact` or `areal` radius + for the grain size. The default is `contact`. +* `filetype::String`: the output file type (default = "png"). +* `gnuplot_terminal::String`: the gnuplot output terminal to use (default = + "png"). +* `skip_fixed::Bool`: ommit grains that are fixed in space from the size + distribution (default = true). +* `log_y::Bool`: plot y-axis in log scale. +* `verbose::String`: show output file as info message in stdout (default = + true). +""" +function plotGrainSizeDistribution(simulation::Simulation; + filename_postfix::String = "", + nbins::Int=12, + size_type::String = "contact", + filetype::String = "png", + gnuplot_terminal::String = "png", + skip_fixed::Bool = true, + log_y::Bool = false, + verbose::Bool = true) + + diameters = Float64[] + for i=1:length(simulation.grains) + if simulation.grains[i].fixed && skip_fixed + continue + end + if size_type == "contact" + push!(diameters, simulation.grains[i].contact_radius*2.) + elseif size_type == "areal" + push!(diameters, simulation.grains[i].areal_radius*2.) + else + error("size_type '$size_type' not understood") + end + end + + filename = string(simulation.id * filename_postfix * + "-grain-size-distribution." * filetype) + + # write data to temporary file on disk + datafile = Base.Filesystem.tempname() + writedlm(datafile, diameters) + gnuplotscript = Base.Filesystem.tempname() + + #if maximum(diameters) ≈ minimum(diameters) + #info("Overriding `nbins = $nbins` -> `nbins = 1`.") + #nbins = 1 + #end + + open(gnuplotscript, "w") do f + + write(f, """#!/usr/bin/env gnuplot + set term $gnuplot_terminal + set out "$(filename)"\n""") + if log_y + write(f, "set logscale y\n") + end + write(f, """set xlabel "Diameter [m]" + set ylabel "Count [-]" + binwidth = $((maximum(diameters) - minimum(diameters)+1e-7)/nbins) + binstart = $(minimum(diameters)) + set boxwidth 1.0*binwidth + set style fill solid 0.5 + set key off + hist = 'u (binwidth*(floor((\$1-binstart)/binwidth)+0.5)+binstart):(1.0) smooth freq w boxes' + plot "$(datafile)" i 0 @hist ls 1 + """) + end + + try + run(`gnuplot $gnuplotscript`) + catch return_signal + if isa(return_signal, Base.UVError) + error("Could not launch external gnuplot process") + end + end + + if verbose + info(filename) + end +end + +export plotGrains +""" + plotGrains(simulation, [filetype, gnuplot_terminal, verbose]) + +Plot the grains using Gnuplot and save the figure to disk. + +# Arguments +* `simulation::Simulation`: the simulation object containing the grains. +* `filetype::String`: the output file type (default = "png"). +* `gnuplot_terminal::String`: the gnuplot output terminal to use (default = + "png"). +* `verbose::String`: show output file as info message in stdout (default = + true). +""" +function plotGrains(sim::Simulation; + filetype::String = "png", + gnuplot_terminal::String = "png", + show_figure::Bool = true, + verbose::Bool = true) + + mkpath(sim.id) + filename = string(sim.id, "/", sim.id, ".grains.", sim.file_number, ".", + filetype) + + x = Float64[] + y = Float64[] + r = Float64[] + for grain in sim.grains + push!(x, grain.lin_pos[1]) + push!(y, grain.lin_pos[2]) + push!(r, grain.contact_radius) + end + + # write data to temporary file on disk + datafile = Base.Filesystem.tempname() + writedlm(datafile, [x y r]) + gnuplotscript = Base.Filesystem.tempname() + + open(gnuplotscript, "w") do f + + write(f, """#!/usr/bin/env gnuplot + set term $(gnuplot_terminal) crop size 1200,1200 + set out "$(filename)" + set palette defined (0 "gray", 1 "white") + set xlabel "x [m]" + set ylabel "y [m]"\n""") + if typeof(sim.ocean.input_file) != Bool + write(f, "set xrange ") + write(f, "[$(sim.ocean.xq[1,1]):$(sim.ocean.xq[end,end])]\n") + write(f, "set yrange ") + write(f, "[$(sim.ocean.yq[1,1]):$(sim.ocean.yq[end,end])]\n") + else + write(f, "set xrange [$(minimum(x - r)):$(maximum(x + r))]\n") + write(f, "set yrange [$(minimum(y - r)):$(maximum(y + r))]\n") + end + write(f, """set cblabel "Diameter [m]" + set size ratio -1 + set key off + plot "$(datafile)" with circles lt 1 lc rgb "black" t "Particle" + """) + end + + try + run(`gnuplot $gnuplotscript`) + catch return_signal + if isa(return_signal, Base.UVError) + error("Could not launch external gnuplot process") + end + end + + if verbose + info(filename) + end + + if show_figure + if is_apple() + run(`open $(filename)`) + elseif is_linux() + run(`xdg-open $(filename)`) + end + end +end