Commit b8b41e2a authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Cleanup of Function and LocalFunction interface, add setter and getter and...

Cleanup of Function and LocalFunction interface, add setter and getter and make LocalFunction evaluate method avare of numComponents
parent 96f8bfb5
......@@ -11,13 +11,13 @@ std::vector<T> DataCollectorInterface<GV,D,P>
::cellDataImpl (VtkFunction const& fct) const
{
std::vector<T> data;
data.reserve(this->numCells() * fct.ncomps());
data.reserve(this->numCells() * fct.numComponents());
auto localFct = localFunction(fct);
for (auto const& e : elements(gridView_, partition)) {
localFct.bind(e);
auto refElem = referenceElement<T,dim>(e.type());
for (int comp = 0; comp < fct.ncomps(); ++comp)
for (int comp = 0; comp < fct.numComponents(); ++comp)
data.emplace_back(localFct.evaluate(comp, refElem.position(0,0)));
localFct.unbind();
}
......
......@@ -119,7 +119,7 @@ namespace Dune
template <class T, class GlobalFunction>
std::vector<T> pointDataImpl (GlobalFunction const& fct) const
{
std::vector<T> data(numPoints_ * fct.ncomps());
std::vector<T> data(numPoints_ * fct.numComponents());
auto const& indexSet = gridView_.indexSet();
auto localFct = localFunction(fct);
for (auto const& e : elements(gridView_, partition)) {
......@@ -127,8 +127,8 @@ namespace Dune
Vtk::CellType cellType{e.type()};
auto refElem = referenceElement(e.geometry());
for (unsigned int j = 0; j < e.subEntities(dim); ++j) {
std::size_t idx = fct.ncomps() * indexMap_[indexSet.subIndex(e,cellType.permutation(j),dim)];
for (int comp = 0; comp < fct.ncomps(); ++comp)
std::size_t idx = fct.numComponents() * indexMap_[indexSet.subIndex(e,cellType.permutation(j),dim)];
for (int comp = 0; comp < fct.numComponents(); ++comp)
data[idx + comp] = T(localFct.evaluate(comp, refElem.position(cellType.permutation(j),dim)));
}
localFct.unbind();
......
......@@ -102,7 +102,7 @@ namespace Dune
template <class T, class GlobalFunction>
std::vector<T> pointDataImpl (GlobalFunction const& fct) const
{
std::vector<T> data(numPoints_ * fct.ncomps());
std::vector<T> data(numPoints_ * fct.numComponents());
auto const& indexSet = gridView_.indexSet();
auto localFct = localFunction(fct);
for (auto const& e : elements(gridView_, partition)) {
......@@ -110,8 +110,8 @@ namespace Dune
Vtk::CellType cellType{e.type()};
auto refElem = referenceElement(e.geometry());
for (unsigned int j = 0; j < e.subEntities(dim); ++j) {
std::size_t idx = fct.ncomps() * indexMap_[indexSet.subIndex(e, cellType.permutation(j), dim)];
for (int comp = 0; comp < fct.ncomps(); ++comp)
std::size_t idx = fct.numComponents() * indexMap_[indexSet.subIndex(e, cellType.permutation(j), dim)];
for (int comp = 0; comp < fct.numComponents(); ++comp)
data[idx + comp] = T(localFct.evaluate(comp, refElem.position(cellType.permutation(j),dim)));
}
localFct.unbind();
......
......@@ -154,7 +154,7 @@ namespace Dune
template <class T, class GlobalFunction>
std::vector<T> pointDataImpl (GlobalFunction const& fct) const
{
int nComps = fct.ncomps();
int nComps = fct.numComponents();
std::vector<T> data(this->numPoints() * nComps);
auto const& indexSet = gridView_.indexSet();
......
......@@ -113,7 +113,7 @@ namespace Dune
template <class T, class GlobalFunction>
std::vector<T> pointDataImpl (GlobalFunction const& fct) const
{
std::vector<T> data(this->numPoints() * fct.ncomps());
std::vector<T> data(this->numPoints() * fct.numComponents());
auto const& indexSet = gridView_.indexSet();
auto localFct = localFunction(fct);
for (auto const& e : elements(gridView_, partition)) {
......@@ -122,14 +122,14 @@ namespace Dune
auto refElem = referenceElement(e.geometry());
for (unsigned int j = 0; j < e.subEntities(dim); ++j) {
int k = cellType.permutation(j);
std::size_t idx = fct.ncomps() * indexSet.subIndex(e, k, dim);
for (int comp = 0; comp < fct.ncomps(); ++comp)
std::size_t idx = fct.numComponents() * indexSet.subIndex(e, k, dim);
for (int comp = 0; comp < fct.numComponents(); ++comp)
data[idx + comp] = T(localFct.evaluate(comp, refElem.position(k, dim)));
}
for (unsigned int j = 0; j < e.subEntities(dim-1); ++j) {
int k = cellType.permutation(e.subEntities(dim) + j);
std::size_t idx = fct.ncomps() * (indexSet.subIndex(e, k, dim-1) + gridView_.size(dim));
for (int comp = 0; comp < fct.ncomps(); ++comp)
std::size_t idx = fct.numComponents() * (indexSet.subIndex(e, k, dim-1) + gridView_.size(dim));
for (int comp = 0; comp < fct.numComponents(); ++comp)
data[idx + comp] = T(localFct.evaluate(comp, refElem.position(k, dim-1)));
}
localFct.unbind();
......
......@@ -21,14 +21,11 @@ namespace Dune
using Entity = typename Interface::Entity;
using LocalCoordinate = typename Interface::LocalCoordinate;
template <class F, class D>
using Range = std::decay_t<decltype(std::declval<F>()(std::declval<D>()))>;
public:
/// Constructor. Stores a copy of the passed `localFct` in a local variable.
template <class LocalFct,
disableCopyMove<Self, LocalFct> = 0>
LocalFunctionWrapper (LocalFct&& localFct)
explicit LocalFunctionWrapper (LocalFct&& localFct)
: localFct_(std::forward<LocalFct>(localFct))
{}
......@@ -67,22 +64,22 @@ namespace Dune
return comp < N ? vec[comp] : 0.0;
}
// Evaluate a component of a vector valued data
template <class T,
std::enable_if_t<IsIndexable<T,int>::value, int> = 0>
double evaluateImpl (int comp, T const& value) const
{
return value[comp];
}
// Evaluate a component of a vector valued data
template <class T,
std::enable_if_t<IsIndexable<T,int>::value, int> = 0>
double evaluateImpl (int comp, T const& value) const
{
return value[comp];
}
// Return the scalar values
template <class T,
std::enable_if_t<not IsIndexable<T,int>::value, int> = 0>
double evaluateImpl (int comp, T const& value) const
{
assert(comp == 0);
return value;
}
// Return the scalar values
template <class T,
std::enable_if_t<not IsIndexable<T,int>::value, int> = 0>
double evaluateImpl (int comp, T const& value) const
{
assert(comp == 0);
return value;
}
private:
LocalFunction localFct_;
......
#pragma once
#include <optional>
#include <type_traits>
#include <dune/common/std/type_traits.hh>
#include <dune/common/typetraits.hh>
#include "localfunction.hh"
#include "types.hh"
......@@ -26,10 +25,14 @@ namespace Dune
template <class F>
using LocalFunction = decltype(localFunction(std::declval<F>()));
using Domain = typename GridView::template Codim<0>::Entity::Geometry::LocalCoordinate;
template <class LF, class E>
using HasBind = decltype(std::declval<LF>().bind(std::declval<E>()));
template <class F>
using Range = std::decay_t<std::result_of_t<F(Domain)>>;
using Element = typename GridView::template Codim<0>::Entity;
using LocalDomain = typename Element::Geometry::LocalCoordinate;
template <class F, class D>
using Range = std::decay_t<std::result_of_t<F(D)>>;
private:
......@@ -48,52 +51,70 @@ namespace Dune
static constexpr int sizeOf () { return decltype(sizeOfImpl(std::declval<T>()))::value; }
public:
/// Constructor VtkFunction from legacy VTKFunction
/// Construct from a LocalFunction directly
/**
* \param fct The VTKFunction to wrap
* \param type The VTK datatype how to write the function values to the output [Vtk::DataTypes::FLOAT64]
**/
Function (std::shared_ptr<VTKFunction<GridView> const> const& fct,
std::optional<Vtk::DataTypes> type = {})
: localFct_(fct)
, name_(fct->name())
, ncomps_(fct->ncomps())
, type_(type ? *type : Vtk::DataTypes::FLOAT32)
{}
/// Construct VtkFunction from dune-functions GridFunction with Signature
// NOTE: Stores the localFunction(fct) by value.
/**
* \param fct A Grid(View)-function, providing a `localFunction(fct)`
* \param name The name to use component identification in the VTK file
* \param localFct A local-function, providing a `bind(Element)` and an `operator()(LocalDomain)`
* \param name The name to use as identification in the VTK file
* \param ncomps Number of components of the pointwise data. Is extracted
* from the range type of the GridFunction if not given.
* \param type The \ref Vtk::DataTypes used in the output. E.g. FLOAT32,
* or FLOAT64. Is extracted from the range type of the
* GridFunction if not given.
*
* NOTE: Stores the localFunction by value.
**/
template <class F,
class = void_t<LocalFunction<F>> >
Function (F&& fct, std::string name,
std::optional<int> ncomps = {},
std::optional<Vtk::DataTypes> type = {})
: localFct_(localFunction(std::forward<F>(fct)))
template <class LF,
class = void_t<HasBind<LF,Element>>,
class R = Range<LF,LocalDomain> >
Function (LF&& localFct, std::string name, int ncomps = sizeOf<R>(),
Vtk::DataTypes type = Vtk::dataTypeOf<R>())
: localFct_(std::forward<LF>(localFct))
, name_(std::move(name))
{
using R = Range<LocalFunction<F>>;
ncomps_ = ncomps ? *ncomps : sizeOf<R>();
type_ = type ? *type : Vtk::Map::type<R>();
setNumComponents(ncomps);
setDataType(type);
}
/// Constructor that forward the number of components and data type to the other constructor
template <class F,
/// 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
*
* Forwards all other arguments to the local-function constructor.
*
* NOTE: Stores the localFunction(fct) by value.
*/
template <class F, class... Args,
disableCopyMove<Function,F> = 0,
class = void_t<LocalFunction<F>> >
Function (F&& fct, Vtk::FieldInfo fieldInfo,
std::optional<Vtk::DataTypes> type = {})
: Function(std::forward<F>(fct), fieldInfo.name(), fieldInfo.ncomps(), type)
Function (F&& fct, std::string name, Args&&... args)
: Function(localFunction(std::forward<F>(fct)), std::move(name), std::forward<Args>(args)...)
{}
/// Constructor that forwards the number of components and data type to the other constructor
template <class F>
Function (F&& fct, Vtk::FieldInfo info)
: Function(std::forward<F>(fct), info.name(), info.numComponents(), info.dataType())
{}
/// Constructor that forwards the number of components and data type to the other constructor
template <class F>
Function (F&& fct, Dune::VTK::FieldInfo info)
: Function(std::forward<F>(fct), info.name(), info.size(), dataTypeOf(info.precision()))
{}
/// Construct from legacy VTKFunction
/**
* \param fct The Dune::VTKFunction to wrap
**/
explicit Function (std::shared_ptr<VTKFunction<GridView> const> const& fct)
: localFct_(fct)
, name_(fct->name())
{
setNumComponents(fct->ncomps());
setDataType(dataTypeOf(fct->precision()));
}
Function () = default;
/// Create a LocalFunction
......@@ -108,23 +129,42 @@ namespace Dune
return name_;
}
/// Return the number of components of the Range
int ncomps () const
/// Set the function name
void setName (std::string name)
{
name_ = std::move(name);
}
/// Return the number of components of the Range as it is written to the file
int numComponents () const
{
return ncomps_ > 3 ? 9 : ncomps_ > 1 ? 3 : 1; // tensor, vector, scalar
}
/// Set the number of components of the Range
void setNumComponents (int ncomps)
{
ncomps_ = ncomps;
localFct_.setNumComponents(ncomps_);
}
/// Return the VTK Datatype associated with the functions range type
Vtk::DataTypes type () const
Vtk::DataTypes dataType () const
{
return dataType_;
}
/// Set the data-type for the components
void setDataType (Vtk::DataTypes type)
{
return type_;
dataType_ = type;
}
private:
Vtk::LocalFunction<GridView> localFct_;
std::string name_;
int ncomps_ = 1;
Vtk::DataTypes type_ = Vtk::DataTypes::FLOAT32;
Vtk::DataTypes dataType_ = Vtk::DataTypes::FLOAT32;
};
} // end namespace Vtk
......
......@@ -21,7 +21,7 @@ namespace Dune
public:
/// Constructor. Stores a shared pointer to the passed Dune::VTKFunction
VTKLocalFunctionWrapper (std::shared_ptr<VTKFunction<GridView> const> const& fct)
explicit VTKLocalFunctionWrapper (std::shared_ptr<VTKFunction<GridView> const> const& fct)
: fct_(fct)
{}
......
......@@ -28,18 +28,48 @@ namespace Dune
template <class LF, class E>
using HasBind = decltype(std::declval<LF>().bind(std::declval<E>()));
private:
struct RangeProxy
{
using field_type = double;
RangeProxy (LocalFunctionInterface<GridView> const& localFct,
std::size_t size, LocalCoordinate const& local)
: localFct_(localFct)
, size_(size)
, local_(local)
{}
std::size_t size () const
{
return size_;
}
double operator[] (std::size_t i) const
{
return i < size_ ? localFct_.evaluate(i, local_) : 0.0;
}
private:
LocalFunctionInterface<GridView> const& localFct_;
std::size_t size_;
LocalCoordinate local_;
};
public:
/// Construct the Vtk::LocalFunction from any function object that has a bind(element) method.
template <class LF,
disableCopyMove<Self, LF> = 0,
class = void_t<HasBind<LF,Entity>> >
LocalFunction (LF&& lf)
explicit LocalFunction (LF&& lf, int ncomps = 1)
: localFct_(std::make_shared<LocalFunctionWrapper<GridView,LF>>(std::forward<LF>(lf)))
, ncomps_(ncomps)
{}
/// Construct a Vtk::LocalFunction from a legacy VTKFunction
LocalFunction (std::shared_ptr<VTKFunction<GridView> const> const& lf)
explicit LocalFunction (std::shared_ptr<VTKFunction<GridView> const> const& lf, int ncomps = 1)
: localFct_(std::make_shared<VTKLocalFunctionWrapper<GridView>>(lf))
, ncomps_(ncomps)
{}
/// Allow the default construction of a Vtk::LocalFunction
......@@ -59,15 +89,28 @@ namespace Dune
localFct_->unbind();
}
/// Return a proxy object to access the components of the range vector
RangeProxy operator() (LocalCoordinate const& xi) const
{
assert(bool(localFct_));
return {*localFct_, ncomps_, xi};
}
/// Evaluate the `comp` component of the Range value at local coordinate `xi`
double evaluate (int comp, LocalCoordinate const& xi) const
{
assert(bool(localFct_));
return localFct_->evaluate(comp, xi);
return comp < ncomps_ ? localFct_->evaluate(comp, xi) : 0.0;
}
void setNumComponents (int ncomps)
{
ncomps_ = ncomps;
}
private:
std::shared_ptr<LocalFunctionInterface<GridView>> localFct_ = nullptr;
int ncomps_ = 1;
};
} // end namespace Vtk
......
#include "types.hh"
#include <iostream>
#include <map>
#include <dune/common/exceptions.hh>
......@@ -20,6 +21,22 @@ std::string to_string (FormatTypes type)
}
}
FormatTypes formatTypeOf (Dune::VTK::OutputType o)
{
switch (o) {
case Dune::VTK::ascii: return Vtk::ASCII;
// case Dune::VTK::base64: return Vtk::BASE64;
case Dune::VTK::appendedraw: return Vtk::BINARY;
// case Dune::VTK::appendedbase64: return Vtk::APPENDED_BASE64;
// case Dune::VTK::binarycompressed: return Vtk::COMPRESSED;
// case Dune::VTK::compressedappended: return Vtk::APPENDED_COMPRESSED;
default:
DUNE_THROW(RangeError, "OutputType not supported.");
std::abort();
}
}
std::string to_string (DataTypes type)
{
switch (type) {
......@@ -39,6 +56,39 @@ std::string to_string (DataTypes type)
}
}
Vtk::DataTypes dataTypeOf (Dune::VTK::Precision p)
{
switch (p) {
case Dune::VTK::Precision::int32: return Vtk::INT32;
case Dune::VTK::Precision::uint8: return Vtk::UINT8;
case Dune::VTK::Precision::uint32: return Vtk::UINT32;
case Dune::VTK::Precision::float32: return Vtk::FLOAT32;
case Dune::VTK::Precision::float64: return Vtk::FLOAT64;
default:
DUNE_THROW(RangeError, "Precision not supported.");
std::abort();
}
}
Vtk::DataTypes dataTypeOf (std::string s)
{
static const std::map<std::string, Vtk::DataTypes> to_datatype{
{"Int8", INT8},
{"UInt8", UINT8},
{"Int16", INT16},
{"UInt16", UINT16},
{"Int32", INT32},
{"UInt32", UINT32},
{"Int64", INT64},
{"UInt64", UINT64},
{"Float32", FLOAT32},
{"Float64", FLOAT64}
};
auto it = to_datatype.find(s);
return it != to_datatype.end() ? it->second : Vtk::UNKNOWN;
}
std::string to_string (CompressorTypes type)
{
switch (type) {
......@@ -51,6 +101,7 @@ std::string to_string (CompressorTypes type)
}
}
GeometryType to_geometry (std::uint8_t cell)
{
switch (cell) {
......@@ -84,21 +135,6 @@ GeometryType to_geometry (std::uint8_t cell)
}
std::map<std::string, DataTypes> Map::to_datatype = {
{"Int8", INT8},
{"UInt8", UINT8},
{"Int16", INT16},
{"UInt16", UINT16},
{"Int32", INT32},
{"UInt32", UINT32},
{"Int64", INT64},
{"UInt64", UINT64},
{"Float32", FLOAT32},
{"Float64", FLOAT64}
};
CellType::CellType (GeometryType const& t, CellParametrization parametrization)
: noPermutation_(true)
{
......
......@@ -8,6 +8,7 @@
#include <dune/common/ftraits.hh>
#include <dune/common/typelist.hh>
#include <dune/geometry/type.hh>
#include <dune/grid/io/file/vtk/common.hh>
#include <dune/vtk/utility/errors.hh>
namespace Dune
......@@ -22,6 +23,10 @@ namespace Dune
};
std::string to_string (FormatTypes);
/// Map the dune-grid OutputType to FormatTypes
FormatTypes formatTypeOf(Dune::VTK::OutputType);
enum DataTypes {
UNKNOWN = 0,
INT8, UINT8,
......@@ -33,72 +38,30 @@ namespace Dune
};
std::string to_string (DataTypes);
enum CompressorTypes {
NONE = 0,
ZLIB,
LZ4,
LZMA
};
std::string to_string (CompressorTypes);
// Map a dune-grid Precision type to DataTypes
Vtk::DataTypes dataTypeOf (Dune::VTK::Precision);
enum CellParametrization {
LINEAR,
QUADRATIC,
LAGRANGE
};
// Map a string to DataTypes
Vtk::DataTypes dataTypeOf (std::string);
enum CellTypes : std::uint8_t {
// Linear VTK cell types
VERTEX = 1,
/* POLY_VERTEX = 2, // not supported */
LINE = 3,
/* POLY_LINE = 4, // not supported */
TRIANGLE = 5,
/* TRIANGLE_STRIP = 6, // not supported */
POLYGON = 7,
/* PIXEL = 8, // not supported */
QUAD = 9,
TETRA = 10,
/* VOXEL = 11, // not supported */
HEXAHEDRON = 12,
WEDGE = 13,
PYRAMID = 14,
// Quadratic VTK cell types
QUADRATIC_EDGE = 21,
QUADRATIC_TRIANGLE = 22,
QUADRATIC_QUAD = 23,
QUADRATIC_TETRA = 24,
QUADRATIC_HEXAHEDRON = 25,
// Arbitrary order Lagrange elements
LAGRANGE_CURVE = 68,
LAGRANGE_TRIANGLE = 69,
LAGRANGE_QUADRILATERAL = 70,
LAGRANGE_TETRAHEDRON = 71,
LAGRANGE_HEXAHEDRON = 72,
LAGRANGE_WEDGE = 73,
LAGRANGE_PYRAMID = 74,
};
GeometryType to_geometry (std::uint8_t);
struct Map
// Map the field_type of T to DataTypes
template <class T>
Vtk::DataTypes dataTypeOf ()
{
static std::map<std::string, DataTypes> to_datatype; // String -> DataTypes
static constexpr DataTypes typeImpl (MetaType<std::int8_t>) { return INT8; }
static constexpr DataTypes typeImpl (MetaType<std::uint8_t>) { return UINT8; }
static constexpr DataTypes typeImpl (MetaType