10#include <kernel/geometry/conformal_mesh.hpp>
11#include <kernel/geometry/index_set.hpp>
12#include <kernel/geometry/mesh_part.hpp>
13#include <kernel/geometry/structured_mesh.hpp>
14#include <kernel/shape.hpp>
16#include <kernel/util/dist_file_io.hpp>
17#include <kernel/util/dist.hpp>
19#include <kernel/util/pack.hpp>
20#include <kernel/util/string.hpp>
21#include <kernel/util/tiny_algebra.hpp>
31#include <kernel/geometry/cgal.hpp>
40 template<
typename Shape_>
44 struct VTKShape<Shape::Simplex<1>>
46 static constexpr std::uint32_t type = 3;
47 static inline int map(
int i)
54 struct VTKShape<Shape::Simplex<2>>
56 static constexpr std::uint32_t type = 5;
57 static inline int map(
int i)
64 struct VTKShape<Shape::Simplex<3>>
66 static constexpr std::uint32_t type = 10;
67 static inline int map(
int i)
74 struct VTKShape<Shape::Hypercube<1>>
76 static constexpr std::uint32_t type = 3;
77 static inline int map(
int i)
84 struct VTKShape<Shape::Hypercube<2>>
86 static constexpr std::uint32_t type = 9;
87 static inline int map(
int i)
90 return (i ^ ((i >> 1) & 1));
95 struct VTKShape<Shape::Hypercube<3>>
97 static constexpr std::uint32_t type = 12;
98 static inline int map(
int i)
101 return (i ^ ((i >> 1) & 1));
105 template<
typename T_>
109 struct VTKType<std::uint8_t>
111 static constexpr std::string_view type =
"UInt8";
115 struct VTKType<std::uint16_t>
117 static constexpr std::string_view type =
"UInt16";
121 struct VTKType<std::uint32_t>
123 static constexpr std::string_view type =
"UInt32";
127 struct VTKType<std::uint64_t>
129 static constexpr std::string_view type =
"UInt64";
133 struct VTKType<std::int8_t>
135 static constexpr std::string_view type =
"Int8";
139 struct VTKType<std::int16_t>
141 static constexpr std::string_view type =
"Int16";
145 struct VTKType<std::int32_t>
147 static constexpr std::string_view type =
"Int32";
151 struct VTKType<std::int64_t>
153 static constexpr std::string_view type =
"Int64";
157 struct VTKType<float>
159 static constexpr std::string_view type =
"Float32";
163 struct VTKType<double>
165 static constexpr std::string_view type =
"Float64";
193 template<
typename Mesh_,
int cell_dim_ = Mesh_::ShapeType::dimension>
213 static constexpr bool can_compress =
true;
215 static constexpr bool can_compress =
false;
220 using VarDeque = std::deque<std::pair<String, std::vector<double>>>;
267 const auto& vertex_set = mesh.get_vertex_set();
268 const auto& index_set = mesh.template get_index_set<cell_dim_, 0>();
273 for(
int j(0); j < vertex_set.num_coords; j++)
275 vert[j] = float(vertex_set[i][j]);
281 tuple[j] = index_set(i, j);
306 const auto& vertex_set = mesh.get_vertex_set();
307 const auto& vertex_target_set = part.template get_target_set<0>();
308 const auto& cell_target_set = part.template get_target_set<cell_dim_>();
313 for(
int j(0); j < vertex_set.num_coords; j++)
315 vert[j] = float(vertex_set[i][j]);
322 const auto& index_set = part.template get_index_set<cell_dim_, 0>();
326 tuple[j] = index_set(i, j);
333 const auto& index_set = mesh.template get_index_set<cell_dim_, 0>();
342 const Index vertex = index_set(cell_target_set[i], j);
343 for(
Index k(0); k < vertex_target_set.get_num_entities(); k++)
345 if(vertex_target_set[k] == vertex)
355#if defined(FEAT_HAVE_CGAL) || defined(DOXYGEN)
367 template<
typename DT_>
373 XASSERTM(cell_dim_ == 2,
"CGAL Export only possible with surface mesh");
376 auto point = cw.
point(i);
379 vert[j] = float(point[j]);
386 for(;it != end; ++it)
459 template<
typename T_>
462 XASSERTM(data !=
nullptr,
"data array is nullptr");
466 d[i] = scaling_factor * double(data[i]);
490 template<
typename T_>
494 const T_* y =
nullptr,
495 const T_* z =
nullptr,
496 double scaling_factor = 1.0)
498 XASSERTM(x !=
nullptr,
"x-data array is nullptr");
501 if(y !=
nullptr && z !=
nullptr)
505 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
506 d[(3 * i) + 1] = scaling_factor *
double(y[i]);
507 d[(3 * i) + 2] = scaling_factor *
double(z[i]);
510 else if(y !=
nullptr)
514 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
515 d[(3 * i) + 1] = scaling_factor *
double(y[i]);
516 d[(3 * i) + 2] = 0.0;
523 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
524 d[(3 * i) + 1] = 0.0;
525 d[(3 * i) + 2] = 0.0;
551 template<
typename VectorType_>
558 for(
Index j(0); j < 3; ++j)
560 d[(
Index(3) * i) + j] =
double(0);
563 for(
int j(0); j < v.BlockSize; ++j)
565 d[(
Index(3) * i) +
Index(j)] = scaling_factor * double(v(i)[j]);
591 template<
typename DT_,
int dim_>
598 for(
Index j(0); j < 3; ++j)
600 d[(
Index(3) * i) + j] =
double(0);
603 for(
int j(0); j < dim_; ++j)
605 d[(
Index(3) * i) +
Index(j)] = scaling_factor * double(v[i][j]);
628 template<
typename T_>
631 XASSERTM(data !=
nullptr,
"data array is nullptr");
635 d[i] = scaling_factor * double(data[i]);
659 template<
typename T_>
663 const T_* y =
nullptr,
664 const T_* z =
nullptr,
665 double scaling_factor = 1.0)
667 XASSERTM(x !=
nullptr,
"x-data array is nullptr");
670 if(y !=
nullptr && z !=
nullptr)
674 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
675 d[(3 * i) + 1] = scaling_factor *
double(y[i]);
676 d[(3 * i) + 2] = scaling_factor *
double(z[i]);
679 else if(y !=
nullptr)
683 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
684 d[(3 * i) + 1] = scaling_factor *
double(y[i]);
685 d[(3 * i) + 2] = 0.0;
692 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
693 d[(3 * i) + 1] = 0.0;
694 d[(3 * i) + 2] = 0.0;
720 template<
typename VectorType_>
727 for(
Index j(0); j < 3; ++j)
729 d[(
Index(3) * i) + j] =
double(0);
732 for(
int j(0); j < v.BlockSize; ++j)
734 d[(
Index(3) * i) +
Index(j)] = scaling_factor * double(v(i)[j]);
760 template<
typename DT_,
int dim_>
767 for(
Index j(0); j < 3; ++j)
769 d[(
Index(3) * i) + j] =
double(0);
772 for(
int j(0); j < dim_; ++j)
774 d[(
Index(3) * i) +
Index(j)] = scaling_factor * double(v[i][j]);
789 String vtu_name(filename +
".vtu");
790 std::ofstream ofs(vtu_name.c_str());
791 if(!(ofs.is_open() && ofs.good()))
793 throw FileError(
"Failed to create '" + vtu_name +
"'");
822 void write(
const String& filename,
const int rank,
const int nparts)
832 XASSERTM((rank >= 0) && (rank < nparts),
"Invalid rank");
835 std::vector<double> rank_array((std::size_t(
_num_cells)),
double(rank));
839 const std::size_t ndigits =
Math::ilog10(std::size_t(nparts - 1));
851 String pvtu_name(filename +
".pvtu");
852 std::ofstream ofs(pvtu_name.c_str());
853 if(!(ofs.is_open() && ofs.good()))
855 throw FileError(
"Failed to create '" + pvtu_name +
"'");
859 std::size_t p = filename.find_last_of(
"\\/");
860 String file_title = filename.substr(p == FEAT::String::npos ? 0 : ++p);
884 std::vector<double> rank_array(std::size_t(
_num_cells),
double(comm.
rank()));
891 std::stringstream stream;
895 String pattern = filename +
"." +
String(ndigits,
'*') +
".vtu";
907 String pvtu_name(filename +
".pvtu");
908 std::ofstream ofs(pvtu_name.c_str());
909 if(!(ofs.is_open() && ofs.good()))
911 throw FileError(
"Failed to create '" + pvtu_name +
"'");
915 std::size_t p = filename.find_last_of(
"\\/");
916 String file_title = filename.substr(p == FEAT::String::npos ? 0 : ++p);
936 os << R
"(<VTKFile type="UnstructuredGrid" version="0.1" byte_order=")";
937 os << (_little_endian() ? "LittleEndian" :
"BigEndian") <<
"\"";
941#ifndef FEAT_HAVE_ZLIB
942 XABORTM(
"Requested compression in ExportVTK, but ZLib is not available!");
944 os <<
" compressor=\"vtkZLibDataCompressor\"";
952 os <<
"<UnstructuredGrid>\n";
953 os <<
"<Piece NumberOfPoints=\"" <<
_num_verts <<
"\" NumberOfCells=\"" <<
_num_cells <<
"\">\n";
958 os <<
"<PointData>\n";
968 os <<
"</PointData>\n";
974 os <<
"<CellData>\n";
986 os <<
"</CellData>\n";
994 os << R
"(<DataArray type="Float32" NumberOfComponents="3" format="ascii" Name="test">)" << "\n";
1003 os <<
" " << vertex[j];
1007 os <<
"</DataArray>\n";
1013 std::pair<String, std::vector<float>> vertices(
"", {});
1023 vertices.second.push_back(
static_cast<float>(vertex[j]));
1029 os <<
"</Points>\n";
1035 os << R
"(<DataArray type="UInt32" Name="connectivity">)" << "\n";
1040 os << cell[VTKShapeType::map(0)];
1043 os <<
" " << cell[VTKShapeType::map(j)];
1047 os <<
"</DataArray>\n";
1052 std::pair<String, std::vector<std::uint32_t>> connectivity(
"connectivity", {});
1061 connectivity.second.push_back(
static_cast<std::uint32_t
>(cell[VTKShapeType::map(j)]));
1070 os << R
"(<DataArray type="UInt32" Name="offsets">)" << "\n";
1075 os <<
"</DataArray>\n";
1080 std::pair<String, std::vector<std::uint32_t>> offsets(
"offsets", {});
1085 offsets.second.push_back(
static_cast<std::uint32_t
>((i + 1) *
verts_per_cell));
1093 os << R
"(<DataArray type="UInt32" Name="types">)" << "\n";
1096 os << VTKShapeType::type <<
"\n";
1098 os <<
"</DataArray>\n";
1103 std::pair<String, std::vector<std::uint32_t>> types(
"types", {});
1108 types.second.push_back(VTKShapeType::type);
1117 os <<
"</UnstructuredGrid>\n";
1118 os <<
"</VTKFile>\n";
1136 os << R
"(<VTKFile type="PUnstructuredGrid" version="0.1" byte_order=")";
1137 os << (_little_endian() ? "LittleEndian" :
"BigEndian") <<
"\"";
1141#ifndef FEAT_HAVE_ZLIB
1142 XABORTM(
"Requested compression in ExportVTK, but ZLib is not available!");
1144 os <<
" compressor=\"vtkZLibDataCompressor\"";
1150 os <<
"<PUnstructuredGrid GhostLevel=\"0\">\n";
1155 os <<
"<PPointData>\n";
1160 os <<
"<PDataArray type=\"Float64\" Name=\"" << vertex_scalar.first <<
"\" />\n";
1165 os <<
"<PDataArray type=\"Float64\" Name=\"" << vertex_vector.first;
1166 os <<
"\" NumberOfComponents=\"3\" />\n";
1169 os <<
"</PPointData>\n";
1175 os <<
"<PCellData>\n";
1179 os <<
"<PDataArray type=\"Float64\" Name=\"" << cell_scalar.first <<
"\" />\n";
1184 os <<
"<PDataArray type=\"Float64\" Name=\"" << cell_vector.first;
1185 os <<
"\" NumberOfComponents=\"3\" />\n";
1187 os <<
"</PCellData>\n";
1191 os <<
"<PPoints>\n";
1192 os <<
"<PDataArray type=\"Float32\" NumberOfComponents=\"3\" />\n";
1193 os <<
"</PPoints>\n";
1196 const std::size_t ndigits =
Math::ilog10(std::size_t(nparts - 1));
1199 for(
int i(0); i < nparts; ++i)
1201 os <<
"<Piece Source=\"" << file_title <<
"." <<
stringify(i).
pad_front(ndigits,
'0');
1202 os <<
".vtu\" />\n";
1206 os <<
"</PUnstructuredGrid>\n";
1207 os <<
"</VTKFile>\n";
1220 std::uint32_t num_bytes;
1222 explicit UncompressedHeader(std::uint32_t number_of_bytes) : num_bytes(number_of_bytes)
1234 std::uint32_t blocks = 1;
1235 std::uint32_t blocksize;
1236 std::uint32_t last_blocksize;
1237 std::uint32_t compressed_blocksizes[1];
1239 explicit CompressedHeader(std::uint32_t uncompressed_bytes, std::uint32_t compressed_bytes) :
1240 blocksize(uncompressed_bytes),
1241 last_blocksize(uncompressed_bytes),
1242 compressed_blocksizes{compressed_bytes}
1261 template<
typename T_>
1269 std::string_view format =
_ascii_output ?
"ascii" :
"binary";
1270 std::string_view type = Intern::VTKType<T_>::type;
1273 os <<
"<DataArray type=\"" << type <<
"\" format=\"" << format <<
"\"";
1274 if(data.first !=
"")
1276 os <<
" Name = \"" << data.first <<
"\"";
1278 if(number_of_components != 0)
1280 os <<
" NumberOfComponents=\"" << number_of_components <<
"\"";
1286 Index num_blocks = data.second.size() / number_of_components;
1287 for(
Index i(0); i < num_blocks; ++i)
1289 for(
Index j(0); j < number_of_components; j++)
1292 os << ((j == number_of_components - 1) ?
"\n" :
" ");
1298 auto uncompressed_size =
static_cast<std::uint32_t
>(data.second.size() *
sizeof(T_));
1301 Pack::Type pack_type = Pack::deduct_type<T_>() | Pack::Type::Mask_Z;
1304 std::vector<Pack::u8> buffer(buffer_size, 0);
1305 std::size_t compressed_size =
Pack::encode(buffer.data(), data.second.data(), buffer_size, data.second.size(), pack_type,
false);
1308 CompressedHeader header(uncompressed_size,
static_cast<std::uint32_t
>(compressed_size));
1309 const auto* header_begin =
reinterpret_cast<const Pack::u8*
>(&header);
1312 const auto* data_begin =
reinterpret_cast<const Pack::u8*
>(buffer.data());
1313 const auto* data_end = data_begin + compressed_size;
1320 UncompressedHeader header(
static_cast<std::uint32_t
>(data.second.size() *
sizeof(T_)));
1322 const auto* header_begin =
reinterpret_cast<const Pack::u8*
>(&header);
1323 const auto* header_end = header_begin +
sizeof(header);
1325 const auto* data_begin =
reinterpret_cast<const Pack::u8*
>(data.second.data());
1326 const auto* data_end = data_begin + header.num_bytes;
1332 os <<
"</DataArray>\n";
1336 bool _little_endian()
const
1339 void* xv = (
void*)&x;
1340 auto* x16 = (int16_t*)xv;
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
int size() const
Returns the size of this communicator.
int rank() const
Returns the rank of this process in this communicator.
static void write_sequence(std::stringstream &stream, const String &pattern, const Dist::Comm &comm, bool truncate=true)
Writes a rank-indexed text file sequence.
Base class for file related errors.
Wrapper for the CGAL Library.
CGALVerticesAroundFaceAdjactor< DT_ > vertices_around_face() const
Returns an adjactor for vertices around faces of the mesh.
PointType point(std::uint32_t idx) const
Returns the point of the surface mesh with the given index.
VTK exporter class template.
ExportVTK(const MeshType &mesh, const MeshPart< MeshType > &part, int var_prec=0)
Constructor.
virtual ~ExportVTK()=default
destructor
VarDeque _vertex_scalars
vertex variable list
void add_vertex_vector(const String &name, const T_ *x, const T_ *y=nullptr, const T_ *z=nullptr, double scaling_factor=1.0)
Adds a vector-field vertex variable to the exporter.
Index _num_verts
number of vertices in mesh
void add_cell_vector(const String &name, const std::vector< Tiny::Vector< DT_, dim_ > > &v, double scaling_factor=1.0)
Adds a vector-field cell variable given by a std::vector of Tiny::Vector to the exporter.
std::function< void(Index, Tiny::Vector< float, num_coords > &)> _vertices
Accessor function for vertices.
bool _use_compression
compressed output flag. Only applicable if _binary_output is true
static constexpr int num_coords
Coordinates per vertex. The VTK documentation states that this is always three.
ExportVTK & operator=(ExportVTK &&other)=default
Move-assignment constructor.
int _var_prec
precision of variables
void write(const String &filename, const Dist::Comm &comm)
Writes out the data to a parallel XML-PVTU file.
void write(const String &filename, const int rank, const int nparts)
Writes out the data to a parallel XML-PVTU file.
void enable_ascii_output(bool flag)
Enable or disable binary output.
void clear()
Clears all vertex and cell variables in the exporter.
void write(const String &filename) const
Writes out the data to a serial XML-VTU file.
typename MeshType::ShapeType ShapeType
our shape type
void write_vtu(std::ostream &os) const
Writes out the mesh and variable data in serial XML-VTU format.
typename Shape::FaceTraits< ShapeType, cell_dim_ >::ShapeType CellShapeType
shape type of exported cells
std::function< void(Index, IndexTuple< verts_per_cell > &)> _cells
Accessor function for cells.
VarDeque _vertex_vectors
vertex field list
void write_pvtu(std::ostream &os, const String &file_title, const int nparts) const
Writes out the partition data in parallel XML-PVTU format.
ExportVTK(const ExportVTK &other)=default
Copy constructor.
Index _num_cells
number of cells in mesh
void add_cell_vector(const String &name, const T_ *x, const T_ *y=nullptr, const T_ *z=nullptr, double scaling_factor=1.0)
Adds a vector-field cell variable to the exporter.
void add_vertex_vector(const String &name, const std::vector< Tiny::Vector< DT_, dim_ > > &v, double scaling_factor=1.0)
Adds a vector-field vertex variable given by a std::vector of Tiny::Vector to the exporter.
ExportVTK(ExportVTK &&other) noexcept=default
Move constructor.
VarDeque _cell_scalars
cell variable list
Intern::VTKShape< CellShapeType > VTKShapeType
our VTK shape type
void add_vertex_vector(const String &name, const VectorType_ &v, double scaling_factor=1.0)
Adds a vector-field vertex variable given by a LAFEM::***VectorBlocked to the exporter.
ExportVTK & operator=(const ExportVTK &other)=default
Copy-assignment constructor.
ExportVTK(const MeshType &mesh, int var_prec=0)
Constructor.
void enable_compression(bool flag)
Enable or disable compression.
void add_cell_scalar(const String &name, const T_ *data, double scaling_factor=1.0)
Adds a scalar cell variable to the exporter.
VarDeque _cell_vectors
cell field list
bool _ascii_output
ascii output flag
void add_vertex_scalar(const String &name, const T_ *data, double scaling_factor=1.0)
Adds a scalar vertex variable to the exporter.
ExportVTK(const Geometry::CGALWrapper< DT_ > &cw, int var_prec=0)
Constructor.
void _write_data_array(std::ostream &os, const std::pair< String, std::vector< T_ > > &data, Index number_of_components=0) const
Writes an DataArray XML-node to the give output stream.
std::deque< std::pair< String, std::vector< double > > > VarDeque
our variable container
static constexpr int verts_per_cell
Vertices per cell.
void add_cell_vector(const String &name, const VectorType_ &v, double scaling_factor=1.0)
Adds a vector-field cell variable given by a LAFEM::***VectorBlocked to the exporter.
Class template for partial meshes.
bool has_topology() const
Checks if this MeshPart has a mesh topology.
String class implementation.
String pad_front(size_type len, char c=' ') const
Pads the front of the string up to a desired length.
Tiny Vector class template.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the vector.
@ other
generic/other permutation strategy
T_ ilog10(T_ x)
Computes the integral base-10 logarithm of an integer, i.e. its number of non-zero decimal digits.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
std::size_t encode(void *buf, const T_ *src, const std::size_t buf_size, const std::size_t count, const Pack::Type pack_type, bool swap_bytes, double tolerance)
Encodes an array into a packed buffer.
std::size_t estimate_size(const std::size_t count, const Pack::Type type, const double tolerance)
Computes the estimated (upper bound) pack buffer size for an array.
String base64_encode(const Pack::u8 *begin, const Pack::u8 *end)
Encodes bytes into a Base64 string.
std::uint8_t u8
8-bit unsigned integer type
String stringify(const T_ &item)
Converts an item into a String.
static constexpr int version_major
FEAT major version number.
static constexpr int version_patch
FEAT patch version number (month)
static constexpr int version_minor
FEAT minor version number (year)
String stringify_fp_sci(DataType_ value, int precision=0, int width=0, bool sign=false)
Prints a floating point value to a string in scientific notation.
std::uint64_t Index
Index data type.
Index Tuple class template.
Face traits tag struct template.