SpECTRE
v2024.12.16
|
Documentation, functions, metafunctions, and classes necessary for using DataBox. More...
Namespaces | |
namespace | db |
Namespace for DataBox related things. | |
Classes | |
class | db::DataBox< tmpl::list< Tags... > > |
A DataBox stores objects that can be retrieved by using Tags. More... | |
struct | db::Subitems< Tag> |
Struct that can be specialized to allow DataBox items to have subitems. Specializations must define: More... | |
struct | db::SimpleTag |
Mark a struct as a simple tag by inheriting from this. More... | |
struct | db::BaseTag |
Mark a (usually) empty struct as a base tag by inheriting from this. More... | |
struct | db::PrefixTag |
Mark a struct as a prefix tag by inheriting from this. More... | |
struct | db::ComputeTag |
Mark a struct as a compute tag by inheriting from this. More... | |
struct | db::ReferenceTag |
Mark a struct as a reference tag by inheriting from this. More... | |
struct | db::is_compute_tag< Tag > |
Check if Tag derives off of db::ComputeTag. More... | |
struct | db::is_reference_tag< Tag > |
Check if Tag derives off of db::ReferenceTag. More... | |
struct | db::is_immutable_item_tag< Tag > |
Check if Tag is a DataBox tag for an immutable item, i.e. a ComputeTag or ReferenceTag. More... | |
struct | db::is_mutable_item_tag< Tag > |
Check if Tag is a DataBox tag for a mutable item, i.e. a SimpleTag. More... | |
struct | db::is_simple_tag< Tag > |
Check if Tag is a simple tag. More... | |
struct | db::is_non_base_tag< Tag > |
Check if Tag is not a base tag. More... | |
struct | db::is_tag< Tag > |
Check if Tag is a DataBox tag, i.e. a BaseTag, SimpleTag, ComputeTag, or ReferenceTag. More... | |
struct | db::is_base_tag< Tag > |
Check if Tag is a base DataBox tag. More... | |
Functions | |
template<typename... MutateTags, typename TagList , typename Invokable , typename... Args> | |
decltype(auto) | db::mutate (Invokable &&invokable, const gsl::not_null< DataBox< TagList > * > box, Args &&... args) |
Allows changing the state of one or more non-computed elements in the DataBox. More... | |
template<typename Tag , typename TagList > | |
const auto & | db::get (const DataBox< TagList > &box) |
Retrieve the item with tag Tag from the DataBox. More... | |
template<typename CopiedItemsTagList , typename DbTagList > | |
auto | db::copy_items (const DataBox< DbTagList > &box) |
Copy the items from the DataBox into a TaggedTuple. More... | |
template<typename Tag , typename TagList > | |
auto & | db::get_mutable_reference (const gsl::not_null< DataBox< TagList > * > box) |
Retrieve a mutable reference to the item with tag Tag from the DataBox. More... | |
template<typename AddMutableItemTags , typename AddImmutableItemTags = tmpl::list<>, typename... Args> | |
constexpr auto | db::create (Args &&... args) |
Create a new DataBox. More... | |
template<size_t VolumeDim, typename TagsList , typename... TagsToSlice> | |
Variables< tmpl::list< TagsToSlice... > > | db::data_on_slice (const db::DataBox< TagsList > &box, const Index< VolumeDim > &element_extents, const size_t sliced_dim, const size_t fixed_index, tmpl::list< TagsToSlice... >) |
Slices volume Tensor s from a DataBox into a Variables More... | |
template<typename Tag > | |
std::string | db::tag_name () |
Get the name of a DataBox tag, including prefixes. More... | |
template<typename MutateTagList , typename BoxTags , typename... Args> | |
constexpr void | Initialization::mutate_assign (const gsl::not_null< db::DataBox< BoxTags > * > box, Args &&... args) |
Perform a mutation to the DataBox box , assigning the args to the tags in MutateTagList in order. | |
Variables | |
template<typename Tag > | |
constexpr bool | db::is_compute_tag_v = is_compute_tag<Tag>::value |
True if Tag derives from db::ComputeTag. | |
template<typename Tag > | |
constexpr bool | db::is_reference_tag_v = is_reference_tag<Tag>::value |
True if Tag derives from db::ReferenceTag. | |
template<typename Tag > | |
constexpr bool | db::is_immutable_item_tag_v = is_immutable_item_tag<Tag>::value |
True if Tag is a DataBox tag for an immutable item, i.e. a ComputeTag or ReferenceTag. | |
template<typename Tag > | |
constexpr bool | db::is_mutable_item_tag_v = is_mutable_item_tag<Tag>::value |
True if Tag is a DataBox tag for a mutable item, i.e. a SimpleTag. | |
template<typename Tag > | |
constexpr bool | db::is_simple_tag_v = is_simple_tag<Tag>::value |
True if Tag is a simple tag. | |
template<typename Tag > | |
constexpr bool | db::is_non_base_tag_v = is_non_base_tag<Tag>::value |
True if Tag is not a base tag. | |
template<typename Tag > | |
constexpr bool | db::is_tag_v = is_tag<Tag>::value |
True if Tag is a DataBox tag. | |
template<typename Tag > | |
constexpr bool | db::is_base_tag_v = is_base_tag<Tag>::value |
True if Tag is a base tag. | |
template<typename Tag , typename DataBoxType > | |
using | db::tag_is_retrievable = implementation defined |
Equal to true if Tag can be retrieved from a DataBox of type DataBoxType . | |
template<typename Tag , typename DataBoxType > | |
constexpr bool | db::tag_is_retrievable_v |
Equal to true if Tag can be retrieved from a DataBox of type DataBoxType . More... | |
template<typename Consumer , typename Provider , typename Box > | |
using | db::tag_depends_on = std::bool_constant< Box::template tag_depends_on< Consumer, Provider >()> |
Check whether the tag Consumer depends on the tag Provider in a given Box . More... | |
template<typename Consumer , typename Provider , typename Box > | |
constexpr bool | db::tag_depends_on_v |
Check whether the tag Consumer depends on the tag Provider in a given Box . More... | |
template<typename MutateTags , typename ArgumentTags , typename F , typename... Args> | |
constexpr decltype(auto) | db::mutate_apply (F &&f, const gsl::not_null< Access * > box, Args &&... args) |
Apply the invokable f mutating items MutateTags and taking as additional arguments ArgumentTags and args . More... | |
template<typename F , typename... Args> | |
constexpr decltype(auto) | db::mutate_apply (F &&f, const gsl::not_null< Access * > box, Args &&... args) |
Apply the invokable f mutating items MutateTags and taking as additional arguments ArgumentTags and args . More... | |
template<typename F , typename... Args> | |
constexpr decltype(auto) | db::mutate_apply (const gsl::not_null< Access * > box, Args &&... args) |
Apply the invokable f mutating items MutateTags and taking as additional arguments ArgumentTags and args . More... | |
template<typename ArgumentTags , typename F , typename BoxTags , typename... Args> | |
constexpr auto | db::apply (F &&f, const DataBox< BoxTags > &box, Args &&... args) |
Apply the invokable f with argument Tags TagsList from DataBox box More... | |
template<typename F , typename BoxTags , typename... Args> | |
constexpr auto | db::apply (F &&f, const DataBox< BoxTags > &box, Args &&... args) |
Apply the invokable f with argument Tags TagsList from DataBox box More... | |
template<typename F , typename BoxTags , typename... Args> | |
constexpr auto | db::apply (const DataBox< BoxTags > &box, Args &&... args) |
Apply the invokable f with argument Tags TagsList from DataBox box More... | |
template<typename MutateTags , typename ArgumentTags , typename F , typename BoxTags , typename... Args> | |
constexpr decltype(auto) | db::mutate_apply (F &&f, const gsl::not_null< DataBox< BoxTags > * > box, Args &&... args) |
Apply the invokable f mutating items MutateTags and taking as additional arguments ArgumentTags and args . More... | |
template<typename F , typename BoxTags , typename... Args> | |
constexpr decltype(auto) | db::mutate_apply (F &&f, const gsl::not_null< DataBox< BoxTags > * > box, Args &&... args) |
Apply the invokable f mutating items MutateTags and taking as additional arguments ArgumentTags and args . More... | |
template<typename F , typename BoxTags , typename... Args> | |
constexpr decltype(auto) | db::mutate_apply (const gsl::not_null< DataBox< BoxTags > * > box, Args &&... args) |
Apply the invokable f mutating items MutateTags and taking as additional arguments ArgumentTags and args . More... | |
Documentation, functions, metafunctions, and classes necessary for using DataBox.
DataBox is a heterogeneous compile-time associative container with lazy evaluation of functions. DataBox can not only store data, but can also store functions that depend on other data inside the DataBox. The functions will be evaluated when the data they return is requested. The result is cached, and if a dependency of the function is modified the cache is invalidated.
The compile-time keys are struct
s called tags, while the values are called items. Tags are quite minimal, containing only the information necessary to store the data and evaluate functions. There are two different types of tags that a DataBox can hold: simple tags and compute tags. Simple tags are for data that is inserted into the DataBox at the time of creation, while compute tags are for data that will be computed from a function when the compute item is retrieved. If a compute item is never retrieved from the DataBox then it is never evaluated.
Simple tags must have a member type alias type
that is the type of the data to be stored and a static std::string name()
method that returns the name of the tag. Simple tags must inherit from db::SimpleTag
.
Compute tags must also have a static std::string name()
method that returns the name of the tag, but they cannot have a type
type alias. Instead, compute tags must have a static member function or static member function pointer named function
. function
can be a function template if necessary. The function
must take all its arguments by const
reference. The arguments to the function are retrieved using tags from the DataBox that the compute tag is in. The tags for the arguments are set in the member type alias argument_tags
, which must be a tmpl::list
of the tags corresponding to each argument. Note that the order of the tags in the argument_list
is the order that they will be passed to the function. Compute tags must inherit from db::ComputeTag
.
Here is an example of a simple tag:
and an example of a compute tag with a function pointer:
If the compute item's tag is inline then the compute item is of the form:
Compute tags can also have their functions be overloaded on the type of its arguments:
or be overloaded on the number of arguments:
Compute tag function templates are implemented as follows:
Finally, overloading, function templates, and variadic functions can be combined to produce extremely generic compute tags. The below compute tag takes as template parameters a parameter pack of integers, which is used to specify several of the arguments. The function is overloaded for the single argument case, and a variadic function template is provided for the multiple arguments case. Note that in practice few compute tags will be this complex.
A simple or compute tag might also hold a collection of data, such as a container of Tensor
s. In many cases you will want to be able to retrieve individual elements of the collection from the DataBox without having to first retrieve the collection. The infrastructure that allows for this is called Subitems. The subitems of the parent tag must refer to a subset of the data inside the parent tag, e.g. one Tensor
in the collection. If the parent tag is Parent
and the subitems tags are Sub<0>, Sub<1>
, then when Parent
is added to the DataBox, so are Sub<0>
and Sub<1>
. This means the retrieval mechanisms described below will work on Parent
, Sub<0>
, and Sub<1>
.
Subitems specify requirements on the tags they act on. For example, there could be a requirement that all tags with a certain type are to be treated as a Subitems. Let's say that the Parent
tag holds a Variables
, and Variables
can be used with the Subitems infrastructure to add the nested Tensor
s. Then all tags that hold a Variables
will have their subitems added into the DataBox. To add a new type as a subitem the db::Subitems
struct must be specialized. See the documentation of db::Subitems
for more details.
The DataBox also supports prefix tags, which are commonly used for items that are related to a different item by some operation. Specifically, say you have a tag MyTensor
and you want to also have the time derivative of MyTensor
, then you can use the prefix tag dt
to get dt<MyTensor>
. The benefit of a prefix tag over, say, a separate tag dtMyTensor
is that prefix tags can be added and removed by the compute tags acting on the original tag. Prefix tags can also be composed, so a second time derivative would be dt<dt<MyTensor>>
. The net result of the prefix tags infrastructure is that the compute tag that returns dt<MyTensor>
only needs to know its input tags, it knows how to name its output based off that. In addition to the normal things a simple or a compute tag must hold, prefix tags must have a nested type alias tag
, which is the tag being prefixed. Prefix tags must also inherit from db::PrefixTag
in addition to inheriting from db::SimpleTag
or db::ComputeTag
.
You should never call the constructor of a DataBox directly. DataBox construction is quite complicated and the helper function db::create
should be used instead. db::create
is used to construct a new DataBox. It takes two typelists as explicit template parameters, the first being a list of the simple tags to add and the second being a list of compute tags to add. If no compute tags are being added then only the simple tags list must be specified. The tags lists should be passed as db::create<db::AddSimpleTags<simple_tags...>, db::AddComputeTags<compute_tags...>>
. The arguments to db::create
are the initial values of the simple tags and must be passed in the same order as the tags in the db::AddSimpleTags
list. If the type of an argument passed to db::create
does not match the type of the corresponding simple tag a static assertion will trigger. Here is an example of how to use db::create
:
To retrieve an item from a DataBox use the db::get
function. db::get
will always return a const
reference to the object stored in the DataBox and will also have full type information available. This means you are able to use const auto&
when retrieving tags from the DataBox. For example,
If you want to mutate the value of a simple item in the DataBox use db::mutate
. Any compute item that depends on the mutated item will have its cached value invalidated and be recomputed the next time it is retrieved from the DataBox. db::mutate
takes a parameter pack of tags to mutate as explicit template parameters, a gsl::not_null
of the DataBox whose items will be mutated, an invokable, and extra arguments to forward to the invokable. The invokable takes the arguments passed from the DataBox by const gsl::not_null
while the extra arguments are forwarded to the invokable. The invokable is not allowed to retrieve anything from the DataBox, so any items must be passed as extra arguments using db::get
to retrieve them. For example,
In addition to retrieving items using db::get
and mutating them using db::mutate
, there is a facility to invoke an invokable with tags from the DataBox. db::apply
takes a tmpl::list
of tags as an explicit template parameter, will retrieve all the tags from the DataBox passed in and then invoke the invokable with the items in the tag list. Similarly, db::mutate_apply
invokes the invokable but allows for mutating some of the tags. See the documentation of db::apply
and db::mutate_apply
for examples of how to use them.
Retrieving items by tags should not require knowing whether the item being retrieved was computed using a compute tag or simply added using a simple tag. The framework that handles this falls under the umbrella term base tags. The reason is that a compute tag can inherit from a simple tag with the same item type, and then calls to db::get
with the simple tag can be used to retrieve the compute item as well. That is, say you have a compute tag ArrayCompute
that derives off of the simple tag Array
, then you can retrieve the compute tag ArrayCompute
and Array
by calling db::get<Array>(box)
. The base tags mechanism requires that only one Array
tag be present in the DataBox, otherwise a static assertion is triggered.
The inheritance idea can be generalized further with what are called base tags. A base tag is an empty struct
that inherits from db::BaseTag
. Any simple or compute item that derives off of the base tag can be retrieved using db::get
. Consider the following VectorBase
and Vector
tag:
It is possible to retrieve Vector<1>
from the DataBox using VectorBase<1>
. Most importantly, base tags can also be used in compute tag arguments, as follows:
As shown in the code example, the base tag mechanism works with function template compute tags, enabling generic programming to be combined with the lazy evaluation and automatic dependency analysis offered by the DataBox. To really demonstrate the power of base tags, let's also have ArrayComputeBase
inherit from a simple tag Array
, which inherits from a base tag ArrayBase
as follows:
To start, let's create a DataBox that holds a Vector<0>
and an ArrayComputeBase<0>
(the concrete tag must be used when creating the DataBox, not the base tags), retrieve the tags using the base tag mechanism, including mutating Vector<0>
, and then verifying that the dependencies are handled correctly.
Notice that we are able to retrieve ArrayComputeBase<0>
with ArrayBase<0>
and Array<0>
. We were also able to mutate Vector<0>
using VectorBase<0>
.
The base tags infrastructure even works with Subitems. Even if you mutate the subitem of a parent using a base tag, the appropriate compute item caches will be invalidated.
db::get
, db::mutate
, db::apply
and db::mutate_apply
.DataBox is a heterogeneous compile-time associative container with lazy evaluation of functions. DataBox can not only store data, but can also store functions that depend on other data inside the DataBox. The functions will be evaluated when the data they return is requested. The result is cached, and if a dependency of the function is modified the cache is invalidated.
The compile-time keys are struct
s called tags, while the values are called items. Tags are quite minimal, containing only the information necessary to store the data and evaluate functions. There are two different types of tags that a DataBox can hold: simple tags and compute tags. Simple tags are for data that is inserted into the DataBox at the time of creation, while compute tags are for data that will be computed from a function when the compute item is retrieved. If a compute item is never retrieved from the DataBox then it is never evaluated.
Simple tags must have a member type alias type
that is the type of the data to be stored and a static std::string name()
method that returns the name of the tag. Simple tags must inherit from db::SimpleTag
.
Compute tags must also have a static std::string name()
method that returns the name of the tag, but they cannot have a type
type alias. Instead, compute tags must have a static member function or static member function pointer named function
. function
can be a function template if necessary. The function
must take all its arguments by const
reference. The arguments to the function are retrieved using tags from the DataBox that the compute tag is in. The tags for the arguments are set in the member type alias argument_tags
, which must be a tmpl::list
of the tags corresponding to each argument. Note that the order of the tags in the argument_list
is the order that they will be passed to the function. Compute tags must inherit from db::ComputeTag
.
Here is an example of a simple tag:
and an example of a compute tag with a function pointer:
If the compute item's tag is inline then the compute item is of the form:
Compute tags can also have their functions be overloaded on the type of its arguments:
or be overloaded on the number of arguments:
Compute tag function templates are implemented as follows:
Finally, overloading, function templates, and variadic functions can be combined to produce extremely generic compute tags. The below compute tag takes as template parameters a parameter pack of integers, which is used to specify several of the arguments. The function is overloaded for the single argument case, and a variadic function template is provided for the multiple arguments case. Note that in practice few compute tags will be this complex.
A simple or compute tag might also hold a collection of data, such as a container of Tensor
s. In many cases you will want to be able to retrieve individual elements of the collection from the DataBox without having to first retrieve the collection. The infrastructure that allows for this is called Subitems. The subitems of the parent tag must refer to a subset of the data inside the parent tag, e.g. one Tensor
in the collection. If the parent tag is Parent
and the subitems tags are Sub<0>, Sub<1>
, then when Parent
is added to the DataBox, so are Sub<0>
and Sub<1>
. This means the retrieval mechanisms described below will work on Parent
, Sub<0>
, and Sub<1>
.
Subitems specify requirements on the tags they act on. For example, there could be a requirement that all tags with a certain type are to be treated as a Subitems. Let's say that the Parent
tag holds a Variables
, and Variables
can be used with the Subitems infrastructure to add the nested Tensor
s. Then all tags that hold a Variables
will have their subitems added into the DataBox. To add a new type as a subitem the db::Subitems
struct must be specialized. See the documentation of db::Subitems
for more details.
The DataBox also supports prefix tags, which are commonly used for items that are related to a different item by some operation. Specifically, say you have a tag MyTensor
and you want to also have the time derivative of MyTensor
, then you can use the prefix tag dt
to get dt<MyTensor>
. The benefit of a prefix tag over, say, a separate tag dtMyTensor
is that prefix tags can be added and removed by the compute tags acting on the original tag. Prefix tags can also be composed, so a second time derivative would be dt<dt<MyTensor>>
. The net result of the prefix tags infrastructure is that the compute tag that returns dt<MyTensor>
only needs to know its input tags, it knows how to name its output based off that. In addition to the normal things a simple or a compute tag must hold, prefix tags must have a nested type alias tag
, which is the tag being prefixed. Prefix tags must also inherit from db::PrefixTag
in addition to inheriting from db::SimpleTag
or db::ComputeTag
.
You should never call the constructor of a DataBox directly. DataBox construction is quite complicated and the helper function db::create
should be used instead. db::create
is used to construct a new DataBox. It takes two typelists as explicit template parameters, the first being a list of the simple tags to add and the second being a list of compute tags to add. If no compute tags are being added then only the simple tags list must be specified. The tags lists should be passed as db::create<db::AddSimpleTags<simple_tags...>, db::AddComputeTags<compute_tags...>>
. The arguments to db::create
are the initial values of the simple tags and must be passed in the same order as the tags in the db::AddSimpleTags
list. If the type of an argument passed to db::create
does not match the type of the corresponding simple tag a static assertion will trigger. Here is an example of how to use db::create
:
To retrieve an item from a DataBox use the db::get
function. db::get
will always return a const
reference to the object stored in the DataBox and will also have full type information available. This means you are able to use const auto&
when retrieving tags from the DataBox. For example,
If you want to mutate the value of a simple item in the DataBox use db::mutate
. Any compute item that depends on the mutated item will have its cached value invalidated and be recomputed the next time it is retrieved from the DataBox. db::mutate
takes a parameter pack of tags to mutate as explicit template parameters, a gsl::not_null
of the DataBox whose items will be mutated, an invokable, and extra arguments to forward to the invokable. The invokable takes the arguments passed from the DataBox by const gsl::not_null
while the extra arguments are forwarded to the invokable. The invokable is not allowed to retrieve anything from the DataBox, so any items must be passed as extra arguments using db::get
to retrieve them. For example,
In addition to retrieving items using db::get
and mutating them using db::mutate
, there is a facility to invoke an invokable with tags from the DataBox. db::apply
takes a tmpl::list
of tags as an explicit template parameter, will retrieve all the tags from the DataBox passed in and then invoke the invokable with the items in the tag list. Similarly, db::mutate_apply
invokes the invokable but allows for mutating some of the tags. See the documentation of db::apply
and db::mutate_apply
for examples of how to use them.
Retrieving items by tags should not require knowing whether the item being retrieved was computed using a compute tag or simply added using a simple tag. The framework that handles this falls under the umbrella term base tags. The reason is that a compute tag can inherit from a simple tag with the same item type, and then calls to db::get
with the simple tag can be used to retrieve the compute item as well. That is, say you have a compute tag ArrayCompute
that derives off of the simple tag Array
, then you can retrieve the compute tag ArrayCompute
and Array
by calling db::get<Array>(box)
. The base tags mechanism requires that only one Array
tag be present in the DataBox, otherwise a static assertion is triggered.
The inheritance idea can be generalized further with what are called base tags. A base tag is an empty struct
that inherits from db::BaseTag
. Any simple or compute item that derives off of the base tag can be retrieved using db::get
. Consider the following VectorBase
and Vector
tag:
It is possible to retrieve Vector<1>
from the DataBox using VectorBase<1>
. Most importantly, base tags can also be used in compute tag arguments, as follows:
As shown in the code example, the base tag mechanism works with function template compute tags, enabling generic programming to be combined with the lazy evaluation and automatic dependency analysis offered by the DataBox. To really demonstrate the power of base tags, let's also have ArrayComputeBase
inherit from a simple tag Array
, which inherits from a base tag ArrayBase
as follows:
To start, let's create a DataBox that holds a Vector<0>
and an ArrayComputeBase<0>
(the concrete tag must be used when creating the DataBox, not the base tags), retrieve the tags using the base tag mechanism, including mutating Vector<0>
, and then verifying that the dependencies are handled correctly.
Notice that we are able to retrieve ArrayComputeBase<0>
with ArrayBase<0>
and Array<0>
. We were also able to mutate Vector<0>
using VectorBase<0>
.
The base tags infrastructure even works with Subitems. Even if you mutate the subitem of a parent using a base tag, the appropriate compute item caches will be invalidated.
db::get
, db::mutate
, db::apply
and db::mutate_apply
. using db::tag_depends_on = typedef std::bool_constant<Box::template tag_depends_on<Consumer, Provider>()> |
Check whether the tag Consumer
depends on the tag Provider
in a given Box
.
This is equivalent to the question of whether changing Provider
(through db::mutate
, updating one of its dependencies, etc.) could change the value of db::get<Consumer>
. Tags depend on themselves, and an item and its subitems all depend on one another.
|
constexpr |
Apply the invokable f
with argument Tags TagsList
from DataBox box
f
must either be invokable with the arguments of type db::const_item_type<TagsList>..., Args...
where the first pack expansion is over the elements in the type list ArgumentTags
, or have a static apply
function that is callable with the same types. If the class that implements the static apply
functions also provides an argument_tags
typelist, then it is used and no explicit ArgumentTags
template parameter should be specified.
Given a function func
that takes arguments of types T1
, T2
, A1
and A2
. Let the Tags for the quantities of types T1
and T2
in the DataBox box
be Tag1
and Tag2
, and objects a1
of type A1
and a2
of type A2
, then
Returns: decltype(func(db::get<Tag1>(box), db::get<Tag2>(box), a1, a2))
Semantics: For tags Tags...
in a DataBox box
, and a function func
that takes sizeof...(Tags)
arguments of types db::const_item_type<Tags>...
, and sizeof...(Args)
arguments of types Args...
,
Using a struct with an apply
method:
If the class F
has no state, you can also use the stateless overload of apply
:
ArgumentTags | typelist of Tags in the order that they are to be passed to f |
F | The invokable to apply |
|
constexpr |
Apply the invokable f
with argument Tags TagsList
from DataBox box
f
must either be invokable with the arguments of type db::const_item_type<TagsList>..., Args...
where the first pack expansion is over the elements in the type list ArgumentTags
, or have a static apply
function that is callable with the same types. If the class that implements the static apply
functions also provides an argument_tags
typelist, then it is used and no explicit ArgumentTags
template parameter should be specified.
Given a function func
that takes arguments of types T1
, T2
, A1
and A2
. Let the Tags for the quantities of types T1
and T2
in the DataBox box
be Tag1
and Tag2
, and objects a1
of type A1
and a2
of type A2
, then
Returns: decltype(func(db::get<Tag1>(box), db::get<Tag2>(box), a1, a2))
Semantics: For tags Tags...
in a DataBox box
, and a function func
that takes sizeof...(Tags)
arguments of types db::const_item_type<Tags>...
, and sizeof...(Args)
arguments of types Args...
,
Using a struct with an apply
method:
If the class F
has no state, you can also use the stateless overload of apply
:
ArgumentTags | typelist of Tags in the order that they are to be passed to f |
F | The invokable to apply |
|
constexpr |
Apply the invokable f
with argument Tags TagsList
from DataBox box
f
must either be invokable with the arguments of type db::const_item_type<TagsList>..., Args...
where the first pack expansion is over the elements in the type list ArgumentTags
, or have a static apply
function that is callable with the same types. If the class that implements the static apply
functions also provides an argument_tags
typelist, then it is used and no explicit ArgumentTags
template parameter should be specified.
Given a function func
that takes arguments of types T1
, T2
, A1
and A2
. Let the Tags for the quantities of types T1
and T2
in the DataBox box
be Tag1
and Tag2
, and objects a1
of type A1
and a2
of type A2
, then
Returns: decltype(func(db::get<Tag1>(box), db::get<Tag2>(box), a1, a2))
Semantics: For tags Tags...
in a DataBox box
, and a function func
that takes sizeof...(Tags)
arguments of types db::const_item_type<Tags>...
, and sizeof...(Args)
arguments of types Args...
,
Using a struct with an apply
method:
If the class F
has no state, you can also use the stateless overload of apply
:
ArgumentTags | typelist of Tags in the order that they are to be passed to f |
F | The invokable to apply |
auto db::copy_items | ( | const DataBox< DbTagList > & | box | ) |
Copy the items from the DataBox into a TaggedTuple.
Returns: The objects corresponding to CopiedItemsTagList
|
constexpr |
Create a new DataBox.
Creates a new DataBox holding types Tags::type filled with the arguments passed to the function. Compute and reference items must be added so that their dependencies are added before themselves. For example, say you have compute items A
and B
where B
depends on A
, then you must add them using db::AddImmutableItemTags<A, B>
.
AddMutableItemTags | the tags of the mutable items that are being added |
AddImmutableItemTags | list of compute item tags and refernce item tags to add to the DataBox |
args | the initial values for the mutable items to add to the DataBox |
Variables< tmpl::list< TagsToSlice... > > db::data_on_slice | ( | const db::DataBox< TagsList > & | box, |
const Index< VolumeDim > & | element_extents, | ||
const size_t | sliced_dim, | ||
const size_t | fixed_index, | ||
tmpl::list< TagsToSlice... > | |||
) |
Slices volume Tensor
s from a DataBox
into a Variables
The slice has a constant logical coordinate in direction sliced_dim
, slicing the volume at fixed_index
in that dimension. For example, to get the lower boundary of sliced_dim
, pass 0
for fixed_index
; to get the upper boundary, pass extents[sliced_dim] - 1
. The last argument to the function is the typelist holding the tags to slice.
const auto & db::get | ( | const DataBox< TagList > & | box | ) |
Retrieve the item with tag Tag
from the DataBox.
Requires: Type Tag
is one of the Tags corresponding to an object stored in the DataBox
Returns: The object corresponding to the tag Tag
auto & db::get_mutable_reference | ( | const gsl::not_null< DataBox< TagList > * > | box | ) |
Retrieve a mutable reference to the item with tag Tag
from the DataBox.
The tag retrieved cannot be used by any compute tags, cannot have subitems, and cannot itself be a subitem. These requirements prevent changes to the retrieved item from affecting any other tags in the DataBox, so it can safely be modified without causing internal inconsistencies.
decltype(auto) db::mutate | ( | Invokable && | invokable, |
const gsl::not_null< DataBox< TagList > * > | box, | ||
Args &&... | args | ||
) |
Allows changing the state of one or more non-computed elements in the DataBox.
mutate()
's second argument is the DataBox from which to retrieve the tags MutateTags
. The objects corresponding to the MutateTags
are then passed to invokable
, which is a lambda or a function object taking as many arguments as there are MutateTags
and with the arguments being of types gsl::not_null<db::item_type<MutateTags>*>...
. Inside the invokable
no items can be retrieved from the DataBox box
. This is to avoid confusing subtleties with order of evaluation of compute items, as well as dangling references. If an invokable
needs read access to items in box
they should be passed as additional arguments to mutate
. Capturing them by reference in a lambda does not work because of a bug in GCC 6.3 and earlier. For a function object the read-only items can also be stored as const references inside the object by passing db::get<TAG>(t)
to the constructor.
The invokable
may have function return values, and any returns are forwarded as returns to the db::mutate
call.
For convenience in generic programming, if Tags::DataBox
is passed as the sole MutateTags
parameter, this function will simply call its first argument with its remaining arguments. Except for this case, Tags::DataBox
is not usable with this function.
db::mutate
returns to obtain non-const references or pointers to box items is potentially very dangerous. The DataBox cannot track any subsequent changes to quantities that have been "unsafely" extracted in this manner, so we consider it undefined behavior to return pointers or references to DataBox contents.
|
constexpr |
Apply the invokable f
mutating items MutateTags
and taking as additional arguments ArgumentTags
and args
.
f
must either be invokable with the arguments of type gsl::not_null<db::item_type<MutateTags>*>..., db::const_item_type<ArgumentTags>..., Args...
where the first two pack expansions are over the elements in the typelists MutateTags
and ArgumentTags
, or have a static apply
function that is callable with the same types. If the type of f
specifies return_tags
and argument_tags
typelists, these are used for the MutateTags
and ArgumentTags
, respectively.
Any return values of the invokable f
are forwarded as returns to the mutate_apply
call.
An example of using mutate_apply
with a lambda:
An example of a class with a static apply
function
and how to use mutate_apply
with the above class
Note that the class exposes return_tags
and argument_tags
typelists, so we don't specify the template parameters explicitly. If the class F
has no state, like in this example,
you can also use the stateless overload of mutate_apply
:
MutateTags | typelist of Tags to mutate |
ArgumentTags | typelist of additional items to retrieve from the Access |
F | The invokable to apply |
|
constexpr |
Apply the invokable f
mutating items MutateTags
and taking as additional arguments ArgumentTags
and args
.
f
must either be invokable with the arguments of type gsl::not_null<db::item_type<MutateTags>*>..., db::const_item_type<ArgumentTags>..., Args...
where the first two pack expansions are over the elements in the typelists MutateTags
and ArgumentTags
, or have a static apply
function that is callable with the same types. If the type of f
specifies return_tags
and argument_tags
typelists, these are used for the MutateTags
and ArgumentTags
, respectively.
Any return values of the invokable f
are forwarded as returns to the mutate_apply
call.
MutateTags
is empty this will forward to db::apply
, so Tags::DataBox
will be available. Otherwise it will call db::mutate
. See those functions for more details on retrieving the entire box.An example of using mutate_apply
with a lambda:
An example of a class with a static apply
function
and how to use mutate_apply
with the above class
Note that the class exposes return_tags
and argument_tags
typelists, so we don't specify the template parameters explicitly. If the class F
has no state, like in this example,
you can also use the stateless overload of mutate_apply
:
MutateTags | typelist of Tags to mutate |
ArgumentTags | typelist of additional items to retrieve from the DataBox |
F | The invokable to apply |
|
constexpr |
Apply the invokable f
mutating items MutateTags
and taking as additional arguments ArgumentTags
and args
.
f
must either be invokable with the arguments of type gsl::not_null<db::item_type<MutateTags>*>..., db::const_item_type<ArgumentTags>..., Args...
where the first two pack expansions are over the elements in the typelists MutateTags
and ArgumentTags
, or have a static apply
function that is callable with the same types. If the type of f
specifies return_tags
and argument_tags
typelists, these are used for the MutateTags
and ArgumentTags
, respectively.
Any return values of the invokable f
are forwarded as returns to the mutate_apply
call.
An example of using mutate_apply
with a lambda:
An example of a class with a static apply
function
and how to use mutate_apply
with the above class
Note that the class exposes return_tags
and argument_tags
typelists, so we don't specify the template parameters explicitly. If the class F
has no state, like in this example,
you can also use the stateless overload of mutate_apply
:
MutateTags | typelist of Tags to mutate |
ArgumentTags | typelist of additional items to retrieve from the Access |
F | The invokable to apply |
|
constexpr |
Apply the invokable f
mutating items MutateTags
and taking as additional arguments ArgumentTags
and args
.
f
must either be invokable with the arguments of type gsl::not_null<db::item_type<MutateTags>*>..., db::const_item_type<ArgumentTags>..., Args...
where the first two pack expansions are over the elements in the typelists MutateTags
and ArgumentTags
, or have a static apply
function that is callable with the same types. If the type of f
specifies return_tags
and argument_tags
typelists, these are used for the MutateTags
and ArgumentTags
, respectively.
Any return values of the invokable f
are forwarded as returns to the mutate_apply
call.
An example of using mutate_apply
with a lambda:
An example of a class with a static apply
function
and how to use mutate_apply
with the above class
Note that the class exposes return_tags
and argument_tags
typelists, so we don't specify the template parameters explicitly. If the class F
has no state, like in this example,
you can also use the stateless overload of mutate_apply
:
MutateTags | typelist of Tags to mutate |
ArgumentTags | typelist of additional items to retrieve from the Access |
F | The invokable to apply |
|
constexpr |
Apply the invokable f
mutating items MutateTags
and taking as additional arguments ArgumentTags
and args
.
f
must either be invokable with the arguments of type gsl::not_null<db::item_type<MutateTags>*>..., db::const_item_type<ArgumentTags>..., Args...
where the first two pack expansions are over the elements in the typelists MutateTags
and ArgumentTags
, or have a static apply
function that is callable with the same types. If the type of f
specifies return_tags
and argument_tags
typelists, these are used for the MutateTags
and ArgumentTags
, respectively.
Any return values of the invokable f
are forwarded as returns to the mutate_apply
call.
MutateTags
is empty this will forward to db::apply
, so Tags::DataBox
will be available. Otherwise it will call db::mutate
. See those functions for more details on retrieving the entire box.An example of using mutate_apply
with a lambda:
An example of a class with a static apply
function
and how to use mutate_apply
with the above class
Note that the class exposes return_tags
and argument_tags
typelists, so we don't specify the template parameters explicitly. If the class F
has no state, like in this example,
you can also use the stateless overload of mutate_apply
:
MutateTags | typelist of Tags to mutate |
ArgumentTags | typelist of additional items to retrieve from the DataBox |
F | The invokable to apply |
|
constexpr |
Apply the invokable f
mutating items MutateTags
and taking as additional arguments ArgumentTags
and args
.
f
must either be invokable with the arguments of type gsl::not_null<db::item_type<MutateTags>*>..., db::const_item_type<ArgumentTags>..., Args...
where the first two pack expansions are over the elements in the typelists MutateTags
and ArgumentTags
, or have a static apply
function that is callable with the same types. If the type of f
specifies return_tags
and argument_tags
typelists, these are used for the MutateTags
and ArgumentTags
, respectively.
Any return values of the invokable f
are forwarded as returns to the mutate_apply
call.
MutateTags
is empty this will forward to db::apply
, so Tags::DataBox
will be available. Otherwise it will call db::mutate
. See those functions for more details on retrieving the entire box.An example of using mutate_apply
with a lambda:
An example of a class with a static apply
function
and how to use mutate_apply
with the above class
Note that the class exposes return_tags
and argument_tags
typelists, so we don't specify the template parameters explicitly. If the class F
has no state, like in this example,
you can also use the stateless overload of mutate_apply
:
MutateTags | typelist of Tags to mutate |
ArgumentTags | typelist of additional items to retrieve from the DataBox |
F | The invokable to apply |
std::string db::tag_name | ( | ) |
Get the name of a DataBox tag, including prefixes.
Given a DataBox tag returns the name of the DataBox tag as a std::string. If the DataBox tag is also a PrefixTag then the prefix is added.
Tag | the DataBox tag whose name to get |
Returns: string holding the DataBox tag's name
|
constexpr |
Check whether the tag Consumer
depends on the tag Provider
in a given Box
.
This is equivalent to the question of whether changing Provider
(through db::mutate
, updating one of its dependencies, etc.) could change the value of db::get<Consumer>
. Tags depend on themselves, and an item and its subitems all depend on one another.
|
constexpr |
Equal to true
if Tag
can be retrieved from a DataBox
of type DataBoxType
.