Commit 87190569 authored by Marcus Mohr's avatar Marcus Mohr
Browse files

Further extends capabilities of VTKOutput

We can now export all of the following functions
- P[1,2]Function
- P[1,2]VectorFunction
- EdgeDoFFunction
- DGFunction
for all of the following value types
- double
- int32_t
- int64_t

Commit extends VTKOutputTest to check that this works and also
makes some details of the implementations in VTK*Writer classes
more consistent.
parent f81aa284
......@@ -57,40 +57,59 @@ void VTKDGDoFWriter::write( const VTKOutput& mgr, std::ostream& output, const ui
output << "<CellData>";
for ( const auto& function : mgr.dgFunctions_ )
for ( const auto& function : mgr.dgFunctions_.getFunctions< double >() )
{
vtk::openDataElement( output, typeToString< real_t >(), function.getFunctionName(), 1, mgr.vtkDataFormat_ );
writeScalarFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
}
for ( const auto& function : mgr.dgFunctions_.getFunctions< int32_t >() )
{
writeScalarFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
}
for ( const auto& function : mgr.dgFunctions_.getFunctions< int64_t >() )
{
writeScalarFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
}
for ( const auto& it : storage->getFaces() )
{
const Face& face = *it.second;
output << "\n</CellData>\n";
uint_t rowsize = levelinfo::num_microvertices_per_edge( level );
uint_t inner_rowsize = rowsize;
output << std::scientific;
vtk::writePieceFooter( output );
}
uint_t idx;
template < typename value_t >
void VTKDGDoFWriter::writeScalarFunction( std::ostream& output,
const DGFunction< value_t >& function,
const std::shared_ptr< PrimitiveStorage >& storage,
const uint_t& level,
bool write2D,
vtk::DataFormat vtkDataFormat )
{
vtk::openDataElement( output, typeToString< real_t >(), function.getFunctionName(), 1, vtkDataFormat );
for ( size_t j = 0; j < rowsize - 1; ++j )
for ( const auto& it : storage->getFaces() )
{
const Face& face = *it.second;
uint_t rowsize = levelinfo::num_microvertices_per_edge( level );
uint_t inner_rowsize = rowsize;
output << std::scientific;
uint_t idx;
for ( size_t j = 0; j < rowsize - 1; ++j )
{
for ( size_t i = 0; i < inner_rowsize - 2; ++i )
{
for ( size_t i = 0; i < inner_rowsize - 2; ++i )
{
idx = facedof::macroface::indexFaceFromGrayFace( level, i, j, stencilDirection::CELL_GRAY_C );
output << face.getData( function.getFaceDataID() )->getPointer( level )[idx] << " ";
idx = facedof::macroface::indexFaceFromBlueFace( level, i, j, stencilDirection::CELL_BLUE_C );
output << face.getData( function.getFaceDataID() )->getPointer( level )[idx] << " ";
}
idx = facedof::macroface::indexFaceFromGrayFace( level, inner_rowsize - 2, j, stencilDirection::CELL_GRAY_C );
idx = facedof::macroface::indexFaceFromGrayFace( level, i, j, stencilDirection::CELL_GRAY_C );
output << face.getData( function.getFaceDataID() )->getPointer( level )[idx] << " ";
idx = facedof::macroface::indexFaceFromBlueFace( level, i, j, stencilDirection::CELL_BLUE_C );
output << face.getData( function.getFaceDataID() )->getPointer( level )[idx] << " ";
--inner_rowsize;
}
idx = facedof::macroface::indexFaceFromGrayFace( level, inner_rowsize - 2, j, stencilDirection::CELL_GRAY_C );
output << face.getData( function.getFaceDataID() )->getPointer( level )[idx] << " ";
--inner_rowsize;
}
output << "\n</DataArray>\n";
}
output << "\n</CellData>\n";
vtk::writePieceFooter( output );
output << "\n</DataArray>\n";
}
} // namespace hyteg
......@@ -29,6 +29,15 @@ class VTKDGDoFWriter
{
public:
static void write( const VTKOutput& mgr, std::ostream& output, const uint_t& level );
private:
template < typename value_t >
static void writeScalarFunction( std::ostream& output,
const DGFunction< value_t >& function,
const std::shared_ptr< PrimitiveStorage >& storage,
const uint_t& level,
bool write2D,
vtk::DataFormat vtkDataFormat );
};
} // namespace hyteg
......@@ -81,13 +81,17 @@ void VTKEdgeDoFWriter::write( const VTKOutput& mgr, std::ostream& output, uint_t
output << "<PointData>\n";
for ( const auto& function : mgr.edgeDoFFunctions_ )
for ( const auto& function : mgr.edgeDoFFunctions_.getFunctions< double >() )
{
writeScalarFunction( mgr, output, function, storage, level, dofType );
}
for ( const auto& function : mgr.edgeDoFFunctions_.getFunctions< int32_t >() )
{
writeScalarFunction( mgr, output, function, storage, level, dofType );
}
for ( const auto& function : mgr.edgeDoFFunctions_.getFunctions< int64_t >() )
{
vtk::openDataElement( output, typeToString< real_t >(), function.getFunctionName(), 1, mgr.vtkDataFormat_ );
writeScalarFunction( mgr, output, function, storage, level, dofType );
output << "\n</DataArray>\n";
}
output << "</PointData>\n";
......@@ -107,20 +111,23 @@ void VTKEdgeDoFWriter::write( const VTKOutput& mgr, std::ostream& output, uint_t
vtk::writePieceFooter( output );
}
template < typename value_t >
void VTKEdgeDoFWriter::writeScalarFunction( const VTKOutput& mgr,
std::ostream& output,
const EdgeDoFFunction< real_t >& function,
const EdgeDoFFunction< value_t >& function,
const std::shared_ptr< PrimitiveStorage >& storage,
uint_t level,
const vtk::DoFType& dofType )
{
using ScalarType = real_t;
WALBERLA_ASSERT_EQUAL( storage, function.getStorage() );
vtk::openDataElement( output, typeToString< value_t >(), function.getFunctionName(), 1, mgr.vtkDataFormat_ );
WALBERLA_ASSERT( dofType == vtk::DoFType::EDGE_X || dofType == vtk::DoFType::EDGE_Y || dofType == vtk::DoFType::EDGE_Z ||
dofType == vtk::DoFType::EDGE_XY || dofType == vtk::DoFType::EDGE_XZ || dofType == vtk::DoFType::EDGE_YZ ||
dofType == vtk::DoFType::EDGE_XYZ );
VTKOutput::VTKStreamWriter< ScalarType > streamWriter( mgr.vtkDataFormat_ );
VTKOutput::VTKStreamWriter< value_t > streamWriter( mgr.vtkDataFormat_ );
if ( mgr.write2D_ )
{
......@@ -130,8 +137,7 @@ void VTKEdgeDoFWriter::writeScalarFunction( const VTKOutput&
switch ( dofType )
{
case vtk::DoFType::EDGE_X:
{
case vtk::DoFType::EDGE_X: {
for ( const auto& itIdx : edgedof::macroface::Iterator( level ) )
{
streamWriter << face.getData( function.getFaceDataID() )
......@@ -139,8 +145,7 @@ void VTKEdgeDoFWriter::writeScalarFunction( const VTKOutput&
}
break;
}
case vtk::DoFType::EDGE_Y:
{
case vtk::DoFType::EDGE_Y: {
for ( const auto& itIdx : edgedof::macroface::Iterator( level ) )
{
streamWriter << face.getData( function.getFaceDataID() )
......@@ -148,8 +153,7 @@ void VTKEdgeDoFWriter::writeScalarFunction( const VTKOutput&
}
break;
}
case vtk::DoFType::EDGE_XY:
{
case vtk::DoFType::EDGE_XY: {
for ( const auto& itIdx : edgedof::macroface::Iterator( level ) )
{
streamWriter << face.getData( function.getFaceDataID() )
......@@ -213,6 +217,8 @@ void VTKEdgeDoFWriter::writeScalarFunction( const VTKOutput&
}
streamWriter.toStream( output );
output << "\n</DataArray>\n";
}
} // namespace hyteg
......@@ -38,9 +38,10 @@ class VTKEdgeDoFWriter
static void write( const VTKOutput& mgr, std::ostream& output, uint_t level, const vtk::DoFType& dofType );
private:
template < typename value_t >
static void writeScalarFunction( const VTKOutput& mgr,
std::ostream& output,
const EdgeDoFFunction< real_t >& function,
const EdgeDoFFunction< value_t >& function,
const std::shared_ptr< PrimitiveStorage >& storage,
uint_t level,
const vtk::DoFType& dofType );
......
......@@ -61,31 +61,6 @@ VTKOutput::VTKOutput( std::string dir,
}
}
void VTKOutput::add( const P2Function< real_t >& function )
{
p2Functions_.push_back( function );
}
void VTKOutput::add( const P1VectorFunction< real_t >& function )
{
p1VecFunctions_.push_back( function );
}
void VTKOutput::add( const P2VectorFunction< real_t >& function )
{
p2VecFunctions_.push_back( function );
}
void VTKOutput::add( const EdgeDoFFunction< real_t >& function )
{
edgeDoFFunctions_.push_back( function );
}
void VTKOutput::add( const DGFunction< real_t >& function )
{
dgFunctions_.push_back( function );
}
void VTKOutput::add( const P1StokesFunction< real_t >& function )
{
add( function.uvw );
......@@ -146,16 +121,16 @@ void VTKOutput::add( const GenericFunction< real_t >& function )
}
const std::map< vtk::DoFType, std::string > VTKOutput::DoFTypeToString_ = {
{vtk::DoFType::VERTEX, "VertexDoF"},
{vtk::DoFType::EDGE_X, "XEdgeDoF"},
{vtk::DoFType::EDGE_Y, "YEdgeDoF"},
{vtk::DoFType::EDGE_Z, "ZEdgeDoF"},
{vtk::DoFType::EDGE_XY, "XYEdgeDoF"},
{vtk::DoFType::EDGE_XZ, "XZEdgeDoF"},
{vtk::DoFType::EDGE_YZ, "YZEdgeDoF"},
{vtk::DoFType::EDGE_XYZ, "XYZEdgeDoF"},
{vtk::DoFType::DG, "DGDoF"},
{vtk::DoFType::P2, "P2"},
{ vtk::DoFType::VERTEX, "VertexDoF" },
{ vtk::DoFType::EDGE_X, "XEdgeDoF" },
{ vtk::DoFType::EDGE_Y, "YEdgeDoF" },
{ vtk::DoFType::EDGE_Z, "ZEdgeDoF" },
{ vtk::DoFType::EDGE_XY, "XYEdgeDoF" },
{ vtk::DoFType::EDGE_XZ, "XZEdgeDoF" },
{ vtk::DoFType::EDGE_YZ, "YZEdgeDoF" },
{ vtk::DoFType::EDGE_XYZ, "XYZEdgeDoF" },
{ vtk::DoFType::DG, "DGDoF" },
{ vtk::DoFType::P2, "P2" },
};
std::string VTKOutput::fileNameExtension( const vtk::DoFType& dofType, const uint_t& level, const uint_t& timestep ) const
......@@ -230,23 +205,23 @@ void VTKOutput::write( const uint_t& level, const uint_t& timestep ) const
{
syncAllFunctions( level );
const std::vector< vtk::DoFType > dofTypes2D = {vtk::DoFType::VERTEX,
vtk::DoFType::EDGE_X,
vtk::DoFType::EDGE_Y,
vtk::DoFType::EDGE_XY,
vtk::DoFType::DG,
vtk::DoFType::P2};
const std::vector< vtk::DoFType > dofTypes3D = {vtk::DoFType::VERTEX,
vtk::DoFType::EDGE_X,
vtk::DoFType::EDGE_Y,
vtk::DoFType::EDGE_Z,
vtk::DoFType::EDGE_XY,
vtk::DoFType::EDGE_XZ,
vtk::DoFType::EDGE_YZ,
vtk::DoFType::EDGE_XYZ,
vtk::DoFType::DG,
vtk::DoFType::P2};
const std::vector< vtk::DoFType > dofTypes2D = { vtk::DoFType::VERTEX,
vtk::DoFType::EDGE_X,
vtk::DoFType::EDGE_Y,
vtk::DoFType::EDGE_XY,
vtk::DoFType::DG,
vtk::DoFType::P2 };
const std::vector< vtk::DoFType > dofTypes3D = { vtk::DoFType::VERTEX,
vtk::DoFType::EDGE_X,
vtk::DoFType::EDGE_Y,
vtk::DoFType::EDGE_Z,
vtk::DoFType::EDGE_XY,
vtk::DoFType::EDGE_XZ,
vtk::DoFType::EDGE_YZ,
vtk::DoFType::EDGE_XYZ,
vtk::DoFType::DG,
vtk::DoFType::P2 };
auto dofTypes = write2D_ ? dofTypes2D : dofTypes3D;
......@@ -283,43 +258,100 @@ void VTKOutput::write( const uint_t& level, const uint_t& timestep ) const
void VTKOutput::syncAllFunctions( const uint_t& level ) const
{
// P1Functions [double, int32_t, int64_t] -------------------------------------------------------------------
for ( const auto& function : p1Functions_.getFunctions<double>() )
// ----------------------------------------
// P1Functions [double, int32_t, int64_t]
// ----------------------------------------
for ( const auto& function : p1Functions_.getFunctions< double >() )
{
hyteg::communication::syncFunctionBetweenPrimitives< hyteg::P1Function< double > >( function, level );
}
for ( const auto& function : p1Functions_.getFunctions<int32_t>() )
for ( const auto& function : p1Functions_.getFunctions< int32_t >() )
{
hyteg::communication::syncFunctionBetweenPrimitives< hyteg::P1Function< int32_t > >( function, level );
}
for ( const auto& function : p1Functions_.getFunctions<int64_t>() )
for ( const auto& function : p1Functions_.getFunctions< int64_t >() )
{
hyteg::communication::syncFunctionBetweenPrimitives< hyteg::P1Function< int64_t > >( function, level );
}
// P1Functions ----------------------------------------------------------------------------------------------
for ( const auto& function : p1VecFunctions_ )
// ----------------------------------------------
// P1VectorFunctions [double, int32_t, int64_t]
// ----------------------------------------------
for ( const auto& function : p1VecFunctions_.getFunctions< double >() )
{
hyteg::communication::syncVectorFunctionBetweenPrimitives( function, level );
}
for ( const auto& function : p1VecFunctions_.getFunctions< int32_t >() )
{
hyteg::communication::syncVectorFunctionBetweenPrimitives( function, level );
}
for ( const auto& function : p1VecFunctions_.getFunctions< int64_t >() )
{
hyteg::communication::syncVectorFunctionBetweenPrimitives( function, level );
}
for ( const auto& function : p2Functions_ )
// ----------------------------------------
// P2Functions [double, int32_t, int64_t]
// ----------------------------------------
for ( const auto& function : p2Functions_.getFunctions< double >() )
{
hyteg::communication::syncP2FunctionBetweenPrimitives( function, level );
}
for ( const auto& function : p2Functions_.getFunctions< int32_t >() )
{
hyteg::communication::syncP2FunctionBetweenPrimitives( function, level );
}
for ( const auto& function : p2Functions_.getFunctions< int64_t >() )
{
hyteg::communication::syncP2FunctionBetweenPrimitives( function, level );
}
for ( const auto& function : p2VecFunctions_ )
// ----------------------------------------------
// P2VectorFunctions [double, int32_t, int64_t]
// ----------------------------------------------
for ( const auto& function : p2VecFunctions_.getFunctions< double >() )
{
hyteg::communication::syncVectorFunctionBetweenPrimitives( function, level );
}
for ( const auto& function : p2VecFunctions_.getFunctions< int32_t >() )
{
hyteg::communication::syncVectorFunctionBetweenPrimitives( function, level );
}
for ( const auto& function : p2VecFunctions_.getFunctions< int64_t >() )
{
hyteg::communication::syncVectorFunctionBetweenPrimitives( function, level );
}
for ( const auto& function : edgeDoFFunctions_ )
// ---------------------------------------------
// EdgeDoFFunctions [double, int32_t, int64_t]
// ---------------------------------------------
for ( const auto& function : edgeDoFFunctions_.getFunctions< double >() )
{
hyteg::communication::syncFunctionBetweenPrimitives< hyteg::EdgeDoFFunction< real_t > >( function, level );
hyteg::communication::syncFunctionBetweenPrimitives( function, level );
}
for ( const auto& function : edgeDoFFunctions_.getFunctions< int32_t >() )
{
hyteg::communication::syncFunctionBetweenPrimitives( function, level );
}
for ( const auto& function : edgeDoFFunctions_.getFunctions< int64_t >() )
{
hyteg::communication::syncFunctionBetweenPrimitives( function, level );
}
for ( const auto& function : dgFunctions_ )
// ----------------------------------------
// DGFunctions [double, int32_t, int64_t]
// ----------------------------------------
for ( const auto& function : dgFunctions_.getFunctions< double >() )
{
function.communicate< Vertex, Edge >( level );
function.communicate< Edge, Face >( level );
}
for ( const auto& function : dgFunctions_.getFunctions< int32_t >() )
{
function.communicate< Vertex, Edge >( level );
function.communicate< Edge, Face >( level );
}
for ( const auto& function : dgFunctions_.getFunctions< int64_t >() )
{
function.communicate< Vertex, Edge >( level );
function.communicate< Edge, Face >( level );
......
......@@ -36,9 +36,14 @@
#include "hyteg/p2functionspace/P2Function.hpp"
// our friends and helpers
// clang off
// ordering matter here, otherwise we need to add forward declarations
#include "hyteg/dataexport/VTKHelpers.hpp"
// clang on
#include "hyteg/dataexport/VTKDGDoFWriter.hpp"
#include "hyteg/dataexport/VTKEdgeDoFWriter.hpp"
#include "hyteg/dataexport/VTKHelpers.hpp"
#include "hyteg/dataexport/VTKMeshWriter.hpp"
#include "hyteg/dataexport/VTKP1Writer.hpp"
#include "hyteg/dataexport/VTKP2Writer.hpp"
......@@ -77,13 +82,35 @@ class VTKOutput
p1Functions_.push_back( function );
}
void add( const P2Function< real_t >& function );
template < typename value_t >
inline void add( const P2Function< value_t >& function )
{
p2Functions_.push_back( function );
}
void add( const EdgeDoFFunction< real_t >& function );
void add( const DGFunction< real_t >& function );
template < typename value_t >
inline void add( const P1VectorFunction< value_t >& function )
{
p1VecFunctions_.push_back( function );
}
void add( const P1VectorFunction< real_t >& function );
void add( const P2VectorFunction< real_t >& function );
template < typename value_t >
inline void add( const P2VectorFunction< value_t >& function )
{
p2VecFunctions_.push_back( function );
}
template < typename value_t >
inline void add( const EdgeDoFFunction< value_t >& function )
{
edgeDoFFunctions_.push_back( function );
}
template < typename value_t >
inline void add( const DGFunction< value_t >& function )
{
dgFunctions_.push_back( function );
}
void add( const P1StokesFunction< real_t >& function );
void add( const P2P1TaylorHoodFunction< real_t >& function );
......@@ -190,15 +217,14 @@ class VTKOutput
bool write2D_;
// std::vector< P1Function< real_t > > p1Functions_;
FunctionMultiStore< P1Function > p1Functions_;
std::vector< P2Function< real_t > > p2Functions_;
FunctionMultiStore< P1Function > p1Functions_;
FunctionMultiStore< P2Function > p2Functions_;
std::vector< P1VectorFunction< real_t > > p1VecFunctions_;
std::vector< P2VectorFunction< real_t > > p2VecFunctions_;
FunctionMultiStore< P1VectorFunction > p1VecFunctions_;
FunctionMultiStore< P2VectorFunction > p2VecFunctions_;
std::vector< EdgeDoFFunction< real_t > > edgeDoFFunctions_;
std::vector< DGFunction< real_t > > dgFunctions_;
FunctionMultiStore< EdgeDoFFunction > edgeDoFFunctions_;
FunctionMultiStore< DGFunction > dgFunctions_;
std::shared_ptr< PrimitiveStorage > storage_;
......
......@@ -75,20 +75,28 @@ void VTKP1Writer::write( const VTKOutput& mgr, std::ostream& output, const uint_
output << "<PointData>\n";
// write all scalar P1Functions of supported value type
for ( const auto& function : mgr.p1Functions_.getFunctions<double>() )
for ( const auto& function : mgr.p1Functions_.getFunctions< double >() )
{
writeScalarFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
}
for ( const auto& function : mgr.p1Functions_.getFunctions<int32_t>() )
for ( const auto& function : mgr.p1Functions_.getFunctions< int32_t >() )
{
writeScalarFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
}
for ( const auto& function : mgr.p1Functions_.getFunctions<int64_t>() )
for ( const auto& function : mgr.p1Functions_.getFunctions< int64_t >() )
{
writeScalarFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
}
for ( const auto& function : mgr.p1VecFunctions_ )
for ( const auto& function : mgr.p1VecFunctions_.getFunctions< double >() )
{
writeVectorFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
}
for ( const auto& function : mgr.p1VecFunctions_.getFunctions< int32_t >() )
{
writeVectorFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
}
for ( const auto& function : mgr.p1VecFunctions_.getFunctions< int64_t >() )
{
writeVectorFunction( output, function, storage, level, mgr.write2D_, mgr.vtkDataFormat_ );
}
......@@ -106,8 +114,9 @@ void VTKP1Writer::writeScalarFunction( std::ostream&
bool write2D,
vtk::DataFormat vtkDataFormat )
{
VTKOutput::VTKStreamWriter< value_t > streamWriter( vtkDataFormat );
WALBERLA_ASSERT_EQUAL( storage, function.getStorage() );
VTKOutput::VTKStreamWriter< value_t > streamWriter( vtkDataFormat );
vtk::openDataElement( output, typeToString< value_t >(), function.getFunctionName(), 1, vtkDataFormat );
if ( write2D )
......@@ -145,12 +154,14 @@ void VTKP1Writer::writeScalarFunction( std::ostream&
template < typename value_t >
void VTKP1Writer::writeVectorFunction( std::ostream& output,
const P1VectorFunction< value_t >& function,
const P1VectorFunction< value_t >& function,
const std::shared_ptr< PrimitiveStorage >& storage,
const uint_t& level,
bool write2D,
vtk::DataFormat vtkDataFormat )
{
WALBERLA_ASSERT_EQUAL( storage, function.getStorage() );
VTKOutput::VTKStreamWriter< value_t > streamWriter( vtkDataFormat );
uint_t dim = write2D ? 2 : 3;
......
......@@ -31,7 +31,7 @@ class VTKP1Writer
static void write( const VTKOutput& mgr, std::ostream& output, const uint_t& level );
private:
template< typename value_t >
template < typename value_t >
static void writeScalarFunction( std::ostream& output,
const vertexdof::VertexDoFFunction< value_t >& function,
const std::shared_ptr< PrimitiveStorage >& storage,
......@@ -39,13 +39,13 @@ class VTKP1Writer
bool write2D,
vtk::DataFormat vtkDataFormat );
template< typename value_t >
static void writeVectorFunction( std::ostream& output,
const P1VectorFunction< value_t >& function,
const std::shared_ptr< PrimitiveStorage >& storage,
const uint_t& level,
bool write2D,
vtk::DataFormat vtkDataFormat );
template < typename value_t >
static void writeVectorFunction( std::ostream& output,
const P1VectorFunction< value_t >& function,
const std::shared_ptr< PrimitiveStorage >& storage,
const uint_t& level,
bool write2D,
vtk::DataFormat vtkDataFormat );
};
} // namespace hyteg
......@@ -70,43 +70,53 @@ void VTKP2Writer::write( const VTKOutput& mgr, std::ostream& output, const uint_
output << "<PointData>\n";