Operator ======= The `Operator` class represents a term in an equation and can be instantiated with different value types. An `Operator` is either explicit, implicit or temporal, and can be scalable by an additional coefficient, for example a scalar value or a further field. The `Operator` implementation uses Type Erasure (more details `[1] `_ `[2] `_ `[3] `_) to achieve polymorphism without inheritance. Consequently, the class needs only to implement the interface which is used in the DSL and which is shown in the below example: Example: .. code-block:: cpp NeoFOAM::dsl::Operator divTerm = Divergence(NeoFOAM::dsl::Operator::Type::Explicit, exec, ...); NeoFOAM::dsl::Operator ddtTerm = TimeTerm(NeoFOAM::dsl::Operator::Type::Temporal, exec, ..); To fit the specification of the Expression (storage in a vector), the Operator needs to be able to be scaled: .. code-block:: cpp NeoFOAM::Field scalingField(exec, nCells, 2.0); auto sF = scalingField.span(); dsl::Operator customTerm = CustomTerm(dsl::Operator::Type::Explicit, exec, nCells, 1.0); auto constantScaledTerm = 2.0 * customTerm; // A constant scaling factor of 2 for the term. auto fieldScaledTerm = scalingField * customTerm; // scalingField is used to scale the term. // Operator also supports a similar syntax as OpenFOAM auto multiScaledTerm = (scale + scale + scale + scale) * customTerm; // Operator also supports the use of a lambda as scaling function to reduce the number of temporaries generated auto lambdaScaledTerm = (KOKKOS_LAMBDA(const NeoFOAM::size_t i) { return sF[i] + sF[i] + sF[i] + sF[i]; }) * customTerm; To add a user-defined `Operator`, a new derived class must be created, inheriting from `OperatorMixin`, and provide the definitions of the below virtual functions that are required for the `Operator` interface: - build: build the term - explicitOperation: perform the explicit operation - implicitOperation: perform the implicit operation - getType: get the type of the term - exec: get the executor - volumeField: get the volume field An example can be found in `test/dsl/operator.cpp`. The required scaling of the term is handled by the `Coeff` type which can be retrieved by the `getCoefficient` function of `Operator`.