Self-Organized Criticality Simulation (SocSim)¶
Self-Organized Criticality Simulation (SocSim)¶
Faculty of Physics. University of Warsaw
Documentation Status
Build Status
codecov
Project is created as part of subject: Team student projects Faculty of Physics
Programs in Python that simulate dynamical systems that have a critical point as an attractor. So called self-organized criticality(SOC)
1. Theoretical problem description¶
Self-organized criticality wiki:
In physics, self-organized criticality (SOC) is a property of dynamical systems that have a critical point as an attractor. Their macroscopic behavior thus displays the spatial or temporal scale-invariance characteristic of the critical point of a phase transition, but without the need to tune control parameters to a precise value, because the system, effectively, tunes itself as it evolves towards criticality.
The concept was put forward by Per Bak, Chao Tang and Kurt Wiesenfeld (“BTW”) in a paper published in 1987 in Physical Review Letters, and is considered to be one of the mechanisms by which complexity arises in nature. Its concepts have been enthusiastically applied across fields as diverse as geophysics, physical cosmology, evolutionary biology and ecology, bio-inspired computing and optimization (mathematics), economics, quantum gravity, sociology, solar physics, plasma physics, neurobiology and others.
SOC is typically observed in slowly driven non-equilibrium systems with a large number of degrees of freedom and strongly nonlinear dynamics. Many individual examples have been identified since BTW’s original paper, but to date there is no known set of general characteristics that guarantee a system will display SOC.
2. Program structure, installation and use cases¶
2.1 Project folder structure¶
Project folder structure is inspired by these sources: sources1 source2 and Kwant project.
socsim:¶
- docsrc - holds Sphinx scripts used for documentation generation.
- docs - GitHub configuration folder, which holds web-page of project.
- resource - Non executable files.
- results - folder used for holding results of simulation, Jupiter notebooks and different use cases.
- SOC - main project folder, which holds all source code.
- models - contains different SOC models, like: Abelian sandpile model, forest-fire model, etc..
- common - common code between all models
- tests - unit tests of code
2.2 Installation and dependencies¶
Dependencies¶
Mostly numerical libraries, visualsation, web page generation etc. For whole list take a look at requirements.txt
2.3 Use cases¶
Running program¶
Program is designed in next way:
- Framework part - placed under
SOCfolder. - Research part - consists of jupyter notebooks(which can be easily deployed to web-page) and is placed under
research folder
Developing the program¶
use python setup.py develop to install a basic set of dependencies and link the package to be importable in your current Python environment.
Running test cases¶
To make folder SOC an import package, run only once:
python setup.py develop
After that, simply use pytest SOC to automatically find and execute all existing test cases.
Web-page generation¶
Web page is generated using Sphinx library.
Under terminal enter into docsrc folder and type:
make html
Web-page will be generated into ./docsrc/build/html folder.
If you want to update web-page, copy generated web-page into /docs folder.
Summary of intial goals:¶
- Make wide coverage of all self-organized criticality models.
- Figuring out the best algorithms.
- Using some best practice of programming:
- Coding conventions
- Unit Tests.
- Creation of common modules.
- Automatic documentation generation.
- Readability of code and easy of use(between clarity and speed, we should choose clarity).
0.2 Commitments¶
Here are described code formatting style and other conventions, to make code more uniform. Also this section is for newcomers and contributors.
Unit Tests¶
SocSim uses the lovely PyTest for its unit testing needs. Tests are run automatically on every commit using TravisCI.
What’s next?¶
- How we can apply Keras? Predictions, finding hidden parameters, etc.
- More tests for the batch processes running (Dask)
- Convenient selection of different boundary conditions of a system (lattice)
- Parametrization of the earthquake model for the coverage of wider selection of submodels (by including eg.: drive with random loading, toppling to the neighbours in a specific state (crack model), delay of the fracture initiation, threshold for the fracture propagation) like in Lomnitz-Adler (1993)
- Database of the simulations
3. Links/References¶
- Bak, P., Tang, C. and Wiesenfeld, K. (1987). “Self-organized criticality: an explanation of 1/f noise”. Physical Review Letters. 59 (4): 381–384. Bibcode:1987PhRvL..59..381B. doi:10.1103/PhysRevLett.59.381. PMID 10035754. Papercore summary: http://papercore.org/Bak1987.
- Abelian sandpile model
- Forest-fire model
- Theoretical Models of Self-Organized Criticality (SOC) Systems
- Pink noise
- Introduction to Self-Organized Criticality & Earthquakes
- 25 Years of Self-Organized Criticality: Solar and Astrophysics
- SOC computer simulations
- Theoretical Models of SOC Systems
Manna model¶
The Manna model is similar in concept to the BTW model. However, where BTW dissipates its “sand grains” deterministically, the Manna model introduces some randomness. Let’s take a look:
[3]:
from SOC import Manna
model = Manna(L=3, save_every=1)
model.critical_value
[3]:
1
This means that the model begins toppling its “sandpiles” once we put two grains somewhere. Let’s try that:
[20]:
model = Manna(L=3, save_every=1)
model.values[2,2] = 2
model.plot_state(with_boundaries=True);
model.AvalancheLoop()
model.plot_state(with_boundaries=True);
Why these two target locations in particular? It actually is random! Let’s rerun that:
[21]:
model = Manna(L=3, save_every=1)
model.values[2,2] = 2
model.plot_state(with_boundaries=True);
model.AvalancheLoop()
model.plot_state(with_boundaries=True);
[22]:
model = Manna(L=3, save_every=1)
model.values[2,2] = 2
model.plot_state(with_boundaries=True);
model.AvalancheLoop()
model.plot_state(with_boundaries=True);
Oh, that’s a bit weird, isn’t it? These seem to have moved awfully far. The trick is that the two grains that fall from the toppling location pick their location at random independently, and here they both picked (1, 1) at first.
Let’s run it for some more time:
[25]:
model = Manna(L=5, save_every=1)
model.run(1000)
model.animate_states(notebook=True)
Waiting for wait_for_n_iters=10 iterations before collecting data. This should let the system thermalize.
Let’s run a larger simulation instead:
[37]:
model = Manna(L=10, save_every=1)
model.run(1000)
model.animate_states(notebook=True)
Waiting for wait_for_n_iters=10 iterations before collecting data. This should let the system thermalize.
If you look closely, you’ll see that the system begins to exhibit very large avalanches very soon:
[38]:
model.data_df.AvalancheSize.plot()
[38]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2828870050>
Let’s take a look at how modifying the critical value affects the simulation. We’ll do some more iterations, so the system has the opportunity to “fill up” better. We’ll also skip some animation frames.
[47]:
model = Manna(L=10, critical_value=4, save_every=10)
model.run(5000, wait_for_n_iters = 1000)
model.animate_states(notebook=True)
Waiting for wait_for_n_iters=1000 iterations before collecting data. This should let the system thermalize.
[48]:
model.data_df.AvalancheSize.plot()
[48]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f281fc7fb90>
Note how the avalanche size grows until a certain period, and then starts to fluctuate randomly at pretty large values. We can try to investigate the histogram of those avalanche sizes. We’ll also fit a line to the linear segment (picked purely subjectively, visually and heuristically).
[53]:
model.get_exponent(low=5, high=20)
y = 3117.481 exp(-1.5522 x)
[53]:
{'exponent': -1.552219845297347, 'intercept': 3.4938038036304393}
One thing for sure, there is a region where the scaling in log-log scale is linear. The line fits rather well.
Let’s run a larger simulation and try to estimate the scaling exponent. We’ll wait for a good while so that the system can thermalize well:
[61]:
model = Manna(L=40, save_every=100)
model.run(100000, wait_for_n_iters=50000)
Waiting for wait_for_n_iters=50000 iterations before collecting data. This should let the system thermalize.
[62]:
model.animate_states(notebook=True)
power-law
mannaexample
ofcexample