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 @@
#include <dune/common/typetraits.hh>
#include <dune/common/version.hh>
#include "localfunction.hh"
#include "types.hh"
#include "utility/arguments.hh"
#include <dune/vtk/localfunction.hh>
#include <dune/vtk/types.hh>
#include <dune/vtk/utility/arguments.hh>
namespace Dune
{
......@@ -25,15 +25,19 @@ namespace Dune
template <class GridView>
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 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>
using Range = std::decay_t<std::result_of_t<F(D)>>;
......@@ -71,15 +75,14 @@ namespace Dune
* NOTE: Stores the localFunction by value.
**/
template <class LF, class... Args,
class = void_t<HasBind<LF,Element>>,
class R = Range<LF,LocalDomain> >
Function (LF&& localFct, std::string name, std::vector<int> components, Args const&... args)
class = IsLocalFunction<LF>>
Function (LF&& localFct, std::string name, std::vector<int> components, Args&&... args)
: localFct_(std::forward<LF>(localFct))
, name_(std::move(name))
{
setComponents(std::move(components));
setRangeType(getArg<Vtk::RangeTypes>(args..., Vtk::RangeTypes::AUTO), components_.size());
setDataType(getArg<Vtk::DataTypes>(args..., Vtk::DataTypes::FLOAT32));
setRangeType(getArg<Vtk::RangeTypes>(args..., Vtk::RangeTypes::UNSPECIFIED), components_.size());
setDataType(getArg<Vtk::DataTypes>(args..., Vtk::DataTypes::FLOAT64));
}
/// (2) Construct from a LocalFunction directly
......@@ -94,25 +97,37 @@ namespace Dune
* NOTE: Stores the localFunction by value.
**/
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> >
Function (LF&& localFct, std::string name, Args const&... args)
: Function(std::forward<LF>(localFct), std::move(name),
allComponents(getArg<int,unsigned int,long,unsigned long>(args..., sizeOf<R>())),
getArg<Vtk::RangeTypes>(args..., Vtk::RangeTypes::AUTO),
getArg<Vtk::DataTypes>(args..., Vtk::DataTypes::FLOAT32))
Function (LF&& localFct, std::string name, Args&&... args)
: Function(std::forward<LF>(localFct), std::move(name), sizeOf<R>(),
std::forward<Args>(args)...)
{}
/// (3) Construct from a Vtk::Function
/// (4) Construct from a Vtk::Function
template <class... Args>
Function (Function<GridView> const& fct, std::string name, Args const&... args)
: Function(fct.localFct_, std::move(name),
explicit Function (Function<GridView> const& fct, Args&&... args)
: 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<Vtk::RangeTypes>(args..., fct.rangeType_),
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 name The name to use as identification in the VTK file
......@@ -121,37 +136,37 @@ namespace Dune
*
* NOTE: Stores the localFunction(fct) by value.
*/
template <class F, class... Args,
disableCopyMove<Function, F> = 0,
class = void_t<LocalFunction<F>> >
Function (F&& fct, std::string name, Args&&... args)
: Function(localFunction(std::forward<F>(fct)), std::move(name), std::forward<Args>(args)...)
template <class GF, class... Args,
disableCopyMove<Function, GF> = 0,
class = IsGridFunction<GF> >
Function (GF&& fct, std::string name, 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>
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())
{}
/// (6) Construct from legacy VTKFunction
/// (7) Construct from legacy VTKFunction
/**
* \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)
, name_(fct->name())
{
setComponents(fct->ncomps());
#if DUNE_VERSION_LT(DUNE_GRID,2,7)
setDataType(Vtk::DataTypes::FLOAT32);
setDataType(Vtk::DataTypes::FLOAT64);
#else
setDataType(dataTypeOf(fct->precision()));
#endif
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;
/// Create a LocalFunction
......@@ -232,7 +247,7 @@ namespace Dune
Vtk::LocalFunction<GridView> localFct_;
std::string name_;
std::vector<int> components_;
Vtk::DataTypes dataType_ = Vtk::DataTypes::FLOAT32;
Vtk::DataTypes dataType_ = Vtk::DataTypes::FLOAT64;
Vtk::RangeTypes rangeType_ = Vtk::RangeTypes::UNSPECIFIED;
};
......
......@@ -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}, "vector4", 3); // calls grid-function constructor
writer.addPointData(Vtk::Function<GridView>{f3, "vector5", {0,1}});
writer.addPointData(Vtk::Function<GridView>{f3, "vector5"}, "vector6", std::vector{0}, Vtk::RangeTypes::VECTOR);
writer.addPointData(Vtk::Function<GridView>{f3, "vector5a", {0,1}});
writer.addPointData(Vtk::Function<GridView>{f3, "vector5"}, "vector5b", std::vector{0}, Vtk::RangeTypes::VECTOR);
// 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, "vector7", Vtk::DataTypes::FLOAT32, Vtk::RangeTypes::UNSPECIFIED, 3u);
writer.addPointData(f3, "vector8", std::vector{0,1});
// test default constructible
Vtk::Function<GridView> func0;
......@@ -90,39 +92,38 @@ int main (int argc, char** argv)
Vtk::Function<GridView> func1{f1};
VTK_ASSERT(func1.numComponents() == 1);
VTK_ASSERT(func1.rangeType() == Vtk::RangeTypes::SCALAR);
VTK_ASSERT(func1.dataType() == Vtk::DataTypes::FLOAT32);
writer.addPointData(func1);
writer.addPointData(func1, "p2");
// 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.rangeType() == Vtk::RangeTypes::SCALAR);
VTK_ASSERT(func2.dataType() == Vtk::DataTypes::FLOAT32);
VTK_ASSERT(func2.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func2.dataType() == Vtk::DataTypes::FLOAT64);
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.rangeType() == Vtk::RangeTypes::VECTOR);
VTK_ASSERT(func3.dataType() == Vtk::DataTypes::FLOAT32);
VTK_ASSERT(func3.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func3.dataType() == Vtk::DataTypes::FLOAT64);
writer.addPointData(func3);
// 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.rangeType() == Vtk::RangeTypes::SCALAR);
VTK_ASSERT(func4a.dataType() == Vtk::DataTypes::FLOAT32);
VTK_ASSERT(func4a.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func4a.dataType() == Vtk::DataTypes::FLOAT64);
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.rangeType() == Vtk::RangeTypes::SCALAR);
VTK_ASSERT(func4b.dataType() == Vtk::DataTypes::FLOAT32);
VTK_ASSERT(func4b.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func4b.dataType() == Vtk::DataTypes::FLOAT64);
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.rangeType() == Vtk::RangeTypes::SCALAR);
VTK_ASSERT(func4c.dataType() == Vtk::DataTypes::FLOAT32);
VTK_ASSERT(func4c.rangeType() == Vtk::RangeTypes::UNSPECIFIED);
VTK_ASSERT(func4c.dataType() == Vtk::DataTypes::FLOAT64);
writer.addPointData(func4c);
// Test copy-constructible
......@@ -141,13 +142,13 @@ int main (int argc, char** argv)
VTK_ASSERT(func7.numComponents() == func3.numComponents());
VTK_ASSERT(func7.rangeType() == func3.rangeType());
VTK_ASSERT(func7.dataType() == func3.dataType());
writer.addPointData(func7, "f7");
writer.addPointData(func7, "func7");
auto func8 = std::move(func6);
VTK_ASSERT(func8.numComponents() == func3.numComponents());
VTK_ASSERT(func8.rangeType() == func3.rangeType());
VTK_ASSERT(func8.dataType() == func3.dataType());
writer.addPointData(func8, "f8");
writer.addPointData(func8, "func8");
// test template-argument deduction
Vtk::Function func9a{func8};
......@@ -155,22 +156,22 @@ int main (int argc, char** argv)
VTK_ASSERT(func9a.rangeType() == func8.rangeType());
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.rangeType() == func8.rangeType());
VTK_ASSERT(func9b.dataType() == func8.dataType());
Vtk::Function func9c{func8, "f9", 2};
VTK_ASSERT(func9c.numComponents() == 3);
Vtk::Function func9c{func8, "func9", 2};
VTK_ASSERT(func9c.numComponents() == 2);
VTK_ASSERT(func9c.rangeType() == func8.rangeType());
VTK_ASSERT(func9c.dataType() == func8.dataType());
Vtk::Function func9d{func8, "f9", std::vector{0}};
VTK_ASSERT(func9d.numComponents() == 3);
Vtk::Function func9d{func8, "func9", std::vector{0}};
VTK_ASSERT(func9d.numComponents() == 1);
VTK_ASSERT(func9d.rangeType() == func8.rangeType());
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.rangeType() == Vtk::RangeTypes::SCALAR);
VTK_ASSERT(func9e.dataType() == func8.dataType());
......
......@@ -105,7 +105,8 @@ namespace Dune
template <class Function, class... 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;
}
......@@ -122,7 +123,8 @@ namespace Dune
template <class Function, class... 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;
}
......
Markdown is supported
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