9#include "kernel/shape.hpp"
11#include <kernel/geometry/conformal_mesh.hpp>
12#include <kernel/geometry/mesh_part.hpp>
13#include <kernel/geometry/structured_mesh.hpp>
14#include <kernel/util/dist.hpp>
15#include <kernel/util/dist_file_io.hpp>
31 template<
typename Shape_>
35 struct VTKShape<Shape::Simplex<1>>
37 static constexpr int type = 3;
38 static inline int map(
int i)
45 struct VTKShape<Shape::Simplex<2>>
47 static constexpr int type = 5;
48 static inline int map(
int i)
55 struct VTKShape<Shape::Simplex<3>>
57 static constexpr int type = 10;
58 static inline int map(
int i)
65 struct VTKShape<Shape::Hypercube<1>>
67 static constexpr int type = 3;
68 static inline int map(
int i)
75 struct VTKShape<Shape::Hypercube<2>>
77 static constexpr int type = 9;
78 static inline int map(
int i)
81 return (i ^ ((i >> 1) & 1));
86 struct VTKShape<Shape::Hypercube<3>>
88 static constexpr int type = 12;
89 static inline int map(
int i)
92 return (i ^ ((i >> 1) & 1));
117 template<
typename Mesh_,
int cell_dim_ = Mesh_::ShapeType::dimension>
132 using VarDeque = std::deque<std::pair<String, std::vector<double>>>;
175 const auto& vertex_set = mesh.get_vertex_set();
176 const auto& index_set = mesh.template get_index_set<cell_dim_, 0>();
179 _cells = [&](
Index i,
int j) {
return index_set(i, j); };
202 const auto& vertex_set = mesh.get_vertex_set();
203 const auto& vertex_target_set = part.template get_target_set<0>();
204 const auto& cell_target_set = part.template get_target_set<cell_dim_>();
206 _vertices = [&](
Index i,
int j) {
return vertex_set[vertex_target_set[i]][j]; };
211 const auto& index_set = part.template get_index_set<cell_dim_, 0>();
212 _cells = [&](
Index i,
int j) {
return index_set(i, j); };
217 const auto& index_set = mesh.template get_index_set<cell_dim_, 0>();
224 const Index vertex = index_set(cell_target_set[i], j);
225 for(
Index k(0); k < vertex_target_set.get_num_entities(); k++)
227 if(vertex_target_set[k] == vertex)
233 XABORTM(
"Lookup of vertex index failed!");
281 template<
typename T_>
284 XASSERTM(data !=
nullptr,
"data array is nullptr");
288 d[i] = scaling_factor * double(data[i]);
312 template<
typename T_>
316 const T_* y =
nullptr,
317 const T_* z =
nullptr,
318 double scaling_factor = 1.0)
320 XASSERTM(x !=
nullptr,
"x-data array is nullptr");
323 if(y !=
nullptr && z !=
nullptr)
327 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
328 d[(3 * i) + 1] = scaling_factor *
double(y[i]);
329 d[(3 * i) + 2] = scaling_factor *
double(z[i]);
332 else if(y !=
nullptr)
336 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
337 d[(3 * i) + 1] = scaling_factor *
double(y[i]);
338 d[(3 * i) + 2] = 0.0;
345 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
346 d[(3 * i) + 1] = 0.0;
347 d[(3 * i) + 2] = 0.0;
373 template<
typename VectorType_>
380 for(
Index j(0); j < 3; ++j)
382 d[(
Index(3) * i) + j] =
double(0);
385 for(
int j(0); j < v.BlockSize; ++j)
387 d[(
Index(3) * i) +
Index(j)] = scaling_factor * double(v(i)[j]);
410 template<
typename T_>
413 XASSERTM(data !=
nullptr,
"data array is nullptr");
417 d[i] = scaling_factor * double(data[i]);
441 template<
typename T_>
445 const T_* y =
nullptr,
446 const T_* z =
nullptr,
447 double scaling_factor = 1.0)
449 XASSERTM(x !=
nullptr,
"x-data array is nullptr");
452 if(y !=
nullptr && z !=
nullptr)
456 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
457 d[(3 * i) + 1] = scaling_factor *
double(y[i]);
458 d[(3 * i) + 2] = scaling_factor *
double(z[i]);
461 else if(y !=
nullptr)
465 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
466 d[(3 * i) + 1] = scaling_factor *
double(y[i]);
467 d[(3 * i) + 2] = 0.0;
474 d[(3 * i) + 0] = scaling_factor *
double(x[i]);
475 d[(3 * i) + 1] = 0.0;
476 d[(3 * i) + 2] = 0.0;
502 template<
typename VectorType_>
509 for(
Index j(0); j < 3; ++j)
511 d[(
Index(3) * i) + j] =
double(0);
514 for(
int j(0); j < v.BlockSize; ++j)
516 d[(
Index(3) * i) +
Index(j)] = scaling_factor * double(v(i)[j]);
531 String vtu_name(filename +
".vtu");
532 std::ofstream ofs(vtu_name.c_str());
533 if(!(ofs.is_open() && ofs.good()))
535 throw FileError(
"Failed to create '" + vtu_name +
"'");
564 void write(
const String& filename,
const int rank,
const int nparts)
574 XASSERTM((rank >= 0) && (rank < nparts),
"Invalid rank");
577 std::vector<double> rank_array((std::size_t(
_num_cells)),
double(rank));
581 const std::size_t ndigits =
Math::ilog10(std::size_t(nparts - 1));
593 String pvtu_name(filename +
".pvtu");
594 std::ofstream ofs(pvtu_name.c_str());
595 if(!(ofs.is_open() && ofs.good()))
597 throw FileError(
"Failed to create '" + pvtu_name +
"'");
601 std::size_t p = filename.find_last_of(
"\\/");
602 String file_title = filename.substr(p == FEAT::String::npos ? 0 : ++p);
626 std::vector<double> rank_array(std::size_t(
_num_cells),
double(comm.
rank()));
633 std::stringstream stream;
637 String pattern = filename +
"." +
String(ndigits,
'*') +
".vtu";
649 String pvtu_name(filename +
".pvtu");
650 std::ofstream ofs(pvtu_name.c_str());
651 if(!(ofs.is_open() && ofs.good()))
653 throw FileError(
"Failed to create '" + pvtu_name +
"'");
657 std::size_t p = filename.find_last_of(
"\\/");
658 String file_title = filename.substr(p == FEAT::String::npos ? 0 : ++p);
676 const int num_coords = MeshType::world_dim;
680 os <<
"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\">\n)";
685 os <<
"<UnstructuredGrid>\n";
686 os <<
"<Piece NumberOfPoints=\"" <<
_num_verts <<
"\" NumberOfCells=\"" <<
_num_cells <<
"\">\n";
691 os <<
"<PointData>\n";
696 os <<
"<DataArray type=\"Float64\" Name=\"" << var.first <<
"\" Format=\"ascii\">\n";
701 os <<
"</DataArray>\n";
706 os <<
"<DataArray type=\"Float64\" Name=\"" << var.first;
707 os <<
"\" NumberOfComponents=\"3\" Format=\"ascii\">\n";
714 os <<
"</DataArray>\n";
717 os <<
"</PointData>\n";
723 os <<
"<CellData>\n";
728 os <<
"<DataArray type=\"Float64\" Name=\"" << var.first <<
"\" Format=\"ascii\">\n";
733 os <<
"</DataArray>\n";
742 os <<
"<DataArray type=\"Float64\" Name=\"" << var.first;
743 os <<
"\" NumberOfComponents=\"3\" Format=\"ascii\">\n";
750 os <<
"</DataArray>\n";
753 os <<
"</CellData>\n";
758 os <<
"<DataArray type=\"Float32\" NumberOfComponents=\"3\" Format=\"ascii\">\n";
762 for(
int j(1); j < num_coords; ++j)
766 for(
int j(num_coords); j < 3; ++j)
772 os <<
"</DataArray>\n";
777 os <<
"<DataArray type=\"UInt32\" Name=\"connectivity\">\n";
780 os <<
_cells(i, VTKShapeType::map(0));
781 for(
int j(1); j < verts_per_cell; ++j)
783 os <<
" " <<
_cells(i, VTKShapeType::map(j));
787 os <<
"</DataArray>\n";
788 os <<
"<DataArray type=\"UInt32\" Name=\"offsets\">\n";
791 os << ((i + 1) * verts_per_cell) <<
"\n";
793 os <<
"</DataArray>\n";
794 os <<
"<DataArray type=\"UInt32\" Name=\"types\">\n";
797 os << VTKShapeType::type <<
"\n";
799 os <<
"</DataArray>\n";
804 os <<
"</UnstructuredGrid>\n";
805 os <<
"</VTKFile>\n";
823 os <<
"<VTKFile type=\"PUnstructuredGrid\" version=\"0.1\">\n";
826 os <<
"<PUnstructuredGrid GhostLevel=\"0\">\n";
831 os <<
"<PPointData>\n";
836 os <<
"<PDataArray type=\"Float64\" Name=\"" << vertex_scalar.first <<
"\" />\n";
841 os <<
"<PDataArray type=\"Float64\" Name=\"" << vertex_vector.first;
842 os <<
"\" NumberOfComponents=\"3\" />\n";
845 os <<
"</PPointData>\n";
851 os <<
"<PCellData>\n";
855 os <<
"<PDataArray type=\"Float64\" Name=\"" << cell_scalar.first <<
"\" />\n";
860 os <<
"<PDataArray type=\"Float64\" Name=\"" << cell_vector.first;
861 os <<
"\" NumberOfComponents=\"3\" />\n";
863 os <<
"</PCellData>\n";
868 os <<
"<PDataArray type=\"Float32\" NumberOfComponents=\"3\" />\n";
869 os <<
"</PPoints>\n";
872 const std::size_t ndigits =
Math::ilog10(std::size_t(nparts - 1));
875 for(
int i(0); i < nparts; ++i)
877 os <<
"<Piece Source=\"" << file_title <<
"." <<
stringify(i).
pad_front(ndigits,
'0');
882 os <<
"</PUnstructuredGrid>\n";
883 os <<
"</VTKFile>\n";
#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.
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
ExportVTK & operator=(ExportVTK &&other)=default
Move-assignment constructor.
int _var_prec
precision of variables
std::function< double(Index, int)> _vertices
Accessor function for vertices.
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 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
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.
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 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
void add_vertex_scalar(const String &name, const T_ *data, double scaling_factor=1.0)
Adds a scalar vertex variable to the exporter.
std::function< Index(Index, int)> _cells
Accessor function for cells.
std::deque< std::pair< String, std::vector< double > > > VarDeque
our variable container
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.
@ 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.
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.
static constexpr int version_minor
FEAT minor version number.
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.
Face traits tag struct template.