SPH
|
The code does not store particle data globally. The class Storage is used to store all quantities of particles used in the simulation. It also contains auxiliary data used by timestepping, etc.
Quantities are stored in structure-of-arrays layout. For each quantity, there is 1-3 arrays (depending on the number of derivatives) containing the quantity values and derivatives for each particle.
Class Quantity stored arrays of single quantity, containing values and derivatives of given quantity for all particles. Usually, it is not needed to manipulate with Quantity object directly, as the stored buffers can be accessed through Storage.
Quantity has order, specified by OrderEnum. Zero order means the quantity only store values, first order means the quantity also contains first derivatives and second order is for quantities containing first and second derivatives. The order of quantities is important for timestepping algorithms. To properly integrate a physical quantity in time, it is only necessary to fill the derivatives with computed values and the timestepping will do the integration. Zero-order quantities are not modified by the timestepping. That does not necessarily mean they are constant in time; they can be computed from other quantities (for example pressure is computed from equation of state) or they can be evolved by direct summation over neighbouring particles instead of by evolutionary equation (for example density when SummationSolver is used).
When accessing the buffer, it is necessary to specify the type of the buffer. This is usually not an issue, since the component of the code creating the quantity is also the component accessing it, so the value type of the quantity is known. A generic access to quantity values is only exposed through Storage.
Contains quantity values and derivatives of the particles and material parameters. The quantities are stored as map QuantityId -> Quantity; every stored quantity is associated with unique ID.
Quantity data can be accessed using getters Storage::getValue, Storage::getDt, Storage::getD2t. To avoid many subsequent calls of getValue function, a variadic getter Storage::getValues exists, returning a static array of references to quantity values. There is currently to analogous function for derivatives. Lastly, to obtain all buffers associated with the quantity (values and all derivatives), you can use function Storage::getAll, returning a static array of references to the buffers. This is just a shortcut for calling getValue, getDt and getD2t with same parameters.
Storage also provides a way to iterate over all quantities in the storage and access the buffers without explicitly specifying the value type. This can be accomplished using function iterate. Function is indended to be used with C++14 generic lambdas to access and modify the buffers in generic way. Example of resizing all buffers in the storage:
Example of setting all second derivatives to zero:
Related function allow to iterate in a pair of storages at once, or pass particle positions together with quantity values into the functor, see iterate, iteratePair, iterateWithPositions documentations for details.
Few notes: