tMerge pull request #5 from anders-dc/ns-cfd - sphere - GPU-based 3D discrete element method algorithm with optional fluid coupling
HTML git clone git://src.adamsgaard.dk/sphere
DIR Log
DIR Files
DIR Refs
DIR LICENSE
---
DIR commit bc41fb46fe0b5458ac8c6573cc573f5000076528
DIR parent ffb388df30a18fc5cd8b198a224fa6570e40fa40
HTML Author: Anders Damsgaard <anders-dc@users.noreply.github.com>
Date: Tue, 25 Mar 2014 14:17:04 +0100
Merge pull request #5 from anders-dc/ns-cfd
Ns cfd merged into master
Diffstat:
A .gitignore | 59 +++++++++++++++++++++++++++++++
M README.rst | 125 +++++++++++--------------------
A conv-png.gp | 14 ++++++++++++++
A conv-png.sh | 10 ++++++++++
A conv.gp | 11 +++++++++++
A conv.sh | 7 +++++++
M doc/Makefile | 9 +++++++++
M doc/html/.buildinfo | 2 +-
A doc/html/_images/math/0001d02b63ed… | 0
A doc/html/_images/math/0027034d8a10… | 0
A doc/html/_images/math/01be15303939… | 0
A doc/html/_images/math/023a7668d083… | 0
A doc/html/_images/math/038474380a07… | 0
A doc/html/_images/math/048938dfaa2d… | 0
A doc/html/_images/math/04e9e1fe54cb… | 0
A doc/html/_images/math/07ff47f8ccf9… | 0
A doc/html/_images/math/082bced08237… | 0
A doc/html/_images/math/092e364e1d9d… | 0
A doc/html/_images/math/0b557fe795a3… | 0
A doc/html/_images/math/0dd32d7f3a00… | 0
A doc/html/_images/math/0e0f0c7e69e0… | 0
A doc/html/_images/math/0f06d8c03699… | 0
A doc/html/_images/math/0f1c7bcfd657… | 0
A doc/html/_images/math/0fdafcde7733… | 0
A doc/html/_images/math/1053df745e2d… | 0
A doc/html/_images/math/10e009bdb83f… | 0
A doc/html/_images/math/11cfb4109b5e… | 0
A doc/html/_images/math/13e4be57cf47… | 0
A doc/html/_images/math/16ef95610462… | 0
A doc/html/_images/math/17c2d34ded49… | 0
A doc/html/_images/math/188c175aac0a… | 0
A doc/html/_images/math/188c20d52c0d… | 0
A doc/html/_images/math/18950ecc92ec… | 0
A doc/html/_images/math/19ab21e013e1… | 0
A doc/html/_images/math/19bc0073dde1… | 0
A doc/html/_images/math/1aa208937d18… | 0
A doc/html/_images/math/1beccd9a659c… | 0
A doc/html/_images/math/1c7a111b8952… | 0
A doc/html/_images/math/1cce9b2c774a… | 0
A doc/html/_images/math/1d24d160d606… | 0
A doc/html/_images/math/1dafb53fb664… | 0
A doc/html/_images/math/1eb29f9de375… | 0
A doc/html/_images/math/1ee5b5b2fe53… | 0
A doc/html/_images/math/1ef7ab23d6fc… | 0
A doc/html/_images/math/1f9530e95b98… | 0
A doc/html/_images/math/213a272621ce… | 0
A doc/html/_images/math/22b6d9dab340… | 0
A doc/html/_images/math/249d76d0a5d3… | 0
A doc/html/_images/math/24edc4190580… | 0
A doc/html/_images/math/25586671e456… | 0
A doc/html/_images/math/257ee6442468… | 0
A doc/html/_images/math/259614407018… | 0
A doc/html/_images/math/26eeb5258ca5… | 0
A doc/html/_images/math/274ad002c530… | 0
A doc/html/_images/math/2822d1531935… | 0
A doc/html/_images/math/28d83ccd3281… | 0
A doc/html/_images/math/29bbcc61ff8f… | 0
A doc/html/_images/math/2ab5affb5906… | 0
A doc/html/_images/math/2c175f60eece… | 0
A doc/html/_images/math/2cb4dea80c94… | 0
A doc/html/_images/math/2da5f268da80… | 0
A doc/html/_images/math/2e399494a982… | 0
A doc/html/_images/math/2e9b3638163a… | 0
A doc/html/_images/math/2eb2a179a616… | 0
A doc/html/_images/math/2ede365ad144… | 0
A doc/html/_images/math/2feb7aaab806… | 0
A doc/html/_images/math/30c34e7f1dd4… | 0
A doc/html/_images/math/30d3be82eb9b… | 0
A doc/html/_images/math/30d5d726338d… | 0
A doc/html/_images/math/3118edbae1a8… | 0
A doc/html/_images/math/32e2ba09618e… | 0
A doc/html/_images/math/32e3fe27ac98… | 0
A doc/html/_images/math/33deba163d5e… | 0
A doc/html/_images/math/3426034f2cd7… | 0
A doc/html/_images/math/34857b3ba74c… | 0
A doc/html/_images/math/3536b174c0e2… | 0
A doc/html/_images/math/35ff36083d20… | 0
A doc/html/_images/math/3640b174f15a… | 0
A doc/html/_images/math/36f73fc1312e… | 0
A doc/html/_images/math/376d888029b6… | 0
A doc/html/_images/math/377d34017898… | 0
A doc/html/_images/math/37a9e7fca70e… | 0
A doc/html/_images/math/37c89c22a072… | 0
A doc/html/_images/math/38a6d1fc5607… | 0
A doc/html/_images/math/3a94e291e910… | 0
A doc/html/_images/math/3b432b0e58de… | 0
A doc/html/_images/math/3b6d032ddaf9… | 0
A doc/html/_images/math/3be873955a77… | 0
A doc/html/_images/math/3c93d2ecf99a… | 0
A doc/html/_images/math/3cbd1baf03f1… | 0
A doc/html/_images/math/3cd61688849a… | 0
A doc/html/_images/math/3d41adff4943… | 0
A doc/html/_images/math/3eca8557203e… | 0
A doc/html/_images/math/40075695a073… | 0
A doc/html/_images/math/402b1a3c2564… | 0
A doc/html/_images/math/41babe6999c8… | 0
A doc/html/_images/math/42ea00932c36… | 0
A doc/html/_images/math/43e42baf6cef… | 0
A doc/html/_images/math/44fafcf5a158… | 0
A doc/html/_images/math/458d3955e23e… | 0
A doc/html/_images/math/45abe7dac102… | 0
A doc/html/_images/math/46a84b389d8f… | 0
A doc/html/_images/math/46bc9db8fc24… | 0
A doc/html/_images/math/474638ec351b… | 0
A doc/html/_images/math/47bc1263e44f… | 0
A doc/html/_images/math/48431e4412db… | 0
A doc/html/_images/math/486938d1819d… | 0
A doc/html/_images/math/49a90589ae1e… | 0
A doc/html/_images/math/4b1fcbd538ee… | 0
A doc/html/_images/math/4d35bf3d410f… | 0
A doc/html/_images/math/4d3f01b8ca8b… | 0
A doc/html/_images/math/4f7d0530f193… | 0
A doc/html/_images/math/507deb1ebb53… | 0
A doc/html/_images/math/522c9c96bc63… | 0
A doc/html/_images/math/552e279b5cf6… | 0
A doc/html/_images/math/55f6b5380d46… | 0
A doc/html/_images/math/571952df1029… | 0
A doc/html/_images/math/587f41674d8c… | 0
A doc/html/_images/math/5b4271afe7fc… | 0
A doc/html/_images/math/5b46624e0dc3… | 0
A doc/html/_images/math/5b7072008fcf… | 0
A doc/html/_images/math/5c4e627793fb… | 0
A doc/html/_images/math/5dfeda3ba68d… | 0
A doc/html/_images/math/5ed37435199e… | 0
A doc/html/_images/math/5fb7b1a39363… | 0
A doc/html/_images/math/6089fb1f882f… | 0
A doc/html/_images/math/6160e3f2050b… | 0
A doc/html/_images/math/66a1d8738af5… | 0
A doc/html/_images/math/68e0c54203bc… | 0
A doc/html/_images/math/6922b3e4505e… | 0
A doc/html/_images/math/697df1516660… | 0
A doc/html/_images/math/69881326e514… | 0
A doc/html/_images/math/69b1fdf87f9a… | 0
A doc/html/_images/math/6adfb975053f… | 0
A doc/html/_images/math/6b038d0d06f6… | 0
A doc/html/_images/math/6ba1c18c095f… | 0
A doc/html/_images/math/6d3199b492cb… | 0
A doc/html/_images/math/6d9528f9b5d0… | 0
A doc/html/_images/math/6d9a9e0ef32e… | 0
A doc/html/_images/math/6e1feb8f41fb… | 0
A doc/html/_images/math/6e62843666dc… | 0
A doc/html/_images/math/6ed2751b928f… | 0
A doc/html/_images/math/701df29c5482… | 0
A doc/html/_images/math/70b8f6d66306… | 0
A doc/html/_images/math/7181906596d0… | 0
A doc/html/_images/math/73b4e0024361… | 0
A doc/html/_images/math/74958bc18d01… | 0
A doc/html/_images/math/74c081db590f… | 0
A doc/html/_images/math/754decd65558… | 0
A doc/html/_images/math/7572a9bb14a9… | 0
A doc/html/_images/math/767762b2cd83… | 0
A doc/html/_images/math/769bfdcb2a43… | 0
A doc/html/_images/math/7727554a4dfa… | 0
A doc/html/_images/math/7774004c6a33… | 0
A doc/html/_images/math/778fcaedc9db… | 0
A doc/html/_images/math/7851cf79108d… | 0
A doc/html/_images/math/79c874e814b2… | 0
A doc/html/_images/math/7ee03c7bfc1e… | 0
A doc/html/_images/math/7fe490dcbc6c… | 0
A doc/html/_images/math/80ba696b882e… | 0
A doc/html/_images/math/8122aa89ea6e… | 0
A doc/html/_images/math/8245434fa793… | 0
A doc/html/_images/math/84bb71d071d3… | 0
A doc/html/_images/math/852f6a447b7c… | 0
A doc/html/_images/math/860ab918d3e4… | 0
A doc/html/_images/math/88fd92ee9e46… | 0
A doc/html/_images/math/89542f863347… | 0
A doc/html/_images/math/8a2e0d0a28c9… | 0
A doc/html/_images/math/8a89933fcdf0… | 0
A doc/html/_images/math/8ad4d2540ea2… | 0
A doc/html/_images/math/8bf1a4afd4cd… | 0
M doc/html/_images/math/8c325612684d… | 0
A doc/html/_images/math/8ce03f78ed94… | 0
A doc/html/_images/math/8cfa62046b3a… | 0
A doc/html/_images/math/8dbae01b96ab… | 0
A doc/html/_images/math/8f28cef89dfa… | 0
A doc/html/_images/math/900be94839e1… | 0
A doc/html/_images/math/9035b87959dc… | 0
A doc/html/_images/math/90c8bfc206db… | 0
A doc/html/_images/math/910a79b832c4… | 0
A doc/html/_images/math/93ddc61f81c0… | 0
A doc/html/_images/math/945e8fc1c1e4… | 0
A doc/html/_images/math/954afa1fc1c8… | 0
A doc/html/_images/math/95b885fe932d… | 0
A doc/html/_images/math/967116fa65cb… | 0
A doc/html/_images/math/98a432864561… | 0
A doc/html/_images/math/99b2691ddceb… | 0
A doc/html/_images/math/9a0695dca61f… | 0
A doc/html/_images/math/9c2a28916b33… | 0
A doc/html/_images/math/9d0d9139c35e… | 0
A doc/html/_images/math/9d3cd4785fd2… | 0
A doc/html/_images/math/9d909a12ad66… | 0
A doc/html/_images/math/9f60d76fad5e… | 0
A doc/html/_images/math/a18e167e42f3… | 0
A doc/html/_images/math/a1a25b9ae9dc… | 0
A doc/html/_images/math/a1ffc0a01262… | 0
A doc/html/_images/math/a31485573165… | 0
M doc/html/_images/math/a32f407296c4… | 0
A doc/html/_images/math/a581f053bbfa… | 0
A doc/html/_images/math/a60e2d788aa8… | 0
A doc/html/_images/math/a6c493a071c2… | 0
A doc/html/_images/math/aad9832dd455… | 0
A doc/html/_images/math/ab2209a9dd14… | 0
A doc/html/_images/math/ac40b5914589… | 0
A doc/html/_images/math/ac73c7c8c596… | 0
A doc/html/_images/math/ad3d39eb3e45… | 0
A doc/html/_images/math/b124ff74afb0… | 0
A doc/html/_images/math/b143c2df6dd4… | 0
A doc/html/_images/math/b2cd17a83bb8… | 0
A doc/html/_images/math/b3cb421b6b32… | 0
A doc/html/_images/math/b4104067dcc5… | 0
A doc/html/_images/math/b4264aa4a69b… | 0
A doc/html/_images/math/b4f82fd61e3f… | 0
A doc/html/_images/math/b51a1f74e439… | 0
A doc/html/_images/math/b531a865c773… | 0
A doc/html/_images/math/b55687e1799d… | 0
A doc/html/_images/math/b55ca7a0aa88… | 0
A doc/html/_images/math/b588eea9cec4… | 0
A doc/html/_images/math/b5e8dba2403c… | 0
A doc/html/_images/math/b770d151d770… | 0
A doc/html/_images/math/b7dd9f89843e… | 0
A doc/html/_images/math/b95363838d60… | 0
A doc/html/_images/math/baa542966f41… | 0
A doc/html/_images/math/bb2c93730dbb… | 0
A doc/html/_images/math/bdc15139139f… | 0
A doc/html/_images/math/bf3f9bbcfd5e… | 0
A doc/html/_images/math/bf7f4ceb6fce… | 0
A doc/html/_images/math/bfdb965399e4… | 0
A doc/html/_images/math/c15067d0b245… | 0
A doc/html/_images/math/c305e13251e6… | 0
A doc/html/_images/math/c323bf28746b… | 0
A doc/html/_images/math/c42a32017c99… | 0
A doc/html/_images/math/c4bb40dd65ea… | 0
A doc/html/_images/math/c4f23b63471b… | 0
A doc/html/_images/math/c51284f727b4… | 0
A doc/html/_images/math/c5446f5064cc… | 0
A doc/html/_images/math/c5671cc4a4d9… | 0
A doc/html/_images/math/c65f07031d99… | 0
A doc/html/_images/math/c6e0b5935589… | 0
A doc/html/_images/math/c78863bcf0ad… | 0
A doc/html/_images/math/c8094929c952… | 0
A doc/html/_images/math/c8e734bf3818… | 0
A doc/html/_images/math/c9264cc70365… | 0
A doc/html/_images/math/cb8fa4f65175… | 0
A doc/html/_images/math/cbac43e2c13c… | 0
A doc/html/_images/math/cbe3f817ae97… | 0
A doc/html/_images/math/cd19c19fc5bc… | 0
A doc/html/_images/math/ce4f41d90f3f… | 0
A doc/html/_images/math/cf699492db92… | 0
A doc/html/_images/math/cfe0e96f0049… | 0
A doc/html/_images/math/d0b4b390a480… | 0
A doc/html/_images/math/d18b93994f64… | 0
A doc/html/_images/math/d1c6b35072ca… | 0
A doc/html/_images/math/d1e970327c74… | 0
A doc/html/_images/math/d32c78b75990… | 0
A doc/html/_images/math/d34109b1b68b… | 0
A doc/html/_images/math/d3b6fc67523d… | 0
A doc/html/_images/math/d4ba00bbbae4… | 0
A doc/html/_images/math/d5a65ff91df0… | 0
A doc/html/_images/math/d5ba56a40217… | 0
A doc/html/_images/math/d6a7ccf879c4… | 0
A doc/html/_images/math/d86c22303458… | 0
A doc/html/_images/math/da419aab4b72… | 0
A doc/html/_images/math/db94af9f89e3… | 0
A doc/html/_images/math/dbcdbe7c53fa… | 0
A doc/html/_images/math/dcf5762fe2b4… | 0
A doc/html/_images/math/dd84cb843a3b… | 0
A doc/html/_images/math/de27eb4f973d… | 0
A doc/html/_images/math/dfa75235bbe9… | 0
A doc/html/_images/math/dfc85915a4cd… | 0
A doc/html/_images/math/dfebf8b683f7… | 0
A doc/html/_images/math/e12eccdaacf4… | 0
A doc/html/_images/math/e29be0a3b865… | 0
A doc/html/_images/math/e31584cdce0b… | 0
A doc/html/_images/math/e35ec9f12692… | 0
A doc/html/_images/math/e3c6f9fd144c… | 0
A doc/html/_images/math/e3de9b8fce0b… | 0
A doc/html/_images/math/e4ca401f97df… | 0
A doc/html/_images/math/e4cd0999828f… | 0
A doc/html/_images/math/e4cd5b31b960… | 0
A doc/html/_images/math/e5101484e2ac… | 0
A doc/html/_images/math/e6eadc1093d6… | 0
A doc/html/_images/math/e8522a3d29a2… | 0
A doc/html/_images/math/e9203da50e10… | 0
A doc/html/_images/math/e9e9403195bb… | 0
A doc/html/_images/math/eaf4418fbe93… | 0
A doc/html/_images/math/eb1910746ff1… | 0
A doc/html/_images/math/ec1ce56da064… | 0
A doc/html/_images/math/edd52ffa94a4… | 0
A doc/html/_images/math/ee1817a60aae… | 0
A doc/html/_images/math/eeae8ea2feac… | 0
A doc/html/_images/math/eee8ed92791a… | 0
A doc/html/_images/math/ef18200849af… | 0
A doc/html/_images/math/f04823ba99f1… | 0
M doc/html/_images/math/f5047d1e0cbb… | 0
A doc/html/_images/math/f574498915fa… | 0
A doc/html/_images/math/f5c280d551f6… | 0
A doc/html/_images/math/f5d499efbd23… | 0
A doc/html/_images/math/f8f0dc31c5c1… | 0
A doc/html/_images/math/f9147d34f15a… | 0
A doc/html/_images/math/f915ce7b55e8… | 0
A doc/html/_images/math/f99450c7a885… | 0
A doc/html/_images/math/fa8a7b2fb896… | 0
A doc/html/_images/math/fc64cd1ec99f… | 0
A doc/html/_images/math/fca2f0caf945… | 0
A doc/html/_images/math/fd26dda3f4f5… | 0
A doc/html/_images/math/fdb63b9e51ab… | 0
A doc/html/_images/math/ff9078c25826… | 0
A doc/html/_sources/cfd.txt | 578 +++++++++++++++++++++++++++++++
M doc/html/_sources/dem.txt | 223 +++++++++++++++++++++++++++++--
M doc/html/_sources/index.txt | 34 ++++++++++++++++----------------
M doc/html/_sources/introduction.txt | 137 +++++++++++++++++++++++++------
M doc/html/_sources/python_api.txt | 22 ++++++++++++++++++++++
M doc/html/_sources/sphere_internals… | 2 --
M doc/html/_static/jquery.js | 2 +-
M doc/html/_static/pygments.css | 4 ++--
M doc/html/_static/searchtools.js | 33 +++++++++++++++++++------------
M doc/html/_static/underscore.js | 959 ++++++++++++++++++++++---------
A doc/html/cfd.html | 601 +++++++++++++++++++++++++++++++
M doc/html/dem.html | 205 +++++++++++++++++++++++++++----
M doc/html/genindex.html | 238 +++++++++++++++++++++++++------
M doc/html/index.html | 71 ++++++++++++++++++++-----------
M doc/html/introduction.html | 164 ++++++++++++++++++++++---------
M doc/html/objects.inv | 0
M doc/html/py-modindex.html | 12 ++++++------
M doc/html/python_api.html | 1899 +++++++++++++++++++++++++++----
M doc/html/search.html | 14 ++++++++------
M doc/html/searchindex.js | 4 ++--
M doc/html/sphere_internals.html | 104 ++++++++++++++++++++++---------
M doc/pdf/sphere.pdf | 0
A doc/sphinx/cfd.rst | 578 +++++++++++++++++++++++++++++++
M doc/sphinx/conf.py | 6 +++---
M doc/sphinx/dem.rst | 223 +++++++++++++++++++++++++++++--
M doc/sphinx/index.rst | 34 ++++++++++++++++----------------
M doc/sphinx/introduction.rst | 137 +++++++++++++++++++++++++------
M doc/sphinx/python_api.rst | 22 ++++++++++++++++++++++
M doc/sphinx/sphere_internals.rst | 2 --
M python/collapse.py | 10 +++-------
M python/collision.py | 17 ++++++++---------
D python/darcy.py | 87 -------------------------------
A python/ns_cons_of_mass.py | 203 +++++++++++++++++++++++++++++++
A python/ns_cons_of_mass_run.sh | 4 ++++
M python/segregation.py | 20 +++++++-------------
M python/shear-test.py | 132 ++++++++++++++++---------------
M python/sphere.py | 3098 +++++++++++++++++++++++--------
M python/uniaxial.py | 12 ++++--------
M src/CMakeLists.txt | 11 +++++++----
M src/constants.h | 2 +-
M src/contactmodels.cuh | 74 ++++++++++++++++++++-----------
M src/contactsearch.cuh | 18 ++++++++++--------
D src/darcy.cpp | 838 -------------------------------
D src/darcy.cuh | 783 ------------------------------
M src/datatypes.h | 147 +++++++++++++++++--------------
M src/debug.h | 23 +++++++++++++++++++++++
M src/device.cu | 1244 ++++++++++++++++++++-----------
M src/file_io.cpp | 143 +++++++++++++++++--------------
M src/forcechains.cpp | 41 ++++++++++++++-----------------
M src/integration.cuh | 424 ++++++++++++++++++-------------
D src/latticeboltzmann.cuh | 762 -------------------------------
M src/main.cpp | 77 +++++++++++++++++--------------
A src/navierstokes.cpp | 349 +++++++++++++++++++++++++++++++
A src/navierstokes.cuh | 2317 +++++++++++++++++++++++++++++++
A src/navierstokes_solver_parameters… | 46 +++++++++++++++++++++++++++++++
M src/porosity.cpp | 34 ++++++++++++-------------------
M src/porousflow.cpp | 3 +++
M src/sorting.cuh | 32 ++++++++++++++++++++-----------
M src/sphere.cpp | 90 ++++++++++++++++++++++---------
M src/sphere.h | 292 ++++++++++++++++---------------
M src/utility.cu | 47 +++++++++++++++++++++++++------
D src/utility.cuh | 10 ----------
M tests/CMakeLists.txt | 9 +++++++++
M tests/bond_tests.py | 14 ++++----------
A tests/cfd_tests.py | 222 ++++++++++++++++++++++++++++++
A tests/cfd_tests_neumann.py | 65 +++++++++++++++++++++++++++++++
A tests/contactmodel_wall.py | 107 +++++++++++++++++++++++++++++++
A tests/dem_cfd_tests.py | 50 +++++++++++++++++++++++++++++++
M tests/io_tests.py | 15 ++++++++++-----
M tests/io_tests_fluid.py | 19 +++++++++++--------
M tests/memcheck_tests.py | 6 +++---
M tests/porosity_tests.py | 15 ++++++++-------
M tests/pytestutils.py | 47 +++++++++++++++++++------------
T tests/sphere.py | 0
M wc.sh | 2 +-
383 files changed, 13187 insertions(+), 5319 deletions(-)
---
DIR diff --git a/.gitignore b/.gitignore
t@@ -0,0 +1,59 @@
+# Compiled source
+sphere
+porosity
+porousflow
+forcechains
+*.o
+
+# Temporary editor files
+*.swp
+*.swo
+
+# Python files
+*.pyc
+
+# Cmake files
+Makefile
+*.cmake
+*.o.depend
+*.o.cmake
+
+# Documentation temporary files
+*.ist
+*.aux
+*.idx
+*.ilg
+*.ind
+*.tex
+*.out
+*.log
+*.toc
+*.sty
+*.cls
+#*.png
+#*.txt
+#*.js
+#*.html
+#*.inv
+#*.css
+
+# Rights prohibit inclusion of NVIDIA header file
+helper_math.h
+
+# Sphere IO
+*.bin
+*.dat
+
+# Folders
+output/
+CMakeFiles
+doc/doctrees
+doc/doxygen/man
+doc/doxygen/xml
+#doc/html
+src/CMakeFiles
+src/forcechains.dir
+src/porosity.dir
+src/porousflow.dir
+src/sphere.dir
+tests/CMakeFiles
DIR diff --git a/README.rst b/README.rst
t@@ -1,84 +1,45 @@
=============
-SPHERE readme
+sphere readme
=============
-Sphere is a 3D discrete element method algorithm utilizing CUDA.
-
-Sphere is licensed under the GNU General Public License, v.3.
-See license.txt for more information.
-
-See the ``doc/`` folder for general reference, by default available in the `html
-<doc/html/index.html>`_ and `pdf <doc/pdf/sphere.pdf>`_ formats.
-
-**Update** (2013-03-13): Sphere has been updated to work with CUDA 5.0 or newer
-*only*.
-
-Requirements
-------------
-The build requirements are:
- * A Nvidia CUDA-supported version of Linux or Mac OS X (see the `CUDA toolkit
- release notes <http://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html>`_
- for more information)
- * `CMake <http://cmake.org>`_, version 2.8 or higher
- * A C/C++ compiler toolkit, e.g. the `GNU Compiler Collection
- <http://gcc.gnu.org/>`_ (GCC)
- * The `Nvidia CUDA toolkit and samples <https://developer.nvidia.com/cuda-downloads>`_, version 5.0
-
-The runtime requirements are:
- * A `CUDA-enabled GPU <http://www.nvidia.com/object/cuda_gpus.html>`_
- with compute capability 2.0 or greater.
- * A Nvidia CUDA-enabled GPU and device driver
-
-Optional tools, required/useful for simulation setup and data processing:
- * `Python 2.7 <http://www.python.org/getit/releases/2.7/>`_
- * `Numpy <http://numpy.scipy.org>`_
- * `Matplotlib <http://matplotlib.org>`_
- * `Imagemagick <http://www.imagemagick.org/script/index.php>`_
- * `ffmpeg <http://ffmpeg.org/>`_
- * `Paraview <http://www.paraview.org>`_
- * `Python-VTK <http://www.vtk.org>`_
-
-Optional tools, required for building the documentation:
- * `Sphinx <http://sphinx-doc.org>`_
- * `Doxygen <http://www.stack.nl/~dimitri/doxygen/>`_
- * `Breathe <http://michaeljones.github.com/breathe/>`_
-
-Obtaining sphere
-----------------
-The best way to keep up to date with subsequent updates, bugfixes and
-development, is to use the Git version control system. To obtain a local
-copy, execute::
- git clone https://github.com/anders-dc/sphere.git
-
-Build instructions
-------------------
-Sphere is built using `cmake`, the platform-specific c/c++ compilers,
-and `nvcc` from the cuda toolkit.
-
-If you plan to run sphere on a Kepler GPU, execute the following commands from
-the root directory::
- cmake . && make
-
-If you instead plan to execute it o a Fermi GPU, change ``set(GPU_GENERATION
-1)`` to ``set(GPU_GENERATION 0`` in `CMakeLists.txt`.
-
-In some cases the CMake FindCUDA module will have troubles locating the
-CUDA samples directory, and will complain about `helper_math.h` not being
-found.
-
-In that case, modify the ``CUDA_SDK_ROOT_DIR`` variable in `src/CMakeLists.txt`
-to the path where you installed the CUDA samples, and run ``cmake . && make``
-again. Alternatively, copy `helper_math.h` from the CUDA sample subdirectory
-`common/inc/helper_math.h` into the sphere `src/` directory, and run `cmake`
-and `make` again. Due to license restrictions, sphere cannot be distributed
-with this file.
-
-After a successfull installation, the `sphere` executable will be located
-in the root folder. To make sure that all components are working correctly,
-execute::
- make test
-
-Updating sphere
----------------
-To update your local version, type the following commands in the sphere root
-directory::
- git pull && cmake . && make
+``sphere`` is a 3D discrete element method algorithm utilizing CUDA.
+
+License
+-------
+``sphere`` is licensed under the GNU General Public License, v.3.
+See `LICENSE.txt <LICENSE.txt>`_ for more information.
+
+About this branch
+-----------------
+The git branch ``ns-cfd`` is a work in progress on implementing a Newtonian
+fluid, fully coupled to the particle dynamics, by the Navier Stokes formulation
+of computational fluid dynamics. The merge into the main branch is planned to
+mark the 1.0 release of ``sphere``.
+
+Important release notes
+-----------------------
+2013-03-13: Sphere has been updated to work with CUDA 5.0 or newer *only*.
+
+2014-01-20: Version fingerprints have been added to the input/output binary
+files, and causes old files to be incompatible with either ``sphere`` or
+``sphere.py``.
+
+2014-01-25: The description of the installation procedure is moved to the
+general documentation.
+
+2014-03-09: The main sphere class (formerly ``spherebin``) has been renamed to
+``sim``.
+
+2014-03-09: The ``writebin`` member function of the ``sim`` class is now
+implicitly called when calling the ``run`` member function.
+
+Documentation
+-------------
+See the separate documentation for general reference and installation
+instructions. The documentation is by default available in
+the `html <doc/html/index.html>`_ and `pdf <doc/pdf/sphere.pdf>`_ formats.
+
+Author
+------
+Anders Damsgaard, `anders.damsgaard@geo.au.dk <mailto:anders.damsgaard@geo.au.dk>`_,
+`blog <http://anders-dc.github.io>`_,
+`more contact information <https://cs.au.dk/~adc>`_.
DIR diff --git a/conv-png.gp b/conv-png.gp
t@@ -0,0 +1,14 @@
+#!/usr/bin/env gnuplot
+
+#set terminal pngcairo
+set terminal pngcairo background "#002b36"
+set border linecolor rgbcolor "#657b83"
+set key textcolor rgbcolor "#657b83"
+set out 'output/'.sid.'-conv.png'
+
+set title "Convergence evolution in CFD solver (".sid.")" textcolor rgb "#93a1a1"
+set xlabel "Time step" textcolor rgb "#657b83"
+set ylabel "Jacobi iterations" textcolor rgb "#657b83"
+set grid
+
+plot 'output/'.sid.'-conv.log' with linespoints notitle linecolor rgb "#657b83"
DIR diff --git a/conv-png.sh b/conv-png.sh
t@@ -0,0 +1,10 @@
+#!/bin/bash
+INTERVAL=10
+INTERVALDIV2=`expr $INTERVAL / 2`
+if [[ "$1" == "" ]]; then
+ echo "Usage: $0 <simulation id>"
+ exit 1
+else
+ feh --reload $INTERVALDIV2 --auto-zoom --image-bg black --scale-down output/${1}-conv.png &
+ watch --interval $INTERVAL --no-title gnuplot -e \"sid=\'$1\'\" conv-png.gp
+fi
DIR diff --git a/conv.gp b/conv.gp
t@@ -0,0 +1,11 @@
+#!/usr/bin/env gnuplot
+
+set terminal dumb
+#set terminal pngcairo
+#set out 'output/'.sid.'-conv.png'
+
+set title "Convergence evolution in CFD solver (".sid.")"
+set xlabel "Time step"
+set ylabel "Jacobi iterations"
+
+plot 'output/'.sid.'-conv.log' with linespoints notitle
DIR diff --git a/conv.sh b/conv.sh
t@@ -0,0 +1,7 @@
+#!/bin/bash
+if [[ "$1" == "" ]]; then
+ echo "Usage: $0 <simulation id>"
+ exit 1
+else
+ watch --interval 5 --no-title gnuplot -e \"sid=\'$1\'\" conv.gp
+fi
DIR diff --git a/doc/Makefile b/doc/Makefile
t@@ -1,2 +1,11 @@
doc:
$(MAKE) -C sphinx/
+
+install-debian-pkgs:
+ sudo apt-get update && \
+ sudo apt-get install build-essential cmake \
+ python python-numpy ipython python-matplotlib python-vtk \
+ imagemagick libav-tools \
+ python-sphinx python-pip doxygen dvipng \
+ python-sphinxcontrib-programoutput texlive-full && \
+ sudo pip install breathe
DIR diff --git a/doc/html/.buildinfo b/doc/html/.buildinfo
t@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: c1c1c2f2bea01e0223aaea2391f75c23
+config: 572cfe56c7acc603f39739a18d514093
tags: fbb0d17656682115ca4d033fb2f83ba1
DIR diff --git a/doc/html/_images/math/0001d02b63ede2fe3219e05a7cd09c82ae6298b6.png b/doc/html/_images/math/0001d02b63ede2fe3219e05a7cd09c82ae6298b6.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/0027034d8a10372a06deaf4f4084c01956587479.png b/doc/html/_images/math/0027034d8a10372a06deaf4f4084c01956587479.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/01be15303939c78ee40a848a717482d046a9ad48.png b/doc/html/_images/math/01be15303939c78ee40a848a717482d046a9ad48.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/023a7668d083165ce2aa65b49e876b83c9cb97f9.png b/doc/html/_images/math/023a7668d083165ce2aa65b49e876b83c9cb97f9.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/038474380a078000f31889a32a1dcf79ac38c223.png b/doc/html/_images/math/038474380a078000f31889a32a1dcf79ac38c223.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/048938dfaa2dd837058556eec573df345d984e62.png b/doc/html/_images/math/048938dfaa2dd837058556eec573df345d984e62.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/04e9e1fe54cb1328e049a45b0acb8c3ccb0ab888.png b/doc/html/_images/math/04e9e1fe54cb1328e049a45b0acb8c3ccb0ab888.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/07ff47f8ccf9ac490e023817a9241de75c30340c.png b/doc/html/_images/math/07ff47f8ccf9ac490e023817a9241de75c30340c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/082bced08237667a772227c2e3eb8359ff9d4af8.png b/doc/html/_images/math/082bced08237667a772227c2e3eb8359ff9d4af8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/092e364e1d9d19ad5fffb0b46ef4cc7f2da02c1c.png b/doc/html/_images/math/092e364e1d9d19ad5fffb0b46ef4cc7f2da02c1c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/0b557fe795a3a7d8b91ff1360e5610ffd6f1445f.png b/doc/html/_images/math/0b557fe795a3a7d8b91ff1360e5610ffd6f1445f.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/0dd32d7f3a000398f4982bdbe7cb1da880e33298.png b/doc/html/_images/math/0dd32d7f3a000398f4982bdbe7cb1da880e33298.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/0e0f0c7e69e0f315aed6d1762a66bf27dd9a155a.png b/doc/html/_images/math/0e0f0c7e69e0f315aed6d1762a66bf27dd9a155a.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/0f06d8c03699aa966cd6c94d11850ede3c97dc41.png b/doc/html/_images/math/0f06d8c03699aa966cd6c94d11850ede3c97dc41.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/0f1c7bcfd65708b716b8817c2e31029f9af2eedf.png b/doc/html/_images/math/0f1c7bcfd65708b716b8817c2e31029f9af2eedf.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/0fdafcde7733804669f8df4846e5bfdb36c7afa7.png b/doc/html/_images/math/0fdafcde7733804669f8df4846e5bfdb36c7afa7.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1053df745e2d73fc7ee27d39a01ad228c360072e.png b/doc/html/_images/math/1053df745e2d73fc7ee27d39a01ad228c360072e.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/10e009bdb83f96c5f47c58b34d5d4b12ef268d5b.png b/doc/html/_images/math/10e009bdb83f96c5f47c58b34d5d4b12ef268d5b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/11cfb4109b5e8ad4a3bc8b07fe844e437d139b46.png b/doc/html/_images/math/11cfb4109b5e8ad4a3bc8b07fe844e437d139b46.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/13e4be57cf47de5302fc2e1746d965a6ee0f332c.png b/doc/html/_images/math/13e4be57cf47de5302fc2e1746d965a6ee0f332c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/16ef95610462b9c2c03cba4c272fe84208bf3c61.png b/doc/html/_images/math/16ef95610462b9c2c03cba4c272fe84208bf3c61.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/17c2d34ded49c3a5cca11a4f1f20d5fe7117f964.png b/doc/html/_images/math/17c2d34ded49c3a5cca11a4f1f20d5fe7117f964.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/188c175aac0a8a9c22499336711b5d7256407254.png b/doc/html/_images/math/188c175aac0a8a9c22499336711b5d7256407254.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/188c20d52c0d5acf0ddac670950204c93791be45.png b/doc/html/_images/math/188c20d52c0d5acf0ddac670950204c93791be45.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/18950ecc92ecc7397337b5f39323453647e6434a.png b/doc/html/_images/math/18950ecc92ecc7397337b5f39323453647e6434a.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/19ab21e013e12d69147e0e08c69dc7acd69d1977.png b/doc/html/_images/math/19ab21e013e12d69147e0e08c69dc7acd69d1977.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/19bc0073dde1bcd1a8e6a32b251e80cced668f04.png b/doc/html/_images/math/19bc0073dde1bcd1a8e6a32b251e80cced668f04.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1aa208937d18ff999c2b86535c86f4dd4705c3a4.png b/doc/html/_images/math/1aa208937d18ff999c2b86535c86f4dd4705c3a4.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1beccd9a659ce57a6a8083a589fe91ad33fa3b06.png b/doc/html/_images/math/1beccd9a659ce57a6a8083a589fe91ad33fa3b06.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1c7a111b8952b4162797cce2cbd426d74083b834.png b/doc/html/_images/math/1c7a111b8952b4162797cce2cbd426d74083b834.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1cce9b2c774a84cb5198a2f138beddb46e6658b5.png b/doc/html/_images/math/1cce9b2c774a84cb5198a2f138beddb46e6658b5.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1d24d160d60604202abbae47aba869e96fb450aa.png b/doc/html/_images/math/1d24d160d60604202abbae47aba869e96fb450aa.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1dafb53fb664c1e6576fc49adc4ef6db8f31a789.png b/doc/html/_images/math/1dafb53fb664c1e6576fc49adc4ef6db8f31a789.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1eb29f9de3753a59530941141fcb5c7aa3fa2e38.png b/doc/html/_images/math/1eb29f9de3753a59530941141fcb5c7aa3fa2e38.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1ee5b5b2fe535711338cab9fde51ba86968186e2.png b/doc/html/_images/math/1ee5b5b2fe535711338cab9fde51ba86968186e2.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1ef7ab23d6fc7d336379d457f66aa6ed57d72ec9.png b/doc/html/_images/math/1ef7ab23d6fc7d336379d457f66aa6ed57d72ec9.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/1f9530e95b98c17e8dd3ed5756dd58c4ca46d46f.png b/doc/html/_images/math/1f9530e95b98c17e8dd3ed5756dd58c4ca46d46f.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/213a272621ce146fc9f90ce519bc3dc1ac3337e8.png b/doc/html/_images/math/213a272621ce146fc9f90ce519bc3dc1ac3337e8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/22b6d9dab340bfe13993da20589e4720449fe391.png b/doc/html/_images/math/22b6d9dab340bfe13993da20589e4720449fe391.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/249d76d0a5d3773b138ce498e5df46c870f402b5.png b/doc/html/_images/math/249d76d0a5d3773b138ce498e5df46c870f402b5.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/24edc419058015022fc9ef15fb0f5d8ec3109f73.png b/doc/html/_images/math/24edc419058015022fc9ef15fb0f5d8ec3109f73.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/25586671e456c2d987cd75cefd64d9cee69f50b9.png b/doc/html/_images/math/25586671e456c2d987cd75cefd64d9cee69f50b9.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/257ee6442468d7529f036a8a81e6050c3832fdbf.png b/doc/html/_images/math/257ee6442468d7529f036a8a81e6050c3832fdbf.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/25961440701892ff5417a2474f7f52bb353e5d98.png b/doc/html/_images/math/25961440701892ff5417a2474f7f52bb353e5d98.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/26eeb5258ca5099acf8fe96b2a1049c48c89a5e6.png b/doc/html/_images/math/26eeb5258ca5099acf8fe96b2a1049c48c89a5e6.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/274ad002c5303a0a45fb61cc2949cfd0e65402cd.png b/doc/html/_images/math/274ad002c5303a0a45fb61cc2949cfd0e65402cd.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2822d1531935f7a072ebaa08533f4c5695731465.png b/doc/html/_images/math/2822d1531935f7a072ebaa08533f4c5695731465.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/28d83ccd32811c0455355169ed8f6978d8d24dbe.png b/doc/html/_images/math/28d83ccd32811c0455355169ed8f6978d8d24dbe.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/29bbcc61ff8f993f8eca2f33c8faf0c7ad80defc.png b/doc/html/_images/math/29bbcc61ff8f993f8eca2f33c8faf0c7ad80defc.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2ab5affb59066624277032c5076d7227db701fd9.png b/doc/html/_images/math/2ab5affb59066624277032c5076d7227db701fd9.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2c175f60eecef1de7560c3bdea495d69f26f719d.png b/doc/html/_images/math/2c175f60eecef1de7560c3bdea495d69f26f719d.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2cb4dea80c947c94642b08f6a92ad5aa939dc9f3.png b/doc/html/_images/math/2cb4dea80c947c94642b08f6a92ad5aa939dc9f3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2da5f268da80c66e332f2a8d4520f7d6685699b6.png b/doc/html/_images/math/2da5f268da80c66e332f2a8d4520f7d6685699b6.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2e399494a98253eb4f7d0cfb51994059389bc825.png b/doc/html/_images/math/2e399494a98253eb4f7d0cfb51994059389bc825.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2e9b3638163af9fc450acac1aba9911e57a5c691.png b/doc/html/_images/math/2e9b3638163af9fc450acac1aba9911e57a5c691.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2eb2a179a6165db84b51c4dc8066b31cd012594f.png b/doc/html/_images/math/2eb2a179a6165db84b51c4dc8066b31cd012594f.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2ede365ad144ab396916ec60458da03860803078.png b/doc/html/_images/math/2ede365ad144ab396916ec60458da03860803078.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/2feb7aaab8068a8c48febc6a15a008f5dfcea9f7.png b/doc/html/_images/math/2feb7aaab8068a8c48febc6a15a008f5dfcea9f7.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/30c34e7f1dd419d28236bdff05af10a01cdd635c.png b/doc/html/_images/math/30c34e7f1dd419d28236bdff05af10a01cdd635c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/30d3be82eb9bf820400a3dc3e46e84fe58e9f2c9.png b/doc/html/_images/math/30d3be82eb9bf820400a3dc3e46e84fe58e9f2c9.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/30d5d726338d5b3ac9d9b0003c564594fd6176ce.png b/doc/html/_images/math/30d5d726338d5b3ac9d9b0003c564594fd6176ce.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3118edbae1a8f9f568f293112ccb85a253fb3608.png b/doc/html/_images/math/3118edbae1a8f9f568f293112ccb85a253fb3608.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/32e2ba09618e2d303d91d673a25ef66e29e94750.png b/doc/html/_images/math/32e2ba09618e2d303d91d673a25ef66e29e94750.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/32e3fe27ac9815b323560775c3f6fcb2b6111edc.png b/doc/html/_images/math/32e3fe27ac9815b323560775c3f6fcb2b6111edc.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/33deba163d5e5027dea810eec538e06a1683ddf1.png b/doc/html/_images/math/33deba163d5e5027dea810eec538e06a1683ddf1.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3426034f2cd72ab441922edec729ae5d5212f047.png b/doc/html/_images/math/3426034f2cd72ab441922edec729ae5d5212f047.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/34857b3ba74ce5cd8607f3ebd23e9015908ada71.png b/doc/html/_images/math/34857b3ba74ce5cd8607f3ebd23e9015908ada71.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3536b174c0e21a837eb33434bbcdfc2ab566d161.png b/doc/html/_images/math/3536b174c0e21a837eb33434bbcdfc2ab566d161.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/35ff36083d208f671a3ed540e1b95395aa2ae10c.png b/doc/html/_images/math/35ff36083d208f671a3ed540e1b95395aa2ae10c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3640b174f15a44d33ad8f0622bc44dce8d8f1692.png b/doc/html/_images/math/3640b174f15a44d33ad8f0622bc44dce8d8f1692.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/36f73fc1312ee0349b3f3a0f3bd9eb5504339011.png b/doc/html/_images/math/36f73fc1312ee0349b3f3a0f3bd9eb5504339011.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/376d888029b69634b51a843c71cf75ba713b4821.png b/doc/html/_images/math/376d888029b69634b51a843c71cf75ba713b4821.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/377d34017898a24f5ba5ee9eba0c1d4d8834d456.png b/doc/html/_images/math/377d34017898a24f5ba5ee9eba0c1d4d8834d456.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/37a9e7fca70e2dce829d902af2088735306bc1a3.png b/doc/html/_images/math/37a9e7fca70e2dce829d902af2088735306bc1a3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/37c89c22a0720d39bbe2dbbc72749255662437dc.png b/doc/html/_images/math/37c89c22a0720d39bbe2dbbc72749255662437dc.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/38a6d1fc56073806115322bcd179578f05c88c02.png b/doc/html/_images/math/38a6d1fc56073806115322bcd179578f05c88c02.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3a94e291e91082dc48a18009bdd3fd70ebedec76.png b/doc/html/_images/math/3a94e291e91082dc48a18009bdd3fd70ebedec76.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3b432b0e58dea7c6cc143bf67184fc19b8cd4336.png b/doc/html/_images/math/3b432b0e58dea7c6cc143bf67184fc19b8cd4336.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3b6d032ddaf923f920fc753c9259dfc5cb626837.png b/doc/html/_images/math/3b6d032ddaf923f920fc753c9259dfc5cb626837.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3be873955a777b3d292f2477e3cc7ba40d1e7897.png b/doc/html/_images/math/3be873955a777b3d292f2477e3cc7ba40d1e7897.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3c93d2ecf99a3c5ee161c98a3ac0040e1b446e09.png b/doc/html/_images/math/3c93d2ecf99a3c5ee161c98a3ac0040e1b446e09.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3cbd1baf03f10cad8678746742cebc8176bdb593.png b/doc/html/_images/math/3cbd1baf03f10cad8678746742cebc8176bdb593.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3cd61688849a22b05ca6c56c937561798da99ef8.png b/doc/html/_images/math/3cd61688849a22b05ca6c56c937561798da99ef8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3d41adff4943d60236fa626d0bae8e238483278a.png b/doc/html/_images/math/3d41adff4943d60236fa626d0bae8e238483278a.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/3eca8557203e86160952e1c0f735f7417f3285b1.png b/doc/html/_images/math/3eca8557203e86160952e1c0f735f7417f3285b1.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/40075695a073185f493a613d8dc7560042b2ae57.png b/doc/html/_images/math/40075695a073185f493a613d8dc7560042b2ae57.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/402b1a3c25643899cdefbe2e62d33eab43b4f616.png b/doc/html/_images/math/402b1a3c25643899cdefbe2e62d33eab43b4f616.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/41babe6999c89406f22db1ce5ed5e05ce939ed49.png b/doc/html/_images/math/41babe6999c89406f22db1ce5ed5e05ce939ed49.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/42ea00932c36940fb8965e6e7f4fb2de5d616ee7.png b/doc/html/_images/math/42ea00932c36940fb8965e6e7f4fb2de5d616ee7.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/43e42baf6cef7e9620082be300b7622d524b3a65.png b/doc/html/_images/math/43e42baf6cef7e9620082be300b7622d524b3a65.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/44fafcf5a158459730d0dd7c293b93cdcf62f0a4.png b/doc/html/_images/math/44fafcf5a158459730d0dd7c293b93cdcf62f0a4.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/458d3955e23ef7ba378c27f284a2e426f756bd3e.png b/doc/html/_images/math/458d3955e23ef7ba378c27f284a2e426f756bd3e.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/45abe7dac102080bf806c2bb40d20c9dab2e4fcb.png b/doc/html/_images/math/45abe7dac102080bf806c2bb40d20c9dab2e4fcb.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/46a84b389d8f594cd16c800ba4267f3cac5e2f30.png b/doc/html/_images/math/46a84b389d8f594cd16c800ba4267f3cac5e2f30.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/46bc9db8fc244ad2bbb5de57bfd7e8a595298471.png b/doc/html/_images/math/46bc9db8fc244ad2bbb5de57bfd7e8a595298471.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/474638ec351b4bfa321564aa3ea75c6a6b16b24c.png b/doc/html/_images/math/474638ec351b4bfa321564aa3ea75c6a6b16b24c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/47bc1263e44f1b74fd90da02d9e7c26bf4b9edbe.png b/doc/html/_images/math/47bc1263e44f1b74fd90da02d9e7c26bf4b9edbe.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/48431e4412db6b2ffa7904f013daf5c0d6c61949.png b/doc/html/_images/math/48431e4412db6b2ffa7904f013daf5c0d6c61949.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/486938d1819df5972cb80ef2d101517b20412366.png b/doc/html/_images/math/486938d1819df5972cb80ef2d101517b20412366.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/49a90589ae1e8a839b1ae6afb3dd1d162b6a094c.png b/doc/html/_images/math/49a90589ae1e8a839b1ae6afb3dd1d162b6a094c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/4b1fcbd538ee9de974b2fbde2b253dfe843ab0e7.png b/doc/html/_images/math/4b1fcbd538ee9de974b2fbde2b253dfe843ab0e7.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/4d35bf3d410f89d028f8652665f0950344b89f41.png b/doc/html/_images/math/4d35bf3d410f89d028f8652665f0950344b89f41.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/4d3f01b8ca8bdab3543eda695ff7e565bcb66381.png b/doc/html/_images/math/4d3f01b8ca8bdab3543eda695ff7e565bcb66381.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/4f7d0530f1939c40a7c9e65b7ecee0e476ac4817.png b/doc/html/_images/math/4f7d0530f1939c40a7c9e65b7ecee0e476ac4817.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/507deb1ebb53483473057e3bcb372d5c8553148b.png b/doc/html/_images/math/507deb1ebb53483473057e3bcb372d5c8553148b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/522c9c96bc63142fa2b83abe960622dcafd75875.png b/doc/html/_images/math/522c9c96bc63142fa2b83abe960622dcafd75875.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/552e279b5cf6a34bb7787589bb4d4e67df465e7d.png b/doc/html/_images/math/552e279b5cf6a34bb7787589bb4d4e67df465e7d.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/55f6b5380d462f954b65d7a2cd05e02ff8cc832e.png b/doc/html/_images/math/55f6b5380d462f954b65d7a2cd05e02ff8cc832e.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/571952df10295a1251ad68112796e94f3fc54598.png b/doc/html/_images/math/571952df10295a1251ad68112796e94f3fc54598.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/587f41674d8c1e5f151655cc5567c7f12cfea34a.png b/doc/html/_images/math/587f41674d8c1e5f151655cc5567c7f12cfea34a.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/5b4271afe7fc7c0ee84172e0ad19b82caf450c00.png b/doc/html/_images/math/5b4271afe7fc7c0ee84172e0ad19b82caf450c00.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/5b46624e0dc3d79b64f388898e2dff17d232656c.png b/doc/html/_images/math/5b46624e0dc3d79b64f388898e2dff17d232656c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/5b7072008fcf4dedaeed4d537fe5c808adedb826.png b/doc/html/_images/math/5b7072008fcf4dedaeed4d537fe5c808adedb826.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/5c4e627793fb72f14a14540abaf5b0789767498b.png b/doc/html/_images/math/5c4e627793fb72f14a14540abaf5b0789767498b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/5dfeda3ba68db3f629c37ad0b4cc75095c2d6570.png b/doc/html/_images/math/5dfeda3ba68db3f629c37ad0b4cc75095c2d6570.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/5ed37435199e280338e0e6dc0c225e4230719b0a.png b/doc/html/_images/math/5ed37435199e280338e0e6dc0c225e4230719b0a.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/5fb7b1a39363304fc1fb9172ecd46e2f39274384.png b/doc/html/_images/math/5fb7b1a39363304fc1fb9172ecd46e2f39274384.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6089fb1f882f20c5b7ccbf543244d38b88c99494.png b/doc/html/_images/math/6089fb1f882f20c5b7ccbf543244d38b88c99494.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6160e3f2050b4cd56b336ff552386a169aa51db8.png b/doc/html/_images/math/6160e3f2050b4cd56b336ff552386a169aa51db8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/66a1d8738af515286414e18d76a6e7f86b989afc.png b/doc/html/_images/math/66a1d8738af515286414e18d76a6e7f86b989afc.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/68e0c54203bc81b45ebe5dbf7d89fc61aa794c1e.png b/doc/html/_images/math/68e0c54203bc81b45ebe5dbf7d89fc61aa794c1e.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6922b3e4505e825344dc326ade5f0c4be45ddd2f.png b/doc/html/_images/math/6922b3e4505e825344dc326ade5f0c4be45ddd2f.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/697df15166603b27c129b6191e2c96c022ea7932.png b/doc/html/_images/math/697df15166603b27c129b6191e2c96c022ea7932.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/69881326e5149864bc6319edea6786188e8d9a94.png b/doc/html/_images/math/69881326e5149864bc6319edea6786188e8d9a94.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/69b1fdf87f9a78aaef8057a34aea7a6c17dad726.png b/doc/html/_images/math/69b1fdf87f9a78aaef8057a34aea7a6c17dad726.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6adfb975053fd90151158bd3317e9b2a04f20d14.png b/doc/html/_images/math/6adfb975053fd90151158bd3317e9b2a04f20d14.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6b038d0d06f6fa38bcb85df9e6f8bed4155ded47.png b/doc/html/_images/math/6b038d0d06f6fa38bcb85df9e6f8bed4155ded47.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6ba1c18c095ff64c7d7b9eaa38630f7ae5dd31e3.png b/doc/html/_images/math/6ba1c18c095ff64c7d7b9eaa38630f7ae5dd31e3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6d3199b492cb754c4cc895caf129a6e9c0f82f44.png b/doc/html/_images/math/6d3199b492cb754c4cc895caf129a6e9c0f82f44.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6d9528f9b5d0a2feda7dca87d5d1e8523d7cc4b1.png b/doc/html/_images/math/6d9528f9b5d0a2feda7dca87d5d1e8523d7cc4b1.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6d9a9e0ef32ea9506bb55413b682112d0f3308a6.png b/doc/html/_images/math/6d9a9e0ef32ea9506bb55413b682112d0f3308a6.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6e1feb8f41fb33ffbf60f657c5e095c2bb780e4d.png b/doc/html/_images/math/6e1feb8f41fb33ffbf60f657c5e095c2bb780e4d.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6e62843666dcc0fe9a45a1c69c532c82a95a9451.png b/doc/html/_images/math/6e62843666dcc0fe9a45a1c69c532c82a95a9451.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/6ed2751b928fdd78923983eb490cb347a1eac8b8.png b/doc/html/_images/math/6ed2751b928fdd78923983eb490cb347a1eac8b8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/701df29c5482cdf1e577052c537c176f5a12caf5.png b/doc/html/_images/math/701df29c5482cdf1e577052c537c176f5a12caf5.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/70b8f6d6630631ad7de5c587e511247f1ce2afe9.png b/doc/html/_images/math/70b8f6d6630631ad7de5c587e511247f1ce2afe9.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/7181906596d0aaac14cbde44ec57dd7e5866c81b.png b/doc/html/_images/math/7181906596d0aaac14cbde44ec57dd7e5866c81b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/73b4e0024361fb95f692baa527cca76a384fdae0.png b/doc/html/_images/math/73b4e0024361fb95f692baa527cca76a384fdae0.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/74958bc18d017328dd0fac99816d2184296bfd3d.png b/doc/html/_images/math/74958bc18d017328dd0fac99816d2184296bfd3d.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/74c081db590f3d35421c1f6b9afd4cdda36ee210.png b/doc/html/_images/math/74c081db590f3d35421c1f6b9afd4cdda36ee210.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/754decd655584a824e0979fc2df27ae24379558e.png b/doc/html/_images/math/754decd655584a824e0979fc2df27ae24379558e.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/7572a9bb14a95da7f7b42fd4b5bec33c42800556.png b/doc/html/_images/math/7572a9bb14a95da7f7b42fd4b5bec33c42800556.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/767762b2cd832672331c1421813b919298d7e3b8.png b/doc/html/_images/math/767762b2cd832672331c1421813b919298d7e3b8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/769bfdcb2a43bde2cd368d82a6f64bd68c876c99.png b/doc/html/_images/math/769bfdcb2a43bde2cd368d82a6f64bd68c876c99.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/7727554a4dfa1572695dec332d6f6ee255815c96.png b/doc/html/_images/math/7727554a4dfa1572695dec332d6f6ee255815c96.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/7774004c6a3397305cc7616b705accbbbfb28632.png b/doc/html/_images/math/7774004c6a3397305cc7616b705accbbbfb28632.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/778fcaedc9db6a87be6c2b7feac7164e55090c5b.png b/doc/html/_images/math/778fcaedc9db6a87be6c2b7feac7164e55090c5b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/7851cf79108da000ebe09e52f7a34a7fa2092517.png b/doc/html/_images/math/7851cf79108da000ebe09e52f7a34a7fa2092517.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/79c874e814b2550448c61e2627dc072653b68197.png b/doc/html/_images/math/79c874e814b2550448c61e2627dc072653b68197.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/7ee03c7bfc1e46255c9d2d47d9b733a068c9ec2b.png b/doc/html/_images/math/7ee03c7bfc1e46255c9d2d47d9b733a068c9ec2b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/7fe490dcbc6c9eb978f05b3334d2a5856dc66149.png b/doc/html/_images/math/7fe490dcbc6c9eb978f05b3334d2a5856dc66149.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/80ba696b882e52c7e4d833039710ff8b4005e777.png b/doc/html/_images/math/80ba696b882e52c7e4d833039710ff8b4005e777.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8122aa89ea6e80784c6513d22787ad86e36ad0cc.png b/doc/html/_images/math/8122aa89ea6e80784c6513d22787ad86e36ad0cc.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8245434fa7935d53a0382eb3cc425ce09de36913.png b/doc/html/_images/math/8245434fa7935d53a0382eb3cc425ce09de36913.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/84bb71d071d3747a4a76292f75c6bb6c2ac15243.png b/doc/html/_images/math/84bb71d071d3747a4a76292f75c6bb6c2ac15243.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/852f6a447b7ccf231f8e43dbcce1ae99280f8020.png b/doc/html/_images/math/852f6a447b7ccf231f8e43dbcce1ae99280f8020.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/860ab918d3e4c8f25b17d691cca049073dab88a0.png b/doc/html/_images/math/860ab918d3e4c8f25b17d691cca049073dab88a0.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/88fd92ee9e463bf55236c5ffe73c46480533b1dd.png b/doc/html/_images/math/88fd92ee9e463bf55236c5ffe73c46480533b1dd.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/89542f86334781895f1f8146368f4a6a3fa58986.png b/doc/html/_images/math/89542f86334781895f1f8146368f4a6a3fa58986.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8a2e0d0a28c9ebec91bd12def7b3b36dd9e92da7.png b/doc/html/_images/math/8a2e0d0a28c9ebec91bd12def7b3b36dd9e92da7.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8a89933fcdf0cde2a59b18d267abc2ce124940d0.png b/doc/html/_images/math/8a89933fcdf0cde2a59b18d267abc2ce124940d0.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8ad4d2540ea2fe0c871b3eb896b64f22018d9bdf.png b/doc/html/_images/math/8ad4d2540ea2fe0c871b3eb896b64f22018d9bdf.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8bf1a4afd4cdf42bf3f7b27c9d9c99377a5d1898.png b/doc/html/_images/math/8bf1a4afd4cdf42bf3f7b27c9d9c99377a5d1898.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8c325612684d41304b9751c175df7bcc0f61f64f.png b/doc/html/_images/math/8c325612684d41304b9751c175df7bcc0f61f64f.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8ce03f78ed945f2ef3dac87c8799b55b393527e7.png b/doc/html/_images/math/8ce03f78ed945f2ef3dac87c8799b55b393527e7.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8cfa62046b3a57f37068f027941acea702d9bd8a.png b/doc/html/_images/math/8cfa62046b3a57f37068f027941acea702d9bd8a.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8dbae01b96ab8dd591a50213f55caa3ac5958631.png b/doc/html/_images/math/8dbae01b96ab8dd591a50213f55caa3ac5958631.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/8f28cef89dfa1989be5e263ac228a61a92736da9.png b/doc/html/_images/math/8f28cef89dfa1989be5e263ac228a61a92736da9.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/900be94839e1ee03a8aa1134961912314905eb27.png b/doc/html/_images/math/900be94839e1ee03a8aa1134961912314905eb27.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/9035b87959dc0646562a6d53308049cc922156bb.png b/doc/html/_images/math/9035b87959dc0646562a6d53308049cc922156bb.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/90c8bfc206db2d9f4d0dd102507c9646a70755db.png b/doc/html/_images/math/90c8bfc206db2d9f4d0dd102507c9646a70755db.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/910a79b832c4678163ca0d7ec5285ed700df12da.png b/doc/html/_images/math/910a79b832c4678163ca0d7ec5285ed700df12da.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/93ddc61f81c056650ee9c02c3e62ed84e4a5327f.png b/doc/html/_images/math/93ddc61f81c056650ee9c02c3e62ed84e4a5327f.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/945e8fc1c1e499c337c7dcdd142bb39604d56309.png b/doc/html/_images/math/945e8fc1c1e499c337c7dcdd142bb39604d56309.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/954afa1fc1c88d82f51ab22e64b4a7450a89f755.png b/doc/html/_images/math/954afa1fc1c88d82f51ab22e64b4a7450a89f755.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/95b885fe932dd6fbab3f54e7ed819923deea95fb.png b/doc/html/_images/math/95b885fe932dd6fbab3f54e7ed819923deea95fb.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/967116fa65cb7eb073c2f71309b21af6aca77a09.png b/doc/html/_images/math/967116fa65cb7eb073c2f71309b21af6aca77a09.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/98a432864561550105d4de621bc0a9b61068c043.png b/doc/html/_images/math/98a432864561550105d4de621bc0a9b61068c043.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/99b2691ddceb12733ac3509c90c732bed0c96e77.png b/doc/html/_images/math/99b2691ddceb12733ac3509c90c732bed0c96e77.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/9a0695dca61ffb4f70433158cdbfcd205c439e26.png b/doc/html/_images/math/9a0695dca61ffb4f70433158cdbfcd205c439e26.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/9c2a28916b33bc70a170729d2f237eabae96c0c0.png b/doc/html/_images/math/9c2a28916b33bc70a170729d2f237eabae96c0c0.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/9d0d9139c35e749d7b4698592c91045d086d8b99.png b/doc/html/_images/math/9d0d9139c35e749d7b4698592c91045d086d8b99.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/9d3cd4785fd2621936d97aa60cb5005a7e95b5b7.png b/doc/html/_images/math/9d3cd4785fd2621936d97aa60cb5005a7e95b5b7.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/9d909a12ad669a49e201a6d94b4211c7aeebb68c.png b/doc/html/_images/math/9d909a12ad669a49e201a6d94b4211c7aeebb68c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/9f60d76fad5e82e626deca0a8d7c986640b417f3.png b/doc/html/_images/math/9f60d76fad5e82e626deca0a8d7c986640b417f3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/a18e167e42f3575a85b73c2e10114ff027067640.png b/doc/html/_images/math/a18e167e42f3575a85b73c2e10114ff027067640.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/a1a25b9ae9dc5911e30e15d5ca2fc5ee8234f1f1.png b/doc/html/_images/math/a1a25b9ae9dc5911e30e15d5ca2fc5ee8234f1f1.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/a1ffc0a012620941fe660cedabff822ce7162eca.png b/doc/html/_images/math/a1ffc0a012620941fe660cedabff822ce7162eca.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/a314855731651c7f7c4be200464c677d127f9015.png b/doc/html/_images/math/a314855731651c7f7c4be200464c677d127f9015.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/a32f407296c4d7fd42fe568d2ad7e8fa81f2df27.png b/doc/html/_images/math/a32f407296c4d7fd42fe568d2ad7e8fa81f2df27.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/a581f053bbfa5115f42c13094857cdd12a37ec49.png b/doc/html/_images/math/a581f053bbfa5115f42c13094857cdd12a37ec49.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/a60e2d788aa8bf7ab909fe82a1cca56107dd12e5.png b/doc/html/_images/math/a60e2d788aa8bf7ab909fe82a1cca56107dd12e5.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/a6c493a071c2c31758bc2bc9adc2beb10d7acfd0.png b/doc/html/_images/math/a6c493a071c2c31758bc2bc9adc2beb10d7acfd0.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/aad9832dd45598090e4be6aaeeaa038dfc093751.png b/doc/html/_images/math/aad9832dd45598090e4be6aaeeaa038dfc093751.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/ab2209a9dd144b06f80bd8b7426bd8b1549be50a.png b/doc/html/_images/math/ab2209a9dd144b06f80bd8b7426bd8b1549be50a.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/ac40b59145892a5a3c0141c5f35023ad85972855.png b/doc/html/_images/math/ac40b59145892a5a3c0141c5f35023ad85972855.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/ac73c7c8c596c32306e6ea203ebd039dd3538f06.png b/doc/html/_images/math/ac73c7c8c596c32306e6ea203ebd039dd3538f06.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/ad3d39eb3e45536da2964b7ddf2bc114090510a6.png b/doc/html/_images/math/ad3d39eb3e45536da2964b7ddf2bc114090510a6.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b124ff74afb0914bb434e8fb849eb56d734412f8.png b/doc/html/_images/math/b124ff74afb0914bb434e8fb849eb56d734412f8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b143c2df6dd4371fa6776f781e9b531868607b86.png b/doc/html/_images/math/b143c2df6dd4371fa6776f781e9b531868607b86.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b2cd17a83bb89dc6b4ff954979dba3b2fbc8e043.png b/doc/html/_images/math/b2cd17a83bb89dc6b4ff954979dba3b2fbc8e043.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b3cb421b6b325deff2bde26de2fa150f94c73246.png b/doc/html/_images/math/b3cb421b6b325deff2bde26de2fa150f94c73246.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b4104067dcc504da8eada0697129bcae9f7cf9b6.png b/doc/html/_images/math/b4104067dcc504da8eada0697129bcae9f7cf9b6.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b4264aa4a69bcd11064747964ae4d69f61174136.png b/doc/html/_images/math/b4264aa4a69bcd11064747964ae4d69f61174136.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b4f82fd61e3f0ad9fbe9067bcf126248eb498b74.png b/doc/html/_images/math/b4f82fd61e3f0ad9fbe9067bcf126248eb498b74.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b51a1f74e439e8b3b84c8fe25870d53a571391ef.png b/doc/html/_images/math/b51a1f74e439e8b3b84c8fe25870d53a571391ef.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b531a865c77331b7c227b22a91e1aa74a8746db3.png b/doc/html/_images/math/b531a865c77331b7c227b22a91e1aa74a8746db3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b55687e1799df2d682b5ba0c207ca16fa9c014fe.png b/doc/html/_images/math/b55687e1799df2d682b5ba0c207ca16fa9c014fe.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b55ca7a0aa88ab7d58f4fc035317fdac39b17861.png b/doc/html/_images/math/b55ca7a0aa88ab7d58f4fc035317fdac39b17861.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b588eea9cec4513a3be72255d8d3df214546bfe7.png b/doc/html/_images/math/b588eea9cec4513a3be72255d8d3df214546bfe7.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b5e8dba2403c0723e1ff60ac53116252af8aeb64.png b/doc/html/_images/math/b5e8dba2403c0723e1ff60ac53116252af8aeb64.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b770d151d770160624bb46bf874ebf6f508cf50f.png b/doc/html/_images/math/b770d151d770160624bb46bf874ebf6f508cf50f.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b7dd9f89843eb79d04a50776ab962d81e72223e6.png b/doc/html/_images/math/b7dd9f89843eb79d04a50776ab962d81e72223e6.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/b95363838d60e863c4cb530ba409fa56dd735728.png b/doc/html/_images/math/b95363838d60e863c4cb530ba409fa56dd735728.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/baa542966f410097c2b4894388e41db6aa3cd996.png b/doc/html/_images/math/baa542966f410097c2b4894388e41db6aa3cd996.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/bb2c93730dbb48558bb3c4738c956c4e8f816437.png b/doc/html/_images/math/bb2c93730dbb48558bb3c4738c956c4e8f816437.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/bdc15139139f2cc22f5656d0456d7b432a72c4e8.png b/doc/html/_images/math/bdc15139139f2cc22f5656d0456d7b432a72c4e8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/bf3f9bbcfd5ec66f5d3cf9863e4ff0f76834a7ab.png b/doc/html/_images/math/bf3f9bbcfd5ec66f5d3cf9863e4ff0f76834a7ab.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/bf7f4ceb6fce455ca0347cd7b704321b92e04f8c.png b/doc/html/_images/math/bf7f4ceb6fce455ca0347cd7b704321b92e04f8c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/bfdb965399e4a77f861930aaf9123ed14f72c98c.png b/doc/html/_images/math/bfdb965399e4a77f861930aaf9123ed14f72c98c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c15067d0b2458f2c3bfd62743d7309f7e48213f9.png b/doc/html/_images/math/c15067d0b2458f2c3bfd62743d7309f7e48213f9.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c305e13251e69e8ce59b2908f84afbbd085b5103.png b/doc/html/_images/math/c305e13251e69e8ce59b2908f84afbbd085b5103.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c323bf28746b8e2634c8d9fcf563736b0fa3f8d7.png b/doc/html/_images/math/c323bf28746b8e2634c8d9fcf563736b0fa3f8d7.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c42a32017c99646f19bb5807728595d4526c3b30.png b/doc/html/_images/math/c42a32017c99646f19bb5807728595d4526c3b30.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c4bb40dd65eae6c11b325989b14e0b8d35e4e3ef.png b/doc/html/_images/math/c4bb40dd65eae6c11b325989b14e0b8d35e4e3ef.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c4f23b63471bb0807346dc89db91e3a684cfa236.png b/doc/html/_images/math/c4f23b63471bb0807346dc89db91e3a684cfa236.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c51284f727b4cb7dac214d351742114146795074.png b/doc/html/_images/math/c51284f727b4cb7dac214d351742114146795074.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c5446f5064ccacb0879e4de7125d4ba077989b35.png b/doc/html/_images/math/c5446f5064ccacb0879e4de7125d4ba077989b35.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c5671cc4a4d93628081c7bf7c0fd2cc6ff6c1cd3.png b/doc/html/_images/math/c5671cc4a4d93628081c7bf7c0fd2cc6ff6c1cd3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c65f07031d99ff5cc529d9ed7df0c615e9a4f1d3.png b/doc/html/_images/math/c65f07031d99ff5cc529d9ed7df0c615e9a4f1d3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c6e0b5935589b4f8948c91faa0de425bf2791db4.png b/doc/html/_images/math/c6e0b5935589b4f8948c91faa0de425bf2791db4.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c78863bcf0ada3d17f98c21c00ca8b115f6b61de.png b/doc/html/_images/math/c78863bcf0ada3d17f98c21c00ca8b115f6b61de.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c8094929c9526b00e767a432d17e2668a910af82.png b/doc/html/_images/math/c8094929c9526b00e767a432d17e2668a910af82.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c8e734bf3818506e254ebfa35047a7957546c2f8.png b/doc/html/_images/math/c8e734bf3818506e254ebfa35047a7957546c2f8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/c9264cc703654b5651cb89a1c9f5e178b5d15cd0.png b/doc/html/_images/math/c9264cc703654b5651cb89a1c9f5e178b5d15cd0.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/cb8fa4f651751e20465cefe0f4795667b8b948fa.png b/doc/html/_images/math/cb8fa4f651751e20465cefe0f4795667b8b948fa.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/cbac43e2c13c3cbcec9f19adc7d3fd94eaf6c15e.png b/doc/html/_images/math/cbac43e2c13c3cbcec9f19adc7d3fd94eaf6c15e.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/cbe3f817ae974accdf9d422c0df8f6c90721037c.png b/doc/html/_images/math/cbe3f817ae974accdf9d422c0df8f6c90721037c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/cd19c19fc5bc5f4d74c11dbaf2e135eb5d6a0ed5.png b/doc/html/_images/math/cd19c19fc5bc5f4d74c11dbaf2e135eb5d6a0ed5.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/ce4f41d90f3fea6e5313ad3c0e8aac4f969ef16b.png b/doc/html/_images/math/ce4f41d90f3fea6e5313ad3c0e8aac4f969ef16b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/cf699492db927585a503d73d1c8a8e93d3fd1567.png b/doc/html/_images/math/cf699492db927585a503d73d1c8a8e93d3fd1567.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/cfe0e96f004950d55bc7f58233eedae9f8b6abc1.png b/doc/html/_images/math/cfe0e96f004950d55bc7f58233eedae9f8b6abc1.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d0b4b390a4806bb739c6b4adbdf572347ecda952.png b/doc/html/_images/math/d0b4b390a4806bb739c6b4adbdf572347ecda952.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d18b93994f644beb72edf4196d4efed3caf5b19c.png b/doc/html/_images/math/d18b93994f644beb72edf4196d4efed3caf5b19c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d1c6b35072ca09fd5e1086a11c0a176d2e3340bf.png b/doc/html/_images/math/d1c6b35072ca09fd5e1086a11c0a176d2e3340bf.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d1e970327c74ae0d8249c6283d2e3134d042f6ff.png b/doc/html/_images/math/d1e970327c74ae0d8249c6283d2e3134d042f6ff.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d32c78b759903e3f4bd4fd2ce0b86358f7500c5d.png b/doc/html/_images/math/d32c78b759903e3f4bd4fd2ce0b86358f7500c5d.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d34109b1b68b9bfbd209053492066ff04075aa16.png b/doc/html/_images/math/d34109b1b68b9bfbd209053492066ff04075aa16.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d3b6fc67523d073c5f5a8ef0911bd24af5a24c7f.png b/doc/html/_images/math/d3b6fc67523d073c5f5a8ef0911bd24af5a24c7f.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d4ba00bbbae4f7118119ee537685dcf90c0fc27c.png b/doc/html/_images/math/d4ba00bbbae4f7118119ee537685dcf90c0fc27c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d5a65ff91df0d520048831e9320e60b4b8d6ce50.png b/doc/html/_images/math/d5a65ff91df0d520048831e9320e60b4b8d6ce50.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d5ba56a402179916023ef587910f0beff5ea1608.png b/doc/html/_images/math/d5ba56a402179916023ef587910f0beff5ea1608.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d6a7ccf879c4a4fe694033606332cb83806db296.png b/doc/html/_images/math/d6a7ccf879c4a4fe694033606332cb83806db296.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/d86c223034583bbd6c0fb7533a09ea48e931cb9b.png b/doc/html/_images/math/d86c223034583bbd6c0fb7533a09ea48e931cb9b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/da419aab4b72e8996af952ad9802b6773a6e9135.png b/doc/html/_images/math/da419aab4b72e8996af952ad9802b6773a6e9135.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/db94af9f89e3d01956eca6e0dc1be147b0bd4246.png b/doc/html/_images/math/db94af9f89e3d01956eca6e0dc1be147b0bd4246.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/dbcdbe7c53fa70f8517907ca1b3c440b28512dfc.png b/doc/html/_images/math/dbcdbe7c53fa70f8517907ca1b3c440b28512dfc.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/dcf5762fe2b4b81adb93ee084951f42a2f1eadbc.png b/doc/html/_images/math/dcf5762fe2b4b81adb93ee084951f42a2f1eadbc.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/dd84cb843a3b1f44c09b5e49fb02ad7ff526920d.png b/doc/html/_images/math/dd84cb843a3b1f44c09b5e49fb02ad7ff526920d.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/de27eb4f973d27763dc4d176bf2453607ecaae42.png b/doc/html/_images/math/de27eb4f973d27763dc4d176bf2453607ecaae42.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/dfa75235bbe9a4311f49a1644137fd212ea3f4bb.png b/doc/html/_images/math/dfa75235bbe9a4311f49a1644137fd212ea3f4bb.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/dfc85915a4cda974f3bd5c3c52b7d2e59598a1eb.png b/doc/html/_images/math/dfc85915a4cda974f3bd5c3c52b7d2e59598a1eb.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/dfebf8b683f78ab2f777eb73b12281d973e058a6.png b/doc/html/_images/math/dfebf8b683f78ab2f777eb73b12281d973e058a6.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e12eccdaacf4bf3867a4e39d2f0be9eb7720060c.png b/doc/html/_images/math/e12eccdaacf4bf3867a4e39d2f0be9eb7720060c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e29be0a3b86507644c82abbc0adfcb22f0edb5e3.png b/doc/html/_images/math/e29be0a3b86507644c82abbc0adfcb22f0edb5e3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e31584cdce0b50ee39c63081564f6e2ec5a7dcbf.png b/doc/html/_images/math/e31584cdce0b50ee39c63081564f6e2ec5a7dcbf.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e35ec9f12692dad5164f15f68fc16f969099e241.png b/doc/html/_images/math/e35ec9f12692dad5164f15f68fc16f969099e241.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e3c6f9fd144c9ed47b5f4dcc9c8ee3574efa18e4.png b/doc/html/_images/math/e3c6f9fd144c9ed47b5f4dcc9c8ee3574efa18e4.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e3de9b8fce0b12c8459947bd22c727e379512fcc.png b/doc/html/_images/math/e3de9b8fce0b12c8459947bd22c727e379512fcc.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e4ca401f97df40e3568bc0624774cafa02d77cc1.png b/doc/html/_images/math/e4ca401f97df40e3568bc0624774cafa02d77cc1.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e4cd0999828f4c050af89db8654fce53c3f98231.png b/doc/html/_images/math/e4cd0999828f4c050af89db8654fce53c3f98231.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e4cd5b31b960f1b94e98198a94b62e3680c17867.png b/doc/html/_images/math/e4cd5b31b960f1b94e98198a94b62e3680c17867.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e5101484e2acde007f2471ef3379937d4bd30d14.png b/doc/html/_images/math/e5101484e2acde007f2471ef3379937d4bd30d14.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e6eadc1093d6e4f5a41f86b8301c0d7559d2c609.png b/doc/html/_images/math/e6eadc1093d6e4f5a41f86b8301c0d7559d2c609.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e8522a3d29a2f0f886fe156c30351ba0489992b9.png b/doc/html/_images/math/e8522a3d29a2f0f886fe156c30351ba0489992b9.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e9203da50e1059455123460d4e716c9c7f440cc3.png b/doc/html/_images/math/e9203da50e1059455123460d4e716c9c7f440cc3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/e9e9403195bb7daf89830f82a342b060c4e39b45.png b/doc/html/_images/math/e9e9403195bb7daf89830f82a342b060c4e39b45.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/eaf4418fbe935c15a606516d8f55dc380cd8e822.png b/doc/html/_images/math/eaf4418fbe935c15a606516d8f55dc380cd8e822.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/eb1910746ff128b185d49f778c89d74ca1df54d1.png b/doc/html/_images/math/eb1910746ff128b185d49f778c89d74ca1df54d1.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/ec1ce56da06483e62a9456229761ff166b345ed2.png b/doc/html/_images/math/ec1ce56da06483e62a9456229761ff166b345ed2.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/edd52ffa94a411e3a7b271caf0a9d1ea6fda0f4c.png b/doc/html/_images/math/edd52ffa94a411e3a7b271caf0a9d1ea6fda0f4c.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/ee1817a60aae189024fe864c85bf32c1e92a699a.png b/doc/html/_images/math/ee1817a60aae189024fe864c85bf32c1e92a699a.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/eeae8ea2feacb63d810fdd882d2472f6323a6874.png b/doc/html/_images/math/eeae8ea2feacb63d810fdd882d2472f6323a6874.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/eee8ed92791a9c140bb435f75178642c8bc57146.png b/doc/html/_images/math/eee8ed92791a9c140bb435f75178642c8bc57146.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/ef18200849afb857a3845934c4967bf7c2366755.png b/doc/html/_images/math/ef18200849afb857a3845934c4967bf7c2366755.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/f04823ba99f1452d779894f7a0745da23b55fbef.png b/doc/html/_images/math/f04823ba99f1452d779894f7a0745da23b55fbef.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/f5047d1e0cbb50ec208923a22cd517c55100fa7b.png b/doc/html/_images/math/f5047d1e0cbb50ec208923a22cd517c55100fa7b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/f574498915fa9e02eeb5141c24835d077eba3e75.png b/doc/html/_images/math/f574498915fa9e02eeb5141c24835d077eba3e75.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/f5c280d551f620f1d0b5abc5b7e9c6bc481cf27b.png b/doc/html/_images/math/f5c280d551f620f1d0b5abc5b7e9c6bc481cf27b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/f5d499efbd23360f6e9229bdccf14e0951954730.png b/doc/html/_images/math/f5d499efbd23360f6e9229bdccf14e0951954730.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/f8f0dc31c5c12bc6e3da6fc71519fa78ea04190b.png b/doc/html/_images/math/f8f0dc31c5c12bc6e3da6fc71519fa78ea04190b.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/f9147d34f15a498240d3232622111204005e72d3.png b/doc/html/_images/math/f9147d34f15a498240d3232622111204005e72d3.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/f915ce7b55e81645409daf9d1458f32462dfcdf8.png b/doc/html/_images/math/f915ce7b55e81645409daf9d1458f32462dfcdf8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/f99450c7a8851772907f28ffd58be080f18894ae.png b/doc/html/_images/math/f99450c7a8851772907f28ffd58be080f18894ae.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/fa8a7b2fb896adf1c9f17077664691e511aeb8e5.png b/doc/html/_images/math/fa8a7b2fb896adf1c9f17077664691e511aeb8e5.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/fc64cd1ec99f3144a0bc0590d0f67e6411cb8a7d.png b/doc/html/_images/math/fc64cd1ec99f3144a0bc0590d0f67e6411cb8a7d.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/fca2f0caf945233a44e5c1c1479f13d636edbf42.png b/doc/html/_images/math/fca2f0caf945233a44e5c1c1479f13d636edbf42.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/fd26dda3f4f507f3fdfaff4fe0b468bee54e7c09.png b/doc/html/_images/math/fd26dda3f4f507f3fdfaff4fe0b468bee54e7c09.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/fdb63b9e51abe6bbb16acfb5d7b773ddbb5bf4a8.png b/doc/html/_images/math/fdb63b9e51abe6bbb16acfb5d7b773ddbb5bf4a8.png
Binary files differ.
DIR diff --git a/doc/html/_images/math/ff9078c258266635e46b9767b0c7e248c865e4ab.png b/doc/html/_images/math/ff9078c258266635e46b9767b0c7e248c865e4ab.png
Binary files differ.
DIR diff --git a/doc/html/_sources/cfd.txt b/doc/html/_sources/cfd.txt
t@@ -0,0 +1,578 @@
+Fluid simulation and particle-fluid interaction
+===============================================
+A new and experimental addition to *sphere* is the ability to simulate a mixture
+of particles and a Newtonian fluid. The fluid is simulated using an Eulerian
+continuum approach, using a custom CUDA solver for GPU computation. This
+approach allows for fast simulations due to the limited need for GPU-CPU
+communications, as well as a flexible code base.
+
+The following sections will describe the theoretical background, as well as the
+solution procedure and the numerical implementation.
+
+Derivation of the Navier Stokes equations with porosity
+-------------------------------------------------------
+Following the outline presented by `Limache and Idelsohn (2006)`_, the
+continuity equation for an incompressible fluid material is given by:
+
+.. math::
+ \nabla \cdot \boldsymbol{v} = 0
+
+and the momentum equation:
+
+.. math::
+ \rho \frac{\partial \boldsymbol{v}}{\partial t}
+ + \rho (\boldsymbol{v} \cdot \nabla \boldsymbol{v})
+ = \nabla \cdot \boldsymbol{\sigma}
+ + \rho \boldsymbol{f}
+
+Here, :math:`\boldsymbol{v}` is the fluid velocity, :math:`\rho` is the
+fluid density, :math:`\boldsymbol{\sigma}` is the `Cauchy stress tensor`_, and
+:math:`\boldsymbol{f}` is a body force (e.g. gravity). For incompressible
+Newtonian fluids, the Cauchy stress is given by:
+
+.. math::
+ \boldsymbol{\sigma} = -p \boldsymbol{I} + \boldsymbol{\tau}
+
+:math:`p` is the fluid pressure, :math:`\boldsymbol{I}` is the identity
+tensor, and :math:`\boldsymbol{\tau}` is the deviatoric stress tensor, given
+by:
+
+.. math::
+ \boldsymbol{\tau} =
+ \mu_f \nabla \boldsymbol{v}
+ + \mu_f (\nabla \boldsymbol{v})^T
+
+By using the following vector identities:
+
+.. math::
+ \nabla \cdot (p \boldsymbol{I}) = \nabla p
+
+ \nabla \cdot (\nabla \boldsymbol{v}) = \nabla^2 \boldsymbol{v}
+
+ \nabla \cdot (\nabla \boldsymbol{v})^T
+ = \nabla (\nabla \cdot \boldsymbol{v})
+
+the deviatoric component of the Cauchy stress tensor simplifies to the
+following, assuming that spatial variations in the viscosity can be neglected:
+
+.. math::
+ = -\nabla p
+ + \mu_f \nabla^2 \boldsymbol{v}
+
+Since we are dealing with fluid flow in a porous medium, additional terms are
+introduced to the equations for conservation of mass and momentum. In the
+following, the equations are derived for the first spatial component. The
+solution for the other components is trivial.
+
+The porosity value (in the saturated porous medium the volumetric fraction of
+the fluid phase) denoted :math:`\phi` is incorporated in the continuity and
+momentum equations. The continuity equation becomes:
+
+.. math::
+ \frac{\partial \phi}{\partial t}
+ + \nabla \cdot (\phi \boldsymbol{v}) = 0
+
+For the :math:`x` component, the Lagrangian formulation of the momentum equation
+with a body force :math:`\boldsymbol{f}` becomes:
+
+.. math::
+ \frac{D (\phi v_x)}{D t}
+ = \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\sigma}) \right]_x
+ + \phi f_x
+
+In the Eulerian formulation, an advection term is added, and the Cauchy stress
+tensor is represented as isotropic and deviatoric components individually:
+
+.. math::
+ \frac{\partial (\phi v_x)}{\partial t}
+ + \boldsymbol{v} \cdot \nabla (\phi v_x)
+ = \frac{1}{\rho} \left[ \nabla \cdot (-\phi p \boldsymbol{I})
+ + \phi \boldsymbol{\tau}) \right]_x
+ + \phi f_x
+
+Using vector identities to rewrite the advection term, and expanding the fluid
+stress tensor term:
+
+.. math::
+ \frac{\partial (\phi v_x)}{\partial t}
+ + \nabla \cdot (\phi v_x \boldsymbol{v})
+ - \phi v_x (\nabla \cdot \boldsymbol{v})
+ = \frac{1}{\rho} \left[ -\nabla \phi p \right]_x
+ + \frac{1}{\rho} \left[ -\phi \nabla p \right]_x
+ + \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
+ + \phi f_x
+
+Spatial variations in the porosity are neglected,
+
+.. math::
+ \nabla \phi := 0
+
+and the pressure is attributed to the fluid phase alone (model B in Zhu et al.
+2007 and Zhou et al. 2010). The divergence of fluid velocities is defined to be
+zero:
+
+.. math::
+ \nabla \cdot \boldsymbol{v} := 0
+
+With these assumptions, the momentum equation simplifies to:
+
+.. math::
+ \frac{\partial (\phi v_x)}{\partial t}
+ + \nabla \cdot (\phi v_x \boldsymbol{v})
+ = -\frac{1}{\rho} \frac{\partial p}{\partial x}
+ + \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
+ + \phi f_x
+
+The remaining part of the advection term is for the :math:`x` component
+found as:
+
+.. math::
+ \nabla \cdot (\phi v_x \boldsymbol{v}) =
+ \left[
+ \frac{\partial}{\partial x},
+ \frac{\partial}{\partial y},
+ \frac{\partial}{\partial z}
+ \right]
+ \left[
+ \begin{array}{c}
+ \phi v_x v_x\\
+ \phi v_x v_y\\
+ \phi v_x v_z\\
+ \end{array}
+ \right]
+ =
+ \frac{\partial (\phi v_x v_x)}{\partial x} +
+ \frac{\partial (\phi v_x v_y)}{\partial y} +
+ \frac{\partial (\phi v_x v_z)}{\partial z}
+
+The deviatoric stress tensor is in this case symmetrical, i.e. :math:`\tau_{ij}
+= \tau_{ji}`, and is found by:
+
+.. math::
+ \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
+ = \frac{1}{\rho}
+ \left[
+ \left[
+ \frac{\partial}{\partial x},
+ \frac{\partial}{\partial y},
+ \frac{\partial}{\partial z}
+ \right]
+ \phi
+ \left[
+ \begin{matrix}
+ \tau_{xx} & \tau_{xy} & \tau_{xz}\\
+ \tau_{yx} & \tau_{yy} & \tau_{yz}\\
+ \tau_{zx} & \tau_{zy} & \tau_{zz}\\
+ \end{matrix}
+ \right]
+ \right]_x
+
+ = \frac{1}{\rho}
+ \left[
+ \begin{array}{c}
+ \frac{\partial (\phi \tau_{xx})}{\partial x}
+ + \frac{\partial (\phi \tau_{xy})}{\partial y}
+ + \frac{\partial (\phi \tau_{xz})}{\partial z}\\
+ \frac{\partial (\phi \tau_{yx})}{\partial x}
+ + \frac{\partial (\phi \tau_{yy})}{\partial y}
+ + \frac{\partial (\phi \tau_{yz})}{\partial z}\\
+ \frac{\partial (\phi \tau_{zx})}{\partial x}
+ + \frac{\partial (\phi \tau_{zy})}{\partial y}
+ + \frac{\partial (\phi \tau_{zz})}{\partial z}\\
+ \end{array}
+ \right]_x
+ = \frac{1}{\rho}
+ \left(
+ \frac{\partial (\phi \tau_{xx})}{\partial x}
+ + \frac{\partial (\phi \tau_{xy})}{\partial y}
+ + \frac{\partial (\phi \tau_{xz})}{\partial z}
+ \right)
+
+In a linear viscous fluid, the stress and strain rate
+(:math:`\dot{\boldsymbol{\epsilon}}`) is linearly dependent, scaled by the
+viscosity parameter :math:`\mu_f`:
+
+.. math::
+ \tau_{ij} = 2 \mu_f \dot{\epsilon}_{ij}
+ = \mu_f \left(
+ \frac{\partial v_i}{\partial x_j} + \frac{\partial v_j}{\partial x_i}
+ \right)
+
+With this relationship, the deviatoric stress tensor components can be
+calculated as:
+
+.. math::
+ \tau_{xx} = 2 \mu_f \frac{\partial v_x}{\partial x} \qquad
+ \tau_{yy} = 2 \mu_f \frac{\partial v_y}{\partial y} \qquad
+ \tau_{zz} = 2 \mu_f \frac{\partial v_z}{\partial z}
+
+ \tau_{xy} = \mu_f \left(
+ \frac{\partial v_x}{\partial y} + \frac{\partial v_y}{\partial x} \right)
+
+ \tau_{xz} = \mu_f \left(
+ \frac{\partial v_x}{\partial z} + \frac{\partial v_z}{\partial x} \right)
+
+ \tau_{yz} = \mu_f \left(
+ \frac{\partial v_y}{\partial z} + \frac{\partial v_z}{\partial y} \right)
+
+where :math:`\mu_f` is the dynamic viscosity. The above formulation of the
+fluid rheology assumes identical bulk and shear viscosities. The derivation of
+the equations for the other spatial components is trivial.
+
+Porosity estimation
+-------------------
+The solid volume in each fluid cell is determined by the ratio of the
+a cell-centered spherical cell volume (:math:`V_c`) and the sum of intersecting
+particle volumes (:math:`V_s`). The spherical cell volume has a center at
+:math:`\boldsymbol{x}_i`, and a radius of :math:`R_i`, which is equal to half
+the fluid cell width. The nearby particles are characterized by position
+:math:`\boldsymbol{x}_j` and radius :math:`r_j`. The center distance is defined
+as:
+
+.. math::
+ d_{ij} = ||\boldsymbol{x}_i - \boldsymbol{x}_j||
+
+The common volume of the two intersecting spheres is zero if the volumes aren't
+intersecting, lens shaped if they are intersecting, and spherical if the
+particle is fully contained by the spherical cell volume:
+
+.. math::
+ V^s_{i} = \sum_j
+ \begin{cases}
+ 0 & \textit{if } R_i + r_j \leq d_{ij} \\
+ \frac{1}{12d_{ij}} \left[ \pi (R_i + r_j - d_{ij})^2
+ (d_{ij}^2 + 2d_{ij}r_j - 3r_j^2 + 2d_{ij} R_i + 6r_j R_i - 3R_i^2)
+ \right] & \textit{if } R_i - r_j < d_{ij} < R_i + r_j \\
+ \frac{4}{3} \pi r^3_j & \textit{if } d_{ij} \leq R_i - r_j
+ \end{cases}
+
+Using this method, the cell porosity values are continuous through time as
+particles enter and exit the cell volume. The rate of porosity change
+(:math:`d\phi/dt`) is estimated by the backwards Euler method
+by considering the previous and current porosity.
+
+Particle-fluid interaction
+--------------------------
+The momentum exchange of the granular and fluid phases follows the procedure
+outlined by Gidaspow 1992 and Shamy and Zhegal 2005. The fluid and particle
+interaction is based on the concept of drag, where the magnitude is based on
+semi-empirical relationships. The drag force scales linearly with the relative
+difference in velocity between the fluid and particle phase. On the base of
+Newton's third law, the resulting drag force is applied with opposite signs to
+the particle and fluid.
+
+For fluid cells with porosities (:math:`\phi`) less or equal to 0.8, the drag
+force is based on the Ergun (1952) equation:
+
+.. math::
+ \bar{\boldsymbol{f}}_d = \left(
+ 150 \frac{\mu_f (1-\phi)^2}{\phi\bar{d}^2}
+ + 1.75 \frac{(1-\phi)\rho_f
+ ||\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p||}{\bar{d}}
+ \right)
+ (\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p)
+
+here, :math:`\bar{d}` denotes the average particle diameter in the cell,
+:math:`\boldsymbol{v}_f` is the fluid flow velocity, and
+:math:`\bar{\boldsymbol{v}}_p` is the average particle velocity in the cell. All
+particles in contact with the previously mentioned cell-centered sphere for
+porosity estimation contribute to the average particle velocity and diameter in
+the fluid cell.
+
+If the porosity is greater than 0.8, the cell-averaged drag force
+(:math:`\bar{\boldsymbol{f}}_d` is found from the Wen and Yu (1966) equation,
+which considers the fluid flow situation:
+
+.. math::
+ \bar{\boldsymbol{f}}_d = \left(
+ \frac{3}{4}
+ \frac{C_d (1-\phi) \phi^{-2.65} \mu_f \rho_f
+ ||\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p||}{\bar{d}}
+ \right)
+ (\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p)
+
+The drag coefficient :math:`C_d` is evaluated depending on the magnitude of the
+Reynolds number :math:`Re`:
+
+.. math::
+ C_d =
+ \begin{cases}
+ \frac{24}{Re} (1+0.15 (Re)^{0.687} & \textit{if } Re < 1,000 \\
+ 0.44 & \textit{if } Re \geq 1,000
+ \end{cases}
+
+where the Reynold's number is found by:
+
+.. math::
+ Re = \frac{\phi\rho_f\bar{d}}{\mu_f}
+ ||\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p||
+
+The interaction force is applied to the fluid with negative sign as a
+contribution to the body force :math:`\boldsymbol{f}`. The fluid interaction
+force applied particles in the fluid cell is:
+
+.. math::
+ \boldsymbol{f}_i = \frac{\bar{\boldsymbol{f}}_d V_p}{1-\phi}
+
+where :math:`V_p` denotes the particle volume. Optionally, the above
+interaction force could be expanded to include the force induced by the fluid
+pressure gradient:
+
+.. math::
+ \boldsymbol{f}_i = \left(
+ -\nabla p +
+ \frac{\bar{\boldsymbol{f}}_d}{1-\phi}
+ \right) V_p
+
+
+Fluid dynamics solution procedure by operator splitting
+-------------------------------------------------------
+The partial differential terms in the previously described equations are found
+using finite central differences. Modifying the operator splitting methodology
+presented by Langtangen et al. (2002), the predicted velocity
+:math:`\boldsymbol{v}^*` after a finite time step
+:math:`\Delta t` is found by explicit integration of the momentum equation.
+
+.. math::
+ \frac{\Delta (\phi v_x)}{\Delta t}
+ + \nabla \cdot (\phi v_x \boldsymbol{v})
+ = - \frac{1}{\rho} \frac{\Delta p}{\Delta x}
+ + \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
+ + \phi f_x
+
+ \Downarrow
+
+ \phi \frac{\Delta v_x}{\Delta t}
+ + v_x \frac{\Delta \phi}{\Delta t}
+ + \nabla \cdot (\phi v_x \boldsymbol{v})
+ = - \frac{1}{\rho} \frac{\Delta p}{\Delta x}
+ + \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
+ + \phi f_x
+
+We want to isolate :math:`\Delta v_x` in the above equation in order to project
+the new velocity.
+
+.. math::
+ \phi \frac{\Delta v_x}{\Delta t}
+ = - \frac{1}{\rho} \frac{\Delta p}{\Delta x}
+ + \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
+ + \phi f_x
+ - v_x \frac{\Delta \phi}{\Delta t}
+ - \nabla \cdot (\phi v_x \boldsymbol{v})
+
+ \Delta v_x
+ = - \frac{1}{\rho} \frac{\Delta p}{\Delta x} \frac{\Delta t}{\phi}
+ + \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
+ \frac{\Delta t}{\phi}
+ + \Delta t f_x
+ - v_x \frac{\Delta \phi}{\phi}
+ - \nabla \cdot (\phi v_x \boldsymbol{v}) \frac{\Delta t}{\phi}
+
+The term :math:`\beta` is introduced as an adjustable, dimensionless parameter
+in the range :math:`[0;1]`, and determines the importance of the old pressure
+values in the solution procedure (Langtangen et al. 2002). A value of 0
+corresponds to `Chorin's projection method`_ originally described
+in `Chorin (1968)`_.
+
+.. math::
+ v_x^* = v_x^t + \Delta v_x
+
+ v_x^* = v_x^t
+ - \frac{\beta}{\rho} \frac{\Delta p^t}{\Delta x} \frac{\Delta t}{\phi^t}
+ + \frac{1}{\rho} \left[ \nabla \cdot (\phi^t \boldsymbol{\tau}^t) \right]_x
+ \frac{\Delta t}{\phi}
+ + \Delta t f_x
+ - v^t_x \frac{\Delta \phi}{\phi^t}
+ - \nabla \cdot (\phi^t v_x^t \boldsymbol{v}^t) \frac{\Delta t}{\phi^t}
+
+Here, :math:`\Delta x` denotes the cell spacing. The velocity found
+(:math:`v_x^*`) is only a prediction of the fluid velocity at time
+:math:`t+\Delta t`, since the estimate isn't constrained by the continuity
+equation:
+
+.. math::
+ \frac{\Delta \phi^t}{\Delta t} + \nabla \cdot (\phi^t
+ \boldsymbol{v}^{t+\Delta t}) = 0
+
+The divergence of a scalar and vector can be `split`_:
+
+.. math::
+ \phi^t \nabla \cdot \boldsymbol{v}^{t+\Delta t} +
+ \boldsymbol{v}^{t+\Delta t} \cdot \nabla \phi^t
+ + \frac{\Delta \phi^t}{\Delta t} = 0
+
+The predicted velocity is corrected using the new pressure (Langtangen et al.
+2002):
+
+.. math::
+ \boldsymbol{v}^{t+\Delta t} = \boldsymbol{v}^*
+ - \frac{\Delta t}{\rho} \nabla \epsilon
+ \quad \text{where} \quad
+ \epsilon = p^{t+\Delta t} - \beta p^t
+
+The above formulation of the future velocity is put into the continuity
+equation:
+
+.. math::
+ \Rightarrow
+ \phi^t \nabla \cdot
+ \left( \boldsymbol{v}^* - \frac{\Delta t}{\rho} \nabla \epsilon \right)
+ +
+ \left( \boldsymbol{v}^* - \frac{\Delta t}{\rho} \nabla \epsilon \right)
+ \cdot \nabla \phi^t + \frac{\Delta \phi^t}{\Delta t} = 0
+
+.. math::
+ \Rightarrow
+ \phi^t \nabla \cdot
+ \boldsymbol{v}^* - \frac{\Delta t}{\rho} \phi^t \nabla^2 \epsilon
+ + \nabla \phi^t \cdot \boldsymbol{v}^*
+ - \nabla \phi^t \cdot \nabla \epsilon \frac{\Delta t}{\rho}
+ + \frac{\Delta \phi^t}{\Delta t} = 0
+
+.. math::
+ \Rightarrow
+ \frac{\Delta t}{\rho} \phi^t \nabla^2 \epsilon
+ = \phi^t \nabla \cdot \boldsymbol{v}^*
+ + \nabla \phi^t \cdot \boldsymbol{v}^*
+ - \nabla \phi^t \cdot \nabla \epsilon \frac{\Delta t}{\rho}
+ + \frac{\Delta \phi^t}{\Delta t}
+
+The pressure difference in time becomes a `Poisson equation`_ with added terms:
+
+.. math::
+ \Rightarrow
+ \nabla^2 \epsilon
+ = \frac{\nabla \cdot \boldsymbol{v}^* \rho}{\Delta t}
+ + \frac{\nabla \phi^t \cdot \boldsymbol{v}^* \rho}{\Delta t \phi^t}
+ - \frac{\nabla \phi^t \cdot \nabla \epsilon}{\phi^t}
+ + \frac{\Delta \phi^t \rho}{\Delta t^2 \phi^t}
+
+The right hand side of the above equation is termed the *forcing function*
+:math:`f`, which is decomposed into two terms, :math:`f_1` and :math:`f_2`:
+
+.. math::
+ f_1
+ = \frac{\nabla \cdot \boldsymbol{v}^* \rho}{\Delta t}
+ + \frac{\nabla \phi^t \cdot \boldsymbol{v}^* \rho}{\Delta t \phi^t}
+ + \frac{\Delta \phi^t \rho}{\Delta t^2 \phi^t}
+
+ f_2 =
+ \frac{\nabla \phi^t \cdot \nabla \epsilon}{\phi^t}
+
+
+During the `Jacobi iterative solution procedure`_ :math:`f_1` remains constant,
+while :math:`f_2` changes value. For this reason, :math:`f_1` is found only
+during the first iteration, while :math:`f_2` is updated every time. The value
+of the forcing function is found as:
+
+.. math::
+ f = f_1 - f_2
+
+Using second-order finite difference approximations of the Laplace operator
+second-order partial derivatives, the differential equations become a system of
+equations that is solved using `iteratively`_ using Jacobi updates. The total
+number of unknowns is :math:`(n_x - 1)(n_y - 1)(n_z - 1)`.
+
+The discrete Laplacian (approximation of the Laplace operator) can be obtained
+by a finite-difference seven-point stencil in a three-dimensional, cubic
+grid with cell spacing :math:`\Delta x, \Delta y, \Delta z`, considering the six
+face neighbors:
+
+.. math::
+ \nabla^2 \epsilon_{i_x,i_y,i_z} \approx
+ \frac{\epsilon_{i_x-1,i_y,i_z} - 2 \epsilon_{i_x,i_y,i_z}
+ + \epsilon_{i_x+1,i_y,i_z}}{\Delta x^2}
+ + \frac{\epsilon_{i_x,i_y-1,i_z} - 2 \epsilon_{i_x,i_y,i_z}
+ + \epsilon_{i_x,i_y+1,i_z}}{\Delta y^2}
+
+ + \frac{\epsilon_{i_x,i_y,i_z-1} - 2 \epsilon_{i_x,i_y,i_z}
+ + \epsilon_{i_x,i_y,i_z+1}}{\Delta z^2}
+ \approx f_{i_x,i_y,i_z}
+
+Within a Jacobi iteration, the value of the unknowns (:math:`\epsilon^n`) is
+used to find an updated solution estimate (:math:`\epsilon^{n+1}`).
+The solution for the updated value takes the form:
+
+.. math::
+ \epsilon^{n+1}_{i_x,i_y,i_z}
+ = \frac{-\Delta x^2 \Delta y^2 \Delta z^2 f_{i_x,i_y,i_z}
+ + \Delta y^2 \Delta z^2 (\epsilon^n_{i_x-1,i_y,i_z} +
+ \epsilon^n_{i_x+1,i_y,i_z})
+ + \Delta x^2 \Delta z^2 (\epsilon^n_{i_x,i_y-1,i_z} +
+ \epsilon^n_{i_x,i_y+1,i_z})
+ + \Delta x^2 \Delta y^2 (\epsilon^n_{i_x,i_y,i_z-1} +
+ \epsilon^n_{i_x,i_y,i_z+1})}
+ {2 (\Delta x^2 \Delta y^2
+ + \Delta x^2 \Delta z^2
+ + \Delta y^2 \Delta z^2) }
+
+The difference between the current and updated value is termed the *normalized
+residual*:
+
+.. math::
+ r_{i_x,i_y,i_z} = \frac{(\epsilon^{n+1}_{i_x,i_y,i_z}
+ - \epsilon^n_{i_x,i_y,i_z})^2}{(\epsilon^{n+1}_{i_x,i_y,i_z})^2}
+
+Note that the :math:`\epsilon` values cannot be 0 due to the above normalization
+of the residual.
+
+The updated values are at the end of the iteration stored as the current values,
+and the maximal value of the normalized residual is found. If this value is
+larger than a tolerance criteria, the procedure is repeated. The iterative
+procedure is ended if the number of iterations exceeds a defined limit.
+
+After the values of :math:`\epsilon` are found, they are used to find the new
+pressures and velocities:
+
+.. math::
+ \bar{p}^{t+\Delta t} = \beta \bar{p}^t + \epsilon
+
+.. math::
+ \bar{\boldsymbol{v}}^{t+\Delta t} =
+ \bar{\boldsymbol{v}}^* - \frac{\Delta t}{\rho} \nabla \epsilon
+
+
+Boundary conditions
+-------------------
+The lateral boundaries are periodic. This cannot be changed in the current
+version of ``sphere``. This means that the fluid properties at the paired,
+parallel lateral (:math:`x` and :math:`y`) boundaries are identical. A flow
+leaving through one side reappears on the opposite side.
+
+The top and bottom boundary conditions of the fluid grid can be either:
+prescribed pressure (Dirichlet), or prescribed velocity (Neumann). The
+(horizontal) velocities parallel to the boundaries are free to attain other
+values (free slip). The Dirichlet boundary condition is enforced by keeping the
+value of :math:`\epsilon` constant at the boundaries, e.g.:
+
+.. math::
+ \epsilon^{n+1}_{i_x,i_y,i_z = 1 \vee n_z}
+ =
+ \epsilon^{n}_{i_x,i_y,i_z = 1 \vee n_z}
+
+The Neumann boundary condition of no flow across the boundary is enforced by
+setting the gradient of :math:`\epsilon` perpendicular to the boundary to zero,
+e.g.:
+
+.. math::
+ \nabla_z \epsilon^{n+1}_{i_x,i_y,i_z = 1 \vee n_z} = 0
+
+
+Numerical implementation
+------------------------
+Ghost nodes
+
+---
+
+
+
+
+.. _Limache and Idelsohn (2006): http://www.cimec.org.ar/ojs/index.php/mc/article/view/486/464
+.. _Cauchy stress tensor: https://en.wikipedia.org/wiki/Cauchy_stress_tensor
+.. _`Chorin's projection method`: https://en.wikipedia.org/wiki/Projection_method_(fluid_dynamics)#Chorin.27s_projection_method
+.. _`Chorin (1968)`: http://www.ams.org/journals/mcom/1968-22-104/S0025-5718-1968-0242392-2/S0025-5718-1968-0242392-2.pdf
+.. _split: http://www.wolframalpha.com/input/?i=div(p+v)
+.. _Poisson equation: https://en.wikipedia.org/wiki/Poisson's_equation
+.. _`Jacobi iterative solution procedure`: http://www.rsmas.miami.edu/personal/miskandarani/Courses/MSC321/Projects/prjpoisson.pdf
+.. _iteratively: https://en.wikipedia.org/wiki/Relaxation_(iterative_method)
+
DIR diff --git a/doc/html/_sources/dem.txt b/doc/html/_sources/dem.txt
t@@ -1,16 +1,217 @@
Discrete element method
=======================
-The discrete element method (or distinct element method) was initially
-formulated by Cundall and Strack (1979). It simulates the physical behavior and
-interaction of discrete, unbreakable particles, with their own mass and inertia,
-under the influence of e.g. gravity and boundary conditions such as moving
-walls. By discretizing time into small time steps, explicit integration of
-Newton's second law of motion is used to predict the new position and kinematic
-values for each particle from the previous sums of forces. This Lagrangian
-approach is ideal for simulating discontinuous materials, such as granular
-matter.
-The complexity of the computations is kept low by representing the particles as
-spheres, which keeps contact-searching algorithms simple.
+Granular material is a very common form of matter, both in nature and industry.
+It can be defined as material consisting of interacting, discrete particles.
+Common granular materials include gravels, sands and soils, ice bergs,
+asteroids, powders, seeds, and other foods. Over 75% of the raw materials that
+pass through industry are granular. This wide occurrence has driven the desire
+to understand the fundamental mechanics of the material.
+Contrary to other common materials such as gases, liquids and solids, a general
+mathematical formulation of it's behavior hasn't yet been found. Granular
+material can, however, display states that somewhat resemble gases, fluids and
+solids.
+.. The discrete element method (or distinct element method) was initially
+ formulated by Cundall and Strack (1979). It simulates the physical behavior and
+ interaction of discrete, unbreakable particles, with their own mass and inertia,
+ under the influence of e.g. gravity and boundary conditions such as moving
+ walls. By discretizing time into small time steps, explicit integration of
+ Newton's second law of motion is used to predict the new position and kinematic
+ values for each particle from the previous sums of forces. This Lagrangian
+ approach is ideal for simulating discontinuous materials, such as granular
+ matter.
+ The complexity of the computations is kept low by representing the particles as
+ spheres, which keeps contact-searching algorithms simple.
+
+The `Discrete Element Method
+<https://en.wikipedia.org/wiki/Discrete_element_method>`_ (DEM) is a numerical
+method that can be used to
+simulate the interaction of particles. Originally derived from
+`Molecular Dynamics <https://en.wikipedia.org/wiki/Molecular_dynamics>`_,
+it simulates particles as separate entities, and calculates their positions,
+velocities, and accelerations through time. See Cundall and Strack (1979) and
+`this blog post
+<http://anders-dc.github.io/2013/10/16/the-discrete-element-method/>`_ for
+general introduction to the DEM. The following sections will highlight the
+DEM implementation in ``sphere``. Some of the details are also described in
+Damsgaard et al. 2013. In the used notation, a bold symbol denotes a
+three-dimensional vector, and a dot denotes that the entity is a temporal
+derivative.
+
+Contact search
+--------------
+Homogeneous cubic grid.
+
+.. math::
+ \delta_n^{ij} = ||\boldsymbol{x}^i - \boldsymbol{x}^j|| - (r^i + r^j)
+
+where :math:`r` is the particle radius, and :math:`\boldsymbol{x}` denotes the
+positional vector of a particle, and :math:`i` and :math:`j` denote the indexes
+of two particles. Negative values of :math:`\delta_n` denote that the particles
+are overlapping.
+
+
+Contact interaction
+-------------------
+Now that the inter-particle contacts have been identified and characterized by
+their overlap, the resulting forces from the interaction can be resolved. The
+interaction is decomposed into normal and tangential components, relative to the
+contact interface orientation. The normal vector to the contact interface is
+found by:
+
+.. math::
+ \boldsymbol{n}^{ij} =
+ \frac{\boldsymbol{x}^i - \boldsymbol{x}^j}
+ {||\boldsymbol{x}^i - \boldsymbol{x}^j||}
+
+The contact velocity :math:`\dot{\boldsymbol{\delta}}` is found by:
+
+.. math::
+ \dot{\boldsymbol{\delta}}^{ij} =
+ (\boldsymbol{x}^i - \boldsymbol{x}^j)
+ + (r^i + \frac{\delta_n^{ij}}{2})
+ (\boldsymbol{n}^{ij} \times \boldsymbol{\omega}^{i})
+ + (r^j + \frac{\delta_n^{ij}}{2})
+ (\boldsymbol{n}^{ij} \times \boldsymbol{\omega}^{j})
+
+The contact velocity is decomposed into normal and tangential components,
+relative to the contact interface. The normal component is:
+
+.. math::
+ \dot{\delta}^{ij}_n =
+ -(\dot{\boldsymbol{\delta}}^{ij} \cdot \boldsymbol{n}^{ij})
+
+and the tangential velocity component is found as:
+
+.. math::
+ \dot{\boldsymbol{\delta}}^{ij}_t =
+ \dot{\boldsymbol{\delta}}^{ij}
+ - \boldsymbol{n}^{ij}
+ (\boldsymbol{n}^{ij} \cdot \dot{\boldsymbol{\delta}}^{ij})
+
+where :math:`\boldsymbol{\omega}` is the rotational velocity vector of a
+particle. The total tangential displacement on the contact plane is found
+incrementally:
+
+.. math::
+ \boldsymbol{\delta}_{t,\text{uncorrected}}^{ij} =
+ \int_0^{t_c}
+ \dot{\boldsymbol{\delta}}^{ij}_t \Delta t
+
+where :math:`t_c` is the duration of the contact and :math:`\Delta t` is the
+computational time step length. The tangential contact interface displacement is
+set to zero when a contact pair no longer overlaps. At each time step, the value
+of :math:`\boldsymbol{\delta}_t` is corrected for rotation of the contact
+interface:
+
+.. math::
+ \boldsymbol{\delta}_t^{ij} = \boldsymbol{\delta}_{t,\text{uncorrected}}^{ij}
+ - (\boldsymbol{n}
+ (\boldsymbol{n} \cdot \boldsymbol{\delta}_{t,\text{uncorrected}}^{ij})
+
+With all the geometrical and kinetic components determined, the resulting forces
+of the particle interaction can be determined using a contact model. ``sphere``
+features only one contact model in the normal direction to the contact; the
+linear-elastic-viscous (*Hookean* with viscous damping, or *Kelvin-Voigt*)
+contact model. The resulting force in the normal direction of the contact
+interface on particle :math:`i` is:
+
+.. math::
+ \boldsymbol{f}_n^{ij} = \left(
+ -k_n \delta_n^{ij} -\gamma_n \dot{\delta_n}^{ij}
+ \right) \boldsymbol{n}^{ij}
+
+The parameter :math:`k_n` is the defined `spring coefficient
+<https://en.wikipedia.org/wiki/Hooke's_law>`_ in the normal direction of the
+contact interface, and :math:`\gamma_n` is the defined contact interface
+viscosity, also in the normal direction. The loss of energy in this interaction
+due to the viscous component is for particle :math:`i` calculated as:
+
+.. math::
+ \dot{e}^i_v = \gamma_n (\dot{\delta}^{ij}_n)^2
+
+The tangential force is determined by either a viscous-frictional contact model,
+or a elastic-viscous-frictional contact model. The former contact model is very
+computationally efficient, but somewhat inaccurate relative to the mechanics of
+real materials. The latter contact model is therefore the default, even though
+it results in longer computational times. The tangential force in the
+visco-frictional contact model:
+
+.. math::
+ \boldsymbol{f}_t^{ij} = -\gamma_t \dot{\boldsymbol{\delta}_t}^{ij}
+
+:math:`\gamma_n` is the defined contact interface viscosity in the tangential
+direction. The tangential displacement along the contact interface
+(:math:`\boldsymbol{\delta}_t`) is not calculated and stored for this contact
+model. The tangential force in the more realistic elastic-viscous-frictional
+contact model:
+
+.. math::
+ \boldsymbol{f}_t^{ij} =
+ -k_t \boldsymbol{\delta}_t^{ij} -\gamma_t \dot{\boldsymbol{\delta}_t}^{ij}
+
+The parameter :math:`k_n` is the defined spring coefficient in the tangential
+direction of the contact interface. Note that the tangential force is only
+found if the tangential displacement (:math:`\delta_t`) or the tangential
+velocity (:math:`\dot{\delta}_t`) is non-zero, in order to avoid division by
+zero. Otherwise it is defined as being :math:`[0,0,0]`.
+
+For both types of contact model, the tangential force is limited by the Coulomb
+criterion of static and dynamic friction:
+
+.. math::
+ ||\boldsymbol{f}^{ij}_t|| \leq
+ \begin{cases}
+ \mu_s ||\boldsymbol{f}^{ij}_n|| &
+ \text{if} \quad ||\boldsymbol{f}_t^{ij}|| = 0 \\
+ \mu_d ||\boldsymbol{f}^{ij}_n|| &
+ \text{if} \quad ||\boldsymbol{f}_t^{ij}|| > 0
+ \end{cases}
+
+If the elastic-viscous-frictional contact model is used and the Coulomb limit is
+reached, the tangential displacement along the contact interface is limited to
+this value:
+
+.. math::
+ \boldsymbol{\delta}_t^{ij} =
+ \frac{1}{k_t} \left(
+ \mu_d ||\boldsymbol{f}_n^{ij}||
+ \frac{\boldsymbol{f}^{ij}_t}{||\boldsymbol{f}^{ij}_t||}
+ + \gamma_t \dot{\boldsymbol{\delta}}_t^{ij} \right)
+
+If the tangential force reaches the Coulomb limit, the energy lost due to
+frictional dissipation is calculated as:
+
+.. math::
+ \dot{e}^i_s = \frac{||\boldsymbol{f}^{ij}_t
+ \dot{\boldsymbol{\delta}}_t^{ij} \Delta t||}{\Delta t}
+
+The loss of energy by viscous dissipation in the tangential direction is not
+found.
+
+
+Temporal integration
+--------------------
+In the DEM, the time is discretized into small steps (:math:`\Delta t`). For each time
+step, the entire network of contacts is resolved, and the resulting forces and
+torques for each particle are found. With these values at hand, the new
+linear and rotational accelerations can be found using
+`Newton's second law <https://en.wikipedia.org/wiki/Newton%27s_laws_of_motion>`_
+of the motion of solid bodies. If a particle with mass :math:`m` at a point in time
+experiences a sum of forces denoted :math:`\boldsymbol{F}`, the resultant acceleration
+(:math:`\boldsymbol{a}`) can be found by rearranging Newton's second law:
+
+.. math::
+ \boldsymbol{F} = m \boldsymbol{a} \Rightarrow \boldsymbol{a} = \frac{\boldsymbol{F}}{m}
+
+The new velocity and position is found by integrating the above equation
+with regards to time. The simplest integration scheme in this regard is the
+`Euler method <https://en.wikipedia.org/wiki/Euler_method>`_:
+
+.. math::
+ \boldsymbol{v} = \boldsymbol{v}_{old} + \boldsymbol{a} \Delta t
+
+.. math::
+ \boldsymbol{p} = \boldsymbol{p}_{old} + \boldsymbol{v} \Delta t
DIR diff --git a/doc/html/_sources/index.txt b/doc/html/_sources/index.txt
t@@ -3,36 +3,36 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
-Welcome to sphere's documentation!
-==================================
-This is the official documentation for the *sphere* discrete element modelling
-software. It presents the theory behind the discrete element method (DEM), the
-structure of the software source code, and the Python API for handling
-simulation setup and data analysis.
-
-*sphere* is developed by Anders Damsgaard Christensen under supervision of David
-Lunbek Egholm and Jan A. Piotrowski, all of the department of Geoscience, Aarhus
-University, Denmark. This document is a work in progress, and is still in an
-early state.
-
-Contact: Anders Damsgaard Christensen, `<http://cs.au.dk/~adc>`_,
+The sphere documentation
+========================
+This is the official documentation for the ``sphere`` discrete element modelling
+software. This document aims at guiding the installation process, documenting
+the usage, and explaining the relevant theory.
+
+``sphere`` is developed by Anders Damsgaard as part as his Ph.D. project, under
+supervision of David Lundbek Egholm and Jan A. Piotrowski, all of the Department
+of Geoscience, Aarhus University, Denmark. The author welcomes interested third
+party developers. This document is a work in progress.
+
+Contact: Anders Damsgaard, `<http://cs.au.dk/~adc>`_,
`<anders.damsgaard@geo.au.dk>`_
-Contents:
-
+Contents
+--------
.. toctree::
:maxdepth: 2
introduction
dem
+ cfd
python_api
- sphere_internals
+ .. sphere_internals
Indices and tables
-==================
+------------------
.. * :ref:`modindex`
DIR diff --git a/doc/html/_sources/introduction.txt b/doc/html/_sources/introduction.txt
t@@ -1,49 +1,75 @@
Introduction
============
-The *sphere*-software is used for three-dimensional discrete element method
+
+The ``sphere``-software is used for three-dimensional discrete element method
(DEM) particle simulations. The source code is written in C++, CUDA C and
Python, and is compiled by the user. The main computations are performed on the
graphics processing unit (GPU) using NVIDIA's general purpose parallel computing
architecture, CUDA. Simulation setup and data analysis is performed with the
included Python API.
-The ultimate aim of the *sphere* software is to simulate soft-bedded subglacial
+The ultimate aim of the ``sphere`` software is to simulate soft-bedded subglacial
conditions, while retaining the flexibility to perform simulations of granular
material in other environments.
The purpose of this documentation is to provide the user with a walk-through of
the installation, work-flow, data-analysis and visualization methods of
-*sphere*. In addition, the *sphere* internals are exposed to provide a way of
+``sphere``. In addition, the ``sphere`` internals are exposed to provide a way of
understanding of the discrete element method numerical routines taking place.
-.. note:: Command examples in this document starting with the symbol ``$`` are meant to be executed in the shell of the operational system, and ``>>>`` means execution in Python.
+.. note:: Command examples in this document starting with the symbol ``$`` are
+ meant to be executed in the shell of the operational system, and ``>>>``
+ means execution in Python. `IPython <http://ipython.org>`_ is an excellent,
+ interactive Python shell.
All numerical values in this document, the source code, and the configuration
files are typeset with strict respect to the SI unit system.
+
Requirements
------------
+
The build requirements are:
+
* A Nvidia CUDA-supported version of Linux or Mac OS X (see the `CUDA toolkit
release notes <http://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html>`_ for more information)
* `GNU Make <https://www.gnu.org/software/make/>`_
- * `CMake <http://www.cmake.org>`_
+ * `CMake <http://www.cmake.org>`_, version 2.8 or newer
* The `GNU Compiler Collection <http://gcc.gnu.org/>`_ (GCC)
- * The `Nvidia CUDA toolkit and SDK <https://developer.nvidia.com/cuda-downloads>`_
+ * The `Nvidia CUDA toolkit <https://developer.nvidia.com/cuda-downloads>`_,
+ version 5.0 or newer
+
+In Debian GNU/Linux, these dependencies can be installed by running::
+
+ $ sudo apt-get install build-essential cmake nvidia-cuda-toolkit
+
+Unfortunately, the Nvidia Toolkit is shipped under a non-free license. In order
+to install it in Debian GNU/Linux, add ``non-free`` archives to your
+``/etc/apt/sources.list``.
The runtime requirements are:
+
* A `CUDA-enabled GPU <http://www.nvidia.com/object/cuda_gpus.html>`_ with
compute capability 1.1 or greater.
* A Nvidia CUDA-enabled GPU and device driver
Optional tools, required for simulation setup and data processing:
- * `Python 2.7 <http://www.python.org/getit/releases/2.7/>`_
+
+ * `Python <http://www.python.org/>`_
* `Numpy <http://numpy.scipy.org>`_
* `Matplotlib <http://matplotlib.org>`_
+ * `Python bindings for VTK <http://www.vtk.org>`_
* `Imagemagick <http://www.imagemagick.org/script/index.php>`_
- * `ffmpeg <http://ffmpeg.org/>`_
+ * `ffmpeg <http://ffmpeg.org/>`_. Soon to be replaced by avconv!
+
+In Debian GNU/Linux, these dependencies can be installed by running::
+
+ $ sudo apt-get install python python-numpy python-matplotlib python-vtk \
+ imagemagick libav-tools
+
+``sphere`` is distributed with a HTML and PDF build of the documentation. The
+following tools are required for building the documentation:
-Optional tools, required for building the documentation:
* `Sphinx <http://sphinx-doc.org>`_
* `sphinxcontrib-programoutput <http://packages.python.org/sphinxcontrib-programoutput/>`_
t@@ -51,23 +77,75 @@ Optional tools, required for building the documentation:
* `Doxygen <http://www.stack.nl/~dimitri/doxygen/>`_
* `Breathe <http://michaeljones.github.com/breathe/>`_
* `dvipng <http://www.nongnu.org/dvipng/>`_
+ * `TeX Live <http://www.tug.org/texlive/>`_, including ``pdflatex``
+
+In Debian GNU/Linux, these dependencies can be installed by running::
+
+ $ sudo apt-get install python-sphinx python-pip doxygen dvipng \
+ python-sphinxcontrib-programoutput texlive-full
+ $ sudo pip install breathe
`Git <http://git-scm.com>`_ is used as the distributed version control system
platform, and the source code is maintained at `Github
-<https://github.com/anders-dc/sphere/>`_. *sphere* is licensed under the `GNU
+<https://github.com/anders-dc/sphere/>`_. ``sphere`` is licensed under the `GNU
Public License, v.3 <https://www.gnu.org/licenses/gpl.html>`_.
+.. note:: All Debian GNU/Linux runtime, optional, and documentation dependencies
+ mentioned above can be installed by executing the following command from the
+ ``doc/`` folder::
+
+ $ make install-debian-pkgs
+
+
+Obtaining sphere
+----------------
+
+The best way to keep up to date with subsequent updates, bugfixes and
+development, is to use the Git version control system. To obtain a local
+copy, execute::
+
+ $ git clone git@github.com:anders-dc/sphere.git
-Building *sphere*
------------------
-All instructions required for building *sphere* are provided in a number of
-``Makefile``'s. To generate the main *sphere* command-line executable, go to the
-root directory, and invoke CMake and GNU Make::
+
+Building ``sphere``
+-------------------
+
+``sphere`` is built using ``cmake``, the platform-specific C/C++ compilers,
+and ``nvcc`` from the Nvidia CUDA toolkit.
+
+If you plan to run ``sphere`` on a Kepler GPU, execute the following commands
+from the root directory::
+
+ $ cmake . && make
+
+If you instead plan to execute it on a Fermi GPU, change ``set(GPU_GENERATION
+1)`` to ``set(GPU_GENERATION 0`` in ``CMakeLists.txt``.
+
+In some cases the CMake FindCUDA module will have troubles locating the
+CUDA samples directory, and will complain about ``helper_math.h`` not being
+found.
+
+In that case, modify the ``CUDA_SDK_ROOT_DIR`` variable in
+``src/CMakeLists.txt`` to the path where you installed the CUDA samples, and run
+``cmake . && make`` again. Alternatively, copy ``helper_math.h`` from the CUDA
+sample subdirectory ``common/inc/helper_math.h`` into the sphere ``src/``
+directory, and run ``cmake`` and ``make`` again. Due to license restrictions,
+sphere cannot be distributed with this file.
+
+After a successfull installation, the ``sphere`` executable will be located
+in the root folder. To make sure that all components are working correctly,
+execute::
+
+ $ make test
+
+All instructions required for building ``sphere`` are provided in a number of
+``Makefile``'s. To generate the main ``sphere`` command-line executable, go to
+the root directory, and invoke CMake and GNU Make::
$ cmake . && make
If successfull, the Makefiles will create the required data folders, object
-files, as well as the *sphere* executable in the root folder. Issue the
+files, as well as the ``sphere`` executable in the root folder. Issue the
following commands to check the executable::
$ ./sphere --version
t@@ -82,8 +160,10 @@ The build can be verified by running a number of automated tests::
The documentation can be read in the `reStructuredText
<http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html>`_-format in
-the ``doc/sphinx/`` folder, or build into e.g. HTML or PDF format with the
-following commands::
+the ``doc/sphinx/`` folder, or in the HTML or PDF formats in the folders
+``doc/html`` and ``doc/pdf``.
+
+Optionally, the documentation can be built using the following commands::
$ cd doc/sphinx
$ make html
t@@ -94,15 +174,26 @@ To see all available output formats, execute::
$ make help
+Updating sphere
+---------------
+
+To update your local version, type the following commands in the ``sphere`` root
+directory::
+
+ $ git pull && cmake . && make
+
+
Work flow
---------
-After compiling the *sphere* binary, the procedure of a creating and handling a
-simulation is typically arranged in the following order:
+
+After compiling the ``sphere`` binary, the procedure of a creating and handling
+a simulation is typically arranged in the following order:
+
* Setup of particle assemblage, physical properties and conditions using the
Python API.
- * Execution of *sphere* software, which simulates the particle behavior as a
+ * Execution of ``sphere`` software, which simulates the particle behavior as a
function of time, as a result of the conditions initially specified in the
input file.
- * Inspection, analysis, interpretation and visualization of *sphere* output in
- Python, and/or scene rendering using the built-in ray tracer.
+ * Inspection, analysis, interpretation and visualization of ``sphere`` output
+ in Python, and/or scene rendering using the built-in ray tracer.
DIR diff --git a/doc/html/_sources/python_api.txt b/doc/html/_sources/python_api.txt
t@@ -1,5 +1,27 @@
Python API
==========
+The Python module ``sphere`` is intended as the main interface to the ``sphere``
+application. It is recommended to use this module for simulation setup,
+simulation execution, and analysis of the simulation output data.
+
+In order to use the API, the file ``sphere.py`` must be placed in the same
+directory as the Python files.
+
+Sample usage
+------------
+Below is a simple, annotated example of how to setup, execute, and post-process
+a ``sphere`` simulation. The example is also found in the ``python/`` folder as
+``collision.py``.
+
+.. literalinclude:: ../../python/collision.py
+ :language: python
+ :linenos:
+
+The full documentation of the ``sphere`` Python API can be found below.
+
+
+The ``sphere`` module
+---------------------
.. automodule:: sphere
:members:
DIR diff --git a/doc/html/_sources/sphere_internals.txt b/doc/html/_sources/sphere_internals.txt
t@@ -207,8 +207,6 @@ An important note is that the \texttt{C} examples of the NVIDIA CUDA SDK should
*sphere* is supplied with several Makefiles, which automate the compilation process. To compile all components, open a shell, go to the \texttt{src/} subfolder and type \texttt{make}. The GNU Make will return the parameters passed to the individual CUDA and GNU compilers (\texttt{nvcc} and \texttt{gcc}). The resulting binary file (\texttt{sphere}) is placed in the *sphere* root folder. ``src/Makefile`` will also compile the raytracer.
-
-
C++ reference
-------------
.. doxygenclass:: DEM
DIR diff --git a/doc/html/_static/jquery.js b/doc/html/_static/jquery.js
t@@ -11,7 +11,7 @@
* Copyright 2011, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
- * Date: Thu Nov 15 18:28:24 BRST 2012
+ * Date: Fri Jul 5 14:07:58 UTC 2013
*/
(function( window, undefined ) {
DIR diff --git a/doc/html/_static/pygments.css b/doc/html/_static/pygments.css
t@@ -13,11 +13,11 @@
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
-.highlight .go { color: #303030 } /* Generic.Output */
+.highlight .go { color: #333333 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.highlight .gt { color: #0040D0 } /* Generic.Traceback */
+.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
DIR diff --git a/doc/html/_static/searchtools.js b/doc/html/_static/searchtools.js
t@@ -239,8 +239,13 @@ var Search = {
},
loadIndex : function(url) {
- $.ajax({type: "GET", url: url, data: null, success: null,
- dataType: "script", cache: true});
+ $.ajax({type: "GET", url: url, data: null,
+ dataType: "script", cache: true,
+ complete: function(jqxhr, textstatus) {
+ if (textstatus != "success") {
+ document.getElementById("searchindexloader").src = url;
+ }
+ }});
},
setIndex : function(index) {
t@@ -301,7 +306,7 @@ var Search = {
},
query : function(query) {
- var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"];
+ var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
// Stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
t@@ -457,16 +462,18 @@ var Search = {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
- $.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' +
- item[0] + '.txt', function(data) {
- if (data != '') {
- listItem.append($.makeSearchSummary(data, searchterms, hlterms));
- Search.output.append(listItem);
- }
- listItem.slideDown(5, function() {
- displayNextItem();
- });
- }, "text");
+ $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt',
+ dataType: "text",
+ complete: function(jqxhr, textstatus) {
+ var data = jqxhr.responseText;
+ if (data !== '') {
+ listItem.append($.makeSearchSummary(data, searchterms, hlterms));
+ }
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ }});
} else {
// no source available, just display title
Search.output.append(listItem);
DIR diff --git a/doc/html/_static/underscore.js b/doc/html/_static/underscore.js
t@@ -1,10 +1,7 @@
-// Underscore.js 1.1.6
-// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore is freely distributable under the MIT license.
-// Portions of Underscore are inspired or borrowed from Prototype,
-// Oliver Steele's Functional, and John Resig's Micro-Templating.
-// For all details and documentation:
-// http://documentcloud.github.com/underscore
+// Underscore.js 1.4.4
+// http://underscorejs.org
+// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore may be freely distributed under the MIT license.
(function() {
t@@ -24,8 +21,9 @@
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
// Create quick reference variables for speed access to core prototypes.
- var slice = ArrayProto.slice,
- unshift = ArrayProto.unshift,
+ var push = ArrayProto.push,
+ slice = ArrayProto.slice,
+ concat = ArrayProto.concat,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
t@@ -46,38 +44,45 @@
nativeBind = FuncProto.bind;
// Create a safe reference to the Underscore object for use below.
- var _ = function(obj) { return new wrapper(obj); };
-
- // Export the Underscore object for **CommonJS**, with backwards-compatibility
- // for the old `require()` API. If we're not in CommonJS, add `_` to the
- // global object.
- if (typeof module !== 'undefined' && module.exports) {
- module.exports = _;
- _._ = _;
+ var _ = function(obj) {
+ if (obj instanceof _) return obj;
+ if (!(this instanceof _)) return new _(obj);
+ this._wrapped = obj;
+ };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object via a string identifier,
+ // for Closure Compiler "advanced" mode.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
} else {
root._ = _;
}
// Current version.
- _.VERSION = '1.1.6';
+ _.VERSION = '1.4.4';
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
- // Handles objects implementing `forEach`, arrays, and raw objects.
+ // Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
- } else if (_.isNumber(obj.length)) {
+ } else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
for (var key in obj) {
- if (hasOwnProperty.call(obj, key)) {
+ if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
t@@ -86,7 +91,7 @@
// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
- _.map = function(obj, iterator, context) {
+ _.map = _.collect = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
t@@ -96,37 +101,54 @@
return results;
};
+ var reduceError = 'Reduce of empty array with no initial value';
+
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
- var initial = memo !== void 0;
+ var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
- if (!initial && index === 0) {
+ if (!initial) {
memo = value;
initial = true;
} else {
memo = iterator.call(context, memo, value, index, list);
}
});
- if (!initial) throw new TypeError("Reduce of empty array with no initial value");
+ if (!initial) throw new TypeError(reduceError);
return memo;
};
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
- return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+ return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+ }
+ var length = obj.length;
+ if (length !== +length) {
+ var keys = _.keys(obj);
+ length = keys.length;
}
- var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
- return _.reduce(reversed, iterator, memo, context);
+ each(obj, function(value, index, list) {
+ index = keys ? keys[--length] : --length;
+ if (!initial) {
+ memo = obj[index];
+ initial = true;
+ } else {
+ memo = iterator.call(context, memo, obj[index], index, list);
+ }
+ });
+ if (!initial) throw new TypeError(reduceError);
+ return memo;
};
// Return the first value which passes a truth test. Aliased as `detect`.
t@@ -156,25 +178,23 @@
// Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) {
- var results = [];
- if (obj == null) return results;
- each(obj, function(value, index, list) {
- if (!iterator.call(context, value, index, list)) results[results.length] = value;
- });
- return results;
+ return _.filter(obj, function(value, index, list) {
+ return !iterator.call(context, value, index, list);
+ }, context);
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, iterator, context) {
+ iterator || (iterator = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
- return result;
+ return !!result;
};
// Determine if at least one element in the object matches a truth test.
t@@ -186,28 +206,27 @@
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
- if (result = iterator.call(context, value, index, list)) return breaker;
+ if (result || (result = iterator.call(context, value, index, list))) return breaker;
});
- return result;
+ return !!result;
};
- // Determine if a given value is included in the array or object using `===`.
- // Aliased as `contains`.
- _.include = _.contains = function(obj, target) {
- var found = false;
- if (obj == null) return found;
+ // Determine if the array or object contains a given value (using `===`).
+ // Aliased as `include`.
+ _.contains = _.include = function(obj, target) {
+ if (obj == null) return false;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
- any(obj, function(value) {
- if (found = value === target) return true;
+ return any(obj, function(value) {
+ return value === target;
});
- return found;
};
// Invoke a method (with arguments) on every item in a collection.
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
+ var isFunc = _.isFunction(method);
return _.map(obj, function(value) {
- return (method.call ? method || value : value[method]).apply(value, args);
+ return (isFunc ? method : value[method]).apply(value, args);
});
};
t@@ -216,10 +235,33 @@
return _.map(obj, function(value){ return value[key]; });
};
+ // Convenience version of a common use case of `filter`: selecting only objects
+ // containing specific `key:value` pairs.
+ _.where = function(obj, attrs, first) {
+ if (_.isEmpty(attrs)) return first ? null : [];
+ return _[first ? 'find' : 'filter'](obj, function(value) {
+ for (var key in attrs) {
+ if (attrs[key] !== value[key]) return false;
+ }
+ return true;
+ });
+ };
+
+ // Convenience version of a common use case of `find`: getting the first object
+ // containing specific `key:value` pairs.
+ _.findWhere = function(obj, attrs) {
+ return _.where(obj, attrs, true);
+ };
+
// Return the maximum element or (element-based computation).
+ // Can't optimize arrays of integers longer than 65,535 elements.
+ // See: https://bugs.webkit.org/show_bug.cgi?id=80797
_.max = function(obj, iterator, context) {
- if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
- var result = {computed : -Infinity};
+ if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
+ return Math.max.apply(Math, obj);
+ }
+ if (!iterator && _.isEmpty(obj)) return -Infinity;
+ var result = {computed : -Infinity, value: -Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed >= result.computed && (result = {value : value, computed : computed});
t@@ -229,8 +271,11 @@
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
- if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
- var result = {computed : Infinity};
+ if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
+ return Math.min.apply(Math, obj);
+ }
+ if (!iterator && _.isEmpty(obj)) return Infinity;
+ var result = {computed : Infinity, value: Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && (result = {value : value, computed : computed});
t@@ -238,101 +283,195 @@
return result.value;
};
+ // Shuffle an array.
+ _.shuffle = function(obj) {
+ var rand;
+ var index = 0;
+ var shuffled = [];
+ each(obj, function(value) {
+ rand = _.random(index++);
+ shuffled[index - 1] = shuffled[rand];
+ shuffled[rand] = value;
+ });
+ return shuffled;
+ };
+
+ // An internal function to generate lookup iterators.
+ var lookupIterator = function(value) {
+ return _.isFunction(value) ? value : function(obj){ return obj[value]; };
+ };
+
// Sort the object's values by a criterion produced by an iterator.
- _.sortBy = function(obj, iterator, context) {
+ _.sortBy = function(obj, value, context) {
+ var iterator = lookupIterator(value);
return _.pluck(_.map(obj, function(value, index, list) {
return {
value : value,
+ index : index,
criteria : iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
+ var a = left.criteria;
+ var b = right.criteria;
+ if (a !== b) {
+ if (a > b || a === void 0) return 1;
+ if (a < b || b === void 0) return -1;
+ }
+ return left.index < right.index ? -1 : 1;
}), 'value');
};
- // Use a comparator function to figure out at what index an object should
- // be inserted so as to maintain order. Uses binary search.
- _.sortedIndex = function(array, obj, iterator) {
- iterator || (iterator = _.identity);
+ // An internal function used for aggregate "group by" operations.
+ var group = function(obj, value, context, behavior) {
+ var result = {};
+ var iterator = lookupIterator(value || _.identity);
+ each(obj, function(value, index) {
+ var key = iterator.call(context, value, index, obj);
+ behavior(result, key, value);
+ });
+ return result;
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = function(obj, value, context) {
+ return group(obj, value, context, function(result, key, value) {
+ (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
+ });
+ };
+
+ // Counts instances of an object that group by a certain criterion. Pass
+ // either a string attribute to count by, or a function that returns the
+ // criterion.
+ _.countBy = function(obj, value, context) {
+ return group(obj, value, context, function(result, key) {
+ if (!_.has(result, key)) result[key] = 0;
+ result[key]++;
+ });
+ };
+
+ // Use a comparator function to figure out the smallest index at which
+ // an object should be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iterator, context) {
+ iterator = iterator == null ? _.identity : lookupIterator(iterator);
+ var value = iterator.call(context, obj);
var low = 0, high = array.length;
while (low < high) {
- var mid = (low + high) >> 1;
- iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
+ var mid = (low + high) >>> 1;
+ iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
}
return low;
};
// Safely convert anything iterable into a real, live array.
- _.toArray = function(iterable) {
- if (!iterable) return [];
- if (iterable.toArray) return iterable.toArray();
- if (_.isArray(iterable)) return iterable;
- if (_.isArguments(iterable)) return slice.call(iterable);
- return _.values(iterable);
+ _.toArray = function(obj) {
+ if (!obj) return [];
+ if (_.isArray(obj)) return slice.call(obj);
+ if (obj.length === +obj.length) return _.map(obj, _.identity);
+ return _.values(obj);
};
// Return the number of elements in an object.
_.size = function(obj) {
- return _.toArray(obj).length;
+ if (obj == null) return 0;
+ return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
};
// Array Functions
// ---------------
// Get the first element of an array. Passing **n** will return the first N
- // values in the array. Aliased as `head`. The **guard** check allows it to work
- // with `_.map`.
- _.first = _.head = function(array, n, guard) {
+ // values in the array. Aliased as `head` and `take`. The **guard** check
+ // allows it to work with `_.map`.
+ _.first = _.head = _.take = function(array, n, guard) {
+ if (array == null) return void 0;
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
};
- // Returns everything but the first entry of the array. Aliased as `tail`.
- // Especially useful on the arguments object. Passing an **index** will return
- // the rest of the values in the array from that index onward. The **guard**
- // check allows it to work with `_.map`.
- _.rest = _.tail = function(array, index, guard) {
- return slice.call(array, (index == null) || guard ? 1 : index);
+ // Returns everything but the last entry of the array. Especially useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N. The **guard** check allows it to work with
+ // `_.map`.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array. The **guard** check allows it to work with `_.map`.
+ _.last = function(array, n, guard) {
+ if (array == null) return void 0;
+ if ((n != null) && !guard) {
+ return slice.call(array, Math.max(array.length - n, 0));
+ } else {
+ return array[array.length - 1];
+ }
};
- // Get the last element of an array.
- _.last = function(array) {
- return array[array.length - 1];
+ // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
+ // Especially useful on the arguments object. Passing an **n** will return
+ // the rest N values in the array. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = _.drop = function(array, n, guard) {
+ return slice.call(array, (n == null) || guard ? 1 : n);
};
// Trim out all falsy values from an array.
_.compact = function(array) {
- return _.filter(array, function(value){ return !!value; });
+ return _.filter(array, _.identity);
+ };
+
+ // Internal implementation of a recursive `flatten` function.
+ var flatten = function(input, shallow, output) {
+ each(input, function(value) {
+ if (_.isArray(value)) {
+ shallow ? push.apply(output, value) : flatten(value, shallow, output);
+ } else {
+ output.push(value);
+ }
+ });
+ return output;
};
// Return a completely flattened version of an array.
- _.flatten = function(array) {
- return _.reduce(array, function(memo, value) {
- if (_.isArray(value)) return memo.concat(_.flatten(value));
- memo[memo.length] = value;
- return memo;
- }, []);
+ _.flatten = function(array, shallow) {
+ return flatten(array, shallow, []);
};
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
- var values = slice.call(arguments, 1);
- return _.filter(array, function(value){ return !_.include(values, value); });
+ return _.difference(array, slice.call(arguments, 1));
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
- _.uniq = _.unique = function(array, isSorted) {
- return _.reduce(array, function(memo, el, i) {
- if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
- return memo;
- }, []);
+ _.uniq = _.unique = function(array, isSorted, iterator, context) {
+ if (_.isFunction(isSorted)) {
+ context = iterator;
+ iterator = isSorted;
+ isSorted = false;
+ }
+ var initial = iterator ? _.map(array, iterator, context) : array;
+ var results = [];
+ var seen = [];
+ each(initial, function(value, index) {
+ if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
+ seen.push(value);
+ results.push(array[index]);
+ }
+ });
+ return results;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(concat.apply(ArrayProto, arguments));
};
// Produce an array that contains every item shared between all the
// passed-in arrays.
- _.intersect = function(array) {
+ _.intersection = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
t@@ -341,16 +480,41 @@
});
};
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
+ return _.filter(array, function(value){ return !_.contains(rest, value); });
+ };
+
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var args = slice.call(arguments);
var length = _.max(_.pluck(args, 'length'));
var results = new Array(length);
- for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
+ for (var i = 0; i < length; i++) {
+ results[i] = _.pluck(args, "" + i);
+ }
return results;
};
+ // Converts lists into objects. Pass either a single array of `[key, value]`
+ // pairs, or two parallel arrays of the same length -- one of keys, and one of
+ // the corresponding values.
+ _.object = function(list, values) {
+ if (list == null) return {};
+ var result = {};
+ for (var i = 0, l = list.length; i < l; i++) {
+ if (values) {
+ result[list[i]] = values[i];
+ } else {
+ result[list[i][0]] = list[i][1];
+ }
+ }
+ return result;
+ };
+
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
t@@ -359,22 +523,28 @@
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
- var i, l;
+ var i = 0, l = array.length;
if (isSorted) {
- i = _.sortedIndex(array, item);
- return array[i] === item ? i : -1;
+ if (typeof isSorted == 'number') {
+ i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
+ } else {
+ i = _.sortedIndex(array, item);
+ return array[i] === item ? i : -1;
+ }
}
- if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
- for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
+ if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
+ for (; i < l; i++) if (array[i] === item) return i;
return -1;
};
-
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
- _.lastIndexOf = function(array, item) {
+ _.lastIndexOf = function(array, item, from) {
if (array == null) return -1;
- if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
- var i = array.length;
+ var hasIndex = from != null;
+ if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
+ return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
+ }
+ var i = (hasIndex ? from : array.length);
while (i--) if (array[i] === item) return i;
return -1;
};
t@@ -405,14 +575,22 @@
// ------------------
// Create a function bound to a given object (assigning `this`, and arguments,
- // optionally). Binding with arguments is also known as `curry`.
- // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
- // We check for `func.bind` first, to fail fast when `func` is undefined.
- _.bind = function(func, obj) {
+ // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
+ // available.
+ _.bind = function(func, context) {
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
var args = slice.call(arguments, 2);
return function() {
- return func.apply(obj, args.concat(slice.call(arguments)));
+ return func.apply(context, args.concat(slice.call(arguments)));
+ };
+ };
+
+ // Partially apply a function by creating a version that has had some of its
+ // arguments pre-filled, without changing its dynamic `this` context.
+ _.partial = function(func) {
+ var args = slice.call(arguments, 1);
+ return function() {
+ return func.apply(this, args.concat(slice.call(arguments)));
};
};
t@@ -420,7 +598,7 @@
// all callbacks defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
- if (funcs.length == 0) funcs = _.functions(obj);
+ if (funcs.length === 0) funcs = _.functions(obj);
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj;
};
t@@ -431,7 +609,7 @@
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
- return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+ return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
};
};
t@@ -439,7 +617,7 @@
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
- return setTimeout(function(){ return func.apply(func, args); }, wait);
+ return setTimeout(function(){ return func.apply(null, args); }, wait);
};
// Defers a function, scheduling it to run after the current call stack has
t@@ -448,31 +626,51 @@
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
- // Internal function used to implement `_.throttle` and `_.debounce`.
- var limit = function(func, wait, debounce) {
- var timeout;
- return function() {
- var context = this, args = arguments;
- var throttler = function() {
- timeout = null;
- func.apply(context, args);
- };
- if (debounce) clearTimeout(timeout);
- if (debounce || !timeout) timeout = setTimeout(throttler, wait);
- };
- };
-
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
- return limit(func, wait, false);
+ var context, args, timeout, result;
+ var previous = 0;
+ var later = function() {
+ previous = new Date;
+ timeout = null;
+ result = func.apply(context, args);
+ };
+ return function() {
+ var now = new Date;
+ var remaining = wait - (now - previous);
+ context = this;
+ args = arguments;
+ if (remaining <= 0) {
+ clearTimeout(timeout);
+ timeout = null;
+ previous = now;
+ result = func.apply(context, args);
+ } else if (!timeout) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
- // N milliseconds.
- _.debounce = function(func, wait) {
- return limit(func, wait, true);
+ // N milliseconds. If `immediate` is passed, trigger the function on the
+ // leading edge, instead of the trailing.
+ _.debounce = function(func, wait, immediate) {
+ var timeout, result;
+ return function() {
+ var context = this, args = arguments;
+ var later = function() {
+ timeout = null;
+ if (!immediate) result = func.apply(context, args);
+ };
+ var callNow = immediate && !timeout;
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ if (callNow) result = func.apply(context, args);
+ return result;
+ };
};
// Returns a function that will be executed at most one time, no matter how
t@@ -482,7 +680,9 @@
return function() {
if (ran) return memo;
ran = true;
- return memo = func.apply(this, arguments);
+ memo = func.apply(this, arguments);
+ func = null;
+ return memo;
};
};
t@@ -491,7 +691,8 @@
// conditionally execute the original function.
_.wrap = function(func, wrapper) {
return function() {
- var args = [func].concat(slice.call(arguments));
+ var args = [func];
+ push.apply(args, arguments);
return wrapper.apply(this, args);
};
};
t@@ -499,10 +700,10 @@
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
- var funcs = slice.call(arguments);
+ var funcs = arguments;
return function() {
- var args = slice.call(arguments);
- for (var i=funcs.length-1; i >= 0; i--) {
+ var args = arguments;
+ for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
return args[0];
t@@ -511,12 +712,14 @@
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
+ if (times <= 0) return func();
return function() {
- if (--times < 1) { return func.apply(this, arguments); }
+ if (--times < 1) {
+ return func.apply(this, arguments);
+ }
};
};
-
// Object Functions
// ----------------
t@@ -525,36 +728,80 @@
_.keys = nativeKeys || function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object');
var keys = [];
- for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
+ for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
- return _.map(obj, _.identity);
+ var values = [];
+ for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
+ return values;
+ };
+
+ // Convert an object into a list of `[key, value]` pairs.
+ _.pairs = function(obj) {
+ var pairs = [];
+ for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
+ return pairs;
+ };
+
+ // Invert the keys and values of an object. The values must be serializable.
+ _.invert = function(obj) {
+ var result = {};
+ for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
+ return result;
};
// Return a sorted list of the function names available on the object.
// Aliased as `methods`
_.functions = _.methods = function(obj) {
- return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
- for (var prop in source) {
- if (source[prop] !== void 0) obj[prop] = source[prop];
+ if (source) {
+ for (var prop in source) {
+ obj[prop] = source[prop];
+ }
}
});
return obj;
};
+ // Return a copy of the object only containing the whitelisted properties.
+ _.pick = function(obj) {
+ var copy = {};
+ var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
+ each(keys, function(key) {
+ if (key in obj) copy[key] = obj[key];
+ });
+ return copy;
+ };
+
+ // Return a copy of the object without the blacklisted properties.
+ _.omit = function(obj) {
+ var copy = {};
+ var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
+ for (var key in obj) {
+ if (!_.contains(keys, key)) copy[key] = obj[key];
+ }
+ return copy;
+ };
+
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
- for (var prop in source) {
- if (obj[prop] == null) obj[prop] = source[prop];
+ if (source) {
+ for (var prop in source) {
+ if (obj[prop] == null) obj[prop] = source[prop];
+ }
}
});
return obj;
t@@ -562,6 +809,7 @@
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
t@@ -573,102 +821,162 @@
return obj;
};
+ // Internal recursive comparison function for `isEqual`.
+ var eq = function(a, b, aStack, bStack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
+ if (a === b) return a !== 0 || 1 / a == 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a instanceof _) a = a._wrapped;
+ if (b instanceof _) b = b._wrapped;
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className != toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, dates, and booleans are compared by value.
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return a == String(b);
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+ // other numeric values.
+ return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a == +b;
+ // RegExps are compared by their source patterns and flags.
+ case '[object RegExp]':
+ return a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase;
+ }
+ if (typeof a != 'object' || typeof b != 'object') return false;
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = aStack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (aStack[length] == a) return bStack[length] == b;
+ }
+ // Add the first object to the stack of traversed objects.
+ aStack.push(a);
+ bStack.push(b);
+ var size = 0, result = true;
+ // Recursively compare objects and arrays.
+ if (className == '[object Array]') {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ size = a.length;
+ result = size == b.length;
+ if (result) {
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (size--) {
+ if (!(result = eq(a[size], b[size], aStack, bStack))) break;
+ }
+ }
+ } else {
+ // Objects with different constructors are not equivalent, but `Object`s
+ // from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
+ _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
+ return false;
+ }
+ // Deep compare objects.
+ for (var key in a) {
+ if (_.has(a, key)) {
+ // Count the expected number of properties.
+ size++;
+ // Deep compare each member.
+ if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
+ }
+ }
+ // Ensure that both objects contain the same number of properties.
+ if (result) {
+ for (key in b) {
+ if (_.has(b, key) && !(size--)) break;
+ }
+ result = !size;
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ aStack.pop();
+ bStack.pop();
+ return result;
+ };
+
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
- // Check object identity.
- if (a === b) return true;
- // Different types?
- var atype = typeof(a), btype = typeof(b);
- if (atype != btype) return false;
- // Basic equality test (watch out for coercions).
- if (a == b) return true;
- // One is falsy and the other truthy.
- if ((!a && b) || (a && !b)) return false;
- // Unwrap any wrapped objects.
- if (a._chain) a = a._wrapped;
- if (b._chain) b = b._wrapped;
- // One of them implements an isEqual()?
- if (a.isEqual) return a.isEqual(b);
- // Check dates' integer values.
- if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
- // Both are NaN?
- if (_.isNaN(a) && _.isNaN(b)) return false;
- // Compare regular expressions.
- if (_.isRegExp(a) && _.isRegExp(b))
- return a.source === b.source &&
- a.global === b.global &&
- a.ignoreCase === b.ignoreCase &&
- a.multiline === b.multiline;
- // If a is not an object by this point, we can't handle it.
- if (atype !== 'object') return false;
- // Check for different array lengths before comparing contents.
- if (a.length && (a.length !== b.length)) return false;
- // Nothing else worked, deep compare the contents.
- var aKeys = _.keys(a), bKeys = _.keys(b);
- // Different object sizes?
- if (aKeys.length != bKeys.length) return false;
- // Recursive comparison of contents.
- for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
- return true;
+ return eq(a, b, [], []);
};
- // Is a given array or object empty?
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
+ if (obj == null) return true;
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
- for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
+ for (var key in obj) if (_.has(obj, key)) return false;
return true;
};
// Is a given value a DOM element?
_.isElement = function(obj) {
- return !!(obj && obj.nodeType == 1);
+ return !!(obj && obj.nodeType === 1);
};
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
- return toString.call(obj) === '[object Array]';
+ return toString.call(obj) == '[object Array]';
};
- // Is a given variable an arguments object?
- _.isArguments = function(obj) {
- return !!(obj && hasOwnProperty.call(obj, 'callee'));
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ return obj === Object(obj);
};
- // Is a given value a function?
- _.isFunction = function(obj) {
- return !!(obj && obj.constructor && obj.call && obj.apply);
- };
+ // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
+ each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
+ _['is' + name] = function(obj) {
+ return toString.call(obj) == '[object ' + name + ']';
+ };
+ });
- // Is a given value a string?
- _.isString = function(obj) {
- return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
- };
+ // Define a fallback version of the method in browsers (ahem, IE), where
+ // there isn't any inspectable "Arguments" type.
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return !!(obj && _.has(obj, 'callee'));
+ };
+ }
+
+ // Optimize `isFunction` if appropriate.
+ if (typeof (/./) !== 'function') {
+ _.isFunction = function(obj) {
+ return typeof obj === 'function';
+ };
+ }
- // Is a given value a number?
- _.isNumber = function(obj) {
- return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
+ // Is a given object a finite number?
+ _.isFinite = function(obj) {
+ return isFinite(obj) && !isNaN(parseFloat(obj));
};
- // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
- // that does not equal itself.
+ // Is the given value `NaN`? (NaN is the only number which does not equal itself).
_.isNaN = function(obj) {
- return obj !== obj;
+ return _.isNumber(obj) && obj != +obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
- return obj === true || obj === false;
- };
-
- // Is a given value a date?
- _.isDate = function(obj) {
- return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
- };
-
- // Is the given value a regular expression?
- _.isRegExp = function(obj) {
- return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
+ return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
};
// Is a given value equal to null?
t@@ -681,6 +989,12 @@
return obj === void 0;
};
+ // Shortcut function for checking if an object has a given property directly
+ // on itself (in other words, not on a prototype).
+ _.has = function(obj, key) {
+ return hasOwnProperty.call(obj, key);
+ };
+
// Utility Functions
// -----------------
t@@ -697,15 +1011,67 @@
};
// Run a function **n** times.
- _.times = function (n, iterator, context) {
- for (var i = 0; i < n; i++) iterator.call(context, i);
+ _.times = function(n, iterator, context) {
+ var accum = Array(n);
+ for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
+ return accum;
+ };
+
+ // Return a random integer between min and max (inclusive).
+ _.random = function(min, max) {
+ if (max == null) {
+ max = min;
+ min = 0;
+ }
+ return min + Math.floor(Math.random() * (max - min + 1));
+ };
+
+ // List of HTML entities for escaping.
+ var entityMap = {
+ escape: {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": ''',
+ '/': '/'
+ }
+ };
+ entityMap.unescape = _.invert(entityMap.escape);
+
+ // Regexes containing the keys and values listed immediately above.
+ var entityRegexes = {
+ escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
+ unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
+ };
+
+ // Functions for escaping and unescaping strings to/from HTML interpolation.
+ _.each(['escape', 'unescape'], function(method) {
+ _[method] = function(string) {
+ if (string == null) return '';
+ return ('' + string).replace(entityRegexes[method], function(match) {
+ return entityMap[method][match];
+ });
+ };
+ });
+
+ // If the value of the named property is a function then invoke it;
+ // otherwise, return it.
+ _.result = function(object, property) {
+ if (object == null) return null;
+ var value = object[property];
+ return _.isFunction(value) ? value.call(object) : value;
};
- // Add your own custom functions to the Underscore object, ensuring that
- // they're correctly added to the OOP wrapper as well.
+ // Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
each(_.functions(obj), function(name){
- addToWrapper(name, _[name] = obj[name]);
+ var func = _[name] = obj[name];
+ _.prototype[name] = function() {
+ var args = [this._wrapped];
+ push.apply(args, arguments);
+ return result.call(this, func.apply(_, args));
+ };
});
};
t@@ -713,7 +1079,7 @@
// Useful for temporary DOM ids.
var idCounter = 0;
_.uniqueId = function(prefix) {
- var id = idCounter++;
+ var id = ++idCounter + '';
return prefix ? prefix + id : id;
};
t@@ -721,56 +1087,103 @@
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
- interpolate : /<%=([\s\S]+?)%>/g
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /(.)^/;
+
+ // Certain characters need to be escaped so that they can be put into a
+ // string literal.
+ var escapes = {
+ "'": "'",
+ '\\': '\\',
+ '\r': 'r',
+ '\n': 'n',
+ '\t': 't',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
};
+ var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
+
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
- _.template = function(str, data) {
- var c = _.templateSettings;
- var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
- 'with(obj||{}){__p.push(\'' +
- str.replace(/\\/g, '\\\\')
- .replace(/'/g, "\\'")
- .replace(c.interpolate, function(match, code) {
- return "'," + code.replace(/\\'/g, "'") + ",'";
- })
- .replace(c.evaluate || null, function(match, code) {
- return "');" + code.replace(/\\'/g, "'")
- .replace(/[\r\n\t]/g, ' ') + "__p.push('";
- })
- .replace(/\r/g, '\\r')
- .replace(/\n/g, '\\n')
- .replace(/\t/g, '\\t')
- + "');}return __p.join('');";
- var func = new Function('obj', tmpl);
- return data ? func(data) : func;
- };
-
- // The OOP Wrapper
- // ---------------
+ _.template = function(text, data, settings) {
+ var render;
+ settings = _.defaults({}, settings, _.templateSettings);
+
+ // Combine delimiters into one regular expression via alternation.
+ var matcher = new RegExp([
+ (settings.escape || noMatch).source,
+ (settings.interpolate || noMatch).source,
+ (settings.evaluate || noMatch).source
+ ].join('|') + '|$', 'g');
+
+ // Compile the template source, escaping string literals appropriately.
+ var index = 0;
+ var source = "__p+='";
+ text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+ source += text.slice(index, offset)
+ .replace(escaper, function(match) { return '\\' + escapes[match]; });
+
+ if (escape) {
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+ }
+ if (interpolate) {
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+ }
+ if (evaluate) {
+ source += "';\n" + evaluate + "\n__p+='";
+ }
+ index = offset + match.length;
+ return match;
+ });
+ source += "';\n";
+ // If a variable is not specified, place data values in local scope.
+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+ source = "var __t,__p='',__j=Array.prototype.join," +
+ "print=function(){__p+=__j.call(arguments,'');};\n" +
+ source + "return __p;\n";
+
+ try {
+ render = new Function(settings.variable || 'obj', '_', source);
+ } catch (e) {
+ e.source = source;
+ throw e;
+ }
+
+ if (data) return render(data, _);
+ var template = function(data) {
+ return render.call(this, data, _);
+ };
+
+ // Provide the compiled function source as a convenience for precompilation.
+ template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
+
+ return template;
+ };
+
+ // Add a "chain" function, which will delegate to the wrapper.
+ _.chain = function(obj) {
+ return _(obj).chain();
+ };
+
+ // OOP
+ // ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
- var wrapper = function(obj) { this._wrapped = obj; };
-
- // Expose `wrapper.prototype` as `_.prototype`
- _.prototype = wrapper.prototype;
// Helper function to continue chaining intermediate results.
- var result = function(obj, chain) {
- return chain ? _(obj).chain() : obj;
- };
-
- // A method to easily add functions to the OOP wrapper.
- var addToWrapper = function(name, func) {
- wrapper.prototype[name] = function() {
- var args = slice.call(arguments);
- unshift.call(args, this._wrapped);
- return result(func.apply(_, args), this._chain);
- };
+ var result = function(obj) {
+ return this._chain ? _(obj).chain() : obj;
};
// Add all of the Underscore functions to the wrapper object.
t@@ -779,29 +1192,35 @@
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
- wrapper.prototype[name] = function() {
- method.apply(this._wrapped, arguments);
- return result(this._wrapped, this._chain);
+ _.prototype[name] = function() {
+ var obj = this._wrapped;
+ method.apply(obj, arguments);
+ if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
+ return result.call(this, obj);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
- wrapper.prototype[name] = function() {
- return result(method.apply(this._wrapped, arguments), this._chain);
+ _.prototype[name] = function() {
+ return result.call(this, method.apply(this._wrapped, arguments));
};
});
- // Start chaining a wrapped Underscore object.
- wrapper.prototype.chain = function() {
- this._chain = true;
- return this;
- };
+ _.extend(_.prototype, {
- // Extracts the result from a wrapped and chained object.
- wrapper.prototype.value = function() {
- return this._wrapped;
- };
+ // Start chaining a wrapped Underscore object.
+ chain: function() {
+ this._chain = true;
+ return this;
+ },
+
+ // Extracts the result from a wrapped and chained object.
+ value: function() {
+ return this._wrapped;
+ }
+
+ });
-})();
+}).call(this);
DIR diff --git a/doc/html/cfd.html b/doc/html/cfd.html
t@@ -0,0 +1,600 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Fluid simulation and particle-fluid interaction — sphere 1.00-alpha documentation</title>
+
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <link rel="stylesheet" href="_static/breathe.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '1.00-alpha',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="sphere 1.00-alpha documentation" href="index.html" />
+ <link rel="next" title="Python API" href="python_api.html" />
+ <link rel="prev" title="Discrete element method" href="dem.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="py-modindex.html" title="Python Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="python_api.html" title="Python API"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="dem.html" title="Discrete element method"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="fluid-simulation-and-particle-fluid-interaction">
+<h1>Fluid simulation and particle-fluid interaction<a class="headerlink" href="#fluid-simulation-and-particle-fluid-interaction" title="Permalink to this headline">¶</a></h1>
+<p>A new and experimental addition to <em>sphere</em> is the ability to simulate a mixture
+of particles and a Newtonian fluid. The fluid is simulated using an Eulerian
+continuum approach, using a custom CUDA solver for GPU computation. This
+approach allows for fast simulations due to the limited need for GPU-CPU
+communications, as well as a flexible code base.</p>
+<p>The following sections will describe the theoretical background, as well as the
+solution procedure and the numerical implementation.</p>
+<div class="section" id="derivation-of-the-navier-stokes-equations-with-porosity">
+<h2>Derivation of the Navier Stokes equations with porosity<a class="headerlink" href="#derivation-of-the-navier-stokes-equations-with-porosity" title="Permalink to this headline">¶</a></h2>
+<p>Following the outline presented by <a class="reference external" href="http://www.cimec.org.ar/ojs/index.php/mc/article/view/486/464">Limache and Idelsohn (2006)</a>, the
+continuity equation for an incompressible fluid material is given by:</p>
+<div class="math">
+<p><img src="_images/math/b588eea9cec4513a3be72255d8d3df214546bfe7.png" alt="\nabla \cdot \boldsymbol{v} = 0"/></p>
+</div><p>and the momentum equation:</p>
+<div class="math">
+<p><img src="_images/math/5b46624e0dc3d79b64f388898e2dff17d232656c.png" alt="\rho \frac{\partial \boldsymbol{v}}{\partial t}
++ \rho (\boldsymbol{v} \cdot \nabla \boldsymbol{v})
+= \nabla \cdot \boldsymbol{\sigma}
++ \rho \boldsymbol{f}"/></p>
+</div><p>Here, <img class="math" src="_images/math/d0b4b390a4806bb739c6b4adbdf572347ecda952.png" alt="\boldsymbol{v}"/> is the fluid velocity, <img class="math" src="_images/math/0027034d8a10372a06deaf4f4084c01956587479.png" alt="\rho"/> is the
+fluid density, <img class="math" src="_images/math/769bfdcb2a43bde2cd368d82a6f64bd68c876c99.png" alt="\boldsymbol{\sigma}"/> is the <a class="reference external" href="https://en.wikipedia.org/wiki/Cauchy_stress_tensor">Cauchy stress tensor</a>, and
+<img class="math" src="_images/math/69b1fdf87f9a78aaef8057a34aea7a6c17dad726.png" alt="\boldsymbol{f}"/> is a body force (e.g. gravity). For incompressible
+Newtonian fluids, the Cauchy stress is given by:</p>
+<div class="math">
+<p><img src="_images/math/c9264cc703654b5651cb89a1c9f5e178b5d15cd0.png" alt="\boldsymbol{\sigma} = -p \boldsymbol{I} + \boldsymbol{\tau}"/></p>
+</div><p><img class="math" src="_images/math/36f73fc1312ee0349b3f3a0f3bd9eb5504339011.png" alt="p"/> is the fluid pressure, <img class="math" src="_images/math/9d909a12ad669a49e201a6d94b4211c7aeebb68c.png" alt="\boldsymbol{I}"/> is the identity
+tensor, and <img class="math" src="_images/math/023a7668d083165ce2aa65b49e876b83c9cb97f9.png" alt="\boldsymbol{\tau}"/> is the deviatoric stress tensor, given
+by:</p>
+<div class="math">
+<p><img src="_images/math/25586671e456c2d987cd75cefd64d9cee69f50b9.png" alt="\boldsymbol{\tau} =
+\mu_f \nabla \boldsymbol{v}
++ \mu_f (\nabla \boldsymbol{v})^T"/></p>
+</div><p>By using the following vector identities:</p>
+<div class="math">
+<p><img src="_images/math/e4ca401f97df40e3568bc0624774cafa02d77cc1.png" alt="\nabla \cdot (p \boldsymbol{I}) = \nabla p
+
+\nabla \cdot (\nabla \boldsymbol{v}) = \nabla^2 \boldsymbol{v}
+
+\nabla \cdot (\nabla \boldsymbol{v})^T
+= \nabla (\nabla \cdot \boldsymbol{v})"/></p>
+</div><p>the deviatoric component of the Cauchy stress tensor simplifies to the
+following, assuming that spatial variations in the viscosity can be neglected:</p>
+<div class="math">
+<p><img src="_images/math/1053df745e2d73fc7ee27d39a01ad228c360072e.png" alt="= -\nabla p
++ \mu_f \nabla^2 \boldsymbol{v}"/></p>
+</div><p>Since we are dealing with fluid flow in a porous medium, additional terms are
+introduced to the equations for conservation of mass and momentum. In the
+following, the equations are derived for the first spatial component. The
+solution for the other components is trivial.</p>
+<p>The porosity value (in the saturated porous medium the volumetric fraction of
+the fluid phase) denoted <img class="math" src="_images/math/2c175f60eecef1de7560c3bdea495d69f26f719d.png" alt="\phi"/> is incorporated in the continuity and
+momentum equations. The continuity equation becomes:</p>
+<div class="math">
+<p><img src="_images/math/f8f0dc31c5c12bc6e3da6fc71519fa78ea04190b.png" alt="\frac{\partial \phi}{\partial t}
++ \nabla \cdot (\phi \boldsymbol{v}) = 0"/></p>
+</div><p>For the <img class="math" src="_images/math/26eeb5258ca5099acf8fe96b2a1049c48c89a5e6.png" alt="x"/> component, the Lagrangian formulation of the momentum equation
+with a body force <img class="math" src="_images/math/69b1fdf87f9a78aaef8057a34aea7a6c17dad726.png" alt="\boldsymbol{f}"/> becomes:</p>
+<div class="math">
+<p><img src="_images/math/900be94839e1ee03a8aa1134961912314905eb27.png" alt="\frac{D (\phi v_x)}{D t}
+= \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\sigma}) \right]_x
++ \phi f_x"/></p>
+</div><p>In the Eulerian formulation, an advection term is added, and the Cauchy stress
+tensor is represented as isotropic and deviatoric components individually:</p>
+<div class="math">
+<p><img src="_images/math/32e2ba09618e2d303d91d673a25ef66e29e94750.png" alt="\frac{\partial (\phi v_x)}{\partial t}
++ \boldsymbol{v} \cdot \nabla (\phi v_x)
+= \frac{1}{\rho} \left[ \nabla \cdot (-\phi p \boldsymbol{I})
++ \phi \boldsymbol{\tau}) \right]_x
++ \phi f_x"/></p>
+</div><p>Using vector identities to rewrite the advection term, and expanding the fluid
+stress tensor term:</p>
+<div class="math">
+<p><img src="_images/math/dcf5762fe2b4b81adb93ee084951f42a2f1eadbc.png" alt="\frac{\partial (\phi v_x)}{\partial t}
++ \nabla \cdot (\phi v_x \boldsymbol{v})
+- \phi v_x (\nabla \cdot \boldsymbol{v})
+= \frac{1}{\rho} \left[ -\nabla \phi p \right]_x
++ \frac{1}{\rho} \left[ -\phi \nabla p \right]_x
++ \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
++ \phi f_x"/></p>
+</div><p>Spatial variations in the porosity are neglected,</p>
+<div class="math">
+<p><img src="_images/math/c42a32017c99646f19bb5807728595d4526c3b30.png" alt="\nabla \phi := 0"/></p>
+</div><p>and the pressure is attributed to the fluid phase alone (model B in Zhu et al.
+2007 and Zhou et al. 2010). The divergence of fluid velocities is defined to be
+zero:</p>
+<div class="math">
+<p><img src="_images/math/44fafcf5a158459730d0dd7c293b93cdcf62f0a4.png" alt="\nabla \cdot \boldsymbol{v} := 0"/></p>
+</div><p>With these assumptions, the momentum equation simplifies to:</p>
+<div class="math">
+<p><img src="_images/math/6e62843666dcc0fe9a45a1c69c532c82a95a9451.png" alt="\frac{\partial (\phi v_x)}{\partial t}
++ \nabla \cdot (\phi v_x \boldsymbol{v})
+= -\frac{1}{\rho} \frac{\partial p}{\partial x}
++ \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
++ \phi f_x"/></p>
+</div><p>The remaining part of the advection term is for the <img class="math" src="_images/math/26eeb5258ca5099acf8fe96b2a1049c48c89a5e6.png" alt="x"/> component
+found as:</p>
+<div class="math">
+<p><img src="_images/math/967116fa65cb7eb073c2f71309b21af6aca77a09.png" alt="\nabla \cdot (\phi v_x \boldsymbol{v}) =
+\left[
+ \frac{\partial}{\partial x},
+ \frac{\partial}{\partial y},
+ \frac{\partial}{\partial z}
+\right]
+\left[
+ \begin{array}{c}
+ \phi v_x v_x\\
+ \phi v_x v_y\\
+ \phi v_x v_z\\
+ \end{array}
+\right]
+=
+\frac{\partial (\phi v_x v_x)}{\partial x} +
+\frac{\partial (\phi v_x v_y)}{\partial y} +
+\frac{\partial (\phi v_x v_z)}{\partial z}"/></p>
+</div><p>The deviatoric stress tensor is in this case symmetrical, i.e. <img class="math" src="_images/math/70b8f6d6630631ad7de5c587e511247f1ce2afe9.png" alt="\tau_{ij}
+= \tau_{ji}"/>, and is found by:</p>
+<div class="math">
+<p><img src="_images/math/9d3cd4785fd2621936d97aa60cb5005a7e95b5b7.png" alt="\frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
+= \frac{1}{\rho}
+\left[
+ \left[
+ \frac{\partial}{\partial x},
+ \frac{\partial}{\partial y},
+ \frac{\partial}{\partial z}
+ \right]
+ \phi
+ \left[
+ \begin{matrix}
+ \tau_{xx} & \tau_{xy} & \tau_{xz}\\
+ \tau_{yx} & \tau_{yy} & \tau_{yz}\\
+ \tau_{zx} & \tau_{zy} & \tau_{zz}\\
+ \end{matrix}
+ \right]
+\right]_x
+
+= \frac{1}{\rho}
+\left[
+ \begin{array}{c}
+ \frac{\partial (\phi \tau_{xx})}{\partial x}
+ + \frac{\partial (\phi \tau_{xy})}{\partial y}
+ + \frac{\partial (\phi \tau_{xz})}{\partial z}\\
+ \frac{\partial (\phi \tau_{yx})}{\partial x}
+ + \frac{\partial (\phi \tau_{yy})}{\partial y}
+ + \frac{\partial (\phi \tau_{yz})}{\partial z}\\
+ \frac{\partial (\phi \tau_{zx})}{\partial x}
+ + \frac{\partial (\phi \tau_{zy})}{\partial y}
+ + \frac{\partial (\phi \tau_{zz})}{\partial z}\\
+ \end{array}
+\right]_x
+= \frac{1}{\rho}
+\left(
+ \frac{\partial (\phi \tau_{xx})}{\partial x}
+ + \frac{\partial (\phi \tau_{xy})}{\partial y}
+ + \frac{\partial (\phi \tau_{xz})}{\partial z}
+\right)"/></p>
+</div><p>In a linear viscous fluid, the stress and strain rate
+(<img class="math" src="_images/math/7727554a4dfa1572695dec332d6f6ee255815c96.png" alt="\dot{\boldsymbol{\epsilon}}"/>) is linearly dependent, scaled by the
+viscosity parameter <img class="math" src="_images/math/6160e3f2050b4cd56b336ff552386a169aa51db8.png" alt="\mu_f"/>:</p>
+<div class="math">
+<p><img src="_images/math/5fb7b1a39363304fc1fb9172ecd46e2f39274384.png" alt="\tau_{ij} = 2 \mu_f \dot{\epsilon}_{ij}
+= \mu_f \left(
+\frac{\partial v_i}{\partial x_j} + \frac{\partial v_j}{\partial x_i}
+\right)"/></p>
+</div><p>With this relationship, the deviatoric stress tensor components can be
+calculated as:</p>
+<div class="math">
+<p><img src="_images/math/f99450c7a8851772907f28ffd58be080f18894ae.png" alt="\tau_{xx} = 2 \mu_f \frac{\partial v_x}{\partial x} \qquad
+\tau_{yy} = 2 \mu_f \frac{\partial v_y}{\partial y} \qquad
+\tau_{zz} = 2 \mu_f \frac{\partial v_z}{\partial z}
+
+\tau_{xy} = \mu_f \left(
+\frac{\partial v_x}{\partial y} + \frac{\partial v_y}{\partial x} \right)
+
+\tau_{xz} = \mu_f \left(
+\frac{\partial v_x}{\partial z} + \frac{\partial v_z}{\partial x} \right)
+
+\tau_{yz} = \mu_f \left(
+\frac{\partial v_y}{\partial z} + \frac{\partial v_z}{\partial y} \right)"/></p>
+</div><p>where <img class="math" src="_images/math/6160e3f2050b4cd56b336ff552386a169aa51db8.png" alt="\mu_f"/> is the dynamic viscosity. The above formulation of the
+fluid rheology assumes identical bulk and shear viscosities. The derivation of
+the equations for the other spatial components is trivial.</p>
+</div>
+<div class="section" id="porosity-estimation">
+<h2>Porosity estimation<a class="headerlink" href="#porosity-estimation" title="Permalink to this headline">¶</a></h2>
+<p>The solid volume in each fluid cell is determined by the ratio of the
+a cell-centered spherical cell volume (<img class="math" src="_images/math/24edc419058015022fc9ef15fb0f5d8ec3109f73.png" alt="V_c"/>) and the sum of intersecting
+particle volumes (<img class="math" src="_images/math/3c93d2ecf99a3c5ee161c98a3ac0040e1b446e09.png" alt="V_s"/>). The spherical cell volume has a center at
+<img class="math" src="_images/math/74958bc18d017328dd0fac99816d2184296bfd3d.png" alt="\boldsymbol{x}_i"/>, and a radius of <img class="math" src="_images/math/1ef7ab23d6fc7d336379d457f66aa6ed57d72ec9.png" alt="R_i"/>, which is equal to half
+the fluid cell width. The nearby particles are characterized by position
+<img class="math" src="_images/math/d1e970327c74ae0d8249c6283d2e3134d042f6ff.png" alt="\boldsymbol{x}_j"/> and radius <img class="math" src="_images/math/2da5f268da80c66e332f2a8d4520f7d6685699b6.png" alt="r_j"/>. The center distance is defined
+as:</p>
+<div class="math">
+<p><img src="_images/math/7fe490dcbc6c9eb978f05b3334d2a5856dc66149.png" alt="d_{ij} = ||\boldsymbol{x}_i - \boldsymbol{x}_j||"/></p>
+</div><p>The common volume of the two intersecting spheres is zero if the volumes aren’t
+intersecting, lens shaped if they are intersecting, and spherical if the
+particle is fully contained by the spherical cell volume:</p>
+<div class="math">
+<p><img src="_images/math/6d9a9e0ef32ea9506bb55413b682112d0f3308a6.png" alt="V^s_{i} = \sum_j
+\begin{cases}
+ 0 & \textit{if } R_i + r_j \leq d_{ij} \\
+ \frac{1}{12d_{ij}} \left[ \pi (R_i + r_j - d_{ij})^2
+ (d_{ij}^2 + 2d_{ij}r_j - 3r_j^2 + 2d_{ij} R_i + 6r_j R_i - 3R_i^2)
+ \right] & \textit{if } R_i - r_j < d_{ij} < R_i + r_j \\
+ \frac{4}{3} \pi r^3_j & \textit{if } d_{ij} \leq R_i - r_j
+\end{cases}"/></p>
+</div><p>Using this method, the cell porosity values are continuous through time as
+particles enter and exit the cell volume. The rate of porosity change
+(<img class="math" src="_images/math/38a6d1fc56073806115322bcd179578f05c88c02.png" alt="d\phi/dt"/>) is estimated by the backwards Euler method
+by considering the previous and current porosity.</p>
+</div>
+<div class="section" id="particle-fluid-interaction">
+<h2>Particle-fluid interaction<a class="headerlink" href="#particle-fluid-interaction" title="Permalink to this headline">¶</a></h2>
+<p>The momentum exchange of the granular and fluid phases follows the procedure
+outlined by Gidaspow 1992 and Shamy and Zhegal 2005. The fluid and particle
+interaction is based on the concept of drag, where the magnitude is based on
+semi-empirical relationships. The drag force scales linearly with the relative
+difference in velocity between the fluid and particle phase. On the base of
+Newton’s third law, the resulting drag force is applied with opposite signs to
+the particle and fluid.</p>
+<p>For fluid cells with porosities (<img class="math" src="_images/math/2c175f60eecef1de7560c3bdea495d69f26f719d.png" alt="\phi"/>) less or equal to 0.8, the drag
+force is based on the Ergun (1952) equation:</p>
+<div class="math">
+<p><img src="_images/math/baa542966f410097c2b4894388e41db6aa3cd996.png" alt="\bar{\boldsymbol{f}}_d = \left(
+150 \frac{\mu_f (1-\phi)^2}{\phi\bar{d}^2}
++ 1.75 \frac{(1-\phi)\rho_f
+ ||\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p||}{\bar{d}}
+\right)
+(\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p)"/></p>
+</div><p>here, <img class="math" src="_images/math/46a84b389d8f594cd16c800ba4267f3cac5e2f30.png" alt="\bar{d}"/> denotes the average particle diameter in the cell,
+<img class="math" src="_images/math/cbe3f817ae974accdf9d422c0df8f6c90721037c.png" alt="\boldsymbol{v}_f"/> is the fluid flow velocity, and
+<img class="math" src="_images/math/3b432b0e58dea7c6cc143bf67184fc19b8cd4336.png" alt="\bar{\boldsymbol{v}}_p"/> is the average particle velocity in the cell. All
+particles in contact with the previously mentioned cell-centered sphere for
+porosity estimation contribute to the average particle velocity and diameter in
+the fluid cell.</p>
+<p>If the porosity is greater than 0.8, the cell-averaged drag force
+(<img class="math" src="_images/math/a6c493a071c2c31758bc2bc9adc2beb10d7acfd0.png" alt="\bar{\boldsymbol{f}}_d"/> is found from the Wen and Yu (1966) equation,
+which considers the fluid flow situation:</p>
+<div class="math">
+<p><img src="_images/math/7181906596d0aaac14cbde44ec57dd7e5866c81b.png" alt="\bar{\boldsymbol{f}}_d = \left(
+\frac{3}{4}
+\frac{C_d (1-\phi) \phi^{-2.65} \mu_f \rho_f
+||\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p||}{\bar{d}}
+\right)
+(\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p)"/></p>
+</div><p>The drag coefficient <img class="math" src="_images/math/47bc1263e44f1b74fd90da02d9e7c26bf4b9edbe.png" alt="C_d"/> is evaluated depending on the magnitude of the
+Reynolds number <img class="math" src="_images/math/16ef95610462b9c2c03cba4c272fe84208bf3c61.png" alt="Re"/>:</p>
+<div class="math">
+<p><img src="_images/math/49a90589ae1e8a839b1ae6afb3dd1d162b6a094c.png" alt="C_d =
+\begin{cases}
+\frac{24}{Re} (1+0.15 (Re)^{0.687} & \textit{if } Re < 1,000 \\
+0.44 & \textit{if } Re \geq 1,000
+\end{cases}"/></p>
+</div><p>where the Reynold’s number is found by:</p>
+<div class="math">
+<p><img src="_images/math/8dbae01b96ab8dd591a50213f55caa3ac5958631.png" alt="Re = \frac{\phi\rho_f\bar{d}}{\mu_f}
+||\boldsymbol{v}_f - \bar{\boldsymbol{v}}_p||"/></p>
+</div><p>The interaction force is applied to the fluid with negative sign as a
+contribution to the body force <img class="math" src="_images/math/69b1fdf87f9a78aaef8057a34aea7a6c17dad726.png" alt="\boldsymbol{f}"/>. The fluid interaction
+force applied particles in the fluid cell is:</p>
+<div class="math">
+<p><img src="_images/math/ac40b59145892a5a3c0141c5f35023ad85972855.png" alt="\boldsymbol{f}_i = \frac{\bar{\boldsymbol{f}}_d V_p}{1-\phi}"/></p>
+</div><p>where <img class="math" src="_images/math/257ee6442468d7529f036a8a81e6050c3832fdbf.png" alt="V_p"/> denotes the particle volume. Optionally, the above
+interaction force could be expanded to include the force induced by the fluid
+pressure gradient:</p>
+<div class="math">
+<p><img src="_images/math/0fdafcde7733804669f8df4846e5bfdb36c7afa7.png" alt="\boldsymbol{f}_i = \left(
+-\nabla p +
+\frac{\bar{\boldsymbol{f}}_d}{1-\phi}
+\right) V_p"/></p>
+</div></div>
+<div class="section" id="fluid-dynamics-solution-procedure-by-operator-splitting">
+<h2>Fluid dynamics solution procedure by operator splitting<a class="headerlink" href="#fluid-dynamics-solution-procedure-by-operator-splitting" title="Permalink to this headline">¶</a></h2>
+<p>The partial differential terms in the previously described equations are found
+using finite central differences. Modifying the operator splitting methodology
+presented by Langtangen et al. (2002), the predicted velocity
+<img class="math" src="_images/math/90c8bfc206db2d9f4d0dd102507c9646a70755db.png" alt="\boldsymbol{v}^*"/> after a finite time step
+<img class="math" src="_images/math/a1ffc0a012620941fe660cedabff822ce7162eca.png" alt="\Delta t"/> is found by explicit integration of the momentum equation.</p>
+<div class="math">
+<p><img src="_images/math/7ee03c7bfc1e46255c9d2d47d9b733a068c9ec2b.png" alt="\frac{\Delta (\phi v_x)}{\Delta t}
++ \nabla \cdot (\phi v_x \boldsymbol{v})
+= - \frac{1}{\rho} \frac{\Delta p}{\Delta x}
++ \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
++ \phi f_x
+
+\Downarrow
+
+\phi \frac{\Delta v_x}{\Delta t}
++ v_x \frac{\Delta \phi}{\Delta t}
++ \nabla \cdot (\phi v_x \boldsymbol{v})
+= - \frac{1}{\rho} \frac{\Delta p}{\Delta x}
++ \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
++ \phi f_x"/></p>
+</div><p>We want to isolate <img class="math" src="_images/math/b5e8dba2403c0723e1ff60ac53116252af8aeb64.png" alt="\Delta v_x"/> in the above equation in order to project
+the new velocity.</p>
+<div class="math">
+<p><img src="_images/math/038474380a078000f31889a32a1dcf79ac38c223.png" alt="\phi \frac{\Delta v_x}{\Delta t}
+= - \frac{1}{\rho} \frac{\Delta p}{\Delta x}
++ \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
++ \phi f_x
+- v_x \frac{\Delta \phi}{\Delta t}
+- \nabla \cdot (\phi v_x \boldsymbol{v})
+
+\Delta v_x
+= - \frac{1}{\rho} \frac{\Delta p}{\Delta x} \frac{\Delta t}{\phi}
++ \frac{1}{\rho} \left[ \nabla \cdot (\phi \boldsymbol{\tau}) \right]_x
+ \frac{\Delta t}{\phi}
++ \Delta t f_x
+- v_x \frac{\Delta \phi}{\phi}
+- \nabla \cdot (\phi v_x \boldsymbol{v}) \frac{\Delta t}{\phi}"/></p>
+</div><p>The term <img class="math" src="_images/math/fdb63b9e51abe6bbb16acfb5d7b773ddbb5bf4a8.png" alt="\beta"/> is introduced as an adjustable, dimensionless parameter
+in the range <img class="math" src="_images/math/402b1a3c25643899cdefbe2e62d33eab43b4f616.png" alt="[0;1]"/>, and determines the importance of the old pressure
+values in the solution procedure (Langtangen et al. 2002). A value of 0
+corresponds to <a class="reference external" href="https://en.wikipedia.org/wiki/Projection_method_(fluid_dynamics)#Chorin.27s_projection_method">Chorin’s projection method</a> originally described
+in <a class="reference external" href="http://www.ams.org/journals/mcom/1968-22-104/S0025-5718-1968-0242392-2/S0025-5718-1968-0242392-2.pdf">Chorin (1968)</a>.</p>
+<div class="math">
+<p><img src="_images/math/dbcdbe7c53fa70f8517907ca1b3c440b28512dfc.png" alt="v_x^* = v_x^t + \Delta v_x
+
+v_x^* = v_x^t
+- \frac{\beta}{\rho} \frac{\Delta p^t}{\Delta x} \frac{\Delta t}{\phi^t}
++ \frac{1}{\rho} \left[ \nabla \cdot (\phi^t \boldsymbol{\tau}^t) \right]_x
+ \frac{\Delta t}{\phi}
++ \Delta t f_x
+- v^t_x \frac{\Delta \phi}{\phi^t}
+- \nabla \cdot (\phi^t v_x^t \boldsymbol{v}^t) \frac{\Delta t}{\phi^t}"/></p>
+</div><p>Here, <img class="math" src="_images/math/1eb29f9de3753a59530941141fcb5c7aa3fa2e38.png" alt="\Delta x"/> denotes the cell spacing. The velocity found
+(<img class="math" src="_images/math/f04823ba99f1452d779894f7a0745da23b55fbef.png" alt="v_x^*"/>) is only a prediction of the fluid velocity at time
+<img class="math" src="_images/math/79c874e814b2550448c61e2627dc072653b68197.png" alt="t+\Delta t"/>, since the estimate isn’t constrained by the continuity
+equation:</p>
+<div class="math">
+<p><img src="_images/math/c305e13251e69e8ce59b2908f84afbbd085b5103.png" alt="\frac{\Delta \phi^t}{\Delta t} + \nabla \cdot (\phi^t
+\boldsymbol{v}^{t+\Delta t}) = 0"/></p>
+</div><p>The divergence of a scalar and vector can be <a class="reference external" href="http://www.wolframalpha.com/input/?i=div(p+v)">split</a>:</p>
+<div class="math">
+<p><img src="_images/math/41babe6999c89406f22db1ce5ed5e05ce939ed49.png" alt="\phi^t \nabla \cdot \boldsymbol{v}^{t+\Delta t} +
+\boldsymbol{v}^{t+\Delta t} \cdot \nabla \phi^t
++ \frac{\Delta \phi^t}{\Delta t} = 0"/></p>
+</div><p>The predicted velocity is corrected using the new pressure (Langtangen et al.
+2002):</p>
+<div class="math">
+<p><img src="_images/math/e3de9b8fce0b12c8459947bd22c727e379512fcc.png" alt="\boldsymbol{v}^{t+\Delta t} = \boldsymbol{v}^*
+- \frac{\Delta t}{\rho} \nabla \epsilon
+\quad \text{where} \quad
+\epsilon = p^{t+\Delta t} - \beta p^t"/></p>
+</div><p>The above formulation of the future velocity is put into the continuity
+equation:</p>
+<div class="math">
+<p><img src="_images/math/25961440701892ff5417a2474f7f52bb353e5d98.png" alt="\Rightarrow
+\phi^t \nabla \cdot
+\left( \boldsymbol{v}^* - \frac{\Delta t}{\rho} \nabla \epsilon \right)
++
+\left( \boldsymbol{v}^* - \frac{\Delta t}{\rho} \nabla \epsilon \right)
+\cdot \nabla \phi^t + \frac{\Delta \phi^t}{\Delta t} = 0"/></p>
+</div><div class="math">
+<p><img src="_images/math/1c7a111b8952b4162797cce2cbd426d74083b834.png" alt="\Rightarrow
+\phi^t \nabla \cdot
+\boldsymbol{v}^* - \frac{\Delta t}{\rho} \phi^t \nabla^2 \epsilon
++ \nabla \phi^t \cdot \boldsymbol{v}^*
+- \nabla \phi^t \cdot \nabla \epsilon \frac{\Delta t}{\rho}
++ \frac{\Delta \phi^t}{\Delta t} = 0"/></p>
+</div><div class="math">
+<p><img src="_images/math/8a2e0d0a28c9ebec91bd12def7b3b36dd9e92da7.png" alt="\Rightarrow
+\frac{\Delta t}{\rho} \phi^t \nabla^2 \epsilon
+= \phi^t \nabla \cdot \boldsymbol{v}^*
++ \nabla \phi^t \cdot \boldsymbol{v}^*
+- \nabla \phi^t \cdot \nabla \epsilon \frac{\Delta t}{\rho}
++ \frac{\Delta \phi^t}{\Delta t}"/></p>
+</div><p>The pressure difference in time becomes a <a class="reference external" href="https://en.wikipedia.org/wiki/Poisson's_equation">Poisson equation</a> with added terms:</p>
+<div class="math">
+<p><img src="_images/math/7572a9bb14a95da7f7b42fd4b5bec33c42800556.png" alt="\Rightarrow
+\nabla^2 \epsilon
+= \frac{\nabla \cdot \boldsymbol{v}^* \rho}{\Delta t}
++ \frac{\nabla \phi^t \cdot \boldsymbol{v}^* \rho}{\Delta t \phi^t}
+- \frac{\nabla \phi^t \cdot \nabla \epsilon}{\phi^t}
++ \frac{\Delta \phi^t \rho}{\Delta t^2 \phi^t}"/></p>
+</div><p>The right hand side of the above equation is termed the <em>forcing function</em>
+<img class="math" src="_images/math/bb2c93730dbb48558bb3c4738c956c4e8f816437.png" alt="f"/>, which is decomposed into two terms, <img class="math" src="_images/math/37a9e7fca70e2dce829d902af2088735306bc1a3.png" alt="f_1"/> and <img class="math" src="_images/math/e31584cdce0b50ee39c63081564f6e2ec5a7dcbf.png" alt="f_2"/>:</p>
+<div class="math">
+<p><img src="_images/math/28d83ccd32811c0455355169ed8f6978d8d24dbe.png" alt="f_1
+= \frac{\nabla \cdot \boldsymbol{v}^* \rho}{\Delta t}
++ \frac{\nabla \phi^t \cdot \boldsymbol{v}^* \rho}{\Delta t \phi^t}
++ \frac{\Delta \phi^t \rho}{\Delta t^2 \phi^t}
+
+f_2 =
+\frac{\nabla \phi^t \cdot \nabla \epsilon}{\phi^t}"/></p>
+</div><p>During the <a class="reference external" href="http://www.rsmas.miami.edu/personal/miskandarani/Courses/MSC321/Projects/prjpoisson.pdf">Jacobi iterative solution procedure</a> <img class="math" src="_images/math/37a9e7fca70e2dce829d902af2088735306bc1a3.png" alt="f_1"/> remains constant,
+while <img class="math" src="_images/math/e31584cdce0b50ee39c63081564f6e2ec5a7dcbf.png" alt="f_2"/> changes value. For this reason, <img class="math" src="_images/math/37a9e7fca70e2dce829d902af2088735306bc1a3.png" alt="f_1"/> is found only
+during the first iteration, while <img class="math" src="_images/math/e31584cdce0b50ee39c63081564f6e2ec5a7dcbf.png" alt="f_2"/> is updated every time. The value
+of the forcing function is found as:</p>
+<div class="math">
+<p><img src="_images/math/c4f23b63471bb0807346dc89db91e3a684cfa236.png" alt="f = f_1 - f_2"/></p>
+</div><p>Using second-order finite difference approximations of the Laplace operator
+second-order partial derivatives, the differential equations become a system of
+equations that is solved using <a class="reference external" href="https://en.wikipedia.org/wiki/Relaxation_(iterative_method)">iteratively</a> using Jacobi updates. The total
+number of unknowns is <img class="math" src="_images/math/954afa1fc1c88d82f51ab22e64b4a7450a89f755.png" alt="(n_x - 1)(n_y - 1)(n_z - 1)"/>.</p>
+<p>The discrete Laplacian (approximation of the Laplace operator) can be obtained
+by a finite-difference seven-point stencil in a three-dimensional, cubic
+grid with cell spacing <img class="math" src="_images/math/3d41adff4943d60236fa626d0bae8e238483278a.png" alt="\Delta x, \Delta y, \Delta z"/>, considering the six
+face neighbors:</p>
+<div class="math">
+<p><img src="_images/math/6e1feb8f41fb33ffbf60f657c5e095c2bb780e4d.png" alt="\nabla^2 \epsilon_{i_x,i_y,i_z} \approx
+\frac{\epsilon_{i_x-1,i_y,i_z} - 2 \epsilon_{i_x,i_y,i_z}
++ \epsilon_{i_x+1,i_y,i_z}}{\Delta x^2}
++ \frac{\epsilon_{i_x,i_y-1,i_z} - 2 \epsilon_{i_x,i_y,i_z}
++ \epsilon_{i_x,i_y+1,i_z}}{\Delta y^2}
+
++ \frac{\epsilon_{i_x,i_y,i_z-1} - 2 \epsilon_{i_x,i_y,i_z}
++ \epsilon_{i_x,i_y,i_z+1}}{\Delta z^2}
+\approx f_{i_x,i_y,i_z}"/></p>
+</div><p>Within a Jacobi iteration, the value of the unknowns (<img class="math" src="_images/math/07ff47f8ccf9ac490e023817a9241de75c30340c.png" alt="\epsilon^n"/>) is
+used to find an updated solution estimate (<img class="math" src="_images/math/0f06d8c03699aa966cd6c94d11850ede3c97dc41.png" alt="\epsilon^{n+1}"/>).
+The solution for the updated value takes the form:</p>
+<div class="math">
+<p><img src="_images/math/5dfeda3ba68db3f629c37ad0b4cc75095c2d6570.png" alt="\epsilon^{n+1}_{i_x,i_y,i_z}
+= \frac{-\Delta x^2 \Delta y^2 \Delta z^2 f_{i_x,i_y,i_z}
++ \Delta y^2 \Delta z^2 (\epsilon^n_{i_x-1,i_y,i_z} +
+ \epsilon^n_{i_x+1,i_y,i_z})
++ \Delta x^2 \Delta z^2 (\epsilon^n_{i_x,i_y-1,i_z} +
+ \epsilon^n_{i_x,i_y+1,i_z})
++ \Delta x^2 \Delta y^2 (\epsilon^n_{i_x,i_y,i_z-1} +
+ \epsilon^n_{i_x,i_y,i_z+1})}
+ {2 (\Delta x^2 \Delta y^2
+ + \Delta x^2 \Delta z^2
+ + \Delta y^2 \Delta z^2) }"/></p>
+</div><p>The difference between the current and updated value is termed the <em>normalized
+residual</em>:</p>
+<div class="math">
+<p><img src="_images/math/c6e0b5935589b4f8948c91faa0de425bf2791db4.png" alt="r_{i_x,i_y,i_z} = \frac{(\epsilon^{n+1}_{i_x,i_y,i_z}
+- \epsilon^n_{i_x,i_y,i_z})^2}{(\epsilon^{n+1}_{i_x,i_y,i_z})^2}"/></p>
+</div><p>Note that the <img class="math" src="_images/math/eaf4418fbe935c15a606516d8f55dc380cd8e822.png" alt="\epsilon"/> values cannot be 0 due to the above normalization
+of the residual.</p>
+<p>The updated values are at the end of the iteration stored as the current values,
+and the maximal value of the normalized residual is found. If this value is
+larger than a tolerance criteria, the procedure is repeated. The iterative
+procedure is ended if the number of iterations exceeds a defined limit.</p>
+<p>After the values of <img class="math" src="_images/math/eaf4418fbe935c15a606516d8f55dc380cd8e822.png" alt="\epsilon"/> are found, they are used to find the new
+pressures and velocities:</p>
+<div class="math">
+<p><img src="_images/math/c15067d0b2458f2c3bfd62743d7309f7e48213f9.png" alt="\bar{p}^{t+\Delta t} = \beta \bar{p}^t + \epsilon"/></p>
+</div><div class="math">
+<p><img src="_images/math/b55687e1799df2d682b5ba0c207ca16fa9c014fe.png" alt="\bar{\boldsymbol{v}}^{t+\Delta t} =
+\bar{\boldsymbol{v}}^* - \frac{\Delta t}{\rho} \nabla \epsilon"/></p>
+</div></div>
+<div class="section" id="boundary-conditions">
+<h2>Boundary conditions<a class="headerlink" href="#boundary-conditions" title="Permalink to this headline">¶</a></h2>
+<p>The lateral boundaries are periodic. This cannot be changed in the current
+version of <tt class="docutils literal"><span class="pre">sphere</span></tt>. This means that the fluid properties at the paired,
+parallel lateral (<img class="math" src="_images/math/26eeb5258ca5099acf8fe96b2a1049c48c89a5e6.png" alt="x"/> and <img class="math" src="_images/math/092e364e1d9d19ad5fffb0b46ef4cc7f2da02c1c.png" alt="y"/>) boundaries are identical. A flow
+leaving through one side reappears on the opposite side.</p>
+<p>The top and bottom boundary conditions of the fluid grid can be either:
+prescribed pressure (Dirichlet), or prescribed velocity (Neumann). The
+(horizontal) velocities parallel to the boundaries are free to attain other
+values (free slip). The Dirichlet boundary condition is enforced by keeping the
+value of <img class="math" src="_images/math/eaf4418fbe935c15a606516d8f55dc380cd8e822.png" alt="\epsilon"/> constant at the boundaries, e.g.:</p>
+<div class="math">
+<p><img src="_images/math/01be15303939c78ee40a848a717482d046a9ad48.png" alt="\epsilon^{n+1}_{i_x,i_y,i_z = 1 \vee n_z}
+=
+\epsilon^{n}_{i_x,i_y,i_z = 1 \vee n_z}"/></p>
+</div><p>The Neumann boundary condition of no flow across the boundary is enforced by
+setting the gradient of <img class="math" src="_images/math/eaf4418fbe935c15a606516d8f55dc380cd8e822.png" alt="\epsilon"/> perpendicular to the boundary to zero,
+e.g.:</p>
+<div class="math">
+<p><img src="_images/math/bdc15139139f2cc22f5656d0456d7b432a72c4e8.png" alt="\nabla_z \epsilon^{n+1}_{i_x,i_y,i_z = 1 \vee n_z} = 0"/></p>
+</div></div>
+<div class="section" id="numerical-implementation">
+<h2>Numerical implementation<a class="headerlink" href="#numerical-implementation" title="Permalink to this headline">¶</a></h2>
+<p>Ghost nodes</p>
+<p>—</p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Fluid simulation and particle-fluid interaction</a><ul>
+<li><a class="reference internal" href="#derivation-of-the-navier-stokes-equations-with-porosity">Derivation of the Navier Stokes equations with porosity</a></li>
+<li><a class="reference internal" href="#porosity-estimation">Porosity estimation</a></li>
+<li><a class="reference internal" href="#particle-fluid-interaction">Particle-fluid interaction</a></li>
+<li><a class="reference internal" href="#fluid-dynamics-solution-procedure-by-operator-splitting">Fluid dynamics solution procedure by operator splitting</a></li>
+<li><a class="reference internal" href="#boundary-conditions">Boundary conditions</a></li>
+<li><a class="reference internal" href="#numerical-implementation">Numerical implementation</a></li>
+</ul>
+</li>
+</ul>
+
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="dem.html"
+ title="previous chapter">Discrete element method</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="python_api.html"
+ title="next chapter">Python API</a></p>
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="_sources/cfd.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+<div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="py-modindex.html" title="Python Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="python_api.html" title="Python API"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="dem.html" title="Discrete element method"
+ >previous</a> |</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
+ </ul>
+ </div>
+ <div class="footer">
+ © Copyright 2014, Anders Damsgaard.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+ </div>
+ </body>
+</html>
+\ No newline at end of file
DIR diff --git a/doc/html/dem.html b/doc/html/dem.html
t@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Discrete element method — sphere 0.35 documentation</title>
+ <title>Discrete element method — sphere 1.00-alpha documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
t@@ -17,7 +17,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
- VERSION: '0.35',
+ VERSION: '1.00-alpha',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
t@@ -26,8 +26,8 @@
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
- <link rel="top" title="sphere 0.35 documentation" href="index.html" />
- <link rel="next" title="Python API" href="python_api.html" />
+ <link rel="top" title="sphere 1.00-alpha documentation" href="index.html" />
+ <link rel="next" title="Fluid simulation and particle-fluid interaction" href="cfd.html" />
<link rel="prev" title="Introduction" href="introduction.html" />
</head>
<body>
t@@ -41,12 +41,12 @@
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
- <a href="python_api.html" title="Python API"
+ <a href="cfd.html" title="Fluid simulation and particle-fluid interaction"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="introduction.html" title="Introduction"
accesskey="P">previous</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
t@@ -57,17 +57,168 @@
<div class="section" id="discrete-element-method">
<h1>Discrete element method<a class="headerlink" href="#discrete-element-method" title="Permalink to this headline">¶</a></h1>
-<p>The discrete element method (or distinct element method) was initially
-formulated by Cundall and Strack (1979). It simulates the physical behavior and
-interaction of discrete, unbreakable particles, with their own mass and inertia,
-under the influence of e.g. gravity and boundary conditions such as moving
-walls. By discretizing time into small time steps, explicit integration of
-Newton’s second law of motion is used to predict the new position and kinematic
-values for each particle from the previous sums of forces. This Lagrangian
-approach is ideal for simulating discontinuous materials, such as granular
-matter.
-The complexity of the computations is kept low by representing the particles as
-spheres, which keeps contact-searching algorithms simple.</p>
+<p>Granular material is a very common form of matter, both in nature and industry.
+It can be defined as material consisting of interacting, discrete particles.
+Common granular materials include gravels, sands and soils, ice bergs,
+asteroids, powders, seeds, and other foods. Over 75% of the raw materials that
+pass through industry are granular. This wide occurrence has driven the desire
+to understand the fundamental mechanics of the material.</p>
+<p>Contrary to other common materials such as gases, liquids and solids, a general
+mathematical formulation of it’s behavior hasn’t yet been found. Granular
+material can, however, display states that somewhat resemble gases, fluids and
+solids.</p>
+<p>The <a class="reference external" href="https://en.wikipedia.org/wiki/Discrete_element_method">Discrete Element Method</a> (DEM) is a numerical
+method that can be used to
+simulate the interaction of particles. Originally derived from
+<a class="reference external" href="https://en.wikipedia.org/wiki/Molecular_dynamics">Molecular Dynamics</a>,
+it simulates particles as separate entities, and calculates their positions,
+velocities, and accelerations through time. See Cundall and Strack (1979) and
+<a class="reference external" href="http://anders-dc.github.io/2013/10/16/the-discrete-element-method/">this blog post</a> for
+general introduction to the DEM. The following sections will highlight the
+DEM implementation in <tt class="docutils literal"><span class="pre">sphere</span></tt>. Some of the details are also described in
+Damsgaard et al. 2013. In the used notation, a bold symbol denotes a
+three-dimensional vector, and a dot denotes that the entity is a temporal
+derivative.</p>
+<div class="section" id="contact-search">
+<h2>Contact search<a class="headerlink" href="#contact-search" title="Permalink to this headline">¶</a></h2>
+<p>Homogeneous cubic grid.</p>
+<div class="math">
+<p><img src="_images/math/b2cd17a83bb89dc6b4ff954979dba3b2fbc8e043.png" alt="\delta_n^{ij} = ||\boldsymbol{x}^i - \boldsymbol{x}^j|| - (r^i + r^j)"/></p>
+</div><p>where <img class="math" src="_images/math/b55ca7a0aa88ab7d58f4fc035317fdac39b17861.png" alt="r"/> is the particle radius, and <img class="math" src="_images/math/4f7d0530f1939c40a7c9e65b7ecee0e476ac4817.png" alt="\boldsymbol{x}"/> denotes the
+positional vector of a particle, and <img class="math" src="_images/math/34857b3ba74ce5cd8607f3ebd23e9015908ada71.png" alt="i"/> and <img class="math" src="_images/math/8122aa89ea6e80784c6513d22787ad86e36ad0cc.png" alt="j"/> denote the indexes
+of two particles. Negative values of <img class="math" src="_images/math/dd84cb843a3b1f44c09b5e49fb02ad7ff526920d.png" alt="\delta_n"/> denote that the particles
+are overlapping.</p>
+</div>
+<div class="section" id="contact-interaction">
+<h2>Contact interaction<a class="headerlink" href="#contact-interaction" title="Permalink to this headline">¶</a></h2>
+<p>Now that the inter-particle contacts have been identified and characterized by
+their overlap, the resulting forces from the interaction can be resolved. The
+interaction is decomposed into normal and tangential components, relative to the
+contact interface orientation. The normal vector to the contact interface is
+found by:</p>
+<div class="math">
+<p><img src="_images/math/8bf1a4afd4cdf42bf3f7b27c9d9c99377a5d1898.png" alt="\boldsymbol{n}^{ij} =
+\frac{\boldsymbol{x}^i - \boldsymbol{x}^j}
+{||\boldsymbol{x}^i - \boldsymbol{x}^j||}"/></p>
+</div><p>The contact velocity <img class="math" src="_images/math/0dd32d7f3a000398f4982bdbe7cb1da880e33298.png" alt="\dot{\boldsymbol{\delta}}"/> is found by:</p>
+<div class="math">
+<p><img src="_images/math/767762b2cd832672331c1421813b919298d7e3b8.png" alt="\dot{\boldsymbol{\delta}}^{ij} =
+(\boldsymbol{x}^i - \boldsymbol{x}^j)
++ (r^i + \frac{\delta_n^{ij}}{2})
+ (\boldsymbol{n}^{ij} \times \boldsymbol{\omega}^{i})
++ (r^j + \frac{\delta_n^{ij}}{2})
+ (\boldsymbol{n}^{ij} \times \boldsymbol{\omega}^{j})"/></p>
+</div><p>The contact velocity is decomposed into normal and tangential components,
+relative to the contact interface. The normal component is:</p>
+<div class="math">
+<p><img src="_images/math/c5671cc4a4d93628081c7bf7c0fd2cc6ff6c1cd3.png" alt="\dot{\delta}^{ij}_n =
+-(\dot{\boldsymbol{\delta}}^{ij} \cdot \boldsymbol{n}^{ij})"/></p>
+</div><p>and the tangential velocity component is found as:</p>
+<div class="math">
+<p><img src="_images/math/249d76d0a5d3773b138ce498e5df46c870f402b5.png" alt="\dot{\boldsymbol{\delta}}^{ij}_t =
+\dot{\boldsymbol{\delta}}^{ij}
+- \boldsymbol{n}^{ij}
+ (\boldsymbol{n}^{ij} \cdot \dot{\boldsymbol{\delta}}^{ij})"/></p>
+</div><p>where <img class="math" src="_images/math/6922b3e4505e825344dc326ade5f0c4be45ddd2f.png" alt="\boldsymbol{\omega}"/> is the rotational velocity vector of a
+particle. The total tangential displacement on the contact plane is found
+incrementally:</p>
+<div class="math">
+<p><img src="_images/math/213a272621ce146fc9f90ce519bc3dc1ac3337e8.png" alt="\boldsymbol{\delta}_{t,\text{uncorrected}}^{ij} =
+\int_0^{t_c}
+\dot{\boldsymbol{\delta}}^{ij}_t \Delta t"/></p>
+</div><p>where <img class="math" src="_images/math/dfc85915a4cda974f3bd5c3c52b7d2e59598a1eb.png" alt="t_c"/> is the duration of the contact and <img class="math" src="_images/math/a1ffc0a012620941fe660cedabff822ce7162eca.png" alt="\Delta t"/> is the
+computational time step length. The tangential contact interface displacement is
+set to zero when a contact pair no longer overlaps. At each time step, the value
+of <img class="math" src="_images/math/bf7f4ceb6fce455ca0347cd7b704321b92e04f8c.png" alt="\boldsymbol{\delta}_t"/> is corrected for rotation of the contact
+interface:</p>
+<div class="math">
+<p><img src="_images/math/9c2a28916b33bc70a170729d2f237eabae96c0c0.png" alt="\boldsymbol{\delta}_t^{ij} = \boldsymbol{\delta}_{t,\text{uncorrected}}^{ij}
+- (\boldsymbol{n}
+ (\boldsymbol{n} \cdot \boldsymbol{\delta}_{t,\text{uncorrected}}^{ij})"/></p>
+</div><p>With all the geometrical and kinetic components determined, the resulting forces
+of the particle interaction can be determined using a contact model. <tt class="docutils literal"><span class="pre">sphere</span></tt>
+features only one contact model in the normal direction to the contact; the
+linear-elastic-viscous (<em>Hookean</em> with viscous damping, or <em>Kelvin-Voigt</em>)
+contact model. The resulting force in the normal direction of the contact
+interface on particle <img class="math" src="_images/math/34857b3ba74ce5cd8607f3ebd23e9015908ada71.png" alt="i"/> is:</p>
+<div class="math">
+<p><img src="_images/math/30d5d726338d5b3ac9d9b0003c564594fd6176ce.png" alt="\boldsymbol{f}_n^{ij} = \left(
+-k_n \delta_n^{ij} -\gamma_n \dot{\delta_n}^{ij}
+\right) \boldsymbol{n}^{ij}"/></p>
+</div><p>The parameter <img class="math" src="_images/math/fd26dda3f4f507f3fdfaff4fe0b468bee54e7c09.png" alt="k_n"/> is the defined <a class="reference external" href="https://en.wikipedia.org/wiki/Hooke's_law">spring coefficient</a> in the normal direction of the
+contact interface, and <img class="math" src="_images/math/55f6b5380d462f954b65d7a2cd05e02ff8cc832e.png" alt="\gamma_n"/> is the defined contact interface
+viscosity, also in the normal direction. The loss of energy in this interaction
+due to the viscous component is for particle <img class="math" src="_images/math/34857b3ba74ce5cd8607f3ebd23e9015908ada71.png" alt="i"/> calculated as:</p>
+<div class="math">
+<p><img src="_images/math/68e0c54203bc81b45ebe5dbf7d89fc61aa794c1e.png" alt="\dot{e}^i_v = \gamma_n (\dot{\delta}^{ij}_n)^2"/></p>
+</div><p>The tangential force is determined by either a viscous-frictional contact model,
+or a elastic-viscous-frictional contact model. The former contact model is very
+computationally efficient, but somewhat inaccurate relative to the mechanics of
+real materials. The latter contact model is therefore the default, even though
+it results in longer computational times. The tangential force in the
+visco-frictional contact model:</p>
+<div class="math">
+<p><img src="_images/math/2e9b3638163af9fc450acac1aba9911e57a5c691.png" alt="\boldsymbol{f}_t^{ij} = -\gamma_t \dot{\boldsymbol{\delta}_t}^{ij}"/></p>
+</div><p><img class="math" src="_images/math/55f6b5380d462f954b65d7a2cd05e02ff8cc832e.png" alt="\gamma_n"/> is the defined contact interface viscosity in the tangential
+direction. The tangential displacement along the contact interface
+(<img class="math" src="_images/math/bf7f4ceb6fce455ca0347cd7b704321b92e04f8c.png" alt="\boldsymbol{\delta}_t"/>) is not calculated and stored for this contact
+model. The tangential force in the more realistic elastic-viscous-frictional
+contact model:</p>
+<div class="math">
+<p><img src="_images/math/18950ecc92ecc7397337b5f39323453647e6434a.png" alt="\boldsymbol{f}_t^{ij} =
+-k_t \boldsymbol{\delta}_t^{ij} -\gamma_t \dot{\boldsymbol{\delta}_t}^{ij}"/></p>
+</div><p>The parameter <img class="math" src="_images/math/fd26dda3f4f507f3fdfaff4fe0b468bee54e7c09.png" alt="k_n"/> is the defined spring coefficient in the tangential
+direction of the contact interface. Note that the tangential force is only
+found if the tangential displacement (<img class="math" src="_images/math/2ab5affb59066624277032c5076d7227db701fd9.png" alt="\delta_t"/>) or the tangential
+velocity (<img class="math" src="_images/math/c51284f727b4cb7dac214d351742114146795074.png" alt="\dot{\delta}_t"/>) is non-zero, in order to avoid division by
+zero. Otherwise it is defined as being <img class="math" src="_images/math/d5ba56a402179916023ef587910f0beff5ea1608.png" alt="[0,0,0]"/>.</p>
+<p>For both types of contact model, the tangential force is limited by the Coulomb
+criterion of static and dynamic friction:</p>
+<div class="math">
+<p><img src="_images/math/1d24d160d60604202abbae47aba869e96fb450aa.png" alt="||\boldsymbol{f}^{ij}_t|| \leq
+\begin{cases}
+\mu_s ||\boldsymbol{f}^{ij}_n|| &
+ \text{if} \quad ||\boldsymbol{f}_t^{ij}|| = 0 \\
+\mu_d ||\boldsymbol{f}^{ij}_n|| &
+ \text{if} \quad ||\boldsymbol{f}_t^{ij}|| > 0
+\end{cases}"/></p>
+</div><p>If the elastic-viscous-frictional contact model is used and the Coulomb limit is
+reached, the tangential displacement along the contact interface is limited to
+this value:</p>
+<div class="math">
+<p><img src="_images/math/ac73c7c8c596c32306e6ea203ebd039dd3538f06.png" alt="\boldsymbol{\delta}_t^{ij} =
+\frac{1}{k_t} \left(
+\mu_d ||\boldsymbol{f}_n^{ij}||
+\frac{\boldsymbol{f}^{ij}_t}{||\boldsymbol{f}^{ij}_t||}
++ \gamma_t \dot{\boldsymbol{\delta}}_t^{ij} \right)"/></p>
+</div><p>If the tangential force reaches the Coulomb limit, the energy lost due to
+frictional dissipation is calculated as:</p>
+<div class="math">
+<p><img src="_images/math/9d0d9139c35e749d7b4698592c91045d086d8b99.png" alt="\dot{e}^i_s = \frac{||\boldsymbol{f}^{ij}_t
+\dot{\boldsymbol{\delta}}_t^{ij} \Delta t||}{\Delta t}"/></p>
+</div><p>The loss of energy by viscous dissipation in the tangential direction is not
+found.</p>
+</div>
+<div class="section" id="temporal-integration">
+<h2>Temporal integration<a class="headerlink" href="#temporal-integration" title="Permalink to this headline">¶</a></h2>
+<p>In the DEM, the time is discretized into small steps (<img class="math" src="_images/math/a1ffc0a012620941fe660cedabff822ce7162eca.png" alt="\Delta t"/>). For each time
+step, the entire network of contacts is resolved, and the resulting forces and
+torques for each particle are found. With these values at hand, the new
+linear and rotational accelerations can be found using
+<a class="reference external" href="https://en.wikipedia.org/wiki/Newton%27s_laws_of_motion">Newton’s second law</a>
+of the motion of solid bodies. If a particle with mass <img class="math" src="_images/math/f5047d1e0cbb50ec208923a22cd517c55100fa7b.png" alt="m"/> at a point in time
+experiences a sum of forces denoted <img class="math" src="_images/math/5ed37435199e280338e0e6dc0c225e4230719b0a.png" alt="\boldsymbol{F}"/>, the resultant acceleration
+(<img class="math" src="_images/math/486938d1819df5972cb80ef2d101517b20412366.png" alt="\boldsymbol{a}"/>) can be found by rearranging Newton’s second law:</p>
+<div class="math">
+<p><img src="_images/math/c78863bcf0ada3d17f98c21c00ca8b115f6b61de.png" alt="\boldsymbol{F} = m \boldsymbol{a} \Rightarrow \boldsymbol{a} = \frac{\boldsymbol{F}}{m}"/></p>
+</div><p>The new velocity and position is found by integrating the above equation
+with regards to time. The simplest integration scheme in this regard is the
+<a class="reference external" href="https://en.wikipedia.org/wiki/Euler_method">Euler method</a>:</p>
+<div class="math">
+<p><img src="_images/math/fca2f0caf945233a44e5c1c1479f13d636edbf42.png" alt="\boldsymbol{v} = \boldsymbol{v}_{old} + \boldsymbol{a} \Delta t"/></p>
+</div><div class="math">
+<p><img src="_images/math/93ddc61f81c056650ee9c02c3e62ed84e4a5327f.png" alt="\boldsymbol{p} = \boldsymbol{p}_{old} + \boldsymbol{v} \Delta t"/></p>
+</div></div>
</div>
t@@ -76,12 +227,22 @@ spheres, which keeps contact-searching algorithms simple.</p>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Discrete element method</a><ul>
+<li><a class="reference internal" href="#contact-search">Contact search</a></li>
+<li><a class="reference internal" href="#contact-interaction">Contact interaction</a></li>
+<li><a class="reference internal" href="#temporal-integration">Temporal integration</a></li>
+</ul>
+</li>
+</ul>
+
<h4>Previous topic</h4>
<p class="topless"><a href="introduction.html"
title="previous chapter">Introduction</a></p>
<h4>Next topic</h4>
- <p class="topless"><a href="python_api.html"
- title="next chapter">Python API</a></p>
+ <p class="topless"><a href="cfd.html"
+ title="next chapter">Fluid simulation and particle-fluid interaction</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/dem.txt"
t@@ -114,16 +275,16 @@ spheres, which keeps contact-searching algorithms simple.</p>
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
- <a href="python_api.html" title="Python API"
+ <a href="cfd.html" title="Fluid simulation and particle-fluid interaction"
>next</a> |</li>
<li class="right" >
<a href="introduction.html" title="Introduction"
>previous</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
<div class="footer">
- © Copyright 2012, Anders Damsgaard.
+ © Copyright 2014, Anders Damsgaard.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
DIR diff --git a/doc/html/genindex.html b/doc/html/genindex.html
t@@ -10,7 +10,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Index — sphere 0.35 documentation</title>
+ <title>Index — sphere 1.00-alpha documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
t@@ -19,7 +19,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
- VERSION: '0.35',
+ VERSION: '1.00-alpha',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
t@@ -28,7 +28,7 @@
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
- <link rel="top" title="sphere 0.35 documentation" href="index.html" />
+ <link rel="top" title="sphere 1.00-alpha documentation" href="index.html" />
</head>
<body>
<div class="related">
t@@ -40,7 +40,7 @@
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
t@@ -75,7 +75,21 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.adjustUpperWall">adjustUpperWall() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.acceleration">acceleration() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.addParticle">addParticle() (sphere.sim method)</a>
+ </dt>
+
+ </dl></td>
+ <td style="width: 33%" valign="top"><dl>
+
+ <dt><a href="python_api.html#sphere.sim.adjustUpperWall">adjustUpperWall() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.adjustWall">adjustWall() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -85,17 +99,17 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.bond">bond() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.bond">bond() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.bondsRose">bondsRose() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.bondsRose">bondsRose() (sphere.sim method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.bulkPorosity">bulkPorosity() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.bulkPorosity">bulkPorosity() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -108,22 +122,32 @@
<dt><a href="python_api.html#sphere.cleanup">cleanup() (in module sphere)</a>
</dt>
+ <dd><dl>
+
+ <dt><a href="python_api.html#sphere.sim.cleanup">(sphere.sim method)</a>
+ </dt>
+
+ </dl></dd>
- <dt><a href="python_api.html#sphere.Spherebin.consolidate">consolidate() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.consolidate">consolidate() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.convert">convert() (in module sphere)</a>
+ <dt><a href="python_api.html#sphere.sim.contactModel">contactModel() (sphere.sim method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.createBondPair">createBondPair() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.convert">convert() (in module sphere)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.createBondPair">createBondPair() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.currentDevs">currentDevs() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.currentNormalStress">currentNormalStress() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -133,7 +157,17 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.defaultParams">defaultParams() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.defaultParams">defaultParams() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.defineWorldBoundaries">defineWorldBoundaries() (sphere.sim method)</a>
+ </dt>
+
+ </dl></td>
+ <td style="width: 33%" valign="top"><dl>
+
+ <dt><a href="python_api.html#sphere.sim.disableFluidPressureModulation">disableFluidPressureModulation() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -143,7 +177,7 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.energy">energy() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.energy">energy() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -153,13 +187,13 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.forcechains">forcechains() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.forcechains">forcechains() (sphere.sim method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.forcechainsRose">forcechainsRose() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.forcechainsRose">forcechainsRose() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -169,13 +203,13 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.generateBimodalRadii">generateBimodalRadii() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.generateBimodalRadii">generateBimodalRadii() (sphere.sim method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.generateRadii">generateRadii() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.generateRadii">generateRadii() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -185,29 +219,33 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.initGrid">initGrid() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.initFluid">initFluid() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.initGridAndWorldsize">initGridAndWorldsize() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.initGrid">initGrid() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.initGridPos">initGridPos() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.initGridAndWorldsize">initGridAndWorldsize() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.initGridPos">initGridPos() (sphere.sim method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.initRandomGridPos">initRandomGridPos() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.initRandomGridPos">initRandomGridPos() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.initRandomPos">initRandomPos() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.initRandomPos">initRandomPos() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.initTemporal">initTemporal() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.initTemporal">initTemporal() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -217,13 +255,49 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.porosities">porosities() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.periodicBoundariesX">periodicBoundariesX() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.periodicBoundariesXY">periodicBoundariesXY() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.plotConvergence">plotConvergence() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.plotFluidDiffAdvPresZ">plotFluidDiffAdvPresZ() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.plotFluidPressuresY">plotFluidPressuresY() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.plotFluidPressuresZ">plotFluidPressuresZ() (sphere.sim method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.porosity">porosity() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.plotFluidVelocitiesY">plotFluidVelocitiesY() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.plotFluidVelocitiesZ">plotFluidVelocitiesZ() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.plotPrescribedFluidPressures">plotPrescribedFluidPressures() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.porosities">porosities() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.porosity">porosity() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -233,22 +307,38 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.random2bonds">random2bonds() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.randomBondPairs">randomBondPairs() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.readbin">readbin() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.readbin">readbin() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.readfirst">readfirst() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.readlast">readlast() (sphere.sim method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
+ <dt><a href="python_api.html#sphere.sim.readsecond">readsecond() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.readstep">readstep() (sphere.sim method)</a>
+ </dt>
+
+
<dt><a href="python_api.html#sphere.render">render() (in module sphere)</a>
</dt>
<dd><dl>
- <dt><a href="python_api.html#sphere.Spherebin.render">(sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.render">(sphere.sim method)</a>
</dt>
</dl></dd>
t@@ -258,7 +348,7 @@
<dd><dl>
- <dt><a href="python_api.html#sphere.Spherebin.run">(sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.run">(sphere.sim method)</a>
</dt>
</dl></dd>
t@@ -269,35 +359,65 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.shear">shear() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.setBeta">setBeta() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.setFluidPressureModulation">setFluidPressureModulation() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.sheardisp">sheardisp() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.setGamma">setGamma() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.shearstrain">shearstrain() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.setMaxIterations">setMaxIterations() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.shearvel">shearvel() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.setTheta">setTheta() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.setTolerance">setTolerance() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.shear">shear() (sphere.sim method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#module-sphere">sphere (module)</a>
+ <dt><a href="python_api.html#sphere.sim.sheardisp">sheardisp() (sphere.sim method)</a>
</dt>
- <dt><a href="python_api.html#sphere.Spherebin">Spherebin (class in sphere)</a>
+ <dt><a href="python_api.html#sphere.sim.shearStrain">shearStrain() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.shearVel">shearVel() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim">sim (class in sphere)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#module-sphere">sphere (module)</a>
</dt>
<dt><a href="python_api.html#sphere.status">status() (in module sphere)</a>
</dt>
+ <dd><dl>
+
+ <dt><a href="python_api.html#sphere.sim.status">(sphere.sim method)</a>
+ </dt>
+
+ </dl></dd>
</dl></td>
</tr></table>
t@@ -305,7 +425,7 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.thinsection_x1x3">thinsection_x1x3() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.thinsection_x1x3">thinsection_x1x3() (sphere.sim method)</a>
</dt>
t@@ -313,7 +433,7 @@
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.torqueScript">torqueScript() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.torqueScript">torqueScript() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -323,7 +443,11 @@
</dt>
- <dt><a href="python_api.html#sphere.torqueScriptSerial3">torqueScriptSerial3() (in module sphere)</a>
+ <dt><a href="python_api.html#sphere.sim.totalMomentum">totalMomentum() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.triaxial">triaxial() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -333,7 +457,7 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.uniaxialStrainRate">uniaxialStrainRate() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.uniaxialStrainRate">uniaxialStrainRate() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -347,9 +471,19 @@
</dt>
+ <dt><a href="python_api.html#sphere.vector_norm">vector_norm() (in module sphere)</a>
+ </dt>
+
+
<dt><a href="python_api.html#sphere.video">video() (in module sphere)</a>
</dt>
+ <dd><dl>
+
+ <dt><a href="python_api.html#sphere.sim.video">(sphere.sim method)</a>
+ </dt>
+
+ </dl></dd>
</dl></td>
<td style="width: 33%" valign="top"><dl>
t@@ -357,7 +491,7 @@
</dt>
- <dt><a href="python_api.html#sphere.Spherebin.voidRatio">voidRatio() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.voidRatio">voidRatio() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -367,7 +501,21 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.writebin">writebin() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.writebin">writebin() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.writeFluidVTK">writeFluidVTK() (sphere.sim method)</a>
+ </dt>
+
+ </dl></td>
+ <td style="width: 33%" valign="top"><dl>
+
+ <dt><a href="python_api.html#sphere.sim.writeVTK">writeVTK() (sphere.sim method)</a>
+ </dt>
+
+
+ <dt><a href="python_api.html#sphere.sim.writeVTKall">writeVTKall() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -377,7 +525,7 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
- <dt><a href="python_api.html#sphere.Spherebin.zeroKinematics">zeroKinematics() (sphere.Spherebin method)</a>
+ <dt><a href="python_api.html#sphere.sim.zeroKinematics">zeroKinematics() (sphere.sim method)</a>
</dt>
</dl></td>
t@@ -419,11 +567,11 @@
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
<div class="footer">
- © Copyright 2012, Anders Damsgaard.
+ © Copyright 2014, Anders Damsgaard.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
DIR diff --git a/doc/html/index.html b/doc/html/index.html
t@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Welcome to sphere’s documentation! — sphere 0.35 documentation</title>
+ <title>The sphere documentation — sphere 1.00-alpha documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
t@@ -17,7 +17,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
- VERSION: '0.35',
+ VERSION: '1.00-alpha',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
t@@ -26,7 +26,7 @@
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
- <link rel="top" title="sphere 0.35 documentation" href="#" />
+ <link rel="top" title="sphere 1.00-alpha documentation" href="#" />
<link rel="next" title="Introduction" href="introduction.html" />
</head>
<body>
t@@ -42,7 +42,7 @@
<li class="right" >
<a href="introduction.html" title="Introduction"
accesskey="N">next</a> |</li>
- <li><a href="#">sphere 0.35 documentation</a> »</li>
+ <li><a href="#">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
t@@ -51,44 +51,60 @@
<div class="bodywrapper">
<div class="body">
- <div class="section" id="welcome-to-sphere-s-documentation">
-<h1>Welcome to sphere’s documentation!<a class="headerlink" href="#welcome-to-sphere-s-documentation" title="Permalink to this headline">¶</a></h1>
-<p>This is the official documentation for the <em>sphere</em> discrete element modelling
-software. It presents the theory behind the discrete element method (DEM), the
-structure of the software source code, and the Python API for handling
-simulation setup and data analysis.</p>
-<p><em>sphere</em> is developed by Anders Damsgaard Christensen under supervision of David
-Lunbek Egholm and Jan A. Piotrowski, all of the department of Geoscience, Aarhus
-University, Denmark. This document is a work in progress, and is still in an
-early state.</p>
-<p>Contact: Anders Damsgaard Christensen, <a class="reference external" href="http://cs.au.dk/~adc">http://cs.au.dk/~adc</a>,
+ <div class="section" id="the-sphere-documentation">
+<h1>The sphere documentation<a class="headerlink" href="#the-sphere-documentation" title="Permalink to this headline">¶</a></h1>
+<p>This is the official documentation for the <tt class="docutils literal"><span class="pre">sphere</span></tt> discrete element modelling
+software. This document aims at guiding the installation process, documenting
+the usage, and explaining the relevant theory.</p>
+<p><tt class="docutils literal"><span class="pre">sphere</span></tt> is developed by Anders Damsgaard as part as his Ph.D. project, under
+supervision of David Lundbek Egholm and Jan A. Piotrowski, all of the Department
+of Geoscience, Aarhus University, Denmark. The author welcomes interested third
+party developers. This document is a work in progress.</p>
+<p>Contact: Anders Damsgaard, <a class="reference external" href="http://cs.au.dk/~adc">http://cs.au.dk/~adc</a>,
<a class="reference external" href="mailto:anders.damsgaard%40geo.au.dk">mailto:anders<span>.</span>damsgaard<span>@</span>geo<span>.</span>au<span>.</span>dk</a></p>
-<p>Contents:</p>
+<div class="section" id="contents">
+<h2>Contents<a class="headerlink" href="#contents" title="Permalink to this headline">¶</a></h2>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="introduction.html">Introduction</a><ul>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#requirements">Requirements</a></li>
-<li class="toctree-l2"><a class="reference internal" href="introduction.html#building-sphere">Building <em>sphere</em></a></li>
+<li class="toctree-l2"><a class="reference internal" href="introduction.html#obtaining-sphere">Obtaining sphere</a></li>
+<li class="toctree-l2"><a class="reference internal" href="introduction.html#building-sphere">Building <tt class="docutils literal"><span class="pre">sphere</span></tt></a></li>
+<li class="toctree-l2"><a class="reference internal" href="introduction.html#updating-sphere">Updating sphere</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#work-flow">Work flow</a></li>
</ul>
</li>
-<li class="toctree-l1"><a class="reference internal" href="dem.html">Discrete element method</a></li>
-<li class="toctree-l1"><a class="reference internal" href="python_api.html">Python API</a></li>
-<li class="toctree-l1"><a class="reference internal" href="sphere_internals.html">sphere internals</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="sphere_internals.html#numerical-algorithm">Numerical algorithm</a></li>
-<li class="toctree-l2"><a class="reference internal" href="sphere_internals.html#c-reference">C++ reference</a></li>
+<li class="toctree-l1"><a class="reference internal" href="dem.html">Discrete element method</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="dem.html#contact-search">Contact search</a></li>
+<li class="toctree-l2"><a class="reference internal" href="dem.html#contact-interaction">Contact interaction</a></li>
+<li class="toctree-l2"><a class="reference internal" href="dem.html#temporal-integration">Temporal integration</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="cfd.html">Fluid simulation and particle-fluid interaction</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="cfd.html#derivation-of-the-navier-stokes-equations-with-porosity">Derivation of the Navier Stokes equations with porosity</a></li>
+<li class="toctree-l2"><a class="reference internal" href="cfd.html#porosity-estimation">Porosity estimation</a></li>
+<li class="toctree-l2"><a class="reference internal" href="cfd.html#particle-fluid-interaction">Particle-fluid interaction</a></li>
+<li class="toctree-l2"><a class="reference internal" href="cfd.html#fluid-dynamics-solution-procedure-by-operator-splitting">Fluid dynamics solution procedure by operator splitting</a></li>
+<li class="toctree-l2"><a class="reference internal" href="cfd.html#boundary-conditions">Boundary conditions</a></li>
+<li class="toctree-l2"><a class="reference internal" href="cfd.html#numerical-implementation">Numerical implementation</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="python_api.html">Python API</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="python_api.html#sample-usage">Sample usage</a></li>
+<li class="toctree-l2"><a class="reference internal" href="python_api.html#module-sphere">The <tt class="docutils literal"><span class="pre">sphere</span></tt> module</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="section" id="indices-and-tables">
-<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1>
+<h2>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h2>
<ul class="simple">
<li><a class="reference internal" href="genindex.html"><em>Index</em></a></li>
<li><a class="reference internal" href="search.html"><em>Search Page</em></a></li>
</ul>
</div>
+</div>
</div>
t@@ -98,11 +114,14 @@ early state.</p>
<div class="sphinxsidebarwrapper">
<h3><a href="#">Table Of Contents</a></h3>
<ul>
-<li><a class="reference internal" href="#">Welcome to sphere’s documentation!</a><ul>
+<li><a class="reference internal" href="#">The sphere documentation</a><ul>
+<li><a class="reference internal" href="#contents">Contents</a><ul>
</ul>
</li>
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
</ul>
+</li>
+</ul>
<h4>Next topic</h4>
<p class="topless"><a href="introduction.html"
t@@ -141,11 +160,11 @@ early state.</p>
<li class="right" >
<a href="introduction.html" title="Introduction"
>next</a> |</li>
- <li><a href="#">sphere 0.35 documentation</a> »</li>
+ <li><a href="#">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
<div class="footer">
- © Copyright 2012, Anders Damsgaard.
+ © Copyright 2014, Anders Damsgaard.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
DIR diff --git a/doc/html/introduction.html b/doc/html/introduction.html
t@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Introduction — sphere 0.35 documentation</title>
+ <title>Introduction — sphere 1.00-alpha documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
t@@ -17,7 +17,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
- VERSION: '0.35',
+ VERSION: '1.00-alpha',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
t@@ -26,9 +26,9 @@
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
- <link rel="top" title="sphere 0.35 documentation" href="index.html" />
+ <link rel="top" title="sphere 1.00-alpha documentation" href="index.html" />
<link rel="next" title="Discrete element method" href="dem.html" />
- <link rel="prev" title="Welcome to sphere’s documentation!" href="index.html" />
+ <link rel="prev" title="The sphere documentation" href="index.html" />
</head>
<body>
<div class="related">
t@@ -44,9 +44,9 @@
<a href="dem.html" title="Discrete element method"
accesskey="N">next</a> |</li>
<li class="right" >
- <a href="index.html" title="Welcome to sphere’s documentation!"
+ <a href="index.html" title="The sphere documentation"
accesskey="P">previous</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
t@@ -57,56 +57,75 @@
<div class="section" id="introduction">
<h1>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h1>
-<p>The <em>sphere</em>-software is used for three-dimensional discrete element method
+<p>The <tt class="docutils literal"><span class="pre">sphere</span></tt>-software is used for three-dimensional discrete element method
(DEM) particle simulations. The source code is written in C++, CUDA C and
Python, and is compiled by the user. The main computations are performed on the
graphics processing unit (GPU) using NVIDIA’s general purpose parallel computing
architecture, CUDA. Simulation setup and data analysis is performed with the
included Python API.</p>
-<p>The ultimate aim of the <em>sphere</em> software is to simulate soft-bedded subglacial
+<p>The ultimate aim of the <tt class="docutils literal"><span class="pre">sphere</span></tt> software is to simulate soft-bedded subglacial
conditions, while retaining the flexibility to perform simulations of granular
material in other environments.</p>
<p>The purpose of this documentation is to provide the user with a walk-through of
the installation, work-flow, data-analysis and visualization methods of
-<em>sphere</em>. In addition, the <em>sphere</em> internals are exposed to provide a way of
+<tt class="docutils literal"><span class="pre">sphere</span></tt>. In addition, the <tt class="docutils literal"><span class="pre">sphere</span></tt> internals are exposed to provide a way of
understanding of the discrete element method numerical routines taking place.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
-<p class="last">Command examples in this document starting with the symbol <tt class="docutils literal"><span class="pre">$</span></tt> are meant to be executed in the shell of the operational system, and <tt class="docutils literal"><span class="pre">>>></span></tt> means execution in Python.</p>
+<p class="last">Command examples in this document starting with the symbol <tt class="docutils literal"><span class="pre">$</span></tt> are
+meant to be executed in the shell of the operational system, and <tt class="docutils literal"><span class="pre">>>></span></tt>
+means execution in Python. <a class="reference external" href="http://ipython.org">IPython</a> is an excellent,
+interactive Python shell.</p>
</div>
<p>All numerical values in this document, the source code, and the configuration
files are typeset with strict respect to the SI unit system.</p>
<div class="section" id="requirements">
<h2>Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline">¶</a></h2>
-<dl class="docutils">
-<dt>The build requirements are:</dt>
-<dd><ul class="first last simple">
+<p>The build requirements are:</p>
+<blockquote>
+<div><ul class="simple">
<li>A Nvidia CUDA-supported version of Linux or Mac OS X (see the <a class="reference external" href="http://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html">CUDA toolkit
release notes</a> for more information)</li>
<li><a class="reference external" href="https://www.gnu.org/software/make/">GNU Make</a></li>
-<li><a class="reference external" href="http://www.cmake.org">CMake</a></li>
+<li><a class="reference external" href="http://www.cmake.org">CMake</a>, version 2.8 or newer</li>
<li>The <a class="reference external" href="http://gcc.gnu.org/">GNU Compiler Collection</a> (GCC)</li>
-<li>The <a class="reference external" href="https://developer.nvidia.com/cuda-downloads">Nvidia CUDA toolkit and SDK</a></li>
+<li>The <a class="reference external" href="https://developer.nvidia.com/cuda-downloads">Nvidia CUDA toolkit</a>,
+version 5.0 or newer</li>
</ul>
-</dd>
-<dt>The runtime requirements are:</dt>
-<dd><ul class="first last simple">
+</div></blockquote>
+<p>In Debian GNU/Linux, these dependencies can be installed by running:</p>
+<div class="highlight-python"><pre>$ sudo apt-get install build-essential cmake nvidia-cuda-toolkit</pre>
+</div>
+<p>Unfortunately, the Nvidia Toolkit is shipped under a non-free license. In order
+to install it in Debian GNU/Linux, add <tt class="docutils literal"><span class="pre">non-free</span></tt> archives to your
+<tt class="docutils literal"><span class="pre">/etc/apt/sources.list</span></tt>.</p>
+<p>The runtime requirements are:</p>
+<blockquote>
+<div><ul class="simple">
<li>A <a class="reference external" href="http://www.nvidia.com/object/cuda_gpus.html">CUDA-enabled GPU</a> with
compute capability 1.1 or greater.</li>
<li>A Nvidia CUDA-enabled GPU and device driver</li>
</ul>
-</dd>
-<dt>Optional tools, required for simulation setup and data processing:</dt>
-<dd><ul class="first last simple">
-<li><a class="reference external" href="http://www.python.org/getit/releases/2.7/">Python 2.7</a></li>
+</div></blockquote>
+<p>Optional tools, required for simulation setup and data processing:</p>
+<blockquote>
+<div><ul class="simple">
+<li><a class="reference external" href="http://www.python.org/">Python</a></li>
<li><a class="reference external" href="http://numpy.scipy.org">Numpy</a></li>
<li><a class="reference external" href="http://matplotlib.org">Matplotlib</a></li>
+<li><a class="reference external" href="http://www.vtk.org">Python bindings for VTK</a></li>
<li><a class="reference external" href="http://www.imagemagick.org/script/index.php">Imagemagick</a></li>
-<li><a class="reference external" href="http://ffmpeg.org/">ffmpeg</a></li>
+<li><a class="reference external" href="http://ffmpeg.org/">ffmpeg</a>. Soon to be replaced by avconv!</li>
</ul>
-</dd>
-<dt>Optional tools, required for building the documentation:</dt>
-<dd><ul class="first last simple">
+</div></blockquote>
+<p>In Debian GNU/Linux, these dependencies can be installed by running:</p>
+<div class="highlight-python"><pre>$ sudo apt-get install python python-numpy python-matplotlib python-vtk \
+ imagemagick libav-tools</pre>
+</div>
+<p><tt class="docutils literal"><span class="pre">sphere</span></tt> is distributed with a HTML and PDF build of the documentation. The
+following tools are required for building the documentation:</p>
+<blockquote>
+<div><ul class="simple">
<li><a class="reference external" href="http://sphinx-doc.org">Sphinx</a><ul>
<li><a class="reference external" href="http://packages.python.org/sphinxcontrib-programoutput/">sphinxcontrib-programoutput</a></li>
</ul>
t@@ -114,22 +133,65 @@ compute capability 1.1 or greater.</li>
<li><a class="reference external" href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a></li>
<li><a class="reference external" href="http://michaeljones.github.com/breathe/">Breathe</a></li>
<li><a class="reference external" href="http://www.nongnu.org/dvipng/">dvipng</a></li>
+<li><a class="reference external" href="http://www.tug.org/texlive/">TeX Live</a>, including <tt class="docutils literal"><span class="pre">pdflatex</span></tt></li>
</ul>
-</dd>
-</dl>
+</div></blockquote>
+<p>In Debian GNU/Linux, these dependencies can be installed by running:</p>
+<div class="highlight-python"><pre>$ sudo apt-get install python-sphinx python-pip doxygen dvipng \
+ python-sphinxcontrib-programoutput texlive-full
+$ sudo pip install breathe</pre>
+</div>
<p><a class="reference external" href="http://git-scm.com">Git</a> is used as the distributed version control system
-platform, and the source code is maintained at <a class="reference external" href="https://github.com/anders-dc/sphere/">Github</a>. <em>sphere</em> is licensed under the <a class="reference external" href="https://www.gnu.org/licenses/gpl.html">GNU
+platform, and the source code is maintained at <a class="reference external" href="https://github.com/anders-dc/sphere/">Github</a>. <tt class="docutils literal"><span class="pre">sphere</span></tt> is licensed under the <a class="reference external" href="https://www.gnu.org/licenses/gpl.html">GNU
Public License, v.3</a>.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p>All Debian GNU/Linux runtime, optional, and documentation dependencies
+mentioned above can be installed by executing the following command from the
+<tt class="docutils literal"><span class="pre">doc/</span></tt> folder:</p>
+<div class="last highlight-python"><pre>$ make install-debian-pkgs</pre>
+</div>
+</div>
+</div>
+<div class="section" id="obtaining-sphere">
+<h2>Obtaining sphere<a class="headerlink" href="#obtaining-sphere" title="Permalink to this headline">¶</a></h2>
+<p>The best way to keep up to date with subsequent updates, bugfixes and
+development, is to use the Git version control system. To obtain a local
+copy, execute:</p>
+<div class="highlight-python"><pre>$ git clone git@github.com:anders-dc/sphere.git</pre>
+</div>
</div>
<div class="section" id="building-sphere">
-<h2>Building <em>sphere</em><a class="headerlink" href="#building-sphere" title="Permalink to this headline">¶</a></h2>
-<p>All instructions required for building <em>sphere</em> are provided in a number of
-<tt class="docutils literal"><span class="pre">Makefile</span></tt>‘s. To generate the main <em>sphere</em> command-line executable, go to the
-root directory, and invoke CMake and GNU Make:</p>
+<h2>Building <tt class="docutils literal"><span class="pre">sphere</span></tt><a class="headerlink" href="#building-sphere" title="Permalink to this headline">¶</a></h2>
+<p><tt class="docutils literal"><span class="pre">sphere</span></tt> is built using <tt class="docutils literal"><span class="pre">cmake</span></tt>, the platform-specific C/C++ compilers,
+and <tt class="docutils literal"><span class="pre">nvcc</span></tt> from the Nvidia CUDA toolkit.</p>
+<p>If you plan to run <tt class="docutils literal"><span class="pre">sphere</span></tt> on a Kepler GPU, execute the following commands
+from the root directory:</p>
+<div class="highlight-python"><pre>$ cmake . && make</pre>
+</div>
+<p>If you instead plan to execute it on a Fermi GPU, change <tt class="docutils literal"><span class="pre">set(GPU_GENERATION</span>
+<span class="pre">1)</span></tt> to <tt class="docutils literal"><span class="pre">set(GPU_GENERATION</span> <span class="pre">0</span></tt> in <tt class="docutils literal"><span class="pre">CMakeLists.txt</span></tt>.</p>
+<p>In some cases the CMake FindCUDA module will have troubles locating the
+CUDA samples directory, and will complain about <tt class="docutils literal"><span class="pre">helper_math.h</span></tt> not being
+found.</p>
+<p>In that case, modify the <tt class="docutils literal"><span class="pre">CUDA_SDK_ROOT_DIR</span></tt> variable in
+<tt class="docutils literal"><span class="pre">src/CMakeLists.txt</span></tt> to the path where you installed the CUDA samples, and run
+<tt class="docutils literal"><span class="pre">cmake</span> <span class="pre">.</span> <span class="pre">&&</span> <span class="pre">make</span></tt> again. Alternatively, copy <tt class="docutils literal"><span class="pre">helper_math.h</span></tt> from the CUDA
+sample subdirectory <tt class="docutils literal"><span class="pre">common/inc/helper_math.h</span></tt> into the sphere <tt class="docutils literal"><span class="pre">src/</span></tt>
+directory, and run <tt class="docutils literal"><span class="pre">cmake</span></tt> and <tt class="docutils literal"><span class="pre">make</span></tt> again. Due to license restrictions,
+sphere cannot be distributed with this file.</p>
+<p>After a successfull installation, the <tt class="docutils literal"><span class="pre">sphere</span></tt> executable will be located
+in the root folder. To make sure that all components are working correctly,
+execute:</p>
+<div class="highlight-python"><pre>$ make test</pre>
+</div>
+<p>All instructions required for building <tt class="docutils literal"><span class="pre">sphere</span></tt> are provided in a number of
+<tt class="docutils literal"><span class="pre">Makefile</span></tt>‘s. To generate the main <tt class="docutils literal"><span class="pre">sphere</span></tt> command-line executable, go to
+the root directory, and invoke CMake and GNU Make:</p>
<div class="highlight-python"><pre>$ cmake . && make</pre>
</div>
<p>If successfull, the Makefiles will create the required data folders, object
-files, as well as the <em>sphere</em> executable in the root folder. Issue the
+files, as well as the <tt class="docutils literal"><span class="pre">sphere</span></tt> executable in the root folder. Issue the
following commands to check the executable:</p>
<div class="highlight-python"><pre>$ ./sphere --version</pre>
</div>
t@@ -152,8 +214,9 @@ following commands to check the executable:</p>
<div class="highlight-python"><pre>$ make test</pre>
</div>
<p>The documentation can be read in the <a class="reference external" href="http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html">reStructuredText</a>-format in
-the <tt class="docutils literal"><span class="pre">doc/sphinx/</span></tt> folder, or build into e.g. HTML or PDF format with the
-following commands:</p>
+the <tt class="docutils literal"><span class="pre">doc/sphinx/</span></tt> folder, or in the HTML or PDF formats in the folders
+<tt class="docutils literal"><span class="pre">doc/html</span></tt> and <tt class="docutils literal"><span class="pre">doc/pdf</span></tt>.</p>
+<p>Optionally, the documentation can be built using the following commands:</p>
<div class="highlight-python"><pre>$ cd doc/sphinx
$ make html
$ make latexpdf</pre>
t@@ -162,19 +225,26 @@ $ make latexpdf</pre>
<div class="highlight-python"><pre>$ make help</pre>
</div>
</div>
+<div class="section" id="updating-sphere">
+<h2>Updating sphere<a class="headerlink" href="#updating-sphere" title="Permalink to this headline">¶</a></h2>
+<p>To update your local version, type the following commands in the <tt class="docutils literal"><span class="pre">sphere</span></tt> root
+directory:</p>
+<div class="highlight-python"><pre>$ git pull && cmake . && make</pre>
+</div>
+</div>
<div class="section" id="work-flow">
<h2>Work flow<a class="headerlink" href="#work-flow" title="Permalink to this headline">¶</a></h2>
-<p>After compiling the <em>sphere</em> binary, the procedure of a creating and handling a
-simulation is typically arranged in the following order:</p>
+<p>After compiling the <tt class="docutils literal"><span class="pre">sphere</span></tt> binary, the procedure of a creating and handling
+a simulation is typically arranged in the following order:</p>
<blockquote>
<div><ul class="simple">
<li>Setup of particle assemblage, physical properties and conditions using the
Python API.</li>
-<li>Execution of <em>sphere</em> software, which simulates the particle behavior as a
+<li>Execution of <tt class="docutils literal"><span class="pre">sphere</span></tt> software, which simulates the particle behavior as a
function of time, as a result of the conditions initially specified in the
input file.</li>
-<li>Inspection, analysis, interpretation and visualization of <em>sphere</em> output in
-Python, and/or scene rendering using the built-in ray tracer.</li>
+<li>Inspection, analysis, interpretation and visualization of <tt class="docutils literal"><span class="pre">sphere</span></tt> output
+in Python, and/or scene rendering using the built-in ray tracer.</li>
</ul>
</div></blockquote>
</div>
t@@ -190,7 +260,9 @@ Python, and/or scene rendering using the built-in ray tracer.</li>
<ul>
<li><a class="reference internal" href="#">Introduction</a><ul>
<li><a class="reference internal" href="#requirements">Requirements</a></li>
-<li><a class="reference internal" href="#building-sphere">Building <em>sphere</em></a></li>
+<li><a class="reference internal" href="#obtaining-sphere">Obtaining sphere</a></li>
+<li><a class="reference internal" href="#building-sphere">Building <tt class="docutils literal"><span class="pre">sphere</span></tt></a></li>
+<li><a class="reference internal" href="#updating-sphere">Updating sphere</a></li>
<li><a class="reference internal" href="#work-flow">Work flow</a></li>
</ul>
</li>
t@@ -198,7 +270,7 @@ Python, and/or scene rendering using the built-in ray tracer.</li>
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
- title="previous chapter">Welcome to sphere’s documentation!</a></p>
+ title="previous chapter">The sphere documentation</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="dem.html"
title="next chapter">Discrete element method</a></p>
t@@ -237,13 +309,13 @@ Python, and/or scene rendering using the built-in ray tracer.</li>
<a href="dem.html" title="Discrete element method"
>next</a> |</li>
<li class="right" >
- <a href="index.html" title="Welcome to sphere’s documentation!"
+ <a href="index.html" title="The sphere documentation"
>previous</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
<div class="footer">
- © Copyright 2012, Anders Damsgaard.
+ © Copyright 2014, Anders Damsgaard.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
DIR diff --git a/doc/html/objects.inv b/doc/html/objects.inv
Binary files differ.
DIR diff --git a/doc/html/py-modindex.html b/doc/html/py-modindex.html
t@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Python Module Index — sphere 0.35 documentation</title>
+ <title>Python Module Index — sphere 1.00-alpha documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
t@@ -17,7 +17,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
- VERSION: '0.35',
+ VERSION: '1.00-alpha',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
t@@ -26,7 +26,7 @@
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
- <link rel="top" title="sphere 0.35 documentation" href="index.html" />
+ <link rel="top" title="sphere 1.00-alpha documentation" href="index.html" />
<script type="text/javascript">
t@@ -45,7 +45,7 @@
<li class="right" >
<a href="#" title="Python Module Index"
>modules</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
t@@ -104,11 +104,11 @@
<li class="right" >
<a href="#" title="Python Module Index"
>modules</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
<div class="footer">
- © Copyright 2012, Anders Damsgaard.
+ © Copyright 2014, Anders Damsgaard.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
DIR diff --git a/doc/html/python_api.html b/doc/html/python_api.html
t@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Python API — sphere 0.35 documentation</title>
+ <title>Python API — sphere 1.00-alpha documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
t@@ -17,7 +17,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
- VERSION: '0.35',
+ VERSION: '1.00-alpha',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
t@@ -26,9 +26,8 @@
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
- <link rel="top" title="sphere 0.35 documentation" href="index.html" />
- <link rel="next" title="sphere internals" href="sphere_internals.html" />
- <link rel="prev" title="Discrete element method" href="dem.html" />
+ <link rel="top" title="sphere 1.00-alpha documentation" href="index.html" />
+ <link rel="prev" title="Fluid simulation and particle-fluid interaction" href="cfd.html" />
</head>
<body>
<div class="related">
t@@ -41,12 +40,9 @@
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
- <a href="sphere_internals.html" title="sphere internals"
- accesskey="N">next</a> |</li>
- <li class="right" >
- <a href="dem.html" title="Discrete element method"
+ <a href="cfd.html" title="Fluid simulation and particle-fluid interaction"
accesskey="P">previous</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
t@@ -55,352 +51,1838 @@
<div class="bodywrapper">
<div class="body">
- <div class="section" id="module-sphere">
-<span id="python-api"></span><h1>Python API<a class="headerlink" href="#module-sphere" title="Permalink to this headline">¶</a></h1>
+ <div class="section" id="python-api">
+<h1>Python API<a class="headerlink" href="#python-api" title="Permalink to this headline">¶</a></h1>
+<p>The Python module <tt class="docutils literal"><span class="pre">sphere</span></tt> is intended as the main interface to the <tt class="docutils literal"><span class="pre">sphere</span></tt>
+application. It is recommended to use this module for simulation setup,
+simulation execution, and analysis of the simulation output data.</p>
+<p>In order to use the API, the file <tt class="docutils literal"><span class="pre">sphere.py</span></tt> must be placed in the same
+directory as the Python files.</p>
+<div class="section" id="sample-usage">
+<h2>Sample usage<a class="headerlink" href="#sample-usage" title="Permalink to this headline">¶</a></h2>
+<p>Below is a simple, annotated example of how to setup, execute, and post-process
+a <tt class="docutils literal"><span class="pre">sphere</span></tt> simulation. The example is also found in the <tt class="docutils literal"><span class="pre">python/</span></tt> folder as
+<tt class="docutils literal"><span class="pre">collision.py</span></tt>.</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59</pre></div></td><td class="code"><div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
+<span class="sd">"""</span>
+<span class="sd">Example of two particles colliding.</span>
+<span class="sd">Place script in sphere/python/ folder, and invoke with `python collision.py`</span>
+<span class="sd">"""</span>
+
+<span class="c"># Import the sphere module for setting up, running, and analyzing the</span>
+<span class="c"># experiment. We also need the numpy module when setting arrays in the sphere</span>
+<span class="c"># object.</span>
+<span class="kn">import</span> <span class="nn">sphere</span>
+<span class="kn">import</span> <span class="nn">numpy</span>
+
+
+<span class="c">### SIMULATION SETUP</span>
+
+<span class="c"># Create a sphere object with two preallocated particles and a simulation ID</span>
+<span class="n">SB</span> <span class="o">=</span> <span class="n">sphere</span><span class="o">.</span><span class="n">sim</span><span class="p">(</span><span class="n">np</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span> <span class="n">sid</span> <span class="o">=</span> <span class="s">'collision'</span><span class="p">)</span>
+
+<span class="n">SB</span><span class="o">.</span><span class="n">radius</span><span class="p">[:]</span> <span class="o">=</span> <span class="mf">0.3</span> <span class="c"># set radii to 0.3 m</span>
+
+<span class="c"># Define the positions of the two particles</span>
+<span class="n">SB</span><span class="o">.</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mf">10.0</span><span class="p">,</span> <span class="mf">5.0</span><span class="p">,</span> <span class="mf">5.0</span><span class="p">])</span> <span class="c"># particle 1 (idx 0)</span>
+<span class="n">SB</span><span class="o">.</span><span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mf">11.0</span><span class="p">,</span> <span class="mf">5.0</span><span class="p">,</span> <span class="mf">5.0</span><span class="p">])</span> <span class="c"># particle 2 (idx 1)</span>
+
+<span class="c"># The default velocity is [0,0,0]. Slam particle 1 into particle 2 by defining</span>
+<span class="c"># a positive x velocity for particle 1.</span>
+<span class="n">SB</span><span class="o">.</span><span class="n">vel</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mf">1.0</span>
+
+<span class="c"># Set the world limits and the particle sorting grid. The particles need to stay</span>
+<span class="c"># within the world limits for the entire simulation, otherwise it will stop!</span>
+<span class="n">SB</span><span class="o">.</span><span class="n">initGridAndWorldsize</span><span class="p">(</span><span class="n">margin</span> <span class="o">=</span> <span class="mf">5.0</span><span class="p">)</span>
+
+<span class="c"># Define the temporal parameters, e.g. the total time (total) and the file</span>
+<span class="c"># output interval (file_dt), both in seconds</span>
+<span class="n">SB</span><span class="o">.</span><span class="n">initTemporal</span><span class="p">(</span><span class="n">total</span> <span class="o">=</span> <span class="mf">2.0</span><span class="p">,</span> <span class="n">file_dt</span> <span class="o">=</span> <span class="mf">0.1</span><span class="p">)</span>
+
+<span class="c"># Using a 'dry' run, the sphere main program will display important parameters.</span>
+<span class="c"># sphere will end after displaying these values.</span>
+<span class="n">SB</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">dry</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
+
+
+<span class="c">### RUNNING THE SIMULATION</span>
+
+<span class="c"># Start the simulation on the GPU from the sphere program</span>
+<span class="n">SB</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
+
+
+<span class="c">### ANALYSIS OF SIMULATION RESULTS</span>
+
+<span class="c"># Plot the system energy through time, image saved as collision-energy.png</span>
+<span class="n">sphere</span><span class="o">.</span><span class="n">visualize</span><span class="p">(</span><span class="n">SB</span><span class="o">.</span><span class="n">sid</span><span class="p">,</span> <span class="n">method</span> <span class="o">=</span> <span class="s">'energy'</span><span class="p">)</span>
+
+<span class="c"># Render the particles using the built-in raytracer</span>
+<span class="n">SB</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+
+<span class="c"># Alternative visualization using ParaView. See the documentation of</span>
+<span class="c"># ``sim.writeVTKall()`` for more information about displaying the</span>
+<span class="c"># particles in ParaView.</span>
+<span class="n">SB</span><span class="o">.</span><span class="n">writeVTKall</span><span class="p">()</span>
+</pre></div>
+</td></tr></table></div>
+<p>The full documentation of the <tt class="docutils literal"><span class="pre">sphere</span></tt> Python API can be found below.</p>
+</div>
+<div class="section" id="module-sphere">
+<span id="the-sphere-module"></span><h2>The <tt class="docutils literal"><span class="pre">sphere</span></tt> module<a class="headerlink" href="#module-sphere" title="Permalink to this headline">¶</a></h2>
+<dl class="function">
+<dt id="sphere.V_sphere">
+<tt class="descclassname">sphere.</tt><tt class="descname">V_sphere</tt><big>(</big><em>r</em><big>)</big><a class="headerlink" href="#sphere.V_sphere" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calculates the volume of a sphere with radius r</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The sphere volume [m^3]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sphere.cleanup">
+<tt class="descclassname">sphere.</tt><tt class="descname">cleanup</tt><big>(</big><em>sim</em><big>)</big><a class="headerlink" href="#sphere.cleanup" title="Permalink to this definition">¶</a></dt>
+<dd><p>Removes the input/output files and images belonging to the object simulation
+ID from the <tt class="docutils literal"><span class="pre">input/</span></tt>, <tt class="docutils literal"><span class="pre">output/</span></tt> and <tt class="docutils literal"><span class="pre">img_out/</span></tt> folders.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>spherebin</strong> (<em>sim</em>) – A sim object</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sphere.convert">
+<tt class="descclassname">sphere.</tt><tt class="descname">convert</tt><big>(</big><em>graphics_format='png'</em>, <em>folder='../img_out'</em><big>)</big><a class="headerlink" href="#sphere.convert" title="Permalink to this definition">¶</a></dt>
+<dd><p>Converts all PPM images in img_out to graphics_format using Imagemagick. All
+PPM images are subsequently removed.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>graphics_format</strong> (<em>str</em>) – Convert the images to this format</li>
+<li><strong>folder</strong> (<em>str</em>) – The folder containing the PPM images to convert</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sphere.render">
+<tt class="descclassname">sphere.</tt><tt class="descname">render</tt><big>(</big><em>binary</em>, <em>method='pres'</em>, <em>max_val=1000.0</em>, <em>lower_cutoff=0.0</em>, <em>graphics_format='png'</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.render" title="Permalink to this definition">¶</a></dt>
+<dd><p>Render target binary using the <tt class="docutils literal"><span class="pre">sphere</span></tt> raytracer.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>method</strong> (<em>str</em>) – The color visualization method to use for the particles.
+Possible values are: ‘normal’: color all particles with the same
+color, ‘pres’: color by pressure, ‘vel’: color by translational
+velocity, ‘angvel’: color by rotational velocity, ‘xdisp’: color by
+total displacement along the x-axis, ‘angpos’: color by angular
+position.</li>
+<li><strong>max_val</strong> (<em>float</em>) – The maximum value of the color bar</li>
+<li><strong>lower_cutoff</strong> (<em>float</em>) – Do not render particles with a value below this
+value, of the field selected by <tt class="docutils literal"><span class="pre">method</span></tt></li>
+<li><strong>graphics_format</strong> (<em>str</em>) – Convert the PPM images generated by the ray
+tracer to this image format using Imagemagick</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show verbose information during ray tracing</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sphere.run">
+<tt class="descclassname">sphere.</tt><tt class="descname">run</tt><big>(</big><em>binary</em>, <em>verbose=True</em>, <em>hideinputfile=False</em><big>)</big><a class="headerlink" href="#sphere.run" title="Permalink to this definition">¶</a></dt>
+<dd><p>Execute <tt class="docutils literal"><span class="pre">sphere</span></tt> with target binary file as input.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>binary</strong> (<em>str</em>) – Input file for <tt class="docutils literal"><span class="pre">sphere</span></tt></li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show <tt class="docutils literal"><span class="pre">sphere</span></tt> output</li>
+<li><strong>hideinputfile</strong> (<em>bool</em>) – Hide the input file</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
<dl class="class">
-<dt id="sphere.Spherebin">
-<em class="property">class </em><tt class="descclassname">sphere.</tt><tt class="descname">Spherebin</tt><big>(</big><em>np=1</em>, <em>nd=3</em>, <em>nw=1</em>, <em>sid='unnamed'</em><big>)</big><a class="headerlink" href="#sphere.Spherebin" title="Permalink to this definition">¶</a></dt>
-<dd><p>Class containing all data SPHERE data.</p>
+<dt id="sphere.sim">
+<em class="property">class </em><tt class="descclassname">sphere.</tt><tt class="descname">sim</tt><big>(</big><em>sid='unnamed'</em>, <em>np=0</em>, <em>nd=3</em>, <em>nw=0</em>, <em>fluid=False</em><big>)</big><a class="headerlink" href="#sphere.sim" title="Permalink to this definition">¶</a></dt>
+<dd><p>Class containing all <tt class="docutils literal"><span class="pre">sphere</span></tt> data.</p>
<p>Contains functions for reading and writing binaries, as well as simulation
-setup and data analysis.</p>
+setup and data analysis. Most arrays are initialized to default values.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>np</strong> (<em>int</em>) – The number of particles to allocate memory for (default = 1)</li>
+<li><strong>nd</strong> (<em>int</em>) – The number of spatial dimensions (default = 3). Note that 2D and
+1D simulations currently are not possible.</li>
+<li><strong>nw</strong> (<em>int</em>) – The number of dynamic walls (default = 1)</li>
+<li><strong>sid</strong> (<em>str</em>) – The simulation id (default = ‘unnamed’). The simulation files
+will be written with this base name.</li>
+<li><strong>fluid</strong> (<em>bool</em>) – Setup fluid simulation (default = False)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<dl class="method">
+<dt id="sphere.sim.acceleration">
+<tt class="descname">acceleration</tt><big>(</big><em>idx=-1</em><big>)</big><a class="headerlink" href="#sphere.sim.acceleration" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the acceleration of one or more particles, selected by their
+index. If the index is equal to -1 (default value), all accelerations
+are returned.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>idx</strong> (<em>int, list or numpy.array</em>) – Index or index range of particles</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">n-by-3 matrix of acceleration(s)</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">numpy.array</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.addParticle">
+<tt class="descname">addParticle</tt><big>(</big><em>x</em>, <em>radius</em>, <em>xysum=array([ 0.</em>, <em>0.])</em>, <em>vel=array([ 0.</em>, <em>0.</em>, <em>0.])</em>, <em>fixvel=array([ 0.])</em>, <em>force=array([ 0.</em>, <em>0.</em>, <em>0.])</em>, <em>angpos=array([ 0.</em>, <em>0.</em>, <em>0.])</em>, <em>angvel=array([ 0.</em>, <em>0.</em>, <em>0.])</em>, <em>torque=array([ 0.</em>, <em>0.</em>, <em>0.])</em>, <em>es_dot=array([ 0.])</em>, <em>es=array([ 0.])</em>, <em>ev_dot=array([ 0.])</em>, <em>ev=array([ 0.])</em>, <em>p=array([ 0.])</em><big>)</big><a class="headerlink" href="#sphere.sim.addParticle" title="Permalink to this definition">¶</a></dt>
+<dd><p>Add a single particle to the simulation object. The only required
+parameters are the position (x) and the radius (radius).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>x</strong> (<em>numpy.array</em>) – A vector pointing to the particle center coordinate.</li>
+<li><strong>radius</strong> (<em>float</em>) – The particle radius</li>
+<li><strong>vel</strong> (<em>numpy.array</em>) – The particle linear velocity (default = [0,0,0])</li>
+<li><strong>fixvel</strong> (<em>float</em>) – Fix horizontal linear velocity (0: No, 1: Yes, default=0)</li>
+<li><strong>angpos</strong> (<em>numpy.array</em>) – The particle angular position (default = [0,0,0])</li>
+<li><strong>angvel</strong> (<em>numpy.array</em>) – The particle angular velocity (default = [0,0,0])</li>
+<li><strong>torque</strong> (<em>numpy.array</em>) – The particle torque (default = [0,0,0])</li>
+<li><strong>es_dot</strong> (<em>float</em>) – The particle shear energy loss rate (default = 0)</li>
+<li><strong>es</strong> (<em>float</em>) – The particle shear energy loss (default = 0)</li>
+<li><strong>ev_dot</strong> (<em>float</em>) – The particle viscous energy rate loss (default = 0)</li>
+<li><strong>ev</strong> (<em>float</em>) – The particle viscous energy loss (default = 0)</li>
+<li><strong>p</strong> (<em>float</em>) – The particle pressure (default = 0)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.adjustUpperWall">
+<tt class="descname">adjustUpperWall</tt><big>(</big><em>z_adjust=1.1</em><big>)</big><a class="headerlink" href="#sphere.sim.adjustUpperWall" title="Permalink to this definition">¶</a></dt>
+<dd><p>Included for legacy purposes, calls <a class="reference internal" href="#sphere.sim.adjustWall" title="sphere.sim.adjustWall"><tt class="xref py py-func docutils literal"><span class="pre">adjustWall()</span></tt></a> with <tt class="docutils literal"><span class="pre">idx=0</span></tt>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>z_adjust</strong> (<em>float</em>) – Increase the world and grid size by this amount to
+allow for wall movement.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.adjustWall">
+<tt class="descname">adjustWall</tt><big>(</big><em>idx</em>, <em>adjust=1.1</em><big>)</big><a class="headerlink" href="#sphere.sim.adjustWall" title="Permalink to this definition">¶</a></dt>
+<dd><p>Adjust grid and dynamic wall to max. particle position</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Param :</th><td class="field-body">idx: The wall to adjust. 0 = +z, upper wall (default), 1 = -x,
+left wall, 2 = +x, right wall, 3 = -y, front wall, 4 = +y, back
+wall.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Parameters:</th><td class="field-body"><strong>z_adjust</strong> (<em>float</em>) – Increase the world and grid size by this amount to
+allow for wall movement.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.bond">
+<tt class="descname">bond</tt><big>(</big><em>i</em>, <em>j</em><big>)</big><a class="headerlink" href="#sphere.sim.bond" title="Permalink to this definition">¶</a></dt>
+<dd><p>Create a bond between particles with index i and j</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>i</strong> (<em>int</em>) – Index of first particle in bond</li>
+<li><strong>j</strong> (<em>int</em>) – Index of second particle in bond</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
<dl class="method">
-<dt id="sphere.Spherebin.adjustUpperWall">
-<tt class="descname">adjustUpperWall</tt><big>(</big><em>z_adjust=1.1</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.adjustUpperWall" title="Permalink to this definition">¶</a></dt>
-<dd><p>Adjust grid and dynamic upper wall to max. particle height</p>
+<dt id="sphere.sim.bondsRose">
+<tt class="descname">bondsRose</tt><big>(</big><em>graphics_format='pdf'</em><big>)</big><a class="headerlink" href="#sphere.sim.bondsRose" title="Permalink to this definition">¶</a></dt>
+<dd><p>Visualize the trend and plunge angles of the bond pairs in a rose plot.
+The plot is saved in the current folder as
+‘bonds-<simulation id>-rose.<graphics_format>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.bond">
-<tt class="descname">bond</tt><big>(</big><em>i</em>, <em>j</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.bond" title="Permalink to this definition">¶</a></dt>
-<dd><p>Create a bond between particles i and j</p>
+<dt id="sphere.sim.bulkPorosity">
+<tt class="descname">bulkPorosity</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.bulkPorosity" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calculates the bulk porosity</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The bulk porosity, in [0:1]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.bondsRose">
-<tt class="descname">bondsRose</tt><big>(</big><em>imgformat='pdf'</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.bondsRose" title="Permalink to this definition">¶</a></dt>
-<dd><p>Visualize strike- and dip angles of the bond pairs in a rose plot.</p>
+<dt id="sphere.sim.cleanup">
+<tt class="descname">cleanup</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.cleanup" title="Permalink to this definition">¶</a></dt>
+<dd><p>Removes the input/output files and images belonging to the object
+simulation ID from the <tt class="docutils literal"><span class="pre">input/</span></tt>, <tt class="docutils literal"><span class="pre">output/</span></tt> and <tt class="docutils literal"><span class="pre">img_out/</span></tt> folders.</p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.bulkPorosity">
-<tt class="descname">bulkPorosity</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.Spherebin.bulkPorosity" title="Permalink to this definition">¶</a></dt>
-<dd><p>Calculate and return the bulk porosity</p>
+<dt id="sphere.sim.consolidate">
+<tt class="descname">consolidate</tt><big>(</big><em>normal_stress=10000.0</em><big>)</big><a class="headerlink" href="#sphere.sim.consolidate" title="Permalink to this definition">¶</a></dt>
+<dd><p>Setup consolidation experiment. Specify the upper wall normal stress in
+Pascal, default value is 10 kPa.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>normal_stress</strong> (<em>float</em>) – The normal stress to apply from the upper wall</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.consolidate">
-<tt class="descname">consolidate</tt><big>(</big><em>deviatoric_stress=10000.0</em>, <em>periodic=1</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.consolidate" title="Permalink to this definition">¶</a></dt>
-<dd><p>Setup consolidation experiment. Specify the upper wall
-deviatoric stress in Pascal, default value is 10 kPa.</p>
+<dt id="sphere.sim.contactModel">
+<tt class="descname">contactModel</tt><big>(</big><em>contactmodel</em><big>)</big><a class="headerlink" href="#sphere.sim.contactModel" title="Permalink to this definition">¶</a></dt>
+<dd><p>Define which contact model to use for the tangential component of
+particle-particle interactions. The elastic-viscous-frictional contact
+model (2) is considered to be the most realistic contact model, while
+the viscous-frictional contact model is significantly faster.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>contactmodel</strong> (<em>int</em>) – The type of tangential contact model to use
+(visco-frictional = 1, elasto-visco-frictional = 2)</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.createBondPair">
-<tt class="descname">createBondPair</tt><big>(</big><em>i</em>, <em>j</em>, <em>spacing=-0.1</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.createBondPair" title="Permalink to this definition">¶</a></dt>
+<dt id="sphere.sim.createBondPair">
+<tt class="descname">createBondPair</tt><big>(</big><em>i</em>, <em>j</em>, <em>spacing=-0.1</em><big>)</big><a class="headerlink" href="#sphere.sim.createBondPair" title="Permalink to this definition">¶</a></dt>
<dd><p>Bond particles i and j. Particle j is moved adjacent to particle i,
-and oriented randomly.
-@param spacing (float) The inter-particle distance prescribed. Positive
-values result in a inter-particle distance, negative equal an overlap.
-The value is relative to the sum of the two radii.</p>
+and oriented randomly.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>i</strong> (<em>int</em>) – Index of first particle in bond</li>
+<li><strong>j</strong> (<em>int</em>) – Index of second particle in bond</li>
+<li><strong>spacing</strong> (<em>float</em>) – The inter-particle distance prescribed. Positive
+values result in a inter-particle distance, negative equal an
+overlap. The value is relative to the sum of the two radii.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.currentDevs">
-<tt class="descname">currentDevs</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.Spherebin.currentDevs" title="Permalink to this definition">¶</a></dt>
-<dd><p>Return current magnitude of the deviatoric normal stress</p>
+<dt id="sphere.sim.currentNormalStress">
+<tt class="descname">currentNormalStress</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.currentNormalStress" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calculates the current magnitude of the top wall normal stress.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The current top wall normal stress in Pascal</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.defaultParams">
-<tt class="descname">defaultParams</tt><big>(</big><em>mu_s=0.4</em>, <em>mu_d=0.4</em>, <em>mu_r=0.0</em>, <em>rho=2600</em>, <em>k_n=1160000000.0</em>, <em>k_t=1160000000.0</em>, <em>k_r=0</em>, <em>gamma_n=0</em>, <em>gamma_t=0</em>, <em>gamma_r=0</em>, <em>gamma_wn=10000.0</em>, <em>gamma_wt=10000.0</em>, <em>capillaryCohesion=0</em>, <em>nu=0.0</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.defaultParams" title="Permalink to this definition">¶</a></dt>
-<dd><p>Initialize particle parameters to default values.
-Radii must be set prior to calling this function.</p>
+<dt id="sphere.sim.defaultParams">
+<tt class="descname">defaultParams</tt><big>(</big><em>mu_s=0.4</em>, <em>mu_d=0.4</em>, <em>mu_r=0.0</em>, <em>rho=2600</em>, <em>k_n=1160000000.0</em>, <em>k_t=1160000000.0</em>, <em>k_r=0</em>, <em>gamma_n=0.0</em>, <em>gamma_t=0.0</em>, <em>gamma_r=0.0</em>, <em>gamma_wn=10000.0</em>, <em>gamma_wt=10000.0</em>, <em>capillaryCohesion=0</em><big>)</big><a class="headerlink" href="#sphere.sim.defaultParams" title="Permalink to this definition">¶</a></dt>
+<dd><p>Initialize particle parameters to default values.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>mu_s</strong> (<em>float</em>) – The coefficient of static friction between particles [-]</li>
+<li><strong>mu_d</strong> (<em>float</em>) – The coefficient of dynamic friction between particles [-]</li>
+<li><strong>rho</strong> (<em>float</em>) – The density of the particle material [kg/(m^3)]</li>
+<li><strong>k_n</strong> (<em>float</em>) – The normal stiffness of the particles [N/m]</li>
+<li><strong>k_t</strong> (<em>float</em>) – The tangential stiffness of the particles [N/m]</li>
+<li><strong>k_r</strong> (<em>float</em>) – The rolling stiffness of the particles [N/rad] <em>Parameter
+not used</em></li>
+<li><strong>gamma_n</strong> (<em>float</em>) – Particle-particle contact normal viscosity [Ns/m]</li>
+<li><strong>gamma_t</strong> (<em>float</em>) – Particle-particle contact tangential viscosity [Ns/m]</li>
+<li><strong>gamma_r</strong> (<em>float</em>) – Particle-particle contact rolling viscosity <em>Parameter
+not used</em></li>
+<li><strong>gamma_wn</strong> (<em>float</em>) – Wall-particle contact normal viscosity [Ns/m]</li>
+<li><strong>gamma_wt</strong> (<em>float</em>) – Wall-particle contact tangential viscosity [Ns/m]</li>
+<li><strong>capillaryCohesion</strong> (<em>int</em>) – Enable particle-particle capillary cohesion
+interaction model (0 = no (default), 1 = yes)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.energy">
-<tt class="descname">energy</tt><big>(</big><em>method</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.energy" title="Permalink to this definition">¶</a></dt>
-<dd><p>Calculate the sum of the energy components of all particles.</p>
+<dt id="sphere.sim.defineWorldBoundaries">
+<tt class="descname">defineWorldBoundaries</tt><big>(</big><em>L, origo=[0.0, 0.0, 0.0], dx=-1</em><big>)</big><a class="headerlink" href="#sphere.sim.defineWorldBoundaries" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the boundaries of the world. Particles will only be able to interact
+within this domain. With dynamic walls, allow space for expansions.
+<em>Important</em>: The particle radii have to be set beforehand. The world
+edges act as static walls.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>L</strong> (<em>numpy.array</em>) – The upper boundary of the domain [m]</li>
+<li><strong>origo</strong> (<em>numpy.array</em>) – The lower boundary of the domain [m]. Negative values
+won’t work. Default = [0.0, 0.0, 0.0].</li>
+<li><strong>dx</strong> (<em>float</em>) – The cell width in any direction. If the default value is used
+(-1), the cell width is calculated to fit the largest particle.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.forcechains">
-<tt class="descname">forcechains</tt><big>(</big><em>lc=200.0</em>, <em>uc=650.0</em>, <em>outformat='png'</em>, <em>disp='2d'</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.forcechains" title="Permalink to this definition">¶</a></dt>
+<dt id="sphere.sim.disableFluidPressureModulation">
+<tt class="descname">disableFluidPressureModulation</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.disableFluidPressureModulation" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the parameters for the sine wave modulating the fluid pressures
+at the top boundary to zero.</p>
+<p>See also: <a class="reference internal" href="#sphere.sim.setFluidPressureModulation" title="sphere.sim.setFluidPressureModulation"><tt class="xref py py-func docutils literal"><span class="pre">setFluidPressureModulation()</span></tt></a></p>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.energy">
+<tt class="descname">energy</tt><big>(</big><em>method</em><big>)</big><a class="headerlink" href="#sphere.sim.energy" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calculates the sum of the energy components of all particles.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>method</strong> (<em>str</em>) – The type of energy to return. Possible values are ‘pot’
+for potential energy [J], ‘kin’ for kinetic energy [J], ‘rot’ for
+rotational energy [J], ‘shear’ for energy lost by friction,
+‘shearrate’ for the rate of frictional energy loss [W], ‘visc_n’ for
+viscous losses normal to the contact [J], ‘visc_n_rate’ for the rate
+of viscous losses normal to the contact [W], and finally ‘bondpot’
+for the potential energy stored in bonds [J]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">The value of the selected energy type</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.forcechains">
+<tt class="descname">forcechains</tt><big>(</big><em>lc=200.0</em>, <em>uc=650.0</em>, <em>outformat='png'</em>, <em>disp='2d'</em><big>)</big><a class="headerlink" href="#sphere.sim.forcechains" title="Permalink to this definition">¶</a></dt>
<dd><p>Visualizes the force chains in the system from the magnitude of the
-normal contact forces, and produces an image of them.
-@param lc: Lower cutoff of contact forces. Contacts below are not
-visualized (float)
-@param uc: Upper cutoff of contact forces. Contacts above are
-visualized with this value (float)
-@param outformat: Format of output image. Possible values are
-‘interactive’, ‘png’, ‘epslatex’, ‘epslatex-color’
-@param disp: Display forcechains in ‘2d’ or ‘3d’
-Warning: Will segfault if no contacts are found.</p>
+normal contact forces, and produces an image of them. Warning: Will
+segfault if no contacts are found.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>lc</strong> (<em>float</em>) – Lower cutoff of contact forces. Contacts below are not
+visualized</li>
+<li><strong>uc</strong> (<em>float</em>) – Upper cutoff of contact forces. Contacts above are
+visualized with this value</li>
+<li><strong>outformat</strong> (<em>str</em>) – Format of output image. Possible values are
+‘interactive’, ‘png’, ‘epslatex’, ‘epslatex-color’</li>
+<li><strong>disp</strong> (<em>str</em>) – Display forcechains in ‘2d’ or ‘3d’</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.forcechainsRose">
-<tt class="descname">forcechainsRose</tt><big>(</big><em>lower_limit=0.25</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.forcechainsRose" title="Permalink to this definition">¶</a></dt>
-<dd><p>Visualize strike- and dip angles of the strongest force chains in a
-rose plot.</p>
+<dt id="sphere.sim.forcechainsRose">
+<tt class="descname">forcechainsRose</tt><big>(</big><em>lower_limit=0.25</em>, <em>graphics_format='pdf'</em><big>)</big><a class="headerlink" href="#sphere.sim.forcechainsRose" title="Permalink to this definition">¶</a></dt>
+<dd><p>Visualize trend and plunge angles of the strongest force chains in a
+rose plot. The plots are saved in the current folder with the name
+‘fc-<simulation id>-rose.pdf’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>lower_limit</strong> (<em>float</em>) – Do not visualize force chains below this relative
+contact force magnitude, in ]0;1[</li>
+<li><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.generateBimodalRadii">
-<tt class="descname">generateBimodalRadii</tt><big>(</big><em>r_small=0.005</em>, <em>r_large=0.05</em>, <em>ratio=0.2</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.generateBimodalRadii" title="Permalink to this definition">¶</a></dt>
-<dd><p>Draw radii from two sizes
-@param r_small: Radii of small population (float), in ]0;r_large[
-@param r_large: Radii of large population (float), in ]r_small;inf[
-@param ratio: Approximate volumetric ratio between the two
-populations (large/small).</p>
+<dt id="sphere.sim.generateBimodalRadii">
+<tt class="descname">generateBimodalRadii</tt><big>(</big><em>r_small=0.005</em>, <em>r_large=0.05</em>, <em>ratio=0.2</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.generateBimodalRadii" title="Permalink to this definition">¶</a></dt>
+<dd><p>Draw random radii from two distinct sizes.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>r_small</strong> (<em>float</em>) – Radii of small population [m], in ]0;r_large[</li>
+<li><strong>r_large</strong> (<em>float</em>) – Radii of large population [m], in ]r_small;inf[</li>
+<li><strong>ratio</strong> (<em>float</em>) – Approximate volumetric ratio between the two
+populations (large/small).</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See also: <a class="reference internal" href="#sphere.sim.generateRadii" title="sphere.sim.generateRadii"><tt class="xref py py-func docutils literal"><span class="pre">generateRadii()</span></tt></a>.</p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.generateRadii">
-<tt class="descname">generateRadii</tt><big>(</big><em>psd='logn'</em>, <em>radius_mean=0.00044</em>, <em>radius_variance=8.8e-09</em>, <em>histogram=True</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.generateRadii" title="Permalink to this definition">¶</a></dt>
-<dd><p>Draw random particle radii from the selected probability distribution.
-Specify mean radius and variance. The variance should be kept at a
-very low value.</p>
+<dt id="sphere.sim.generateRadii">
+<tt class="descname">generateRadii</tt><big>(</big><em>psd='logn'</em>, <em>radius_mean=0.00044</em>, <em>radius_variance=8.8e-09</em>, <em>histogram=True</em><big>)</big><a class="headerlink" href="#sphere.sim.generateRadii" title="Permalink to this definition">¶</a></dt>
+<dd><p>Draw random particle radii from a selected probability distribution.
+The larger the variance of radii is, the slower the computations will
+run. The reason is two-fold: The smallest particle dictates the time
+step length, where smaller particles cause shorter time steps. At the
+same time, the largest particle determines the sorting cell size, where
+larger particles cause larger cells. Larger cells are likely to contain
+more particles, causing more contact checks.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>psd</strong> (<em>str</em>) – The particle side distribution. One possible value is
+<tt class="docutils literal"><span class="pre">logn</span></tt>, which is a log-normal probability distribution, suitable
+for approximating well-sorted, coarse sediments. The other possible
+value is <tt class="docutils literal"><span class="pre">uni</span></tt>, which is a uniform distribution from
+<tt class="docutils literal"><span class="pre">radius_mean-radius_variance</span></tt> to <tt class="docutils literal"><span class="pre">radius_mean+radius_variance</span></tt>.</li>
+<li><strong>radius_mean</strong> (<em>float</em>) – The mean radius [m] (default = 440e-6 m)</li>
+<li><strong>radius_variance</strong> (<em>float</em>) – The variance in the probability distribution
+[m].</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See also: <a class="reference internal" href="#sphere.sim.generateBimodalRadii" title="sphere.sim.generateBimodalRadii"><tt class="xref py py-func docutils literal"><span class="pre">generateBimodalRadii()</span></tt></a>.</p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.initGrid">
-<tt class="descname">initGrid</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.Spherebin.initGrid" title="Permalink to this definition">¶</a></dt>
+<dt id="sphere.sim.initFluid">
+<tt class="descname">initFluid</tt><big>(</big><em>mu=0.00089</em><big>)</big><a class="headerlink" href="#sphere.sim.initFluid" title="Permalink to this definition">¶</a></dt>
+<dd><p>Initialize the fluid arrays and the fluid viscosity. The default value
+of <tt class="docutils literal"><span class="pre">mu</span></tt> equals the dynamic viscosity of water at 25 degrees Celcius.
+The value for water at 0 degrees Celcius is 17.87e-4 kg/(m*s).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>mu</strong> (<em>float</em>) – The fluid dynamic viscosity [kg/(m*s)]</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.initGrid">
+<tt class="descname">initGrid</tt><big>(</big><em>dx=-1</em><big>)</big><a class="headerlink" href="#sphere.sim.initGrid" title="Permalink to this definition">¶</a></dt>
<dd><p>Initialize grid suitable for the particle positions set previously.
The margin parameter adjusts the distance (in no. of max. radii)
-from the particle boundaries.</p>
+from the particle boundaries.
+<em>Important</em>: The particle radii have to be set beforehand if the cell
+width isn’t specified by <cite>dx</cite>.
+:param dx: The cell width in any direction. If the default value is used</p>
+<blockquote>
+<div>(-1), the cell width is calculated to fit the largest particle.</div></blockquote>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.initGridAndWorldsize">
-<tt class="descname">initGridAndWorldsize</tt><big>(</big><em>g=array([ 0.</em>, <em>0.</em>, <em>-9.80665])</em>, <em>margin=2.0</em>, <em>periodic=1</em>, <em>contactmodel=2</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.initGridAndWorldsize" title="Permalink to this definition">¶</a></dt>
+<dt id="sphere.sim.initGridAndWorldsize">
+<tt class="descname">initGridAndWorldsize</tt><big>(</big><em>margin=2.0</em><big>)</big><a class="headerlink" href="#sphere.sim.initGridAndWorldsize" title="Permalink to this definition">¶</a></dt>
<dd><p>Initialize grid suitable for the particle positions set previously.
The margin parameter adjusts the distance (in no. of max. radii)
-from the particle boundaries.</p>
+from the particle boundaries. If the upper wall is dynamic, it is placed
+at the top boundary of the world.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>margin</strong> (<em>float</em>) – Distance to world boundary in no. of max. particle radii</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.initGridPos">
-<tt class="descname">initGridPos</tt><big>(</big><em>g=array([ 0.</em>, <em>0.</em>, <em>-9.80665])</em>, <em>gridnum=array([12</em>, <em>12</em>, <em>36])</em>, <em>periodic=1</em>, <em>contactmodel=2</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.initGridPos" title="Permalink to this definition">¶</a></dt>
+<dt id="sphere.sim.initGridPos">
+<tt class="descname">initGridPos</tt><big>(</big><em>gridnum=array([12</em>, <em>12</em>, <em>36])</em><big>)</big><a class="headerlink" href="#sphere.sim.initGridPos" title="Permalink to this definition">¶</a></dt>
<dd><p>Initialize particle positions in loose, cubic configuration.
-Radii must be set beforehand.
-xynum is the number of rows in both x- and y- directions.</p>
+<tt class="docutils literal"><span class="pre">gridnum</span></tt> is the number of cells in the x, y and z directions.
+<em>Important</em>: The particle radii and the boundary conditions (periodic or
+not) for the x and y boundaries have to be set beforehand.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>gridnum</strong> (<em>numpy.array</em>) – The number of particles in x, y and z directions</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.initRandomGridPos">
-<tt class="descname">initRandomGridPos</tt><big>(</big><em>g=array([ 0.</em>, <em>0.</em>, <em>-9.80665])</em>, <em>gridnum=array([12</em>, <em>12</em>, <em>32])</em>, <em>periodic=1</em>, <em>contactmodel=2</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.initRandomGridPos" title="Permalink to this definition">¶</a></dt>
-<dd><p>Initialize particle positions in loose, cubic configuration.
-Radii must be set beforehand.
-xynum is the number of rows in both x- and y- directions.</p>
+<dt id="sphere.sim.initRandomGridPos">
+<tt class="descname">initRandomGridPos</tt><big>(</big><em>gridnum=array([12</em>, <em>12</em>, <em>32])</em><big>)</big><a class="headerlink" href="#sphere.sim.initRandomGridPos" title="Permalink to this definition">¶</a></dt>
+<dd><p>Initialize particle positions in loose, cubic configuration with some
+variance. <tt class="docutils literal"><span class="pre">gridnum</span></tt> is the number of cells in the x, y and z
+directions. <em>Important</em>: The particle radii and the boundary conditions
+(periodic or not) for the x and y boundaries have to be set beforehand.
+The world size and grid height (in the z direction) is readjusted to fit
+the particle positions.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>gridnum</strong> (<em>numpy.array</em>) – The number of particles in x, y and z directions</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.initRandomPos">
-<tt class="descname">initRandomPos</tt><big>(</big><em>g=array([ 0.</em>, <em>0.</em>, <em>-9.80665])</em>, <em>gridnum=array([12</em>, <em>12</em>, <em>36])</em>, <em>periodic=1</em>, <em>contactmodel=2</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.initRandomPos" title="Permalink to this definition">¶</a></dt>
-<dd><p>Initialize particle positions in loose, cubic configuration.
-Radii must be set beforehand.
-xynum is the number of rows in both x- and y- directions.</p>
+<dt id="sphere.sim.initRandomPos">
+<tt class="descname">initRandomPos</tt><big>(</big><em>gridnum=array([12</em>, <em>12</em>, <em>36])</em><big>)</big><a class="headerlink" href="#sphere.sim.initRandomPos" title="Permalink to this definition">¶</a></dt>
+<dd><p>Initialize particle positions in completely random configuration. Radii
+<em>must</em> be set beforehand. If the x and y boundaries are set as periodic,
+the particle centers will be placed all the way to the edge. On regular,
+non-periodic boundaries, the particles are restrained at the edges to
+make space for their radii within the bounding box.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>gridnum</strong> (<em>numpy.array</em>) – The number of sorting cells in each spatial direction
+(default = [12, 12, 36])</li>
+<li><strong>dx</strong> (<em>float</em>) – The cell width in any direction. If the default value is used
+(-1), the cell width is calculated to fit the largest particle.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.initTemporal">
-<tt class="descname">initTemporal</tt><big>(</big><em>total</em>, <em>current=0.0</em>, <em>file_dt=0.05</em>, <em>step_count=0</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.initTemporal" title="Permalink to this definition">¶</a></dt>
-<dd><p>Set temporal parameters for the simulation.
-Particle radii and physical parameters need to be set
-prior to these.</p>
+<dt id="sphere.sim.initTemporal">
+<tt class="descname">initTemporal</tt><big>(</big><em>total</em>, <em>current=0.0</em>, <em>file_dt=0.05</em>, <em>step_count=0</em>, <em>dt=-1</em><big>)</big><a class="headerlink" href="#sphere.sim.initTemporal" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set temporal parameters for the simulation. <em>Important</em>: Particle radii,
+physical parameters, and the optional fluid grid need to be set prior to
+these if the computational time step (dt) isn’t set explicitly. If the
+parameter <cite>dt</cite> is the default value (-1), the function will estimate the
+best time step length. The value of the computational time step for the
+DEM is checked for stability in the CFD solution if fluid simulation is
+included.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>total</strong> (<em>float</em>) – The time at which to end the simulation [s]</li>
+<li><strong>current</strong> – The current time [s] (default = 0.0 s)</li>
+<li><strong>file_dt</strong> – The interval between output files [s] (default = 0.05 s)</li>
+<li><strong>dt</strong> – The computational time step length [s]</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Step_count :</th><td class="field-body"><p class="first last">The number of the first output file (default = 0)</p>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.porosities">
-<tt class="descname">porosities</tt><big>(</big><em>outformat='pdf'</em>, <em>zslices=16</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.porosities" title="Permalink to this definition">¶</a></dt>
-<dd><p>Plot porosities with depth</p>
+<dt id="sphere.sim.periodicBoundariesX">
+<tt class="descname">periodicBoundariesX</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.periodicBoundariesX" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the x boundary conditions to be periodic.</p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.porosity">
-<tt class="descname">porosity</tt><big>(</big><em>slices=10</em>, <em>verbose=False</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.porosity" title="Permalink to this definition">¶</a></dt>
-<dd><p>Calculate the porosity as a function of depth, by averaging values
-in horizontal slabs.
-Returns porosity values and depth</p>
+<dt id="sphere.sim.periodicBoundariesXY">
+<tt class="descname">periodicBoundariesXY</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.periodicBoundariesXY" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the x and y boundary conditions to be periodic.</p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.random2bonds">
-<tt class="descname">random2bonds</tt><big>(</big><em>ratio=0.3</em>, <em>spacing=-0.1</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.random2bonds" title="Permalink to this definition">¶</a></dt>
-<dd><p>Bond an amount of particles in two-particle clusters
-@param ratio: The amount of particles to bond, values in ]0.0;1.0] (float)
-@param spacing: The distance relative to the sum of radii between bonded
-particles, neg. values denote an overlap. Values in ]0.0,inf[ (float).
-The particles should be initialized beforehand.
-Note: The actual number of bonds is likely to be somewhat smaller than
-specified, due to the random selection algorithm.</p>
+<dt id="sphere.sim.plotConvergence">
+<tt class="descname">plotConvergence</tt><big>(</big><em>graphics_format='png'</em><big>)</big><a class="headerlink" href="#sphere.sim.plotConvergence" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plot the convergence evolution in the CFD solver. The plot is saved
+in the output folder with the file name
+‘<simulation id>-conv.<graphics_format>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.readbin">
-<tt class="descname">readbin</tt><big>(</big><em>targetbin</em>, <em>verbose=True</em>, <em>bonds=True</em>, <em>devsmod=True</em>, <em>fluid=True</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.readbin" title="Permalink to this definition">¶</a></dt>
-<dd><p>Reads a target SPHERE binary file</p>
+<dt id="sphere.sim.plotFluidDiffAdvPresZ">
+<tt class="descname">plotFluidDiffAdvPresZ</tt><big>(</big><em>graphics_format='png'</em><big>)</big><a class="headerlink" href="#sphere.sim.plotFluidDiffAdvPresZ" title="Permalink to this definition">¶</a></dt>
+<dd><p>Compare contributions to the velocity from diffusion and advection,
+assuming the flow is 1D along the z-axis, phi = 1, and dphi = 0. This
+solution is analog to the predicted velocity and not constrained by the
+conservation of mass. The plot is saved in the output folder with the
+name format ‘<simulation id>-diff_adv-t=<current time>s-mu=<dynamic
+viscosity>Pa-s.<graphics_format>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.render">
-<tt class="descname">render</tt><big>(</big><em>method='pres'</em>, <em>max_val=1000.0</em>, <em>lower_cutoff=0.0</em>, <em>graphicsformat='png'</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.render" title="Permalink to this definition">¶</a></dt>
-<dd><p>Render all output files that belong to the simulation, determined by sid.</p>
+<dt id="sphere.sim.plotFluidPressuresY">
+<tt class="descname">plotFluidPressuresY</tt><big>(</big><em>y=-1</em>, <em>graphics_format='png'</em><big>)</big><a class="headerlink" href="#sphere.sim.plotFluidPressuresY" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plot fluid pressures in a plane normal to the second axis.
+The plot is saved in the current folder with the format
+‘p_f-<simulation id>-y<y value>.<graphics_format>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>y</strong> (<em>int</em>) – Plot pressures in fluid cells with these y axis values. If
+this value is -1, the center y position is used.</li>
+<li><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See also: <a class="reference internal" href="#sphere.sim.writeFluidVTK" title="sphere.sim.writeFluidVTK"><tt class="xref py py-func docutils literal"><span class="pre">writeFluidVTK()</span></tt></a> and <a class="reference internal" href="#sphere.sim.plotFluidPressuresZ" title="sphere.sim.plotFluidPressuresZ"><tt class="xref py py-func docutils literal"><span class="pre">plotFluidPressuresZ()</span></tt></a></p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.run">
-<tt class="descname">run</tt><big>(</big><em>verbose=True</em>, <em>hideinputfile=False</em>, <em>dry=False</em>, <em>valgrind=False</em>, <em>cudamemcheck=False</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.run" title="Permalink to this definition">¶</a></dt>
-<dd><p>Execute sphere with target project</p>
+<dt id="sphere.sim.plotFluidPressuresZ">
+<tt class="descname">plotFluidPressuresZ</tt><big>(</big><em>z=-1</em>, <em>graphics_format='png'</em><big>)</big><a class="headerlink" href="#sphere.sim.plotFluidPressuresZ" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plot fluid pressures in a plane normal to the third axis.
+The plot is saved in the current folder with the format
+‘p_f-<simulation id>-z<z value>.<graphics_format>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>z</strong> (<em>int</em>) – Plot pressures in fluid cells with these z axis values. If
+this value is -1, the center z position is used.</li>
+<li><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See also: <a class="reference internal" href="#sphere.sim.writeFluidVTK" title="sphere.sim.writeFluidVTK"><tt class="xref py py-func docutils literal"><span class="pre">writeFluidVTK()</span></tt></a> and <a class="reference internal" href="#sphere.sim.plotFluidPressuresY" title="sphere.sim.plotFluidPressuresY"><tt class="xref py py-func docutils literal"><span class="pre">plotFluidPressuresY()</span></tt></a></p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.shear">
-<tt class="descname">shear</tt><big>(</big><em>shear_strain_rate=1</em>, <em>periodic=1</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.shear" title="Permalink to this definition">¶</a></dt>
-<dd><p>Setup shear experiment. Specify the upper wall
-deviatoric stress in Pascal, default value is 10 kPa.
-The shear strain rate is the shear length divided by the
-initial height per second.</p>
+<dt id="sphere.sim.plotFluidVelocitiesY">
+<tt class="descname">plotFluidVelocitiesY</tt><big>(</big><em>y=-1</em>, <em>graphics_format='png'</em><big>)</big><a class="headerlink" href="#sphere.sim.plotFluidVelocitiesY" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plot fluid velocities in a plane normal to the second axis.
+The plot is saved in the current folder with the format
+‘v_f-<simulation id>-z<z value>.<graphics_format>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>y</strong> (<em>int</em>) – Plot velocities in fluid cells with these y axis values. If
+this value is -1, the center y position is used.</li>
+<li><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See also: <a class="reference internal" href="#sphere.sim.writeFluidVTK" title="sphere.sim.writeFluidVTK"><tt class="xref py py-func docutils literal"><span class="pre">writeFluidVTK()</span></tt></a> and <a class="reference internal" href="#sphere.sim.plotFluidVelocitiesZ" title="sphere.sim.plotFluidVelocitiesZ"><tt class="xref py py-func docutils literal"><span class="pre">plotFluidVelocitiesZ()</span></tt></a></p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.sheardisp">
-<tt class="descname">sheardisp</tt><big>(</big><em>outformat='pdf'</em>, <em>zslices=32</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.sheardisp" title="Permalink to this definition">¶</a></dt>
-<dd><p>Show particle x-displacement vs. the z-pos</p>
+<dt id="sphere.sim.plotFluidVelocitiesZ">
+<tt class="descname">plotFluidVelocitiesZ</tt><big>(</big><em>z=-1</em>, <em>graphics_format='png'</em><big>)</big><a class="headerlink" href="#sphere.sim.plotFluidVelocitiesZ" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plot fluid velocities in a plane normal to the third axis.
+The plot is saved in the current folder with the format
+‘v_f-<simulation id>-z<z value>.<graphics_format>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>z</strong> (<em>int</em>) – Plot velocities in fluid cells with these z axis values. If
+this value is -1, the center z position is used.</li>
+<li><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See also: <a class="reference internal" href="#sphere.sim.writeFluidVTK" title="sphere.sim.writeFluidVTK"><tt class="xref py py-func docutils literal"><span class="pre">writeFluidVTK()</span></tt></a> and <a class="reference internal" href="#sphere.sim.plotFluidVelocitiesY" title="sphere.sim.plotFluidVelocitiesY"><tt class="xref py py-func docutils literal"><span class="pre">plotFluidVelocitiesY()</span></tt></a></p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.shearstrain">
-<tt class="descname">shearstrain</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.Spherebin.shearstrain" title="Permalink to this definition">¶</a></dt>
-<dd><p>Calculates and returns the current shear strain (gamma) value of the experiment</p>
+<dt id="sphere.sim.plotPrescribedFluidPressures">
+<tt class="descname">plotPrescribedFluidPressures</tt><big>(</big><em>graphics_format='png'</em><big>)</big><a class="headerlink" href="#sphere.sim.plotPrescribedFluidPressures" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plot the prescribed fluid pressures through time that may be
+modulated through the class parameters p_mod_A, p_mod_f, and p_mod_phi.
+The plot is saved in the output folder with the file name
+‘<simulation id>-pres.<graphics_format>’.</p>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.shearvel">
-<tt class="descname">shearvel</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.Spherebin.shearvel" title="Permalink to this definition">¶</a></dt>
-<dd><p>Calculates and returns the shear velocity (gamma_dot) of the experiment</p>
+<dt id="sphere.sim.porosities">
+<tt class="descname">porosities</tt><big>(</big><em>graphics_format='pdf'</em>, <em>zslices=16</em><big>)</big><a class="headerlink" href="#sphere.sim.porosities" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plot the averaged porosities with depth. The plot is saved in the format
+‘<simulation id>-porosity.<graphics_format>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</li>
+<li><strong>zslices</strong> (<em>int</em>) – The number of points along the vertical axis to sample
+the porosity in</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.thinsection_x1x3">
-<tt class="descname">thinsection_x1x3</tt><big>(</big><em>x2='center'</em>, <em>graphicsformat='png'</em>, <em>cbmax=None</em>, <em>arrowscale=0.01</em>, <em>velarrowscale=1.0</em>, <em>slipscale=1.0</em>, <em>verbose=False</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.thinsection_x1x3" title="Permalink to this definition">¶</a></dt>
-<dd><p>Produce a 2D image of particles on a x1,x3 plane, intersecting the second axis at x2.
-Output is saved as ‘<sid>-ts-x1x3.txt’ in the current folder.</p>
-<p>An upper limit to the pressure color bar range can be set by the cbmax parameter.</p>
+<dt id="sphere.sim.porosity">
+<tt class="descname">porosity</tt><big>(</big><em>slices=10</em>, <em>verbose=False</em><big>)</big><a class="headerlink" href="#sphere.sim.porosity" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calculates the porosity as a function of depth, by averaging values in
+horizontal slabs. Returns porosity values and their corresponding depth.
+The values are calculated using the external <tt class="docutils literal"><span class="pre">porosity</span></tt> program.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>slices</strong> (<em>int</em>) – The number of vertical slabs to find porosities in.</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show the file name of the temporary file written to
+disk</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">A 2d array of depths and their averaged porosities</p>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">numpy.array</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.randomBondPairs">
+<tt class="descname">randomBondPairs</tt><big>(</big><em>ratio=0.3</em>, <em>spacing=-0.1</em><big>)</big><a class="headerlink" href="#sphere.sim.randomBondPairs" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bond an amount of particles in two-particle clusters. The particles
+should be initialized beforehand. Note: The actual number of bonds is
+likely to be somewhat smaller than specified, due to the random
+selection algorithm.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>ratio</strong> (<em>float</em>) – The amount of particles to bond, values in ]0.0;1.0]</li>
+<li><strong>spacing</strong> (<em>float</em>) – The distance relative to the sum of radii between bonded
+particles, neg. values denote an overlap. Values in ]0.0,inf[.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.readbin">
+<tt class="descname">readbin</tt><big>(</big><em>targetbin</em>, <em>verbose=True</em>, <em>bonds=True</em>, <em>devsmod=True</em>, <em>esysparticle=False</em><big>)</big><a class="headerlink" href="#sphere.sim.readbin" title="Permalink to this definition">¶</a></dt>
+<dd><p>Reads a target <tt class="docutils literal"><span class="pre">sphere</span></tt> binary file.</p>
+<p>See also <a class="reference internal" href="#sphere.sim.writebin" title="sphere.sim.writebin"><tt class="xref py py-func docutils literal"><span class="pre">writebin()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readfirst" title="sphere.sim.readfirst"><tt class="xref py py-func docutils literal"><span class="pre">readfirst()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readlast" title="sphere.sim.readlast"><tt class="xref py py-func docutils literal"><span class="pre">readlast()</span></tt></a>,
+<a class="reference internal" href="#sphere.sim.readsecond" title="sphere.sim.readsecond"><tt class="xref py py-func docutils literal"><span class="pre">readsecond()</span></tt></a>, and <a class="reference internal" href="#sphere.sim.readstep" title="sphere.sim.readstep"><tt class="xref py py-func docutils literal"><span class="pre">readstep()</span></tt></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>targetbin</strong> (<em>str</em>) – The path to the binary <tt class="docutils literal"><span class="pre">sphere</span></tt> file</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show diagnostic information (default = True)</li>
+<li><strong>bonds</strong> (<em>bool</em>) – The input file contains bond information (default = True).
+This parameter should be true for all recent <tt class="docutils literal"><span class="pre">sphere</span></tt> versions.</li>
+<li><strong>devsmod</strong> (<em>bool</em>) – The input file contains information about modulating
+stresses at the top wall (default = True). This parameter should be
+true for all recent <tt class="docutils literal"><span class="pre">sphere</span></tt> versions.</li>
+<li><strong>esysparticle</strong> (<em>bool</em>) – Stop reading the file after reading the kinematics,
+which is useful for reading output files from other DEM programs.
+(default = False)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.readfirst">
+<tt class="descname">readfirst</tt><big>(</big><em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.readfirst" title="Permalink to this definition">¶</a></dt>
+<dd><p>Read the first output file from the <tt class="docutils literal"><span class="pre">../output/</span></tt> folder, corresponding
+to the object simulation id (<tt class="docutils literal"><span class="pre">self.sid</span></tt>).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>verbose</strong> (<em>bool</em>) – Display diagnostic information (default = True)</td>
+</tr>
+</tbody>
+</table>
+<p>See also <a class="reference internal" href="#sphere.sim.readbin" title="sphere.sim.readbin"><tt class="xref py py-func docutils literal"><span class="pre">readbin()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readlast" title="sphere.sim.readlast"><tt class="xref py py-func docutils literal"><span class="pre">readlast()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readsecond" title="sphere.sim.readsecond"><tt class="xref py py-func docutils literal"><span class="pre">readsecond()</span></tt></a>, and
+<a class="reference internal" href="#sphere.sim.readstep" title="sphere.sim.readstep"><tt class="xref py py-func docutils literal"><span class="pre">readstep()</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.readlast">
+<tt class="descname">readlast</tt><big>(</big><em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.readlast" title="Permalink to this definition">¶</a></dt>
+<dd><p>Read the last output file from the <tt class="docutils literal"><span class="pre">../output/</span></tt> folder, corresponding
+to the object simulation id (<tt class="docutils literal"><span class="pre">self.sid</span></tt>).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>verbose</strong> (<em>bool</em>) – Display diagnostic information (default = True)</td>
+</tr>
+</tbody>
+</table>
+<p>See also <a class="reference internal" href="#sphere.sim.readbin" title="sphere.sim.readbin"><tt class="xref py py-func docutils literal"><span class="pre">readbin()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readfirst" title="sphere.sim.readfirst"><tt class="xref py py-func docutils literal"><span class="pre">readfirst()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readsecond" title="sphere.sim.readsecond"><tt class="xref py py-func docutils literal"><span class="pre">readsecond()</span></tt></a>, and
+<a class="reference internal" href="#sphere.sim.readstep" title="sphere.sim.readstep"><tt class="xref py py-func docutils literal"><span class="pre">readstep()</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.readsecond">
+<tt class="descname">readsecond</tt><big>(</big><em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.readsecond" title="Permalink to this definition">¶</a></dt>
+<dd><p>Read the second output file from the <tt class="docutils literal"><span class="pre">../output/</span></tt> folder,
+corresponding to the object simulation id (<tt class="docutils literal"><span class="pre">self.sid</span></tt>).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>verbose</strong> (<em>bool</em>) – Display diagnostic information (default = True)</td>
+</tr>
+</tbody>
+</table>
+<p>See also <a class="reference internal" href="#sphere.sim.readbin" title="sphere.sim.readbin"><tt class="xref py py-func docutils literal"><span class="pre">readbin()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readfirst" title="sphere.sim.readfirst"><tt class="xref py py-func docutils literal"><span class="pre">readfirst()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readlast" title="sphere.sim.readlast"><tt class="xref py py-func docutils literal"><span class="pre">readlast()</span></tt></a>,
+and <a class="reference internal" href="#sphere.sim.readstep" title="sphere.sim.readstep"><tt class="xref py py-func docutils literal"><span class="pre">readstep()</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.readstep">
+<tt class="descname">readstep</tt><big>(</big><em>step</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.readstep" title="Permalink to this definition">¶</a></dt>
+<dd><p>Read a output file from the <tt class="docutils literal"><span class="pre">../output/</span></tt> folder, corresponding
+to the object simulation id (<tt class="docutils literal"><span class="pre">self.sid</span></tt>).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>step</strong> (<em>int</em>) – The output file number to read, starting from 0.</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Display diagnostic information (default = True)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See also <a class="reference internal" href="#sphere.sim.readbin" title="sphere.sim.readbin"><tt class="xref py py-func docutils literal"><span class="pre">readbin()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readfirst" title="sphere.sim.readfirst"><tt class="xref py py-func docutils literal"><span class="pre">readfirst()</span></tt></a>, <a class="reference internal" href="#sphere.sim.readlast" title="sphere.sim.readlast"><tt class="xref py py-func docutils literal"><span class="pre">readlast()</span></tt></a>,
+and <a class="reference internal" href="#sphere.sim.readsecond" title="sphere.sim.readsecond"><tt class="xref py py-func docutils literal"><span class="pre">readsecond()</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.render">
+<tt class="descname">render</tt><big>(</big><em>method='pres'</em>, <em>max_val=1000.0</em>, <em>lower_cutoff=0.0</em>, <em>graphics_format='png'</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.render" title="Permalink to this definition">¶</a></dt>
+<dd><p>Using the built-in ray tracer, render all output files that belong to
+the simulation, determined by the simulation id (<tt class="docutils literal"><span class="pre">sid</span></tt>).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>method</strong> (<em>str</em>) – The color visualization method to use for the particles.
+Possible values are: ‘normal’: color all particles with the same
+color, ‘pres’: color by pressure, ‘vel’: color by translational
+velocity, ‘angvel’: color by rotational velocity, ‘xdisp’: color by
+total displacement along the x-axis, ‘angpos’: color by angular
+position.</li>
+<li><strong>max_val</strong> (<em>float</em>) – The maximum value of the color bar</li>
+<li><strong>lower_cutoff</strong> (<em>float</em>) – Do not render particles with a value below this
+value, of the field selected by <tt class="docutils literal"><span class="pre">method</span></tt></li>
+<li><strong>graphics_format</strong> (<em>str</em>) – Convert the PPM images generated by the ray
+tracer to this image format using Imagemagick</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show verbose information during ray tracing</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.run">
+<tt class="descname">run</tt><big>(</big><em>verbose=True</em>, <em>hideinputfile=False</em>, <em>dry=False</em>, <em>valgrind=False</em>, <em>cudamemcheck=False</em><big>)</big><a class="headerlink" href="#sphere.sim.run" title="Permalink to this definition">¶</a></dt>
+<dd><p>Start <tt class="docutils literal"><span class="pre">sphere</span></tt> calculations on the <tt class="docutils literal"><span class="pre">sim</span></tt> object</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>verbose</strong> (<em>bool</em>) – Show <tt class="docutils literal"><span class="pre">sphere</span></tt> output</li>
+<li><strong>hideinputfile</strong> (<em>bool</em>) – Hide the file name of the <tt class="docutils literal"><span class="pre">sphere</span></tt> input file</li>
+<li><strong>dry</strong> (<em>bool</em>) – Perform a dry run. Important parameter values are shown by
+the <tt class="docutils literal"><span class="pre">sphere</span></tt> program, and it exits afterwards.</li>
+<li><strong>valgrind</strong> (<em>bool</em>) – Run the program with <tt class="docutils literal"><span class="pre">valgrind</span></tt> in order to check
+memory leaks in the host code. This causes a significant increase in
+computational time.</li>
+<li><strong>cudamemcheck</strong> (<em>bool</em>) – Run the program with <tt class="docutils literal"><span class="pre">cudamemcheck</span></tt> in order to
+check for device memory leaks and errors. This causes a significant
+increase in computational time.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.setBeta">
+<tt class="descname">setBeta</tt><big>(</big><em>beta</em><big>)</big><a class="headerlink" href="#sphere.sim.setBeta" title="Permalink to this definition">¶</a></dt>
+<dd><p>Beta is a fluid solver parameter, used in velocity prediction and
+pressure iteration 1.0: Use old pressures for fluid velocity prediction
+(see Langtangen et al. 2002) 0.0: Do not use old pressures for fluid
+velocity prediction (Chorin’s original projection method, see Chorin
+(1968) and “Projection method (fluid dynamics)” page on Wikipedia. The
+best results precision and performance-wise are obtained by using a beta
+of 0 and a low tolerance criteria value.</p>
+<p>The default and recommended value is 0.0.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.setFluidPressureModulation">
+<tt class="descname">setFluidPressureModulation</tt><big>(</big><em>A</em>, <em>f</em>, <em>phi=0.0</em><big>)</big><a class="headerlink" href="#sphere.sim.setFluidPressureModulation" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the parameters for the sine wave modulating the fluid pressures
+at the top boundary. Note that a cos-wave is obtained with phi=pi/2.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>A</strong> (<em>float</em>) – Fluctuation amplitude [Pa]</li>
+<li><strong>f</strong> (<em>float</em>) – Fluctuation frequency [Hz]</li>
+<li><strong>phi</strong> (<em>float</em>) – Fluctuation phase shift (default=0.0)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See also: <a class="reference internal" href="#sphere.sim.disableFluidPressureModulation" title="sphere.sim.disableFluidPressureModulation"><tt class="xref py py-func docutils literal"><span class="pre">disableFluidPressureModulation()</span></tt></a></p>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.setGamma">
+<tt class="descname">setGamma</tt><big>(</big><em>gamma</em><big>)</big><a class="headerlink" href="#sphere.sim.setGamma" title="Permalink to this definition">¶</a></dt>
+<dd><p>Gamma is a fluid solver parameter, used for smoothing the pressure
+values. The epsilon (pressure) values are smoothed by including the
+average epsilon value of the six closest (face) neighbor cells. This
+parameter should be in the range [0.0;1.0[. The higher the value, the
+more averaging is introduced. A value of 0.0 disables all averaging.</p>
+<p>The default and recommended value is 0.5.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>theta</strong> (<em>float</em>) – The smoothing parameter value</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.setMaxIterations">
+<tt class="descname">setMaxIterations</tt><big>(</big><em>maxiter</em><big>)</big><a class="headerlink" href="#sphere.sim.setMaxIterations" title="Permalink to this definition">¶</a></dt>
+<dd><p>A fluid solver parameter, the value of the maxiter parameter denotes the
+maximal allowed number of fluid solver iterations before ending the
+fluid solver loop prematurely. The residual values are at that point not
+fulfilling the tolerance criteria. The parameter is included to avoid
+infinite hangs.</p>
+<p>The default and recommended value is 1e4.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>maxiter</strong> (<em>int</em>) – The maximum number of Jacobi iterations in the fluid
+solver</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.setTheta">
+<tt class="descname">setTheta</tt><big>(</big><em>theta</em><big>)</big><a class="headerlink" href="#sphere.sim.setTheta" title="Permalink to this definition">¶</a></dt>
+<dd><p>Theta is a fluid solver under-relaxation parameter, used in solution of
+Poisson equation. The value should be within the range ]0.0;1.0]. At a
+value of 1.0, the new estimate of epsilon values is used exclusively. At
+lower values, a linear interpolation between new and old values is used.
+The solution typically converges faster with a value of 1.0, but
+instabilities may be avoided with lower values.</p>
+<p>The default and recommended value is 1.0.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>theta</strong> (<em>float</em>) – The under-relaxation parameter value</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.setTolerance">
+<tt class="descname">setTolerance</tt><big>(</big><em>tolerance</em><big>)</big><a class="headerlink" href="#sphere.sim.setTolerance" title="Permalink to this definition">¶</a></dt>
+<dd><p>A fluid solver parameter, the value of the tolerance parameter denotes
+the required value of the maximum normalized residual for the fluid
+solver.</p>
+<p>The default and recommended value is 1.0e-8.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>tolerance</strong> (<em>float</em>) – The tolerance criteria for the maximal normalized
+residual</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.shear">
+<tt class="descname">shear</tt><big>(</big><em>shear_strain_rate=1.0</em><big>)</big><a class="headerlink" href="#sphere.sim.shear" title="Permalink to this definition">¶</a></dt>
+<dd><p>Setup shear experiment. The shear strain rate is the shear velocity
+divided by the initial height per second. The shear movement is along
+the positive x axis. The function zeroes the tangential wall viscosity
+(gamma_wt) and the wall friction coefficients (mu_ws, mu_wn).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>shear_strain_rate</strong> (<em>float</em>) – The shear strain rate to use.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.shearStrain">
+<tt class="descname">shearStrain</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.shearStrain" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calculates and returns the current shear strain (gamma) value of the
+experiment. The shear strain is found by determining the total x-axis
+displacement of the upper, fixed particles.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The total shear strain [-]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.shearVel">
+<tt class="descname">shearVel</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.shearVel" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calculates and returns the shear velocity (gamma_dot) of the
+experiment. The shear velocity is the x-axis velocity value of the
+upper particles.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The shear velocity applied by the upper, fixed particles [m/s]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.sheardisp">
+<tt class="descname">sheardisp</tt><big>(</big><em>graphics_format='pdf'</em>, <em>zslices=32</em><big>)</big><a class="headerlink" href="#sphere.sim.sheardisp" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plot the particle x-axis displacement against the original vertical
+particle position. The plot is saved in the current directory with the
+file name ‘<simulation id>-sheardisp.<graphics_format>’.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>graphics_format</strong> (<em>str</em>) – Save the plot in this format</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.status">
+<tt class="descname">status</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.status" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the current simulation status by using the simulation id
+(<tt class="docutils literal"><span class="pre">sid</span></tt>) as an identifier.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The number of the last output file written</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">int</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.thinsection_x1x3">
+<tt class="descname">thinsection_x1x3</tt><big>(</big><em>x2='center'</em>, <em>graphics_format='png'</em>, <em>cbmax=None</em>, <em>arrowscale=0.01</em>, <em>velarrowscale=1.0</em>, <em>slipscale=1.0</em>, <em>verbose=False</em><big>)</big><a class="headerlink" href="#sphere.sim.thinsection_x1x3" title="Permalink to this definition">¶</a></dt>
+<dd><p>Produce a 2D image of particles on a x1,x3 plane, intersecting the
+second axis at x2. Output is saved as ‘<sid>-ts-x1x3.txt’ in the
+current folder.</p>
+<p>An upper limit to the pressure color bar range can be set by the
+cbmax parameter.</p>
<dl class="docutils">
<dt>The data can be plotted in gnuplot with:</dt>
<dd>gnuplot> set size ratio -1
gnuplot> set palette defined (0 “blue”, 0.5 “gray”, 1 “red”)
-gnuplot> plot ‘<sid>-ts-x1x3.txt’ with circles palette fs transparent solid 0.4 noborder</dd>
+gnuplot> plot ‘<sid>-ts-x1x3.txt’ with circles palette fs transparent solid 0.4 noborder</dd>
</dl>
+<p>This function also saves a plot of the inter-particle slip angles.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>x2</strong> (<em>foat</em>) – The position along the second axis of the intersecting plane</li>
+<li><strong>graphics_format</strong> (<em>str</em>) – Save the slip angle plot in this format</li>
+<li><strong>cbmax</strong> (<em>float</em>) – The maximal value of the pressure color bar range</li>
+<li><strong>arrowscale</strong> (<em>float</em>) – Scale the rotational arrows by this value</li>
+<li><strong>velarrowscale</strong> (<em>float</em>) – Scale the translational arrows by this value</li>
+<li><strong>slipscale</strong> (<em>float</em>) – Scale the slip arrows by this value</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show function output during calculations</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.torqueScript">
-<tt class="descname">torqueScript</tt><big>(</big><em>email='adc@geo.au.dk'</em>, <em>email_alerts='ae'</em>, <em>walltime='24:00:00'</em>, <em>queue='qfermi'</em>, <em>cudapath='/com/cuda/4.0.17/cuda'</em>, <em>spheredir='/home/adc/code/sphere'</em>, <em>workdir='/scratch'</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.torqueScript" title="Permalink to this definition">¶</a></dt>
-<dd><p>Create job script for the Torque queue manager for the binary</p>
+<dt id="sphere.sim.torqueScript">
+<tt class="descname">torqueScript</tt><big>(</big><em>email='adc@geo.au.dk'</em>, <em>email_alerts='ae'</em>, <em>walltime='24:00:00'</em>, <em>queue='qfermi'</em>, <em>cudapath='/com/cuda/4.0.17/cuda'</em>, <em>spheredir='/home/adc/code/sphere'</em>, <em>use_workdir=False</em>, <em>workdir='/scratch'</em><big>)</big><a class="headerlink" href="#sphere.sim.torqueScript" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates a job script for the Torque queue manager for the simulation
+object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>email</strong> (<em>str</em>) – The e-mail address that Torque messages should be sent to</li>
+<li><strong>email_alerts</strong> (<em>str</em>) – The type of Torque messages to send to the e-mail
+address. The character ‘b’ causes a mail to be sent when the
+execution begins. The character ‘e’ causes a mail to be sent when
+the execution ends normally. The character ‘a’ causes a mail to be
+sent if the execution ends abnormally. The characters can be written
+in any order.</li>
+<li><strong>walltime</strong> (<em>str</em>) – The maximal allowed time for the job, in the format
+‘HH:MM:SS’.</li>
+<li><strong>queue</strong> (<em>str</em>) – The Torque queue to schedule the job for</li>
+<li><strong>cudapath</strong> (<em>str</em>) – The path of the CUDA library on the cluster compute
+nodes</li>
+<li><strong>spheredir</strong> (<em>str</em>) – The path to the root directory of sphere on the
+cluster</li>
+<li><strong>use_workdir</strong> (<em>bool</em>) – Use a different working directory than the sphere
+folder</li>
+<li><strong>workdir</strong> (<em>str</em>) – The working directory during the calculations, if
+<cite>use_workdir=True</cite></li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.uniaxialStrainRate">
-<tt class="descname">uniaxialStrainRate</tt><big>(</big><em>wvel=-0.001</em>, <em>periodic=1</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.uniaxialStrainRate" title="Permalink to this definition">¶</a></dt>
-<dd><p>Setup consolidation experiment. Specify the upper wall
-velocity in m/s, default value is -0.001 m/s (i.e. downwards).</p>
+<dt id="sphere.sim.totalMomentum">
+<tt class="descname">totalMomentum</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.totalMomentum" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the sum of particle momentums.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The sum of particle momentums (m*v) [N*s]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.voidRatio">
-<tt class="descname">voidRatio</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.Spherebin.voidRatio" title="Permalink to this definition">¶</a></dt>
-<dd><p>Returns the current void ratio</p>
+<dt id="sphere.sim.triaxial">
+<tt class="descname">triaxial</tt><big>(</big><em>wvel=-0.001</em>, <em>normal_stress=10000.0</em><big>)</big><a class="headerlink" href="#sphere.sim.triaxial" title="Permalink to this definition">¶</a></dt>
+<dd><p>Setup triaxial experiment. The upper wall is moved at a fixed velocity
+in m/s, default values is -0.001 m/s (i.e. downwards). The side walls
+are exerting a defined normal stress.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>wvel</strong> (<em>float</em>) – Upper wall velocity. Negative values mean that the wall
+moves downwards.</li>
+<li><strong>normal_stress</strong> (<em>float</em>) – The normal stress to apply from the upper wall.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.writebin">
-<tt class="descname">writebin</tt><big>(</big><em>folder='../input/'</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.Spherebin.writebin" title="Permalink to this definition">¶</a></dt>
-<dd><p>Writes to a target SPHERE binary file</p>
+<dt id="sphere.sim.uniaxialStrainRate">
+<tt class="descname">uniaxialStrainRate</tt><big>(</big><em>wvel=-0.001</em><big>)</big><a class="headerlink" href="#sphere.sim.uniaxialStrainRate" title="Permalink to this definition">¶</a></dt>
+<dd><p>Setup consolidation experiment. Specify the upper wall velocity in m/s,
+default value is -0.001 m/s (i.e. downwards).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>wvel</strong> (<em>float</em>) – Upper wall velocity. Negative values mean that the wall
+moves downwards.</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="method">
-<dt id="sphere.Spherebin.zeroKinematics">
-<tt class="descname">zeroKinematics</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.Spherebin.zeroKinematics" title="Permalink to this definition">¶</a></dt>
-<dd><p>Zero kinematics of particles</p>
+<dt id="sphere.sim.video">
+<tt class="descname">video</tt><big>(</big><em>out_folder='./'</em>, <em>video_format='mp4'</em>, <em>graphics_folder='../img_out/'</em>, <em>graphics_format='png'</em>, <em>fps=25</em>, <em>qscale=1</em>, <em>bitrate=1800</em>, <em>verbose=False</em><big>)</big><a class="headerlink" href="#sphere.sim.video" title="Permalink to this definition">¶</a></dt>
+<dd><p>Uses ffmpeg to combine images to animation. All images should be
+rendered beforehand using func:<cite>render()</cite>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>out_folder</strong> (<em>str</em>) – The output folder for the video file</li>
+<li><strong>video_format</strong> (<em>str</em>) – The format of the output video</li>
+<li><strong>graphics_folder</strong> (<em>str</em>) – The folder containing the rendered images</li>
+<li><strong>graphics_format</strong> (<em>str</em>) – The format of the rendered images</li>
+<li><strong>fps</strong> (<em>int</em>) – The number of frames per second to use in the video</li>
+<li><strong>qscale</strong> (<em>float</em>) – The output video quality, in ]0;1]</li>
+<li><strong>bitrate</strong> (<em>int</em>) – The bitrate to use in the output video</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show ffmpeg output</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
+<dl class="method">
+<dt id="sphere.sim.voidRatio">
+<tt class="descname">voidRatio</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.voidRatio" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calculates the current void ratio</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">The void ratio, in [0:1]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="function">
-<dt id="sphere.V_sphere">
-<tt class="descclassname">sphere.</tt><tt class="descname">V_sphere</tt><big>(</big><em>r</em><big>)</big><a class="headerlink" href="#sphere.V_sphere" title="Permalink to this definition">¶</a></dt>
-<dd><p>Returns the volume of a sphere with radius r</p>
+<dl class="method">
+<dt id="sphere.sim.writeFluidVTK">
+<tt class="descname">writeFluidVTK</tt><big>(</big><em>folder='../output/'</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.writeFluidVTK" title="Permalink to this definition">¶</a></dt>
+<dd><p>Writes a VTK file for the fluid grid to the <tt class="docutils literal"><span class="pre">../output/</span></tt> folder by
+default. The file name will be in the format <tt class="docutils literal"><span class="pre">fluid-<self.sid>.vti</span></tt>.
+The vti files can be used for visualizing the fluid in ParaView.</p>
+<p>The fluid grid is visualized by opening the vti files, and pressing
+“Apply” to import all fluid field properties. To visualize the scalar
+fields, such as the pressure, the porosity, the porosity change or the
+velocity magnitude, choose “Surface” or “Surface With Edges” as the
+“Representation”. Choose the desired property as the “Coloring” field.
+It may be desirable to show the color bar by pressing the “Show” button,
+and “Rescale” to fit the color range limits to the current file. The
+coordinate system can be displayed by checking the “Show Axis” field.
+All adjustments by default require the “Apply” button to be pressed
+before regenerating the view.</p>
+<p>The fluid vector fields (e.g. the fluid velocity) can be visualizing by
+e.g. arrows. To do this, select the fluid data in the “Pipeline
+Browser”. Press “Glyph” from the “Common” toolbar, or go to the
+“Filters” mennu, and press “Glyph” from the “Common” list. Make sure
+that “Arrow” is selected as the “Glyph type”, and “Velocity” as the
+“Vectors” value. Adjust the “Maximum Number of Points” to be at least as
+big as the number of fluid cells in the grid. Press “Apply” to visualize
+the arrows.</p>
+<p>If several data files are generated for the same simulation (e.g. using
+the <a class="reference internal" href="#sphere.sim.writeVTKall" title="sphere.sim.writeVTKall"><tt class="xref py py-func docutils literal"><span class="pre">writeVTKall()</span></tt></a> function), it is able to step the
+visualization through time by using the ParaView controls.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>folder</strong> (<em>str</em>) – The folder where to place the output binary file (default
+(default = ‘../output/’)</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show diagnostic information (default = True)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="function">
-<dt id="sphere.cleanup">
-<tt class="descclassname">sphere.</tt><tt class="descname">cleanup</tt><big>(</big><em>spherebin</em><big>)</big><a class="headerlink" href="#sphere.cleanup" title="Permalink to this definition">¶</a></dt>
-<dd><p>Remove input/output files and images from simulation</p>
+<dl class="method">
+<dt id="sphere.sim.writeVTK">
+<tt class="descname">writeVTK</tt><big>(</big><em>folder='../output/'</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.writeVTK" title="Permalink to this definition">¶</a></dt>
+<dd><p>Writes a VTK file with particle information to the <tt class="docutils literal"><span class="pre">../output/</span></tt> folder
+by default. The file name will be in the format <tt class="docutils literal"><span class="pre"><self.sid>.vtu</span></tt>.
+The vtu files can be used to visualize the particles in ParaView.</p>
+<p>After opening the vtu files, the particle fields will show up in the
+“Properties” list. Press “Apply” to import all fields into the ParaView
+session. The particles are visualized by selecting the imported data in
+the “Pipeline Browser”. Afterwards, click the “Glyph” button in the
+“Common” toolbar, or go to the “Filters” menu, and press “Glyph” from
+the “Common” list. Choose “Sphere” as the “Glyph Type”, set “Radius” to
+1.0, choose “scalar” as the “Scale Mode”. Check the “Edit” checkbox, and
+set the “Set Scale Factor” to 1.0. The field “Maximum Number of Points”
+may be increased if the number of particles exceed the default value.
+Finally press “Apply”, and the particles will appear in the main window.</p>
+<p>The sphere resolution may be adjusted (“Theta resolution”, “Phi
+resolution”) to increase the quality and the computational requirements
+of the rendering. All adjustments by default require the “Apply” button
+to be pressed before regenerating the view.</p>
+<p>If several vtu files are generated for the same simulation (e.g. using
+the :func:<tt class="docutils literal"><span class="pre">writeVTKall()</span></tt> function), it is able to step the
+visualization through time by using the ParaView controls.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>folder</strong> (<em>str</em>) – The folder where to place the output binary file (default
+(default = ‘../output/’)</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show diagnostic information (default = True)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="function">
-<dt id="sphere.convert">
-<tt class="descclassname">sphere.</tt><tt class="descname">convert</tt><big>(</big><em>graphicsformat='png'</em>, <em>folder='../img_out'</em><big>)</big><a class="headerlink" href="#sphere.convert" title="Permalink to this definition">¶</a></dt>
-<dd><p>Converts all PPM images in img_out to graphicsformat, using ImageMagick</p>
+<dl class="method">
+<dt id="sphere.sim.writeVTKall">
+<tt class="descname">writeVTKall</tt><big>(</big><em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.writeVTKall" title="Permalink to this definition">¶</a></dt>
+<dd><p>Writes a VTK file for each simulation output file with particle
+information and the fluid grid to the <tt class="docutils literal"><span class="pre">../output/</span></tt> folder by default.
+The file name will be in the format <tt class="docutils literal"><span class="pre"><self.sid>.vtu</span></tt> and
+<tt class="docutils literal"><span class="pre">fluid-<self.sid>.vti</span></tt>. The vtu files can be used to visualize the
+particles, and the vti files for visualizing the fluid in ParaView.</p>
+<p>After opening the vtu files, the particle fields will show up in the
+“Properties” list. Press “Apply” to import all fields into the ParaView
+session. The particles are visualized by selecting the imported data in
+the “Pipeline Browser”. Afterwards, click the “Glyph” button in the
+“Common” toolbar, or go to the “Filters” menu, and press “Glyph” from
+the “Common” list. Choose “Sphere” as the “Glyph Type”, set “Radius” to
+1.0, choose “scalar” as the “Scale Mode”. Check the “Edit” checkbox, and
+set the “Set Scale Factor” to 1.0. The field “Maximum Number of Points”
+may be increased if the number of particles exceed the default value.
+Finally press “Apply”, and the particles will appear in the main window.</p>
+<p>The sphere resolution may be adjusted (“Theta resolution”, “Phi
+resolution”) to increase the quality and the computational requirements
+of the rendering.</p>
+<p>The fluid grid is visualized by opening the vti files, and pressing
+“Apply” to import all fluid field properties. To visualize the scalar
+fields, such as the pressure, the porosity, the porosity change or the
+velocity magnitude, choose “Surface” or “Surface With Edges” as the
+“Representation”. Choose the desired property as the “Coloring” field.
+It may be desirable to show the color bar by pressing the “Show” button,
+and “Rescale” to fit the color range limits to the current file. The
+coordinate system can be displayed by checking the “Show Axis” field.
+All adjustments by default require the “Apply” button to be pressed
+before regenerating the view.</p>
+<p>The fluid vector fields (e.g. the fluid velocity) can be visualizing by
+e.g. arrows. To do this, select the fluid data in the “Pipeline
+Browser”. Press “Glyph” from the “Common” toolbar, or go to the
+“Filters” mennu, and press “Glyph” from the “Common” list. Make sure
+that “Arrow” is selected as the “Glyph type”, and “Velocity” as the
+“Vectors” value. Adjust the “Maximum Number of Points” to be at least as
+big as the number of fluid cells in the grid. Press “Apply” to visualize
+the arrows.</p>
+<p>If several data files are generated for the same simulation (e.g. using
+the <a class="reference internal" href="#sphere.sim.writeVTKall" title="sphere.sim.writeVTKall"><tt class="xref py py-func docutils literal"><span class="pre">writeVTKall()</span></tt></a> function), it is able to step the
+visualization through time by using the ParaView controls.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>verbose</strong> (<em>bool</em>) – Show diagnostic information (default = True)</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="function">
-<dt id="sphere.render">
-<tt class="descclassname">sphere.</tt><tt class="descname">render</tt><big>(</big><em>binary</em>, <em>method='pres'</em>, <em>max_val=1000.0</em>, <em>lower_cutoff=0.0</em>, <em>graphicsformat='png'</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.render" title="Permalink to this definition">¶</a></dt>
-<dd><p>Render target binary using the sphere raytracer.</p>
+<dl class="method">
+<dt id="sphere.sim.writebin">
+<tt class="descname">writebin</tt><big>(</big><em>folder='../input/'</em>, <em>verbose=True</em><big>)</big><a class="headerlink" href="#sphere.sim.writebin" title="Permalink to this definition">¶</a></dt>
+<dd><p>Writes a <tt class="docutils literal"><span class="pre">sphere</span></tt> binary file to the <tt class="docutils literal"><span class="pre">../input/</span></tt> folder by default.
+The file name will be in the format <tt class="docutils literal"><span class="pre"><self.sid>.bin</span></tt>.</p>
+<p>See also <a class="reference internal" href="#sphere.sim.readbin" title="sphere.sim.readbin"><tt class="xref py py-func docutils literal"><span class="pre">readbin()</span></tt></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>folder</strong> (<em>str</em>) – The folder where to place the output binary file</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show diagnostic information (default = True)</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sphere.sim.zeroKinematics">
+<tt class="descname">zeroKinematics</tt><big>(</big><big>)</big><a class="headerlink" href="#sphere.sim.zeroKinematics" title="Permalink to this definition">¶</a></dt>
+<dd><p>Zero all kinematic parameters of the particles. This function is useful
+when output from one simulation is reused in another simulation.</p>
</dd></dl>
-<dl class="function">
-<dt id="sphere.run">
-<tt class="descclassname">sphere.</tt><tt class="descname">run</tt><big>(</big><em>binary</em>, <em>verbose=True</em>, <em>hideinputfile=False</em><big>)</big><a class="headerlink" href="#sphere.run" title="Permalink to this definition">¶</a></dt>
-<dd><p>Execute sphere with target binary as input</p>
</dd></dl>
<dl class="function">
<dt id="sphere.status">
<tt class="descclassname">sphere.</tt><tt class="descname">status</tt><big>(</big><em>project</em><big>)</big><a class="headerlink" href="#sphere.status" title="Permalink to this definition">¶</a></dt>
-<dd><p>Check the status.dat file for the target project,
-and return the last file numer.</p>
+<dd><p>Check the status.dat file for the target project, and return the last output
+file number.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>project</strong> (<em>str</em>) – The simulation id of the target project</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">The last output file written in the simulation calculations</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">int</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="function">
<dt id="sphere.thinsectionVideo">
<tt class="descclassname">sphere.</tt><tt class="descname">thinsectionVideo</tt><big>(</big><em>project</em>, <em>out_folder='./'</em>, <em>video_format='mp4'</em>, <em>fps=25</em>, <em>qscale=1</em>, <em>bitrate=1800</em>, <em>verbose=False</em><big>)</big><a class="headerlink" href="#sphere.thinsectionVideo" title="Permalink to this definition">¶</a></dt>
-<dd><p>Use ffmpeg to combine thin section images to animation.
-This function will start off by rendering the images.</p>
+<dd><p>Uses ffmpeg to combine thin section images to an animation. This function
+will implicity render the thin section images beforehand.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>project</strong> (<em>str</em>) – The simulation id of the project to render</li>
+<li><strong>out_folder</strong> (<em>str</em>) – The output folder for the video file</li>
+<li><strong>video_format</strong> (<em>str</em>) – The format of the output video</li>
+<li><strong>fps</strong> (<em>int</em>) – The number of frames per second to use in the video</li>
+<li><strong>qscale</strong> (<em>float</em>) – The output video quality, in ]0;1]</li>
+<li><strong>bitrate</strong> (<em>int</em>) – The bitrate to use in the output video</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show ffmpeg output</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="function">
<dt id="sphere.torqueScriptParallel3">
-<tt class="descclassname">sphere.</tt><tt class="descname">torqueScriptParallel3</tt><big>(</big><em>obj1</em>, <em>obj2</em>, <em>obj3</em>, <em>email='adc@geo.au.dk'</em>, <em>email_alerts='ae'</em>, <em>walltime='24:00:00'</em>, <em>queue='qfermi'</em>, <em>cudapath='/com/cuda/4.0.17/cuda'</em>, <em>spheredir='/home/adc/code/sphere'</em>, <em>workdir='/scratch'</em><big>)</big><a class="headerlink" href="#sphere.torqueScriptParallel3" title="Permalink to this definition">¶</a></dt>
+<tt class="descclassname">sphere.</tt><tt class="descname">torqueScriptParallel3</tt><big>(</big><em>obj1</em>, <em>obj2</em>, <em>obj3</em>, <em>email='adc@geo.au.dk'</em>, <em>email_alerts='ae'</em>, <em>walltime='24:00:00'</em>, <em>queue='qfermi'</em>, <em>cudapath='/com/cuda/4.0.17/cuda'</em>, <em>spheredir='/home/adc/code/sphere'</em>, <em>use_workdir=False</em>, <em>workdir='/scratch'</em><big>)</big><a class="headerlink" href="#sphere.torqueScriptParallel3" title="Permalink to this definition">¶</a></dt>
<dd><p>Create job script for the Torque queue manager for three binaries,
-executed in parallel.
-Returns the filename of the script</p>
+executed in parallel, ideally on three GPUs.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>email</strong> (<em>str</em>) – The e-mail address that Torque messages should be sent to</li>
+<li><strong>email_alerts</strong> (<em>str</em>) – The type of Torque messages to send to the e-mail
+address. The character ‘b’ causes a mail to be sent when the
+execution begins. The character ‘e’ causes a mail to be sent when
+the execution ends normally. The character ‘a’ causes a mail to be
+sent if the execution ends abnormally. The characters can be written
+in any order.</li>
+<li><strong>walltime</strong> (<em>str</em>) – The maximal allowed time for the job, in the format
+‘HH:MM:SS’.</li>
+<li><strong>queue</strong> (<em>str</em>) – The Torque queue to schedule the job for</li>
+<li><strong>cudapath</strong> (<em>str</em>) – The path of the CUDA library on the cluster compute nodes</li>
+<li><strong>spheredir</strong> (<em>str</em>) – The path to the root directory of sphere on the cluster</li>
+<li><strong>use_workdir</strong> (<em>bool</em>) – Use a different working directory than the sphere folder</li>
+<li><strong>workdir</strong> (<em>str</em>) – The working directory during the calculations, if
+<cite>use_workdir=True</cite></li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">The filename of the script</p>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">str</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>See also <tt class="xref py py-func docutils literal"><span class="pre">torqueScript()</span></tt></p>
</dd></dl>
<dl class="function">
-<dt id="sphere.torqueScriptSerial3">
-<tt class="descclassname">sphere.</tt><tt class="descname">torqueScriptSerial3</tt><big>(</big><em>obj1</em>, <em>obj2</em>, <em>obj3</em>, <em>email='adc@geo.au.dk'</em>, <em>email_alerts='ae'</em>, <em>walltime='24:00:00'</em>, <em>queue='qfermi'</em>, <em>cudapath='/com/cuda/4.0.17/cuda'</em>, <em>spheredir='/home/adc/code/sphere'</em>, <em>workdir='/scratch'</em><big>)</big><a class="headerlink" href="#sphere.torqueScriptSerial3" title="Permalink to this definition">¶</a></dt>
-<dd><p>Create job script for the Torque queue manager for three binaries</p>
+<dt id="sphere.vector_norm">
+<tt class="descclassname">sphere.</tt><tt class="descname">vector_norm</tt><big>(</big><em>ndvector</em><big>)</big><a class="headerlink" href="#sphere.vector_norm" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns a 1D vector of normalized values. The input array should have
+one row per particle, and three rows; one per Euclidean axis.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">A value of the velocity magnutude per particle</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">numpy.array</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="function">
<dt id="sphere.video">
<tt class="descclassname">sphere.</tt><tt class="descname">video</tt><big>(</big><em>project</em>, <em>out_folder='./'</em>, <em>video_format='mp4'</em>, <em>graphics_folder='../img_out/'</em>, <em>graphics_format='png'</em>, <em>fps=25</em>, <em>qscale=1</em>, <em>bitrate=1800</em>, <em>verbose=False</em><big>)</big><a class="headerlink" href="#sphere.video" title="Permalink to this definition">¶</a></dt>
-<dd><p>Use ffmpeg to combine images to animation. All images should be rendered beforehand.</p>
+<dd><p>Uses ffmpeg to combine images to animation. All images should be
+rendered beforehand using func:<cite>render()</cite>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>project</strong> (<em>str</em>) – The simulation id of the project to render</li>
+<li><strong>out_folder</strong> (<em>str</em>) – The output folder for the video file</li>
+<li><strong>video_format</strong> (<em>str</em>) – The format of the output video</li>
+<li><strong>graphics_folder</strong> (<em>str</em>) – The folder containing the rendered images</li>
+<li><strong>graphics_format</strong> (<em>str</em>) – The format of the rendered images</li>
+<li><strong>fps</strong> (<em>int</em>) – The number of frames per second to use in the video</li>
+<li><strong>qscale</strong> (<em>float</em>) – The output video quality, in ]0;1]</li>
+<li><strong>bitrate</strong> (<em>int</em>) – The bitrate to use in the output video</li>
+<li><strong>verbose</strong> (<em>bool</em>) – Show ffmpeg output</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
<dl class="function">
<dt id="sphere.visualize">
<tt class="descclassname">sphere.</tt><tt class="descname">visualize</tt><big>(</big><em>project</em>, <em>method='energy'</em>, <em>savefig=True</em>, <em>outformat='png'</em><big>)</big><a class="headerlink" href="#sphere.visualize" title="Permalink to this definition">¶</a></dt>
-<dd><p>Visualize output from the target project,
-where the temporal progress is of interest.</p>
+<dd><p>Visualize output from the target project, where the temporal progress is of
+interest. The output will be saved in the current folder with a name
+combining the simulation id of the project, and the visualization method.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>project</strong> (<em>str</em>) – The simulation id of the project to render</li>
+<li><strong>method</strong> (<em>str</em>) – The type of plot to render. Possible values are ‘energy’,
+‘walls’, ‘triaxial’ and ‘shear’</li>
+<li><strong>savefig</strong> (<em>bool</em>) – Save the image instead of showing it on screen</li>
+<li><strong>outformat</strong> – The output format of the plot data. This can be an image
+format, or in text (‘txt’).</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
</div>
+</div>
</div>
t@@ -408,12 +1890,18 @@ where the temporal progress is of interest.</p>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Python API</a><ul>
+<li><a class="reference internal" href="#sample-usage">Sample usage</a></li>
+<li><a class="reference internal" href="#module-sphere">The <tt class="docutils literal"><span class="pre">sphere</span></tt> module</a></li>
+</ul>
+</li>
+</ul>
+
<h4>Previous topic</h4>
- <p class="topless"><a href="dem.html"
- title="previous chapter">Discrete element method</a></p>
- <h4>Next topic</h4>
- <p class="topless"><a href="sphere_internals.html"
- title="next chapter">sphere internals</a></p>
+ <p class="topless"><a href="cfd.html"
+ title="previous chapter">Fluid simulation and particle-fluid interaction</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/python_api.txt"
t@@ -446,16 +1934,13 @@ where the temporal progress is of interest.</p>
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
- <a href="sphere_internals.html" title="sphere internals"
- >next</a> |</li>
- <li class="right" >
- <a href="dem.html" title="Discrete element method"
+ <a href="cfd.html" title="Fluid simulation and particle-fluid interaction"
>previous</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
<div class="footer">
- © Copyright 2012, Anders Damsgaard.
+ © Copyright 2014, Anders Damsgaard.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
DIR diff --git a/doc/html/search.html b/doc/html/search.html
t@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Search — sphere 0.35 documentation</title>
+ <title>Search — sphere 1.00-alpha documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
t@@ -17,7 +17,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
- VERSION: '0.35',
+ VERSION: '1.00-alpha',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
t@@ -27,10 +27,12 @@
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
- <link rel="top" title="sphere 0.35 documentation" href="index.html" />
+ <link rel="top" title="sphere 1.00-alpha documentation" href="index.html" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
+
+ <script type="text/javascript" id="searchindexloader"></script>
</head>
t@@ -44,7 +46,7 @@
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
t@@ -95,11 +97,11 @@
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
- <li><a href="index.html">sphere 0.35 documentation</a> »</li>
+ <li><a href="index.html">sphere 1.00-alpha documentation</a> »</li>
</ul>
</div>
<div class="footer">
- © Copyright 2012, Anders Damsgaard.
+ © Copyright 2014, Anders Damsgaard.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
DIR diff --git a/doc/html/searchindex.js b/doc/html/searchindex.js
t@@ -1 +1 @@
mx1.adamsgaard.dk:70 /src/sphere/commit/bc41fb46fe0b5458ac8c6573cc573f5000076528.gph:7897: line too long