Skip to content
Snippets Groups Projects
Commit a2ee6796 authored by Tim Keil's avatar Tim Keil
Browse files

[combined] rename combined.hh -> combined-grid-functions

parent ab112e8b
No related branches found
No related tags found
No related merge requests found
// This file is part of the dune-xt-functions project: // This file is part of the dune-xt-functions project:
// https://github.com/dune-community/dune-xt-functions // https://github.com/dune-community/dune-xt-functions
// Copyright 2009-2018 dune-xt-functions developers and contributors. All rights reserved. // Copyright 2009-2018 dune-xt-functions developers and contributors. All rights
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause) // reserved.
// License: Dual licensed as BSD 2-Clause License
// (http://opensource.org/licenses/BSD-2-Clause)
// or GPL-2.0+ (http://opensource.org/licenses/gpl-license) // or GPL-2.0+ (http://opensource.org/licenses/gpl-license)
// with "runtime exception" (http://www.dune-project.org/license.html) // with "runtime exception" (http://www.dune-project.org/license.html)
// Authors: // Authors:
...@@ -9,34 +11,32 @@ ...@@ -9,34 +11,32 @@
// Rene Milk (2014 - 2018) // Rene Milk (2014 - 2018)
// Tobias Leibner (2014, 2017) // Tobias Leibner (2014, 2017)
#ifndef DUNE_XT_FUNCTIONS_BASE_COMBINED_HH #ifndef DUNE_XT_FUNCTIONS_BASE_COMBINED_GRID_FUNCTIONS_HH
#define DUNE_XT_FUNCTIONS_BASE_COMBINED_HH #define DUNE_XT_FUNCTIONS_BASE_COMBINED_GRID_FUNCTIONS_HH
#include <dune/xt/functions/interfaces/grid-function.hh> #include <dune/xt/functions/base/combined-functions.hh>
#include <dune/xt/functions/interfaces/function.hh> #include <dune/xt/functions/interfaces/function.hh>
#include <dune/xt/functions/interfaces/grid-function.hh>
namespace Dune { namespace Dune {
namespace XT { namespace XT {
namespace Functions { namespace Functions {
namespace internal { namespace internal {
/**
*
* todo: this can probably be done more intelligent
*/
enum class Combination enum class Combinations { difference, sum, product }; // enum class Combinations
{
difference,
sum,
product
}; // enum class Combination
/** /**
* \brief Helper class defining types of combined functions, if available. * \brief Helper class defining types of combined functions, if available.
* *
* \note Most likely you do not want to use this class directly, but Combined. * \note Most likely you do not want to use this class directly, but Combined.
*/ */
template <class LeftType, class RightType, Combination comb> template <class LeftType, class RightType, Combinations comb>
class SelectCombined class SelectCombinedGridFunction {
{
static_assert(is_grid_function<LeftType>::value, ""); static_assert(is_grid_function<LeftType>::value, "");
static_assert(is_grid_function<RightType>::value, ""); static_assert(is_grid_function<RightType>::value, "");
...@@ -47,47 +47,51 @@ public: ...@@ -47,47 +47,51 @@ public:
using R = typename LeftType::RangeFieldType; using R = typename LeftType::RangeFieldType;
private: private:
static_assert(std::is_same<typename RightType::ElementType, E>::value, "Types do not match!"); static_assert(std::is_same<typename RightType::ElementType, E>::value,
static_assert(std::is_same<typename RightType::DomainFieldType, D>::value, "Types do not match!"); "Types do not match!");
static_assert(std::is_same<typename RightType::DomainFieldType, D>::value,
"Types do not match!");
static_assert(RightType::domain_dim == d, "Dimensions do not match!"); static_assert(RightType::domain_dim == d, "Dimensions do not match!");
static_assert(std::is_same<typename RightType::RangeFieldType, R>::value, "Types do not match!"); static_assert(std::is_same<typename RightType::RangeFieldType, R>::value,
"Types do not match!");
template <class L, class R>
class Choose template <class L, class R> class Choose {
{ template <size_t rL, size_t rR, size_t rCL, size_t rcR, Combinations cc,
template <size_t rL, size_t rR, size_t rCL, size_t rcR, Combination cc, bool anything = true> bool anything = true>
class Dimension class Dimension {
{ static_assert(!anything,
static_assert(!anything, "No combination for these dimensions available!"); "No combination for these dimensions available!");
}; };
template <size_t r_in, size_t rC_in, bool anything> template <size_t r_in, size_t rC_in, bool anything>
class Dimension<r_in, r_in, rC_in, rC_in, Combination::difference, anything> class Dimension<r_in, r_in, rC_in, rC_in, Combinations::difference,
{ anything> {
public: public:
static const size_t r = r_in; static const size_t r = r_in;
static const size_t rC = rC_in; static const size_t rC = rC_in;
}; };
template <size_t r_in, size_t rC_in, bool anything> template <size_t r_in, size_t rC_in, bool anything>
class Dimension<r_in, r_in, rC_in, rC_in, Combination::sum, anything> class Dimension<r_in, r_in, rC_in, rC_in, Combinations::sum, anything> {
{
public: public:
static const size_t r = r_in; static const size_t r = r_in;
static const size_t rC = rC_in; static const size_t rC = rC_in;
}; };
template <size_t r_in, size_t rC_in, bool anything> template <size_t r_in, size_t rC_in, bool anything>
class Dimension<1, r_in, 1, rC_in, Combination::product, anything> class Dimension<1, r_in, 1, rC_in, Combinations::product, anything> {
{
public: public:
static const size_t r = r_in; static const size_t r = r_in;
static const size_t rC = rC_in; static const size_t rC = rC_in;
}; };
public: public:
static const size_t r = Dimension<L::range_dim, R::range_dim, L::range_dim_cols, R::range_dim_cols, comb>::r; static const size_t r =
static const size_t rC = Dimension<L::range_dim, R::range_dim, L::range_dim_cols, R::range_dim_cols, comb>::rC; Dimension<L::range_dim, R::range_dim, L::range_dim_cols,
R::range_dim_cols, comb>::r;
static const size_t rC =
Dimension<L::range_dim, R::range_dim, L::range_dim_cols,
R::range_dim_cols, comb>::rC;
}; // class Choose }; // class Choose
public: public:
...@@ -99,166 +103,145 @@ public: ...@@ -99,166 +103,145 @@ public:
using DomainType = typename ElementFunctionInterface<E, r, rC, R>::DomainType; using DomainType = typename ElementFunctionInterface<E, r, rC, R>::DomainType;
using RangeType = typename RightType::LocalFunctionType::RangeType; using RangeType = typename RightType::LocalFunctionType::RangeType;
using ScalarRangeType = typename LeftType::LocalFunctionType::RangeType; using ScalarRangeType = typename LeftType::LocalFunctionType::RangeType;
using DerivativeRangeType = typename ElementFunctionInterface<E, r, rC, R>::DerivativeRangeType; using DerivativeRangeType =
using DerivativeRangeReturnType = typename ElementFunctionInterface<E, r, rC, R>::DerivativeRangeReturnType; typename ElementFunctionInterface<E, r, rC, R>::DerivativeRangeType;
using DerivativeRangeReturnType =
typename ElementFunctionInterface<E, r, rC, R>::DerivativeRangeReturnType;
private: private:
template <Combination cc, bool anything = true> template <Combinations cc, bool anything = true> class Call {
class Call
{
static_assert(!anything, "Nothing available for these combinations!"); static_assert(!anything, "Nothing available for these combinations!");
}; // class Call }; // class Call
template <bool anything> template <bool anything> class Call<Combinations::difference, anything> {
class Call<Combination::difference, anything>
{
public: public:
static std::string type() static std::string type() { return "difference"; }
{
return "difference";
}
static size_t order(const size_t left_order, const size_t right_order) static size_t order(const size_t left_order, const size_t right_order) {
{
return std::max(left_order, right_order); return std::max(left_order, right_order);
} }
static RangeType evaluate(const LeftLocalFunctionType& left_local, static RangeType evaluate(const LeftLocalFunctionType &left_local,
const RightLocalFunctionType& right_local, const RightLocalFunctionType &right_local,
const DomainType& point_in_reference_element, const DomainType &point_in_reference_element,
const Common::Parameter& param) const Common::Parameter &param) {
{ return left_local.evaluate(point_in_reference_element, param) -
return left_local.evaluate(point_in_reference_element, param) right_local.evaluate(point_in_reference_element, param);
- right_local.evaluate(point_in_reference_element, param);
} }
static DerivativeRangeReturnType jacobian(const LeftLocalFunctionType& left_local, static DerivativeRangeReturnType
const RightLocalFunctionType& right_local, jacobian(const LeftLocalFunctionType &left_local,
const DomainType& point_in_reference_element, const RightLocalFunctionType &right_local,
const Common::Parameter& param) const DomainType &point_in_reference_element,
{ const Common::Parameter &param) {
return left_local.jacobian(point_in_reference_element, param) return left_local.jacobian(point_in_reference_element, param) -
- right_local.jacobian(point_in_reference_element, param); right_local.jacobian(point_in_reference_element, param);
} // ... jacobian(...) } // ... jacobian(...)
}; // class Call< ..., difference > }; // class Call< ..., difference >
template <bool anything> template <bool anything> class Call<Combinations::sum, anything> {
class Call<Combination::sum, anything>
{
public: public:
static std::string type() static std::string type() { return "sum"; }
{
return "sum";
}
static size_t order(const size_t left_order, const size_t right_order) static size_t order(const size_t left_order, const size_t right_order) {
{
return std::max(left_order, right_order); return std::max(left_order, right_order);
} }
static RangeType evaluate(const LeftLocalFunctionType& left_local, static RangeType evaluate(const LeftLocalFunctionType &left_local,
const RightLocalFunctionType& right_local, const RightLocalFunctionType &right_local,
const DomainType& point_in_reference_element, const DomainType &point_in_reference_element,
const Common::Parameter& param) const Common::Parameter &param) {
{ return left_local.evaluate(point_in_reference_element, param) +
return left_local.evaluate(point_in_reference_element, param) right_local.evaluate(point_in_reference_element, param);
+ right_local.evaluate(point_in_reference_element, param);
} // ... evaluate(...) } // ... evaluate(...)
static DerivativeRangeReturnType jacobian(const LeftLocalFunctionType& left_local, static DerivativeRangeReturnType
const RightLocalFunctionType& right_local, jacobian(const LeftLocalFunctionType &left_local,
const DomainType& point_in_reference_element, const RightLocalFunctionType &right_local,
const Common::Parameter& param) const DomainType &point_in_reference_element,
{ const Common::Parameter &param) {
return left_local.jacobian(point_in_reference_element, param) return left_local.jacobian(point_in_reference_element, param) +
+ right_local.jacobian(point_in_reference_element, param); right_local.jacobian(point_in_reference_element, param);
} // ... jacobian(...) } // ... jacobian(...)
}; // class Call< ..., sum > }; // class Call< ..., sum >
// left only scalar atm // left only scalar atm
template <bool anything> template <bool anything> class Call<Combinations::product, anything> {
class Call<Combination::product, anything>
{
public: public:
static std::string type() static std::string type() { return "product"; }
{
return "product";
}
static size_t order(const size_t left_order, const size_t right_order) static size_t order(const size_t left_order, const size_t right_order) {
{
return left_order + right_order; return left_order + right_order;
} }
static RangeType evaluate(const LeftLocalFunctionType& left_local, static RangeType evaluate(const LeftLocalFunctionType &left_local,
const RightLocalFunctionType& right_local, const RightLocalFunctionType &right_local,
const DomainType& point_in_reference_element, const DomainType &point_in_reference_element,
const Common::Parameter& param) const Common::Parameter &param) {
{ ScalarRangeType left_eval =
ScalarRangeType left_eval = left_local.evaluate(point_in_reference_element, param); left_local.evaluate(point_in_reference_element, param);
RangeType right_eval = right_local.evaluate(point_in_reference_element, param); RangeType right_eval =
right_local.evaluate(point_in_reference_element, param);
if (left_eval.size() != 1) if (left_eval.size() != 1)
DUNE_THROW(NotImplemented, "Only available for scalar left type!"); DUNE_THROW(NotImplemented, "Only available for scalar left type!");
right_eval *= left_eval[0]; right_eval *= left_eval[0];
return right_eval; return right_eval;
} // ... evaluate(...) } // ... evaluate(...)
static DerivativeRangeReturnType jacobian(const LeftLocalFunctionType& /*left_local*/, static DerivativeRangeReturnType
const RightLocalFunctionType& /*right_local*/, jacobian(const LeftLocalFunctionType & /*left_local*/,
const DomainType& /*point_in_reference_element*/, const RightLocalFunctionType & /*right_local*/,
const Common::Parameter& /*param*/) const DomainType & /*point_in_reference_element*/,
{ const Common::Parameter & /*param*/) {
DUNE_THROW(NotImplemented, "If you need this, implement it!"); DUNE_THROW(NotImplemented, "If you need this, implement it!");
return DerivativeRangeReturnType(); return DerivativeRangeReturnType();
} }
}; // class Call< ..., product > }; // class Call< ..., product >
public: public:
static std::string type() static std::string type() { return Call<comb>::type(); }
{
return Call<comb>::type();
}
static size_t order(const size_t left_order, const size_t right_order) static size_t order(const size_t left_order, const size_t right_order) {
{
return Call<comb>::order(left_order, right_order); return Call<comb>::order(left_order, right_order);
} }
static RangeType evaluate(const LeftLocalFunctionType& left_local, static RangeType evaluate(const LeftLocalFunctionType &left_local,
const RightLocalFunctionType& right_local, const RightLocalFunctionType &right_local,
const DomainType& point_in_reference_element, const DomainType &point_in_reference_element,
const Common::Parameter& param) const Common::Parameter &param) {
{ return Call<comb>::evaluate(left_local, right_local,
return Call<comb>::evaluate(left_local, right_local, point_in_reference_element, param); point_in_reference_element, param);
} }
static DerivativeRangeReturnType jacobian(const LeftLocalFunctionType& left_local, static DerivativeRangeReturnType
const RightLocalFunctionType& right_local, jacobian(const LeftLocalFunctionType &left_local,
const DomainType& point_in_reference_element, const RightLocalFunctionType &right_local,
const Common::Parameter& param) const DomainType &point_in_reference_element,
{ const Common::Parameter &param) {
return Call<comb>::jacobian(left_local, right_local, point_in_reference_element, param); return Call<comb>::jacobian(left_local, right_local,
point_in_reference_element, param);
} }
}; // class SelectCombined }; // class SelectCombinedGridFunction
/** /**
* \brief Generic combined local function. * \brief Generic combined local function.
* *
* \note Most likely you do not want to use this class directly, but Combined. * \note Most likely you do not want to use this class directly, but Combined.
*/ */
template <class LeftType, class RightType, Combination type> template <class LeftType, class RightType, Combinations type>
class CombinedLocalFunction : public ElementFunctionInterface<typename SelectCombined<LeftType, RightType, type>::E, class CombinedLocalFunction
SelectCombined<LeftType, RightType, type>::r, : public ElementFunctionInterface<
SelectCombined<LeftType, RightType, type>::rC, typename SelectCombinedGridFunction<LeftType, RightType, type>::E,
typename SelectCombined<LeftType, RightType, type>::R> SelectCombinedGridFunction<LeftType, RightType, type>::r,
{ SelectCombinedGridFunction<LeftType, RightType, type>::rC,
using BaseType = ElementFunctionInterface<typename SelectCombined<LeftType, RightType, type>::E, typename SelectCombinedGridFunction<LeftType, RightType, type>::R> {
SelectCombined<LeftType, RightType, type>::r, using BaseType = ElementFunctionInterface<
SelectCombined<LeftType, RightType, type>::rC, typename SelectCombinedGridFunction<LeftType, RightType, type>::E,
typename SelectCombined<LeftType, RightType, type>::R>; SelectCombinedGridFunction<LeftType, RightType, type>::r,
SelectCombinedGridFunction<LeftType, RightType, type>::rC,
using Select = SelectCombined<LeftType, RightType, type>; typename SelectCombinedGridFunction<LeftType, RightType, type>::R>;
using Select = SelectCombinedGridFunction<LeftType, RightType, type>;
public: public:
using typename BaseType::ElementType; using typename BaseType::ElementType;
...@@ -268,36 +251,33 @@ public: ...@@ -268,36 +251,33 @@ public:
using typename BaseType::RangeReturnType; using typename BaseType::RangeReturnType;
using typename BaseType::DerivativeRangeReturnType; using typename BaseType::DerivativeRangeReturnType;
CombinedLocalFunction(const LeftType& left, const RightType& right) CombinedLocalFunction(const LeftType &left, const RightType &right)
: BaseType() : BaseType(), left_local_(left.local_function()),
, left_local_(left.local_function()) right_local_(right.local_function()) {}
, right_local_(right.local_function())
{
}
protected: protected:
void post_bind(const ElementType& element) override final void post_bind(const ElementType &element) override final {
{
left_local_->bind(element); left_local_->bind(element);
right_local_->bind(element); right_local_->bind(element);
} }
public: public:
int order(const XT::Common::Parameter& param = {}) const override final int order(const XT::Common::Parameter &param = {}) const override final {
{
return Select::order(left_local_->order(param), right_local_->order(param)); return Select::order(left_local_->order(param), right_local_->order(param));
} }
RangeReturnType evaluate(const DomainType& point_in_reference_element, RangeReturnType
const Common::Parameter& param = {}) const override final evaluate(const DomainType &point_in_reference_element,
{ const Common::Parameter &param = {}) const override final {
return Select::evaluate(*left_local_, *right_local_, point_in_reference_element, param); return Select::evaluate(*left_local_, *right_local_,
point_in_reference_element, param);
} }
DerivativeRangeReturnType jacobian(const DomainType& point_in_reference_element, DerivativeRangeReturnType
const Common::Parameter& param = {}) const override final jacobian(const DomainType &point_in_reference_element,
{ const Common::Parameter &param = {}) const override final {
return Select::jacobian(*left_local_, *right_local_, point_in_reference_element, param); return Select::jacobian(*left_local_, *right_local_,
point_in_reference_element, param);
} }
private: private:
...@@ -305,14 +285,17 @@ private: ...@@ -305,14 +285,17 @@ private:
std::unique_ptr<typename RightType::LocalFunctionType> right_local_; std::unique_ptr<typename RightType::LocalFunctionType> right_local_;
}; // class CombinedLocalFunction }; // class CombinedLocalFunction
/** /**
* \brief Generic combined function. * \brief Generic combined function.
* *
* This class combines two given functions of type LeftType and RightType using the given combination * This class combines two given functions of type LeftType and RightType
* Combination. This class (and any derived class, like Difference, Sum or Product) can be used in two ways: using the given combination
* - You can pass references of the left and right operand to this class. This is done for instance when calling * Combinations. This class (and any derived class, like Difference, Sum
* operator+, operator- or operator* on any function deriving from GridFunctionInterface: or Product) can be used in two ways:
* - You can pass references of the left and right operand to this class.
This is done for instance when calling
* operator+, operator- or operator* on any function deriving from
GridFunctionInterface:
\code \code
using IndicatorType = Functions::IndicatorFunction< ..., double>; using IndicatorType = Functions::IndicatorFunction< ..., double>;
IndicatorType one( ... ); IndicatorType one( ... );
...@@ -322,9 +305,11 @@ auto difference = one - two; ...@@ -322,9 +305,11 @@ auto difference = one - two;
// is equivalent to // is equivalent to
Difference< IndicatorType, IndicatorType > difference(one, two); Difference< IndicatorType, IndicatorType > difference(one, two);
// and // and
internal::Combined< IndicatorType, IndicatorType, Combination::difference > difference(one, tow); internal::Combined< IndicatorType, IndicatorType, Combinations::difference >
difference(one, tow);
\endcode \endcode
* In this situation you are responsible to ensure that the arguments given are valid throughout the lifetime * In this situation you are responsible to ensure that the arguments
given are valid throughout the lifetime
* of this class. The following will lead to a segfault: * of this class. The following will lead to a segfault:
\code \code
using IndicatorType = Functions::IndicatorFunction< ..., double >; using IndicatorType = Functions::IndicatorFunction< ..., double >;
...@@ -336,7 +321,8 @@ Difference< IndicatorType, IndicatorType > stupid_difference() ...@@ -336,7 +321,8 @@ Difference< IndicatorType, IndicatorType > stupid_difference()
return one - two; return one - two;
} }
\endcode \endcode
* - You can pass shared_ptr of the left and right operands to this class. In this case the following is valid: * - You can pass shared_ptr of the left and right operands to this
class. In this case the following is valid:
\code \code
using IndicatorType = Functions::IndicatorFunction< ..., double >; using IndicatorType = Functions::IndicatorFunction< ..., double >;
...@@ -348,183 +334,186 @@ Difference< IndicatorType, IndicatorType > stupid_difference() ...@@ -348,183 +334,186 @@ Difference< IndicatorType, IndicatorType > stupid_difference()
} }
\endcode \endcode
* *
* \note Most likely you do not want to use this class diretly, but one of Difference, Sum or Product. * \note Most likely you do not want to use this class diretly, but one of
Difference, Sum or Product.
*/ */
template <class LeftType, class RightType, Combination comb> template <class LeftType, class RightType, Combinations comb>
class Combined : public GridFunctionInterface<typename SelectCombined<LeftType, RightType, comb>::E, class CombinedGridFunction
SelectCombined<LeftType, RightType, comb>::r, : public GridFunctionInterface<
SelectCombined<LeftType, RightType, comb>::rC, typename SelectCombinedGridFunction<LeftType, RightType, comb>::E,
typename SelectCombined<LeftType, RightType, comb>::R> SelectCombinedGridFunction<LeftType, RightType, comb>::r,
{ SelectCombinedGridFunction<LeftType, RightType, comb>::rC,
using BaseType = GridFunctionInterface<typename SelectCombined<LeftType, RightType, comb>::E, typename SelectCombinedGridFunction<LeftType, RightType, comb>::R> {
SelectCombined<LeftType, RightType, comb>::r, using BaseType = GridFunctionInterface<
SelectCombined<LeftType, RightType, comb>::rC, typename SelectCombinedGridFunction<LeftType, RightType, comb>::E,
typename SelectCombined<LeftType, RightType, comb>::R>; SelectCombinedGridFunction<LeftType, RightType, comb>::r,
SelectCombinedGridFunction<LeftType, RightType, comb>::rC,
typename SelectCombinedGridFunction<LeftType, RightType, comb>::R>;
using LeftStorageType = Common::ConstStorageProvider<LeftType>; using LeftStorageType = Common::ConstStorageProvider<LeftType>;
using RightStorageType = Common::ConstStorageProvider<RightType>; using RightStorageType = Common::ConstStorageProvider<RightType>;
using ThisType = Combined<LeftType, RightType, comb>; using ThisType = CombinedGridFunction<LeftType, RightType, comb>;
public: public:
using ElementType = typename BaseType::ElementType; using ElementType = typename BaseType::ElementType;
using LocalFunctionType = typename BaseType::LocalFunctionType; using LocalFunctionType = typename BaseType::LocalFunctionType;
Combined(const LeftType& left, const RightType& right, const std::string nm = "") CombinedGridFunction(const LeftType &left, const RightType &right,
: left_(Common::make_unique<LeftStorageType>(left)) const std::string nm = "")
, right_(Common::make_unique<RightStorageType>(right)) : left_(Common::make_unique<LeftStorageType>(left)),
, name_(nm.empty() right_(Common::make_unique<RightStorageType>(right)),
? SelectCombined<LeftType, RightType, comb>::type() + " of '" + left.name() + "' and '" + right.name() name_(nm.empty()
+ "'" ? SelectCombinedGridFunction<LeftType, RightType,
: nm) comb>::type() +
{ " of '" + left.name() + "' and '" + right.name() + "'"
} : nm) {}
Combined(const std::shared_ptr<const LeftType> left, CombinedGridFunction(const std::shared_ptr<const LeftType> left,
const std::shared_ptr<const RightType> right, const std::shared_ptr<const RightType> right,
const std::string nm = "") const std::string nm = "")
: left_(Common::make_unique<LeftStorageType>(left)) : left_(Common::make_unique<LeftStorageType>(left)),
, right_(Common::make_unique<RightStorageType>(right)) right_(Common::make_unique<RightStorageType>(right)),
, name_(nm.empty() name_(nm.empty()
? SelectCombined<LeftType, RightType, comb>::type() + " of '" + left_->access().name() + "' and '" ? SelectCombinedGridFunction<LeftType, RightType,
+ right_->access().name() comb>::type() +
+ "'" " of '" + left_->access().name() + "' and '" +
: nm) right_->access().name() + "'"
{ : nm) {}
}
CombinedGridFunction(ThisType &&source) = default;
Combined(ThisType&& source) = default;
CombinedGridFunction(const ThisType &other) = delete;
Combined(const ThisType& other) = delete;
ThisType &operator=(const ThisType &other) = delete;
ThisType& operator=(const ThisType& other) = delete;
ThisType &operator=(ThisType &&other) = delete;
ThisType& operator=(ThisType&& other) = delete;
std::unique_ptr<LocalFunctionType> local_function() const override final {
std::unique_ptr<LocalFunctionType> local_function() const override final using RealLocalFunctionType =
{ CombinedLocalFunction<LeftType, RightType, comb>;
using RealLocalFunctionType = CombinedLocalFunction<LeftType, RightType, comb>;
assert(left_); assert(left_);
assert(right_); assert(right_);
return Common::make_unique<RealLocalFunctionType>(left_->access(), right_->access()); return Common::make_unique<RealLocalFunctionType>(left_->access(),
right_->access());
} // ... local_function(...) } // ... local_function(...)
std::string type() const override final std::string type() const override final {
{ return SelectCombinedGridFunction<LeftType, RightType, comb>::type() +
return SelectCombined<LeftType, RightType, comb>::type() + " of '" + left_->access().type() + "' and '" " of '" + left_->access().type() + "' and '" +
+ right_->access().type() + "'"; right_->access().type() + "'";
} // ... type(...) } // ... type(...)
std::string name() const override final std::string name() const override final { return name_; }
{
return name_;
}
private: private:
std::unique_ptr<const LeftStorageType> left_; std::unique_ptr<const LeftStorageType> left_;
std::unique_ptr<const RightStorageType> right_; std::unique_ptr<const RightStorageType> right_;
const std::string name_; const std::string name_;
}; // class Combined }; // class CombinedGridFunction
} // namespace internal } // namespace internal
/** /**
* \brief Function representing the difference between two functions. * \brief Function representing the difference between two functions.
* *
* \see internal::Combined * \see internal::CombinedGridFunction
*/ */
template <class MinuendType, class SubtrahendType> template <class MinuendType, class SubtrahendType>
class DifferenceFunction : public internal::Combined<MinuendType, SubtrahendType, internal::Combination::difference> class DifferenceGridFunction
{ : public internal::CombinedGridFunction<
using BaseType = internal::Combined<MinuendType, SubtrahendType, internal::Combination::difference>; MinuendType, SubtrahendType, internal::Combinations::difference> {
using BaseType =
internal::CombinedGridFunction<MinuendType, SubtrahendType,
internal::Combinations::difference>;
public: public:
template <class... Args> template <class... Args>
explicit DifferenceFunction(Args&&... args) explicit DifferenceGridFunction(Args &&... args)
: BaseType(std::forward<Args>(args)...) : BaseType(std::forward<Args>(args)...) {}
{ }; // class DifferenceGridFunction
}
}; // class DifferenceFunction
/** /**
* \brief Function representing the sum of two functions. * \brief Function representing the sum of two functions.
* *
* \see internal::Combined * \see internal::CombinedGridFunction
*/ */
template <class LeftSummandType, class RightSummandType> template <class LeftSummandType, class RightSummandType>
class SumFunction : public internal::Combined<LeftSummandType, RightSummandType, internal::Combination::sum> class SumGridFunction
{ : public internal::CombinedGridFunction<LeftSummandType, RightSummandType,
using BaseType = internal::Combined<LeftSummandType, RightSummandType, internal::Combination::sum>; internal::Combinations::sum> {
using BaseType =
internal::CombinedGridFunction<LeftSummandType, RightSummandType,
internal::Combinations::sum>;
public: public:
template <class... Args> template <class... Args>
explicit SumFunction(Args&&... args) explicit SumGridFunction(Args &&... args)
: BaseType(std::forward<Args>(args)...) : BaseType(std::forward<Args>(args)...) {}
{ }; // class SumGridFunction
}
}; // class SumFunction
/** /**
* \brief Function representing the product of two functions. * \brief Function representing the product of two functions.
* *
* \see internal::Combined * \see internal::CombinedGridFunction
*/ */
template <class LeftSummandType, class RightSummandType> template <class LeftSummandType, class RightSummandType>
class ProductFunction : public internal::Combined<LeftSummandType, RightSummandType, internal::Combination::product> class ProductGridFunction
{ : public internal::CombinedGridFunction<LeftSummandType, RightSummandType,
using BaseType = internal::Combined<LeftSummandType, RightSummandType, internal::Combination::product>; internal::Combinations::product> {
using BaseType =
internal::CombinedGridFunction<LeftSummandType, RightSummandType,
internal::Combinations::product>;
public: public:
template <class... Args> template <class... Args>
explicit ProductFunction(Args&&... args) explicit ProductGridFunction(Args &&... args)
: BaseType(std::forward<Args>(args)...) : BaseType(std::forward<Args>(args)...) {}
{ }; // class ProductGridFunction
}
}; // class ProductFunction
template <class T1, class T2, class... Args> template <class T1, class T2, class... Args>
std::shared_ptr<DifferenceFunction<T1, T2>> make_difference(const T1& left, const T2& right, Args&&... args) std::shared_ptr<DifferenceGridFunction<T1, T2>>
{ make_difference(const T1 &left, const T2 &right, Args &&... args) {
return std::make_shared<DifferenceFunction<T1, T2>>(left, right, std::forward<Args>(args)...); return std::make_shared<DifferenceGridFunction<T1, T2>>(
left, right, std::forward<Args>(args)...);
} }
template <class T1, class T2, class... Args> template <class T1, class T2, class... Args>
std::shared_ptr<DifferenceFunction<T1, T2>> std::shared_ptr<DifferenceGridFunction<T1, T2>>
make_difference(std::shared_ptr<T1> left, std::shared_ptr<T2> right, Args&&... args) make_difference(std::shared_ptr<T1> left, std::shared_ptr<T2> right,
{ Args &&... args) {
return std::make_shared<DifferenceFunction<T1, T2>>(left, right, std::forward<Args>(args)...); return std::make_shared<DifferenceGridFunction<T1, T2>>(
left, right, std::forward<Args>(args)...);
} }
template <class T1, class T2, class... Args> template <class T1, class T2, class... Args>
std::shared_ptr<SumFunction<T1, T2>> make_sum(const T1& left, const T2& right, Args&&... args) std::shared_ptr<SumGridFunction<T1, T2>>
{ make_sum(const T1 &left, const T2 &right, Args &&... args) {
return std::make_shared<SumFunction<T1, T2>>(left, right, std::forward<Args>(args)...); return std::make_shared<SumGridFunction<T1, T2>>(left, right,
std::forward<Args>(args)...);
} }
template <class T1, class T2, class... Args> template <class T1, class T2, class... Args>
std::shared_ptr<SumFunction<T1, T2>> make_sum(std::shared_ptr<T1> left, std::shared_ptr<T2> right, Args&&... args) std::shared_ptr<SumGridFunction<T1, T2>>
{ make_sum(std::shared_ptr<T1> left, std::shared_ptr<T2> right, Args &&... args) {
return std::make_shared<SumFunction<T1, T2>>(left, right, std::forward<Args>(args)...); return std::make_shared<SumGridFunction<T1, T2>>(left, right,
std::forward<Args>(args)...);
} }
template <class T1, class T2, class... Args> template <class T1, class T2, class... Args>
std::shared_ptr<ProductFunction<T1, T2>> make_product(const T1& left, const T2& right, Args&&... args) std::shared_ptr<ProductGridFunction<T1, T2>>
{ make_product(const T1 &left, const T2 &right, Args &&... args) {
return std::make_shared<ProductFunction<T1, T2>>(left, right, std::forward<Args>(args)...); return std::make_shared<ProductGridFunction<T1, T2>>(
left, right, std::forward<Args>(args)...);
} }
template <class T1, class T2, class... Args> template <class T1, class T2, class... Args>
std::shared_ptr<ProductFunction<T1, T2>> std::shared_ptr<ProductGridFunction<T1, T2>>
make_product(std::shared_ptr<T1> left, std::shared_ptr<T2> right, Args&&... args) make_product(std::shared_ptr<T1> left, std::shared_ptr<T2> right,
{ Args &&... args) {
return std::make_shared<ProductFunction<T1, T2>>(left, right, std::forward<Args>(args)...); return std::make_shared<ProductGridFunction<T1, T2>>(
left, right, std::forward<Args>(args)...);
} }
} // namespace Functions } // namespace Functions
} // namespace XT } // namespace XT
} // namespace Dune } // namespace Dune
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment