This tutorial will introduce some useful features of the waLBerla framework which can make your life easier.
You can checkpoint the current state of your rigid body dynamics simulation at any point to restore it afterwards. First you have to store the current domain partitioning using blockforest::BlockForest::saveToFile().
Then you have to store the current simulation data using domain_decomposition::BlockStorage::saveBlockData().
This will store all non global rigid bodies to the file system.
To load everything again you start by creating the blockforest::BlockForest. This time you will use a different constructor.
Instead of initializing the Storage BlockDatum like you normally would
you have to use domain_decomposition::BlockStorage::loadBlockData()
Unfortunately due to a misorder in the loading scheme you have to reload your coarse collision detection.
Hopefully this gets fixed in the future. ;)
A fully working example can be found in the SerializeDeserialize.cpp test of the pe module.
Currently only spheres are supported for VTK output but you can easily write your own SphereVtkOutput and adapt it to the body you like.
To actually write something to disc call vtk::VTKOutput::write():
You can call this every time step if you want. The files will be automatically numbered so that ParaView can generate an animation.
To get values from the config call config::Config::getParameter():
Certain tasks already have predefined loading functions. You can for example directly create a BlockForest from the config file.
The corresponding block in the config file looks like:
Also the HardContact solver can be configured directly from the config file:
The config file looks like:
To get additional information where your application spends its time you can use the WcTimingTree. It will give you a hierarchical view of the time used. Usage example:
Before you output the information you should collect all the information from all the processes if you are running in parallel.
Many built-in functions like solver or synchronization methods come with an additional parameter where you can specify your timing tree. They will then include detailed information in your timing tree.
waLBerla also supports SQLite databases for simulation data output. This can come in handy in parallel simulations as well as in data analysis. To store information in a SQLite database you have to fill three property maps depending on the type of information you want to store.
You can then dump the information to disc. timing::TimingPool and timing::TimingTree already have predefined save functions so you do not have to extract all the information yourself and save it in the property array.
Using the pe::raytracing::Raytracer you can generate images of the simulation for each timestep and output them as PNG files. Setup the raytracer by reading a config object and optionally supply a shading and a visibility function, as it is done in the second pe tutorial. The shading function will be called during rendering for each body to apply user defined coloring to bodies, the visibility function to determine if a body should be visible or not.
Alternatively it may also be setup entirely in code:
After the configuration is done, images can be generated each timestep by calling Raytracer::generateImage<BodyTuple>() which will be output to the specified directory.
To hide certain bodies during rendering, the visibility function will be called with a BodyID as its sole argument and should return true if the object is supposed to be visible, false if not:
For an overview over predefined shading functions, visit the file ShadingFunctions.h. For further information see the documentation for the classes pe::raytracing::Raytracer, pe::raytracing::Lighting and pe::raytracing::Color, the pe::raytracing::ShadingParameters struct and ShadingFunctions.h file may also be useful.