Commit 938c9f1e authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

restructured gridcreators

parent 455c1402
......@@ -8,7 +8,6 @@ install(FILES
defaultvtkfunction.hh
filereader.hh
filewriter.hh
gridcreator.hh
legacyvtkfunction.hh
pvdwriter.hh
pvdwriter.impl.hh
......@@ -26,5 +25,6 @@ install(FILES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/vtkwriter)
add_subdirectory(datacollectors)
add_subdirectory(gridcreators)
add_subdirectory(utility)
add_subdirectory(writers)
......@@ -9,18 +9,6 @@
namespace Dune
{
namespace Impl
{
// Should be specialized for concrete structured grid
template <class GridView, class Grid>
struct StructuredDataCollectorImpl;
}
template <class GridView>
using StructuredDataCollector = typename Impl::StructuredDataCollectorImpl<GridView, typename GridView::Grid>::type;
/// The Interface for structured data-collectors
template <class GridView, class Derived>
class StructuredDataCollectorInterface
......
......@@ -4,6 +4,8 @@
#include <string>
#include <utility>
#include <dune/vtk/forward.hh>
namespace Dune
{
template <class Grid, class FilerReaderImp>
......
......@@ -3,6 +3,8 @@
#include <string>
#include <dune/common/std/optional.hh>
#include <dune/vtk/forward.hh>
namespace Dune
{
class FileWriter
......
#pragma once
namespace Dune
{
// forward declaration of all classes in dune-vtk
template <class GridView, class Derived>
class DataCollectorInterface;
// @{ datacollectors
template <class GridView, class Derived>
class UnstructuredDataCollectorInterface;
// @{ unstructured-datacollectors
template <class GridView>
class ContinuousDataCollector;
template <class GridView>
class DiscontinuousDataCollector;
template <class GridView>
class QuadraticDataCollector;
// @} unstructured-datacollectors
template <class GridView, class Derived>
class StructuredDataCollectorInterface;
namespace Impl
{
// Should be specialized for concrete structured grid
template <class GridView, class Grid>
struct StructuredDataCollectorImpl;
}
template <class GridView>
using StructuredDataCollector = typename Impl::StructuredDataCollectorImpl<GridView, typename GridView::Grid>::type;
// @{ structured-datacollectors
template <class GridView>
class SPDataCollector;
template <class GridView>
class YaspDataCollector;
// @} structured-datacollectors
// @} datacollectors
template <class Grid, class Derived>
class GridCreatorInterface;
template <class GridCreator, class Derived>
struct DerivedGridCreator;
// @{ gridcreators
template <class Grid>
struct ContinuousGridCreator;
template <class Grid>
struct DiscontinuousGridCreator;
template <class Grid>
struct ParallelGridCreator;
template <class Grid>
struct SerialGridCreator;
// @} gridcreators
template <class Grid, class FilerReaderImp>
class FileReader;
template <class Grid, class GridCreator = ContinuousGridCreator<Grid>>
class VtkReader;
class FileWriter;
// @{ filewriters
template <class VtkWriter>
class PvdWriter;
template <class VtkWriter>
class VtkTimeseriesWriter;
template <class GridView, class DataCollector>
class VtkWriterInterface;
// @{ vtkwriters
template <class GridView, class DataCollector = StructuredDataCollector<GridView>>
class VtkImageDataWriter;
template <class GridView, class DataCollector = StructuredDataCollector<GridView>>
class VtkRectilinearGridWriter;
template <class GridView, class DataCollector = StructuredDataCollector<GridView>>
class VtkStructuredGridWriter;
template <class GridView, class DataCollector = ContinuousDataCollector<GridView>>
class VtkUnstructuredGridWriter;
// @} vtkwriters
// @} filewriters
} // end namespace Dune
#pragma once
#include <cassert>
#include <cstdint>
#include <limits>
#include <vector>
#include <dune/common/exceptions.hh>
#include <dune/common/hybridutilities.hh>
#include <dune/grid/common/gridfactory.hh>
#include "vtktypes.hh"
namespace Dune
{
template <class Factory, class... Args>
using HasInsertVertex = decltype( std::declval<Factory>().insertVertex(std::declval<Args>()...) );
namespace Impl
{
template <class GF, class = void>
struct VertexIdType { using type = unsigned int; };
template <class GF>
struct VertexIdType<GF, typename GF::VertexId> { using type = typename GF::VertexId; };
}
template <class GF>
using VertexId_t = typename Impl::VertexIdType<GF>::type;
// Create a grid where the input points and connectivity is already
// connected correctly.
struct DefaultGridCreator
{
template <class Grid, class Coord>
static void create (GridFactory<Grid>& factory,
std::vector<Coord> const& points,
std::vector<std::uint64_t> const& point_ids,
std::vector<std::uint8_t> const& types,
std::vector<std::int64_t> const& offsets,
std::vector<std::int64_t> const& connectivity)
{
const auto hasInsertVertex = Std::is_detected<HasInsertVertex, GridFactory<Grid>, Coord, unsigned int>{};
if (point_ids.empty() || !hasInsertVertex.value) {
for (auto const& p : points)
factory.insertVertex(p);
} else {
Hybrid::ifElse(hasInsertVertex,
[&](auto id) {
using VertexId = VertexId_t<GridFactory<Grid>>;
for (std::size_t i = 0; i < points.size(); ++i)
id(factory).insertVertex(points[i], VertexId(point_ids[i]));
});
}
std::size_t idx = 0;
for (std::size_t i = 0; i < types.size(); ++i) {
auto type = Vtk::to_geometry(types[i]);
Vtk::CellType cellType{type};
auto refElem = referenceElement<double,Grid::dimension>(type);
int nNodes = offsets[i] - (i == 0 ? 0 : offsets[i-1]);
assert(nNodes == refElem.size(Grid::dimension));
std::vector<unsigned int> vtk_cell; vtk_cell.reserve(nNodes);
for (int j = 0; j < nNodes; ++j)
vtk_cell.push_back( connectivity[idx++] );
if (cellType.noPermutation())
factory.insertElement(type,vtk_cell);
else {
// apply index permutation
std::vector<unsigned int> cell(nNodes);
for (int j = 0; j < nNodes; ++j)
cell[j] = vtk_cell[cellType.permutation(j)];
factory.insertElement(type,cell);
}
}
}
};
// Create a grid where the input points are not connected and the connectivity
// describes separated elements.
struct ConnectedGridCreator
{
struct CoordLess
{
template <class T, int N>
bool operator() (FieldVector<T,N> const& lhs, FieldVector<T,N> const& rhs) const
{
for (int i = 0; i < N; ++i) {
if (std::abs(lhs[i] - rhs[i]) < std::numeric_limits<T>::epsilon())
continue;
return lhs[i] < rhs[i];
}
return false;
}
};
template <class Grid, class Coord>
static void create (GridFactory<Grid>& factory,
std::vector<Coord> const& points,
std::vector<std::uint64_t> const& point_ids,
std::vector<std::uint8_t> const& types,
std::vector<std::int64_t> const& offsets,
std::vector<std::int64_t> const& connectivity)
{
std::size_t idx = 0;
std::map<Coord, std::size_t, CoordLess> unique_points;
const auto hasInsertVertex = Std::is_detected<HasInsertVertex, GridFactory<Grid>, Coord, unsigned int>{};
if (point_ids.empty() || !hasInsertVertex.value) {
for (auto const& p : points) {
auto b = unique_points.emplace(std::make_pair(p,idx));
if (b.second) {
factory.insertVertex(p);
++idx;
}
}
} else {
Hybrid::ifElse(hasInsertVertex,
[&](auto id) {
using VertexId = VertexId_t<GridFactory<Grid>>;
for (std::size_t i = 0; i < points.size(); ++i) {
auto b = unique_points.emplace(std::make_pair(points[i],idx));
if (b.second) {
id(factory).insertVertex(points[i], VertexId(point_ids[i]));
++idx;
}
}
});
}
idx = 0;
for (std::size_t i = 0; i < types.size(); ++i) {
auto type = Vtk::to_geometry(types[i]);
Vtk::CellType cellType{type};
int nNodes = offsets[i] - (i == 0 ? 0 : offsets[i-1]);
assert(nNodes > 0);
std::vector<unsigned int> vtk_cell; vtk_cell.reserve(nNodes);
for (int j = 0; j < nNodes; ++j) {
std::size_t v_j = connectivity[idx++];
std::size_t new_idx = unique_points[points[v_j]];
vtk_cell.push_back(new_idx);
}
if (cellType.noPermutation())
factory.insertElement(type,vtk_cell);
else {
// apply index permutation
std::vector<unsigned int> cell(nNodes);
for (int j = 0; j < nNodes; ++j)
cell[j] = vtk_cell[cellType.permutation(j)];
factory.insertElement(type,cell);
}
}
}
};
} // end namespace Dune
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <dune/common/version.hh>
#include <dune/grid/common/gridfactory.hh>
#include <dune/vtk/forward.hh>
namespace Dune {
template <class G, class Derived>
class GridCreatorInterface
{
public:
using Grid = G;
using GlobalCoordinate = typename Grid::template Codim<0>::Entity::Geometry::GlobalCoordinate;
public:
GridCreatorInterface (GridFactory<Grid>& factory)
: factory_(&factory)
{
#if DUNE_VERSION_LT(DUNE_GRID,2,7)
// old GridFactory implementation does not provide access to its collective communication
#if HAVE_MPI
MPI_Comm_rank(MPI_COMM_WORLD, &rank_);
MPI_Comm_size(MPI_COMM_WORLD, &numRanks_);
#endif
#else
rank_ = factory.comm().rank();
numRanks_ = factory.comm().size();
#endif
}
/// Insert all points as vertices into the factory
void insertVertices (std::vector<GlobalCoordinate> const& points,
std::vector<std::uint64_t> const& point_ids)
{
asDerived().insertVerticesImpl(points, point_ids);
}
/// Create elements based on type and connectivity description
void insertElements (std::vector<std::uint8_t> const& types,
std::vector<std::int64_t> const& offsets,
std::vector<std::int64_t> const& connectivity)
{
asDerived().insertElementsImpl(types, offsets, connectivity);
}
/// Insert part of a grid stored in file into factory
void insertPieces (std::vector<std::string> const& pieces)
{
asDerived().insertPiecesImpl(pieces);
}
/// Return the associated GridFactory
GridFactory<Grid>& factory ()
{
return *factory_;
}
/// Return the MPI_Comm_rank of the factory, (or of MPI_COMM_WORLD)
int rank () const
{
return rank_;
}
/// Return the MPI_Comm_size of the factory, (or of MPI_COMM_WORLD)
int size () const
{
return numRanks_;
}
protected: // cast to derived type
Derived& asDerived ()
{
return static_cast<Derived&>(*this);
}
const Derived& asDerived () const
{
return static_cast<const Derived&>(*this);
}
public: // default implementations
void insertVerticesImpl (std::vector<GlobalCoordinate> const&,
std::vector<std::uint64_t> const&)
{
/* do nothing */
}
void insertElementsImpl (std::vector<std::uint8_t> const&,
std::vector<std::int64_t> const&,
std::vector<std::int64_t> const&)
{
/* do nothing */
}
void insertPiecesImpl (std::vector<std::string> const&)
{
/* do nothing */;
}
protected:
GridFactory<Grid>* factory_;
int rank_ = 0;
int numRanks_ = 1;
};
} // end namespace Dune
#install headers
install(FILES
common.hh
continuousgridcreator.hh
derivedgridcreator.hh
discontinuousgridcreator.hh
parallelgridcreator.hh
serialgridcreator.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/vtkwriter/gridcreators)
#pragma once
#include <type_traits>
namespace Dune
{
template <class Factory, class... Args>
using HasInsertVertex = decltype( std::declval<Factory>().insertVertex(std::declval<Args>()...) );
namespace Impl
{
template <class GF, class = void>
struct VertexIdType { using type = unsigned int; };
template <class GF>
struct VertexIdType<GF, typename GF::VertexId> { using type = typename GF::VertexId; };
}
template <class GF>
using VertexId_t = typename Impl::VertexIdType<GF>::type;
} // end namespace Dune
#pragma once
#include <cassert>
#include <cstdint>
#include <limits>
#include <vector>
#include <dune/common/exceptions.hh>
#include <dune/common/hybridutilities.hh>
#include <dune/grid/common/gridfactory.hh>
#include <dune/vtk/vtktypes.hh>
#include <dune/vtk/gridcreatorinterface.hh>
namespace Dune
{
// Create a grid where the input points and connectivity is already
// connected correctly.
template <class Grid>
struct ContinuousGridCreator
: public GridCreatorInterface<Grid, ContinuousGridCreator<Grid>>
{
using Super = GridCreatorInterface<Grid, ContinuousGridCreator<Grid>>;
using GlobalCoordinate = typename Super::GlobalCoordinate;
ContinuousGridCreator (GridFactory<Grid>& factory)
: Super(factory)
{}
using Super::factory;
void insertVerticesImpl (std::vector<GlobalCoordinate> const& points,
std::vector<std::uint64_t> const& /*point_ids*/)
{
for (auto const& p : points)
factory().insertVertex(p);
}
void insertElementsImpl (std::vector<std::uint8_t> const& types,
std::vector<std::int64_t> const& offsets,
std::vector<std::int64_t> const& connectivity)
{
std::size_t idx = 0;
for (std::size_t i = 0; i < types.size(); ++i) {
auto type = Vtk::to_geometry(types[i]);
Vtk::CellType cellType{type};
auto refElem = referenceElement<double,Grid::dimension>(type);
int nNodes = offsets[i] - (i == 0 ? 0 : offsets[i-1]);
assert(nNodes == refElem.size(Grid::dimension));
std::vector<unsigned int> vtk_cell; vtk_cell.reserve(nNodes);
for (int j = 0; j < nNodes; ++j)
vtk_cell.push_back( connectivity[idx++] );
if (cellType.noPermutation())
factory().insertElement(type,vtk_cell);
else {
// apply index permutation
std::vector<unsigned int> cell(nNodes);
for (int j = 0; j < nNodes; ++j)
cell[j] = vtk_cell[cellType.permutation(j)];
factory().insertElement(type,cell);
}
}
}
};
} // end namespace Dune
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <dune/grid/common/gridfactory.hh>
#include <dune/vtk/forward.hh>
#include <dune/vtk/gridcreatorinterface.hh>
#include <dune/vtk/gridcreators/common.hh>
#include <dune/vtk/gridcreators/continuousgridcreator.hh>
namespace Dune
{
template <class GridCreator, class Derived>
struct DerivedGridCreator
: public GridCreatorInterface<typename GridCreator::Grid, Derived>
{
using Self = DerivedGridCreator;
using Super = GridCreatorInterface<typename GridCreator::Grid, Derived>;
using Grid = typename GridCreator::Grid;
using GlobalCoordinate = typename Super::GlobalCoordinate;
DerivedGridCreator (GridFactory<Grid>& factory)
: Super(factory)
, gridCreator_(factory)
{}
void insertVerticesImpl (std::vector<GlobalCoordinate> const& points,
std::vector<std::uint64_t> const& point_ids)
{
gridCreator_.insertVertices(points, point_ids);
}
void insertElementsImpl (std::vector<std::uint8_t> const& types,
std::vector<std::int64_t> const& offsets,
std::vector<std::int64_t> const& connectivity)
{
gridCreator_.insertElements(types, offsets, connectivity);
}
void insertPiecesImpl (std::vector<std::string> const& pieces)
{
gridCreator_.insertPieces(pieces);
}
private:
GridCreator gridCreator_;
};
} // end namespace Dune
#pragma once
#include <cassert>
#include <cstdint>
#include <limits>
#include <vector>
#include <dune/common/exceptions.hh>
#include <dune/common/hybridutilities.hh>
#include <dune/grid/common/gridfactory.hh>
#include <dune/vtk/vtktypes.hh>
#include <dune/vtk/gridcreatorinterface.hh>