SPH
|
Container storing all quantities used within the simulations. More...
#include <Storage.h>
Public Types | |
enum class | IndicesFlag { INDICES_SORTED = 1 << 0 } |
enum class | ResizeFlag { KEEP_EMPTY_UNCHANGED = 1 << 0 } |
Options for the storage resize. More... | |
enum class | ValidFlag { COMPLETE = 1 << 0 } |
Public Member Functions | |
Storage () | |
Creates a storage with no material. More... | |
Storage (const SharedPtr< IMaterial > &material) | |
Initialize a storage with a material. More... | |
~Storage () | |
Storage (Storage &&other) | |
Storage & | operator= (Storage &&other) |
bool | has (const QuantityId key) const |
Checks if the storage contains quantity with given key. More... | |
template<typename TValue > | |
bool | has (const QuantityId key, const OrderEnum order) const |
Checks if the storage contains quantity with given key, value type and order. More... | |
Quantity & | getQuantity (const QuantityId key) |
Retrieves quantity with given key from the storage. More... | |
const Quantity & | getQuantity (const QuantityId key) const |
Retrieves quantity with given key from the storage, const version. More... | |
template<typename TValue > | |
StaticArray< Array< TValue > &, 3 > | getAll (const QuantityId key) |
Retrieves quantity buffers from the storage, given its key and value type. More... | |
template<typename TValue > | |
StaticArray< const Array< TValue > &, 3 > | getAll (const QuantityId key) const |
Retrieves quantity buffers from the storage, given its key and value type, const version. More... | |
template<typename TValue > | |
Array< TValue > & | getValue (const QuantityId key) |
Retrieves a quantity values from the storage, given its key and value type. More... | |
template<typename TValue > | |
const Array< TValue > & | getValue (const QuantityId key) const |
Retrieves a quantity values from the storage, given its key and value type. More... | |
template<typename TValue > | |
Array< TValue > & | getDt (const QuantityId key) |
Retrieves a quantity derivative from the storage, given its key and value type. More... | |
template<typename TValue > | |
const Array< TValue > & | getDt (const QuantityId key) const |
Retrieves a quantity derivative from the storage, given its key and value type, const version. More... | |
template<typename TValue > | |
Array< TValue > & | getD2t (const QuantityId key) |
Retrieves a quantity second derivative from the storage, given its key and value type. More... | |
template<typename TValue > | |
const Array< TValue > & | getD2t (const QuantityId key) const |
Retrieves a quantity second derivative from the storage, given its key and value type. More... | |
template<typename TValue , typename... TArgs> | |
auto | getValues (const QuantityId first, const QuantityId second, const TArgs... others) |
Retrieves an array of quantities from the key. More... | |
template<typename TValue , typename... TArgs> | |
auto | getValues (const QuantityId first, const QuantityId second, const TArgs... others) const |
Retrieves an array of quantities from the key, const version. More... | |
template<typename TValue > | |
Quantity & | insert (const QuantityId key, const OrderEnum order, const TValue &defaultValue) |
Creates a quantity in the storage, given its key, value type and order. More... | |
template<typename TValue > | |
Quantity & | insert (const QuantityId key, const OrderEnum order, Array< TValue > &&values) |
Creates a quantity in the storage, given array of values. More... | |
void | addDependent (const WeakPtr< Storage > &other) |
Registers a dependent storage. More... | |
MaterialView | getMaterial (const Size matIdx) const |
Returns an object containing a reference to given material. More... | |
MaterialView | getMaterialOfParticle (const Size particleIdx) const |
Returns material view for material of given particle. More... | |
void | setMaterial (const Size matIdx, const SharedPtr< IMaterial > &material) |
Modifies material with given index. More... | |
Interval | getRange (const QuantityId id, const Size matIdx) const |
Returns the bounding range of given quantity. More... | |
template<typename TValue > | |
Array< TValue > | getMaterialParams (const BodySettingsId param) const |
Returns the given material parameter for all materials in the storage. More... | |
bool | isHomogeneous (const BodySettingsId param) const |
Checks if the particles in the storage are homogeneous with respect to given parameter. More... | |
StorageSequence | getQuantities () |
Returns the sequence of quantities. More... | |
ConstStorageSequence | getQuantities () const |
Returns the sequence of quantities, const version. More... | |
void | propagate (const Function< void(Storage &storage)> &functor) |
Executes a given functor recursively for all dependent storages. More... | |
Size | getMaterialCnt () const |
Return the number of materials in the storage. More... | |
Size | getQuantityCnt () const |
Returns the number of stored quantities. More... | |
Size | getParticleCnt () const |
Returns the number of particles. More... | |
bool | empty () const |
Checks if the storage is empty, i.e. without particles. More... | |
void | merge (Storage &&other) |
Merges another storage into this object. More... | |
void | zeroHighestDerivatives () |
Sets all highest-level derivatives of quantities to zero. More... | |
Array< Size > | duplicate (ArrayView< const Size > idxs, const Flags< IndicesFlag > flags=EMPTY_FLAGS) |
Duplicates some particles in the storage. More... | |
void | remove (ArrayView< const Size > idxs, const Flags< IndicesFlag > flags=EMPTY_FLAGS) |
Removes specified particles from the storage. More... | |
void | removeAll () |
Removes all particles with all quantities (including materials) from the storage. More... | |
Storage | clone (const Flags< VisitorEnum > buffers) const |
Clones specified buffers of the storage. More... | |
void | resize (const Size newParticleCnt, const Flags< ResizeFlag > flags=EMPTY_FLAGS) |
Changes number of particles for all quantities stored in the storage. More... | |
void | swap (Storage &other, const Flags< VisitorEnum > flags) |
Swap quantities or given subset of quantities between two storages. More... | |
Outcome | isValid (const Flags< ValidFlag > flags=ValidFlag::COMPLETE) const |
Checks whether the storage is in valid state. More... | |
void | setUserData (SharedPtr< IStorageUserData > newData) |
Stores new user data into the storage. More... | |
SharedPtr< IStorageUserData > | getUserData () const |
Returns the stored user data. More... | |
Public Member Functions inherited from Noncopyable | |
Noncopyable ()=default | |
Noncopyable (const Noncopyable &)=delete | |
Noncopyable (Noncopyable &&)=default | |
Noncopyable & | operator= (const Noncopyable &)=delete |
Noncopyable & | operator= (Noncopyable &&)=default |
Container storing all quantities used within the simulations.
Storage provides a convenient way to store quantities, iterate over specified subset of quantities, modify quantities etc. Every quantity is a Quantity object and is identified by QuantityId key. The quantities are stored as key-value pairs; for every QuantityId there can be at most one Quantity stored.
Storage can contain scalar, vector, tensor and integer quantities. Every quantity can also have associated one or two derivatives. There is no constraint on quantity order or type for given QuantityId, i.e. as far as Storage object is concerned, one can create a QuantityId::ENERGY tensor quantity with second derivatives or integer quantity QuantityId::SOUND_SPEED. Different parts of the code require certain types for some quantities, though. Particle positions, QuantityId::POSITION, are mostly assumed to be vector quantities of second order. Inconsistency of types will cause an assert when encountered.
Storage can hold arbitrary number of materials, objects derived from IMaterial. In theory, every particle can have a different material (different equation of state, different rheology, ...). The storage can also exist with no material; this is a valid state, useful for situations where no material is necessary. A storage with material can be created using constructor Storage(AutoPtr<IMaterial>&& material). All particles subsequently added into the storage will have the material passed in the parameter of the constructor. Storage with multiple materials can then be created by merging the storage with another object, using function merge.
Storage is not thread-safe. If used in multithreaded context, any calls of member functions must be synchonized by the caller.
The following demostrates how to access the particle data:
When adding a new quantity into the storage, it is necessary to specify the type of the quantity and the number of derivatives using OrderEnum. Quantity can be either initialized by providing a single default value (used for all particles), or an array of values; see functions insert. To add arbitrary quantity, use:
In some cases, it is useful to read or modify all quantities in the storage, without the need to fetch them manually using getValue and related function. There are two different ways to iterate over quantities stored in storage. You can use the function getQuantities, which returns a range (pair of iterators) and thus allows to visit quantities in a for-loop:
This approach can be utilized to access properties of the quantities (as in the example above), clone quantities, etc. The downside is that we still need to know the value type to actually access the quantity values. To overcome this problem and access the quantity values in generic (type-agnostic) way, consider using the function iterate:
Note that arguments of the provided functor differ for each VisitorEnum.
|
strong |
|
strong |
|
strong |
|
default |
Creates a storage with no material.
Any call of getMaterial function will result in an assert.
Initialize a storage with a material.
All particles of the storage will have the same material. To create a heterogeneous storage, it is necessary to merge another storage object into this one, using merge function.
Definition at line 108 of file Storage.cpp.
|
default |
Storage::Storage | ( | Storage && | other | ) |
Definition at line 114 of file Storage.cpp.
Registers a dependent storage.
A dependent storage mirrors changes of particle counts. Every time new particles are added into the storage or when some particles are removed, the same action is performed on all (existing) dependent storages. However, no other action is handled this way, namely new quantities have to be added manually to all storages. Same goes for clearing the derivatives, changing materials, etc.
Note that the storage holds weak references, the dependent storages must be held in SharedPtr somewhere to keep the link.
Definition at line 339 of file Storage.cpp.
Storage Storage::clone | ( | const Flags< VisitorEnum > | buffers | ) | const |
Clones specified buffers of the storage.
Cloned (sub)set of buffers is given by flags. Cloned storage will have the same number of quantities and the order and types of quantities will match; if some buffer is excluded from cloning, it is simply left empty. Note that materials are NOT cloned, but rather shared with the parent storage. Modifying material parameters in cloned storage will also modify the parameters in the parent storage.
Definition at line 563 of file Storage.cpp.
Array< Size > Storage::duplicate | ( | ArrayView< const Size > | idxs, |
const Flags< IndicesFlag > | flags = EMPTY_FLAGS |
||
) |
Duplicates some particles in the storage.
New particles are added to an unspecified positions in the storage, copying all the quantities and materials from the source particles. Note that this is not intended to be used without further modifications of the newly created particles as we never want to create particle pairs; make sure to move the created particles to required positions and modify their quantities as needed. The function can be used to add new particles with materials already existing in the storage.
idxs | Indices of the particles to duplicate. |
Definition at line 674 of file Storage.cpp.
bool Storage::empty | ( | ) | const |
Checks if the storage is empty, i.e. without particles.
Definition at line 453 of file Storage.cpp.
StaticArray< Array< TValue > &, 3 > Storage::getAll | ( | const QuantityId | key | ) |
Retrieves quantity buffers from the storage, given its key and value type.
The stored quantity must be of type TValue, checked by assert. Quantity must already exist in the storage, checked by assert. To check whether the quantity is stored, use has() method.
Definition at line 163 of file Storage.cpp.
StaticArray< const Array< TValue > &, 3 > Storage::getAll | ( | const QuantityId | key | ) | const |
Retrieves quantity buffers from the storage, given its key and value type, const version.
Definition at line 177 of file Storage.cpp.
Array< TValue > & Storage::getD2t | ( | const QuantityId | key | ) |
Retrieves a quantity second derivative from the storage, given its key and value type.
The stored quantity must be of type TValue, checked by assert. Quantity must already exist in the storage and must be second order, checked by assert.
Definition at line 243 of file Storage.cpp.
const Array< TValue > & Storage::getD2t | ( | const QuantityId | key | ) | const |
Retrieves a quantity second derivative from the storage, given its key and value type.
The stored quantity must be of type TValue, checked by assert. Quantity must already exist in the storage and must be second order, checked by assert.
Definition at line 257 of file Storage.cpp.
Array< TValue > & Storage::getDt | ( | const QuantityId | key | ) |
Retrieves a quantity derivative from the storage, given its key and value type.
The stored quantity must be of type TValue, checked by assert. Quantity must already exist in the storage and must be first or second order, checked by assert.
Definition at line 217 of file Storage.cpp.
const Array< TValue > & Storage::getDt | ( | const QuantityId | key | ) | const |
Retrieves a quantity derivative from the storage, given its key and value type, const version.
Definition at line 231 of file Storage.cpp.
MaterialView Storage::getMaterial | ( | const Size | matIdx | ) | const |
Returns an object containing a reference to given material.
The object can also be used to iterate over indices of particles belonging to given material.
matIdx | Index of given material in storage. Materials are stored in unspecified order; to get material of given particle, use getMaterialOfParticle. |
Definition at line 366 of file Storage.cpp.
Size Storage::getMaterialCnt | ( | ) | const |
Return the number of materials in the storage.
Material indices from 0 to (getMaterialCnt() - 1) are valid input for getMaterialView function.
Definition at line 437 of file Storage.cpp.
MaterialView Storage::getMaterialOfParticle | ( | const Size | particleIdx | ) | const |
Returns material view for material of given particle.
Definition at line 372 of file Storage.cpp.
Array< TValue > Storage::getMaterialParams | ( | const BodySettingsId | param | ) | const |
Returns the given material parameter for all materials in the storage.
To get the material parameter for given particle, use the index given by material ID.
Definition at line 408 of file Storage.cpp.
Size Storage::getParticleCnt | ( | ) | const |
Returns the number of particles.
The number of particle is always the same for all quantities.
Definition at line 445 of file Storage.cpp.
StorageSequence Storage::getQuantities | ( | ) |
Returns the sequence of quantities.
Definition at line 416 of file Storage.cpp.
ConstStorageSequence Storage::getQuantities | ( | ) | const |
Returns the sequence of quantities, const version.
Definition at line 420 of file Storage.cpp.
Quantity & Storage::getQuantity | ( | const QuantityId | key | ) |
Retrieves quantity with given key from the storage.
Quantity must be already stored, checked by assert.
Definition at line 150 of file Storage.cpp.
const Quantity & Storage::getQuantity | ( | const QuantityId | key | ) | const |
Retrieves quantity with given key from the storage, const version.
Definition at line 156 of file Storage.cpp.
Size Storage::getQuantityCnt | ( | ) | const |
Returns the number of stored quantities.
Definition at line 441 of file Storage.cpp.
Interval Storage::getRange | ( | const QuantityId | id, |
const Size | matIdx | ||
) | const |
Returns the bounding range of given quantity.
Provides an easy access to the material range without construcing intermediate object of MaterialView, otherwise this function is equivalent to:
Definition at line 402 of file Storage.cpp.
SharedPtr< IStorageUserData > Storage::getUserData | ( | ) | const |
Returns the stored user data.
If no data are stored, the function returns nullptr.
Definition at line 828 of file Storage.cpp.
Array< TValue > & Storage::getValue | ( | const QuantityId | key | ) |
Retrieves a quantity values from the storage, given its key and value type.
The stored quantity must be of type TValue, checked by assert. Quantity must already exist in the storage, checked by assert.
Definition at line 191 of file Storage.cpp.
const Array< TValue > & Storage::getValue | ( | const QuantityId | key | ) | const |
Retrieves a quantity values from the storage, given its key and value type.
The stored quantity must be of type TValue, checked by assert. Quantity must already exist in the storage, checked by assert.
Definition at line 205 of file Storage.cpp.
|
inline |
|
inline |
bool Storage::has | ( | const QuantityId | key | ) | const |
Checks if the storage contains quantity with given key.
Type or order of unit is not specified, any quantity with this key will match.
Definition at line 130 of file Storage.cpp.
bool Storage::has | ( | const QuantityId | key, |
const OrderEnum | order | ||
) | const |
Checks if the storage contains quantity with given key, value type and order.
Definition at line 135 of file Storage.cpp.
Quantity & Storage::insert | ( | const QuantityId | key, |
const OrderEnum | order, | ||
Array< TValue > && | values | ||
) |
Creates a quantity in the storage, given array of values.
The size of the array must match the number of particles. Derivatives of the quantity are set to zero. If this is the first quantity inserted into the storage, it sets the number of particles; all quantities added after that must have the same size. If a quantity with the same key already exists in the storage, its values are overriden. Derivatives are not changed. In this case, the function checks that the quantity type is the same; if it isn't, InvalidSetup exception is thrown.
Definition at line 296 of file Storage.cpp.
Quantity & Storage::insert | ( | const QuantityId | key, |
const OrderEnum | order, | ||
const TValue & | defaultValue | ||
) |
Creates a quantity in the storage, given its key, value type and order.
Quantity is resized and filled with default value. This cannot be used to set number of particles, the size of the quantity is set to match current particle number. If the quantity is already stored in the storage, function only checks that the type of the quantity matches, but otherwise keeps the previously stored values. If the required order of quantity is larger than the one currently stored, additional derivatives are created with no assert nor exception, otherwise the order is unchanged.
TValue | Type of the quantity. Can be scalar, vector, tensor or traceless tensor. |
key | Unique key of the quantity. |
TOrder | Order (number of derivatives) associated with the quantity. |
defaultValue | Value to which quantity is initialized. If the quantity already exists in the storage, the value is unused. |
Definition at line 270 of file Storage.cpp.
bool Storage::isHomogeneous | ( | const BodySettingsId | param | ) | const |
Checks if the particles in the storage are homogeneous with respect to given parameter.
It is assumed that the parameter is scalar.
Definition at line 386 of file Storage.cpp.
Outcome Storage::isValid | ( | const Flags< ValidFlag > | flags = ValidFlag::COMPLETE | ) | const |
Checks whether the storage is in valid state.
The valid state means that all quantities have the same number of particles and materials are stored consecutively in the storage. This should be handled automatically, the function is mainly for debugging purposes.
Definition at line 609 of file Storage.cpp.
void Storage::merge | ( | Storage && | other | ) |
Merges another storage into this object.
The passed storage is moved in the process. All materials in the merged storage are conserved; particles will keep the materials they had before the merge. The merge is only allowed for storages that both have materials or neither have one. Merging a storage without a material into a storage with at least one material will result in assert. Similarly for merging a storage with materials into a storage without materials.
The function invalidates any reference or ArrayView to quantity values or derivatives. For this reason, storages can only be merged when setting up initial conditions or inbetween timesteps, never while evaluating solver!
Definition at line 472 of file Storage.cpp.
Definition at line 118 of file Storage.cpp.
Executes a given functor recursively for all dependent storages.
This storage is not visited, the functor is executed with child storages, grandchild storages, etc. If one of dependent storages expired (no shared pointer is currently holding it), it is removed from the list.
Definition at line 424 of file Storage.cpp.
void Storage::remove | ( | ArrayView< const Size > | idxs, |
const Flags< IndicesFlag > | flags = EMPTY_FLAGS |
||
) |
Removes specified particles from the storage.
If all particles of some material are removed by this, the material is also removed from the storage. Same particles are also removed from all dependent storages.
idxs | Indices of particles to remove. No need to sort the indices. |
Definition at line 756 of file Storage.cpp.
void Storage::removeAll | ( | ) |
Removes all particles with all quantities (including materials) from the storage.
The storage is left is a state as if it was default-constructed. Dependent storages are also cleared.
Definition at line 810 of file Storage.cpp.
void Storage::resize | ( | const Size | newParticleCnt, |
const Flags< ResizeFlag > | flags = EMPTY_FLAGS |
||
) |
Changes number of particles for all quantities stored in the storage.
If the new number of particles is larger than the current one, the quantities of the newly created particles are set to zero, regardless of the actual initial value. This is true for all quantity values and derivatives. Storage must already contain at least one quantity, checked by assert. All dependent storages are resized as well. Can be only used on storages with no material or storages with only a single material, checked by assert.
newParticleCnt | New number of particles. |
flags | Options of the resizing, see ResizeFlag enum. By default, all quantities are resized. |
Definition at line 579 of file Storage.cpp.
Modifies material with given index.
The new material cannot be nullptr.
Definition at line 377 of file Storage.cpp.
void Storage::setUserData | ( | SharedPtr< IStorageUserData > | newData | ) |
Stores new user data into the storage.
Previous user data are overriden.
Definition at line 824 of file Storage.cpp.
void Storage::swap | ( | Storage & | other, |
const Flags< VisitorEnum > | flags | ||
) |
Swap quantities or given subset of quantities between two storages.
Note that materials of the storages are NOT changed.
Definition at line 602 of file Storage.cpp.
void Storage::zeroHighestDerivatives | ( | ) |
Sets all highest-level derivatives of quantities to zero.
Other values are unchanged.
Definition at line 556 of file Storage.cpp.