PLaSK library
|
This page describe providers and receivers mechanism, which allow for data exchange between solvers.
Provider is an object which has type derived from plask::Provider and provide some value(s) (has operator() which return provided value(s)). It also has set of listeners which are inform about changes of provided data.
Receiver is an object of class, which is typically connected with provider and allow for reading value(s)provided by it (has operator() which return provided value(s)).
Each type of provider has corresponding type of receiver (see plask::Receiver), and only provider and receiver witch corresponding types can be connected.
Each solver should have one provider class field for each physical property which it want to make available for other solvers and reports and it also should have one receiver field for each physical property which value it wants to know (needs for calculations). Most providers are classes obtain by using plask::ProviderFor template.
See How to write a new calculation solver? for more details and examples.
An example of using providers and receivers in solvers can be found in description of plask::Temperature.
The easiest way to create new provider and corresponding receiver types is to write physical property tag class and use it to specialize plask::ProviderFor and plask::ReceiverFor templates.
Physical property tag class is an class which only has static fields and methods and typedefs which describe physical property. It can be easy obtain by subclass instantiation of one of templates:
This subclass can include static field and methods:
static constexpr const char* NAME = "(lowercase) name of the property"
,static inline ValueType getDefaultValue() { return ...; }
- construct and return initial/default instance of variable with provided type (default implementation returns ValueType()
),static inline ValueType2D getDefaultValue2D() { return ...; }
and static inline ValueType3D getDefaultValue3D() { return ...; }
- like above for properties which uses different types in 2D and 3D spaces (e.g. plask::VectorFieldProperty),static const ValueType2D& value3Dto2D(const ValueType3D& v) { return ...; }
(convert v to 2D) and static const ValueType3D& value2Dto3D(const ValueType2D& v) { return ...; }
(convert v to 3D) - convert values between 2D and 3D spaces, only for properties which uses different types in 2D and 3D spaces, used by filters.Extra templates parameters can be passed to each property tag class template described above. This parameters are types of extra arguments required by provider to obtain value.
Both templates plask::ProviderFor and plask::ReceiverFor may take two parameters:
plask::ProviderFor class cannot be used directly, but one must declare it using some specialized class within the plask::ProviderFor namespace. E.g. plask::ProviderFor<MyProperty>::WithValue. The specialized class WithValue specifies how the provided values can be obtained. You can choose from the following options:
Example:
The (described above) method of creating providers and receivers should be sufficient for most cases. However, there is also a harder but more flexible approach than using plask::ProviderFor and plask::ReceiverFor templates. You can write your own provider class which inherits from plask::Provider and has operator(), which for some parameters (depending on your choice) returns the provided value.
Receiver class for your provider still may be very easy obtained by plask::Receiver template. This template requires only one parameter: the type of the provider. You can use it directly or as a base class for your receiver.
Example: