tadd sedimentation example, fix render command by removing import - Granular.jl… | |
git clone git://src.adamsgaard.dk/Granular.jl | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit cd4e192c01d957b17d2ff205151b214458f1961b | |
parent 22209caf17f3edd5bdf18ce66a2570d9e0cc50ed | |
Author: Anders Damsgaard <[email protected]> | |
Date: Wed, 8 Nov 2017 11:37:29 -0500 | |
add sedimentation example, fix render command by removing import | |
Diffstat: | |
M docs/src/man/getting_started.md | 143 +++++++++++++++++++++++++++++… | |
A examples/sedimentation.jl | 41 +++++++++++++++++++++++++++++… | |
M src/io.jl | 4 ---- | |
3 files changed, 182 insertions(+), 6 deletions(-) | |
--- | |
diff --git a/docs/src/man/getting_started.md b/docs/src/man/getting_started.md | |
t@@ -20,7 +20,7 @@ name>`. An example: | |
```julia-repl | |
julia> ?Granular.fitGridToGrains! | |
- fitGridToGrains!(simulation, grid[, padding]) | |
+ fitGridToGrains!(simulation, grid[, padding, verbose]) | |
Fit the ocean or atmosphere grid for a simulation to the current grains and … | |
t@@ -38,7 +38,7 @@ julia> ?Granular.fitGridToGrains! | |
``` | |
## Collision between two particles | |
-For this simple example (`example/two-grains.jl`), we will create two grains, | |
+For this simple example (`examples/two-grains.jl`), we will create two grains, | |
where one of the grains is bumping in to the other. | |
As the first command, we import all the Granular.jl functionality: | |
t@@ -243,6 +243,12 @@ chosen parameter under the *Glyph1* object in the *Pipeli… | |
left, and selecting a different field for *Coloring*. Press the *Apply* butto… | |
to see the changes in effect. | |
+**Tip:** If you have the command `pvpython` (ParaView Python) available from | |
+the command line, you can visualize the simulation directly from the command | |
+line without entering ParaView by the command `sim.render()`. Furthermore, if | |
+you have the `convert` command from ImageMagick installed (`brew install | |
+imagemagick` on macOS), the output images will be merged into an animated GIF. | |
+ | |
### Exercises | |
To gain more familiarity with the simulation procedure, I suggest experimentin… | |
with the following: | |
t@@ -256,3 +262,136 @@ with the following: | |
affected by the choice of time step length? Try setting different time | |
step values, e.g. with `sim.time_step = 0.1234` and rerun the simulation. | |
+## Sedimentation of grains | |
+Grains are known to settle under gravitation in water according to *Stoke's | |
+law*, where resistive drag acts opposite of gravity and with a magnitude | |
+according to the squareroot of velocity difference between water and grain. | |
+ | |
+Granular.jl offers simple fluid grids with prescribed velocity fields, and the | |
+grains are met with drag in this grid. | |
+ | |
+In this example (`examples/sedimentation.jl`) we will initialize a range of | |
+grain sizes in a loose configuration, add gravity and a surrounding fluid grid… | |
+and let the grains settle towards the bottom. | |
+ | |
+As in the previous example, we start by creating a fluid grid: | |
+ | |
+```julia-repl | |
+julia> import Granular | |
+julia> sim = Granular.createSimulation(id="sedimentation.jl") | |
+``` | |
+ | |
+### Creating a pseudo-random grain packing | |
+Instead of manually adding grains one by one, we can use the | |
+`regularPacking!()` function to add a regular grid of random-sized grains to | |
+the simulation. Below, we specify that we want the grid of grains to be 10 | |
+grains wide along x, and 50 grains tall along y. We also specify the grain | |
+radii to fall between 0.02 and 0.2 m. The sizes will be drawn from a power-la… | |
+distribution, by default. | |
+ | |
+```julia-repl | |
+julia> Granular.regularPacking!(sim, [10, 50], 0.02, 0.2) | |
+``` | |
+ | |
+Since we haven't explicitly set the grain sizes for this example, we can | |
+inspect the values by plotting a histogram of sizes: | |
+ | |
+```julia-repl | |
+julia> Granular.plotGrainSizeDistribution(sim) | |
+INFO: sedimentation-grain-size-distribution.png | |
+``` | |
+ | |
+The output informs us that we have the plot saved as an image with the file | |
+name `sedimentation-grain-size-distribution.png`. | |
+ | |
+### Creating a fluid grid | |
+We can now create a fluid (ocean) grid spanning the extent of the grains | |
+created above: | |
+ | |
+```julia-repl | |
+julia> Granular.fitGridToGrains!(sim, sim.ocean) | |
+``` | |
+ | |
+We want the boundaries of the above grid to be impermeable for the grains, so | |
+they stack up at the bottom. Granular.jl acknowledges the boundary types with | |
+a confirmation message: | |
+ | |
+```julia-repl | |
+julia> Granular.setGridBoundaryConditions!(sim.ocean, "impermeable") | |
+West (-x): impermeable (3) | |
+East (+x): impermeable (3) | |
+South (-y): impermeable (3) | |
+North (+y): impermeable (3) | |
+``` | |
+ | |
+### Adding gravitational acceleration | |
+If we started the simulation now, nothing would happen as gravity is disabled | |
+by default. We can enable gravitational acceleration as a constant body force | |
+for each grain (`Force = mass * acceleration`): | |
+ | |
+```julia-repl | |
+julia> g = [0.0, -9.8]; | |
+julia> for grain in sim.grains | |
+ Granular.addBodyForce!(grain, grain.mass*g) | |
+ end | |
+``` | |
+ | |
+### Setting temporal parameters | |
+As before, we ask the code to select a suitable computational time step based | |
+on grain sizes and properties: | |
+ | |
+```julia-repl | |
+julia> Granular.setTimeStep!(sim) | |
+INFO: Time step length t=1.6995699879716792e-5 s | |
+``` | |
+ | |
+We also again set the total simulation time as well as the output file | |
+interval: | |
+ | |
+```julia-repl | |
+julia> Granular.setTotalTime!(sim, 5.0) | |
+julia> Granular.setOutputFileInterval!(sim, 0.2) | |
+``` | |
+ | |
+### Running the simulation | |
+We are now ready to run the simulation: | |
+ | |
+```julia-repl | |
+julia> Granular.run!(sim) | |
+INFO: Output file: ./sedimentation/sedimentation.grains.1.vtu | |
+INFO: Output file: ./sedimentation/sedimentation.ocean.1.vts | |
+INFO: wrote status to ./sedimentation/sedimentation.status.txt | |
+ t = 0.19884968859273294/5.0 s | |
+INFO: Output file: ./sedimentation/sedimentation.grains.2.vtu | |
+INFO: Output file: ./sedimentation/sedimentation.ocean.2.vts | |
+INFO: wrote status to ./sedimentation/sedimentation.status.txt | |
+ t = 0.3993989471735396/5.0 s | |
+ | |
+... | |
+ | |
+INFO: Output file: ./sedimentation/sedimentation.grains.25.vtu | |
+INFO: Output file: ./sedimentation/sedimentation.ocean.25.vts | |
+INFO: wrote status to ./sedimentation/sedimentation.status.txt | |
+ t = 4.998435334626701/5.0 s | |
+INFO: ./sedimentation/sedimentation.py written, execute with 'pvpython /Users/… | |
+INFO: wrote status to ./sedimentation/sedimentation.status.txt | |
+ t = 5.00001593471549/5.0 s | |
+``` | |
+ | |
+The output can be plotted in ParaView as discribed in the `two-grain` example | |
+above, or, if `pvpython` is available from the command line, directly from | |
+Julia with the following command: | |
+ | |
+```julia-repl | |
+julia> Granular.render(sim, trim=false) | |
+``` | |
+ | |
+### Exercises | |
+- How are the granular contact pressures distributed in the final result? | |
+- Try running the above example, but without fluid drag. Disable the drag by | |
+ including the call `Granlar.disableOceanDrag!(grain)` in the `for` loop | |
+ where gravitational acceleration is set for each grain. | |
+- How does the range of grain sizes affect the result? Try making all grains | |
+ bigger or smaller. | |
+- How is the model performance effected if the grain-size distribution is | |
+ wide or narrow? | |
diff --git a/examples/sedimentation.jl b/examples/sedimentation.jl | |
t@@ -0,0 +1,41 @@ | |
+#/usr/bin/env julia | |
+import Granular | |
+ | |
+#### Create a loose granular assemblage and let it settle at towards -y | |
+sim = Granular.createSimulation(id="sedimentation") | |
+ | |
+# Generate 10 grains along x and 50 grains along y, with radii between 0.2 and | |
+# 1.0 m. | |
+Granular.regularPacking!(sim, [10, 50], 0.02, 0.2) | |
+ | |
+# Visualize the grain-size distribution | |
+Granular.plotGrainSizeDistribution(sim) | |
+ | |
+# Create a grid for contact searching spanning the extent of the grains in the | |
+# simulation | |
+Granular.fitGridToGrains!(sim, sim.ocean) | |
+ | |
+# Make the grid boundaries impermeable for the grains, which | |
+Granular.setGridBoundaryConditions!(sim.ocean, "impermeable") | |
+ | |
+# Add gravitational acceleration to all grains | |
+g = [0., -9.8] | |
+for grain in sim.grains | |
+ Granular.addBodyForce!(grain, grain.mass*g) | |
+end | |
+ | |
+# Automatically set the computational time step based on grain sizes and | |
+# properties | |
+Granular.setTimeStep!(sim) | |
+ | |
+# Set the total simulation time for this step [s] | |
+Granular.setTotalTime!(sim, 5.0) | |
+ | |
+# Set the interval in model time between simulation files [s] | |
+Granular.setOutputFileInterval!(sim, 0.2) | |
+ | |
+# Start the simulation | |
+Granular.run!(sim) | |
+ | |
+# Try to render the simulation if `pvpython` is installed on the system | |
+Granular.render(sim, trim=false) | |
diff --git a/src/io.jl b/src/io.jl | |
t@@ -947,10 +947,6 @@ function render(simulation::Simulation; pvpython::String=… | |
# use ImageMagick installed with Homebrew.jl if available, | |
# otherwise search for convert in $PATH | |
convert = "convert" | |
- if is_apple() | |
- import Homebrew | |
- convert = Homebrew.prefix() * "/bin/convert" | |
- end | |
run(`$convert $trim_string +repage -delay 10 | |
-transparent-color white |