Commit 4988a659 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'issue/function_overloads' into 'master'

Make the Vtk::Function overloads more robust and set better default values

See merge request extensions/dune-vtk!16
parents 3612f5f1 79f22d34
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
#include <dune/common/typetraits.hh> #include <dune/common/typetraits.hh>
#include <dune/common/version.hh> #include <dune/common/version.hh>
#include "localfunction.hh" #include <dune/vtk/localfunction.hh>
#include "types.hh" #include <dune/vtk/types.hh>
#include "utility/arguments.hh" #include <dune/vtk/utility/arguments.hh>
namespace Dune namespace Dune
{ {
...@@ -25,15 +25,19 @@ namespace Dune ...@@ -25,15 +25,19 @@ namespace Dune
template <class GridView> template <class GridView>
class Function class Function
{ {
template <class F>
using LocalFunction = decltype(localFunction(std::declval<F>()));
template <class LF, class E>
using HasBind = decltype(std::declval<std::decay_t<LF>&>().bind(std::declval<E>()));
using Element = typename GridView::template Codim<0>::Entity; using Element = typename GridView::template Codim<0>::Entity;
using LocalDomain = typename Element::Geometry::LocalCoordinate; using LocalDomain = typename Element::Geometry::LocalCoordinate;
template <class GF>
using IsGridFunction = decltype(localFunction(std::declval<GF>()));
template <class LocalFunction, class LF = std::decay_t<LocalFunction>>
using IsLocalFunction = decltype((
std::declval<LF&>().bind(std::declval<Element>()),
std::declval<LF&>().unbind(),
std::declval<LF>()(std::declval<LocalDomain>()),
0));
template <class F, class D> template <class F, class D>
using Range = std::decay_t<std::result_of_t<F(D)>>; using Range = std::decay_t<std::result_of_t<F(D)>>;
...@@ -71,15 +75,14 @@ namespace Dune ...@@ -71,15 +75,14 @@ namespace Dune
* NOTE: Stores the localFunction by value. * NOTE: Stores the localFunction by value.
**/ **/
template <class LF, class... Args, template <class LF, class... Args,
class = void_t<HasBind<LF,Element>>, class = IsLocalFunction<LF>>
class R = Range<LF,LocalDomain> > Function (LF&& localFct, std::string name, std::vector<int> components, Args&&... args)
Function (LF&& localFct, std::string name, std::vector<int> components, Args const&... args)
: localFct_(std::forward<LF>(localFct)) : localFct_(std::forward<LF>(localFct))
, name_(std::move(name)) , name_(std::move(name))
{ {
setComponents(std::move(components)); setComponents(std::move(components));
setRangeType(getArg<Vtk::RangeTypes>(args..., Vtk::RangeTypes::AUTO), components_.size()); setRangeType(getArg<Vtk::RangeTypes>(args..., Vtk::RangeTypes::UNSPECIFIED), components_.size());
setDataType(getArg<Vtk::DataTypes>(args..., Vtk::DataTypes::FLOAT32)); setDataType(getArg<Vtk::DataTypes>(args..., Vtk::DataTypes::FLOAT64));
} }
/// (2) Construct from a LocalFunction directly /// (2) Construct from a LocalFunction directly
...@@ -94,25 +97,37 @@ namespace Dune ...@@ -94,25 +97,37 @@ namespace Dune
* NOTE: Stores the localFunction by value. * NOTE: Stores the localFunction by value.
**/ **/
template <class LF, class... Args, template <class LF, class... Args,
class = void_t<HasBind<LF,Element>>, class = IsLocalFunction<LF>>
Function (LF&& localFct, std::string name, int ncomps, Args&&... args)
: Function(std::forward<LF>(localFct), std::move(name), allComponents(ncomps),
std::forward<Args>(args)...)
{}
/// (3) Construct from a LocalFunction directly.
/**
* Same as Constructor (1) or (2) but deduces the number of components from
* the static range type of the local-function. This defaults to 1 of no
* static size information could be extracted.
**/
template <class LF, class... Args,
class = IsLocalFunction<LF>,
class R = Range<LF,LocalDomain> > class R = Range<LF,LocalDomain> >
Function (LF&& localFct, std::string name, Args const&... args) Function (LF&& localFct, std::string name, Args&&... args)
: Function(std::forward<LF>(localFct), std::move(name), : Function(std::forward<LF>(localFct), std::move(name), sizeOf<R>(),
allComponents(getArg<int,unsigned int,long,unsigned long>(args..., sizeOf<R>())), std::forward<Args>(args)...)
getArg<Vtk::RangeTypes>(args..., Vtk::RangeTypes::AUTO),
getArg<Vtk::DataTypes>(args..., Vtk::DataTypes::FLOAT32))
{} {}
/// (3) Construct from a Vtk::Function /// (4) Construct from a Vtk::Function
template <class... Args> template <class... Args>
Function (Function<GridView> const& fct, std::string name, Args const&... args) explicit Function (Function<GridView> const& fct, Args&&... args)
: Function(fct.localFct_, std::move(name), : Function(fct.localFct_,
getArg<std::string, char const*>(args..., fct.name_),
getArg<int,unsigned int,long,unsigned long,std::vector<int>>(args..., fct.components_), getArg<int,unsigned int,long,unsigned long,std::vector<int>>(args..., fct.components_),
getArg<Vtk::RangeTypes>(args..., fct.rangeType_), getArg<Vtk::RangeTypes>(args..., fct.rangeType_),
getArg<Vtk::DataTypes>(args..., fct.dataType_)) getArg<Vtk::DataTypes>(args..., fct.dataType_))
{} {}
/// (4) Construct from a GridFunction /// (5) Construct from a GridFunction
/** /**
* \param fct A Grid(View)-function, providing a `localFunction(fct)` * \param fct A Grid(View)-function, providing a `localFunction(fct)`
* \param name The name to use as identification in the VTK file * \param name The name to use as identification in the VTK file
...@@ -121,37 +136,37 @@ namespace Dune ...@@ -121,37 +136,37 @@ namespace Dune
* *
* NOTE: Stores the localFunction(fct) by value. * NOTE: Stores the localFunction(fct) by value.
*/ */
template <class F, class... Args, template <class GF, class... Args,
disableCopyMove<Function, F> = 0, disableCopyMove<Function, GF> = 0,
class = void_t<LocalFunction<F>> > class = IsGridFunction<GF> >
Function (F&& fct, std::string name, Args&&... args) Function (GF&& fct, std::string name, Args&&... args)
: Function(localFunction(std::forward<F>(fct)), std::move(name), std::forward<Args>(args)...) : Function(localFunction(std::forward<GF>(fct)), std::move(name), std::forward<Args>(args)...)
{} {}
/// (5) Constructor that forwards the number of components and data type to the other constructor /// (6) Constructor that forwards the number of components and data type to the other constructor
template <class F> template <class F>
Function (F&& fct, Vtk::FieldInfo info) Function (F&& fct, Vtk::FieldInfo info, ...)
: Function(std::forward<F>(fct), info.name(), info.size(), info.rangeType(), info.dataType()) : Function(std::forward<F>(fct), info.name(), info.size(), info.rangeType(), info.dataType())
{} {}
/// (6) Construct from legacy VTKFunction /// (7) Construct from legacy VTKFunction
/** /**
* \param fct The Dune::VTKFunction to wrap * \param fct The Dune::VTKFunction to wrap
**/ **/
explicit Function (std::shared_ptr<VTKFunction<GridView> const> const& fct) explicit Function (std::shared_ptr<VTKFunction<GridView> const> const& fct, ...)
: localFct_(fct) : localFct_(fct)
, name_(fct->name()) , name_(fct->name())
{ {
setComponents(fct->ncomps()); setComponents(fct->ncomps());
#if DUNE_VERSION_LT(DUNE_GRID,2,7) #if DUNE_VERSION_LT(DUNE_GRID,2,7)
setDataType(Vtk::DataTypes::FLOAT32); setDataType(Vtk::DataTypes::FLOAT64);
#else #else
setDataType(dataTypeOf(fct->precision())); setDataType(dataTypeOf(fct->precision()));
#endif #endif
setRangeType(rangeTypeOf(fct->ncomps())); setRangeType(rangeTypeOf(fct->ncomps()));
} }
/// (7) Default constructor. After construction, the function is an an invalid state. /// (8) Default constructor. After construction, the function is an an invalid state.
Function () = default; Function () = default;
/// Create a LocalFunction /// Create a LocalFunction
...@@ -232,7 +247,7 @@ namespace Dune ...@@ -232,7 +247,7 @@ namespace Dune
Vtk::LocalFunction<GridView> localFct_; Vtk::LocalFunction<GridView> localFct_;
std::string name_; std::string name_;
std::vector<int> components_; std::vector<int> components_;
Vtk::DataTypes dataType_ = Vtk::DataTypes::FLOAT32; Vtk::DataTypes dataType_ = Vtk::DataTypes::FLOAT64;
Vtk::RangeTypes rangeType_ = Vtk::RangeTypes::UNSPECIFIED; Vtk::RangeTypes rangeType_ = Vtk::RangeTypes::UNSPECIFIED;
}; };
......
...@@ -76,13 +76,15 @@ int main (int argc, char** argv) ...@@ -76,13 +76,15 @@ int main (int argc, char** argv)
writer.addPointData(Vtk::Function<GridView>{f3, "vector3", 3}); // calls copy-constructor of Vtk::Function writer.addPointData(Vtk::Function<GridView>{f3, "vector3", 3}); // calls copy-constructor of Vtk::Function
writer.addPointData(Vtk::Function<GridView>{f3, "vector3", 3}, "vector4", 3); // calls grid-function constructor writer.addPointData(Vtk::Function<GridView>{f3, "vector3", 3}, "vector4", 3); // calls grid-function constructor
writer.addPointData(Vtk::Function<GridView>{f3, "vector5", {0,1}}); writer.addPointData(Vtk::Function<GridView>{f3, "vector5a", {0,1}});
writer.addPointData(Vtk::Function<GridView>{f3, "vector5"}, "vector6", std::vector{0}, Vtk::RangeTypes::VECTOR); writer.addPointData(Vtk::Function<GridView>{f3, "vector5"}, "vector5b", std::vector{0}, Vtk::RangeTypes::VECTOR);
// 6. pass argument to FieldInfo and Function in any order // 6. pass argument to FieldInfo and Function in any order
writer.addPointData(f3, Dune::Vtk::FieldInfo{"vector6", Vtk::DataTypes::FLOAT32, Vtk::RangeTypes::VECTOR, 3}); writer.addPointData(f3, Dune::Vtk::FieldInfo{"vector6", Vtk::DataTypes::FLOAT32, Vtk::RangeTypes::VECTOR, 3});
writer.addPointData(f3, "vector7", Vtk::DataTypes::FLOAT32, Vtk::RangeTypes::UNSPECIFIED, 3u); writer.addPointData(f3, "vector7", Vtk::DataTypes::FLOAT32, Vtk::RangeTypes::UNSPECIFIED, 3u);
writer.addPointData(f3, "vector8", std::vector{0,1});
// test default constructible // test default constructible
Vtk::Function<GridView> func0; Vtk::Function<GridView> func0;
...@@ -90,39 +92,38 @@ int main (int argc, char** argv) ...@@ -90,39 +92,38 @@ int main (int argc, char** argv)
Vtk::Function<GridView> func1{f1}; Vtk::Function<GridView> func1{f1};
VTK_ASSERT(func1.numComponents() == 1); VTK_ASSERT(func1.numComponents() == 1);
VTK_ASSERT(func1.rangeType() == Vtk::RangeTypes::SCALAR); VTK_ASSERT(func1.rangeType() == Vtk::RangeTypes::SCALAR);
VTK_ASSERT(func1.dataType() == Vtk::DataTypes::FLOAT32); writer.addPointData(func1, "p2");
writer.addPointData(func1);
// test constructible by local-function // test constructible by local-function
Vtk::Function<GridView> func2{f2, "f2"}; Vtk::Function<GridView> func2{f2, "func2"};
VTK_ASSERT(func2.numComponents() == 1); VTK_ASSERT(func2.numComponents() == 1);
VTK_ASSERT(func2.rangeType() == Vtk::RangeTypes::SCALAR); VTK_ASSERT(func2.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func2.dataType() == Vtk::DataTypes::FLOAT32); VTK_ASSERT(func2.dataType() == Vtk::DataTypes::FLOAT64);
writer.addPointData(func2); writer.addPointData(func2);
Vtk::Function<GridView> func3{f3, "f3", 3}; Vtk::Function<GridView> func3{f3, "func3", 3};
VTK_ASSERT(func3.numComponents() == 3); VTK_ASSERT(func3.numComponents() == 3);
VTK_ASSERT(func3.rangeType() == Vtk::RangeTypes::VECTOR); VTK_ASSERT(func3.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func3.dataType() == Vtk::DataTypes::FLOAT32); VTK_ASSERT(func3.dataType() == Vtk::DataTypes::FLOAT64);
writer.addPointData(func3); writer.addPointData(func3);
// test constructible with component vector // test constructible with component vector
Vtk::Function<GridView> func4a{f3, "f4a", 1}; Vtk::Function<GridView> func4a{f3, "func4a", 1};
VTK_ASSERT(func4a.numComponents() == 1); VTK_ASSERT(func4a.numComponents() == 1);
VTK_ASSERT(func4a.rangeType() == Vtk::RangeTypes::SCALAR); VTK_ASSERT(func4a.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func4a.dataType() == Vtk::DataTypes::FLOAT32); VTK_ASSERT(func4a.dataType() == Vtk::DataTypes::FLOAT64);
writer.addPointData(func4a); writer.addPointData(func4a);
Vtk::Function<GridView> func4b{f3, "f4b", {1}}; // == func4a Vtk::Function<GridView> func4b{f3, "func4b", {1}}; // == func4a
VTK_ASSERT(func4b.numComponents() == 1); VTK_ASSERT(func4b.numComponents() == 1);
VTK_ASSERT(func4b.rangeType() == Vtk::RangeTypes::SCALAR); VTK_ASSERT(func4b.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func4b.dataType() == Vtk::DataTypes::FLOAT32); VTK_ASSERT(func4b.dataType() == Vtk::DataTypes::FLOAT64);
writer.addPointData(func4b); writer.addPointData(func4b);
Vtk::Function<GridView> func4c{f3, "f4c", std::vector{1}}; Vtk::Function<GridView> func4c{f3, "func4c", std::vector{1}};
VTK_ASSERT(func4c.numComponents() == 1); VTK_ASSERT(func4c.numComponents() == 1);
VTK_ASSERT(func4c.rangeType() == Vtk::RangeTypes::SCALAR); VTK_ASSERT(func4c.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func4c.dataType() == Vtk::DataTypes::FLOAT32); VTK_ASSERT(func4c.dataType() == Vtk::DataTypes::FLOAT64);
writer.addPointData(func4c); writer.addPointData(func4c);
// Test copy-constructible // Test copy-constructible
...@@ -141,13 +142,13 @@ int main (int argc, char** argv) ...@@ -141,13 +142,13 @@ int main (int argc, char** argv)
VTK_ASSERT(func7.numComponents() == func3.numComponents()); VTK_ASSERT(func7.numComponents() == func3.numComponents());
VTK_ASSERT(func7.rangeType() == func3.rangeType()); VTK_ASSERT(func7.rangeType() == func3.rangeType());
VTK_ASSERT(func7.dataType() == func3.dataType()); VTK_ASSERT(func7.dataType() == func3.dataType());
writer.addPointData(func7, "f7"); writer.addPointData(func7, "func7");
auto func8 = std::move(func6); auto func8 = std::move(func6);
VTK_ASSERT(func8.numComponents() == func3.numComponents()); VTK_ASSERT(func8.numComponents() == func3.numComponents());
VTK_ASSERT(func8.rangeType() == func3.rangeType()); VTK_ASSERT(func8.rangeType() == func3.rangeType());
VTK_ASSERT(func8.dataType() == func3.dataType()); VTK_ASSERT(func8.dataType() == func3.dataType());
writer.addPointData(func8, "f8"); writer.addPointData(func8, "func8");
// test template-argument deduction // test template-argument deduction
Vtk::Function func9a{func8}; Vtk::Function func9a{func8};
...@@ -155,22 +156,22 @@ int main (int argc, char** argv) ...@@ -155,22 +156,22 @@ int main (int argc, char** argv)
VTK_ASSERT(func9a.rangeType() == func8.rangeType()); VTK_ASSERT(func9a.rangeType() == func8.rangeType());
VTK_ASSERT(func9a.dataType() == func8.dataType()); VTK_ASSERT(func9a.dataType() == func8.dataType());
Vtk::Function func9b{func8, "f9"}; Vtk::Function func9b{func8, "func9"};
VTK_ASSERT(func9b.numComponents() == func8.numComponents()); VTK_ASSERT(func9b.numComponents() == func8.numComponents());
VTK_ASSERT(func9b.rangeType() == func8.rangeType()); VTK_ASSERT(func9b.rangeType() == func8.rangeType());
VTK_ASSERT(func9b.dataType() == func8.dataType()); VTK_ASSERT(func9b.dataType() == func8.dataType());
Vtk::Function func9c{func8, "f9", 2}; Vtk::Function func9c{func8, "func9", 2};
VTK_ASSERT(func9c.numComponents() == 3); VTK_ASSERT(func9c.numComponents() == 2);
VTK_ASSERT(func9c.rangeType() == func8.rangeType()); VTK_ASSERT(func9c.rangeType() == func8.rangeType());
VTK_ASSERT(func9c.dataType() == func8.dataType()); VTK_ASSERT(func9c.dataType() == func8.dataType());
Vtk::Function func9d{func8, "f9", std::vector{0}}; Vtk::Function func9d{func8, "func9", std::vector{0}};
VTK_ASSERT(func9d.numComponents() == 3); VTK_ASSERT(func9d.numComponents() == 1);
VTK_ASSERT(func9d.rangeType() == func8.rangeType()); VTK_ASSERT(func9d.rangeType() == func8.rangeType());
VTK_ASSERT(func9d.dataType() == func8.dataType()); VTK_ASSERT(func9d.dataType() == func8.dataType());
Vtk::Function func9e{func8, "f9", Vtk::RangeTypes::SCALAR}; Vtk::Function func9e{func8, "func9", Vtk::RangeTypes::SCALAR};
VTK_ASSERT(func9e.numComponents() == 1); VTK_ASSERT(func9e.numComponents() == 1);
VTK_ASSERT(func9e.rangeType() == Vtk::RangeTypes::SCALAR); VTK_ASSERT(func9e.rangeType() == Vtk::RangeTypes::SCALAR);
VTK_ASSERT(func9e.dataType() == func8.dataType()); VTK_ASSERT(func9e.dataType() == func8.dataType());
......
...@@ -105,7 +105,8 @@ namespace Dune ...@@ -105,7 +105,8 @@ namespace Dune
template <class Function, class... Args> template <class Function, class... Args>
VtkWriterInterface& addPointData (Function&& fct, Args&&... args) VtkWriterInterface& addPointData (Function&& fct, Args&&... args)
{ {
pointData_.emplace_back(std::forward<Function>(fct), std::forward<Args>(args)...); pointData_.emplace_back(std::forward<Function>(fct), std::forward<Args>(args)...,
datatype_, Vtk::RangeTypes::AUTO);
return *this; return *this;
} }
...@@ -122,7 +123,8 @@ namespace Dune ...@@ -122,7 +123,8 @@ namespace Dune
template <class Function, class... Args> template <class Function, class... Args>
VtkWriterInterface& addCellData (Function&& fct, Args&&... args) VtkWriterInterface& addCellData (Function&& fct, Args&&... args)
{ {
cellData_.emplace_back(std::forward<Function>(fct), std::forward<Args>(args)...); cellData_.emplace_back(std::forward<Function>(fct), std::forward<Args>(args)...,
datatype_, Vtk::RangeTypes::AUTO);
return *this; return *this;
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment