10#ifndef __3e48c7b32a034cb3be3dbca884ff4f6c
11#define __3e48c7b32a034cb3be3dbca884ff4f6c
13#include <lf/mesh/mesh.h>
14#include <lf/mesh/utils/utils.h>
16#include <boost/variant/variant.hpp>
45 VTK_TRIANGLE_STRIP = 6,
54 VTK_QUADRATIC_EDGE = 21,
55 VTK_QUADRATIC_TRIANGLE = 22,
56 VTK_QUADRATIC_QUAD = 23,
57 VTK_QUADRATIC_TETRA = 24,
58 VTK_QUADRATIC_HEXAHEDRON = 25,
59 VTK_LAGRANGE_CURVE = 68,
60 VTK_LAGRANGE_TRIANGLE = 69,
61 VTK_LAGRANGE_QUADRILATERAL = 70,
62 VTK_LAGRANGE_TETRAHEDRON = 71,
63 VTK_LAGRANGE_HEXAHEDRON = 72,
64 VTK_LAGRANGE_WEDGE = 73,
65 VTK_LAGRANGE_PYRAMID = 74
71 std::vector<std::vector<size_type>>
cells;
99 :
name(std::move(data_name)),
108 std::vector<Eigen::Matrix<T, 3, 1>>
data;
113 std::vector<Eigen::Matrix<T, 3, 1>>
data)
295 VtkWriter(std::shared_ptr<const mesh::Mesh> mesh, std::string filename,
296 dim_t codim = 0,
unsigned char order = 1);
325 unsigned char undefined_value = 0);
341 char undefined_value = 0);
357 unsigned int undefined_value = 0);
373 int undefined_value = 0);
389 float undefined_value = 0.F);
405 double undefined_value = 0.);
421 const Eigen::Vector2d& undefined_value = {0, 0});
437 const Eigen::Vector2f& undefined_value = {0, 0});
452 const mesh::utils::MeshDataSet<Eigen::Vector3d>& mds,
453 const Eigen::Vector3d& undefined_value = {0, 0, 0});
468 const mesh::utils::MeshDataSet<Eigen::Vector3f>& mds,
469 const Eigen::Vector3f& undefined_value = {0, 0, 0});
486 const std::string& name,
487 const mesh::utils::MeshDataSet<Eigen::VectorXd>& mds,
488 const Eigen::VectorXd& undefined_value = Eigen::Vector3d(0, 0, 0));
505 const std::string& name,
506 const mesh::utils::MeshDataSet<Eigen::VectorXf>& mds,
507 const Eigen::VectorXf& undefined_value = Eigen::Vector3f(0, 0, 0));
543 class = std::enable_if_t<lf::mesh::utils::isMeshFunction<MESH_FUNCTION>>>
545 const MESH_FUNCTION& mesh_function);
558 const mesh::utils::MeshDataSet<unsigned char>& mds,
559 unsigned char undefined_value = 0);
572 const mesh::utils::MeshDataSet<char>& mds,
573 char undefined_value = 0);
586 const mesh::utils::MeshDataSet<unsigned int>& mds,
587 unsigned int undefined_value = 0);
600 const mesh::utils::MeshDataSet<int>& mds,
601 int undefined_value = 0);
614 const mesh::utils::MeshDataSet<float>& mds,
615 float undefined_value = 0);
628 const mesh::utils::MeshDataSet<double>& mds,
629 double undefined_value = 0);
641 const mesh::utils::MeshDataSet<Eigen::Vector2d>& mds,
642 const Eigen::Vector2d& undefined_value = {0, 0});
654 const mesh::utils::MeshDataSet<Eigen::Vector2f>& mds,
655 const Eigen::Vector2f& undefined_value = {0, 0});
667 const mesh::utils::MeshDataSet<Eigen::Vector3d>& mds,
668 const Eigen::Vector3d& undefined_value = {0, 0, 0});
680 const mesh::utils::MeshDataSet<Eigen::Vector3f>& mds,
681 const Eigen::Vector3f& undefined_value = {0, 0, 0});
695 const std::string& name,
696 const mesh::utils::MeshDataSet<Eigen::VectorXd>& mds,
697 const Eigen::VectorXd& undefined_value = Eigen::Vector3d(0, 0, 0));
711 const std::string& name,
712 const mesh::utils::MeshDataSet<Eigen::VectorXf>& mds,
713 const Eigen::VectorXf& undefined_value = Eigen::Vector3f(0, 0, 0));
745 class = std::enable_if_t<lf::mesh::utils::isMeshFunction<MESH_FUNCTION>>>
747 const MESH_FUNCTION& mesh_function);
771 void WriteGlobalData(
const std::string& name, std::vector<float> data);
783 void WriteGlobalData(
const std::string& name, std::vector<double> data);
791 std::shared_ptr<const mesh::Mesh>
mesh_;
810 template <
int ROWS,
class T>
812 const std::string& name,
814 const Eigen::Matrix<T, ROWS, 1>& undefined_value);
821 template <
int ROWS,
class T>
823 const std::string& name,
825 const Eigen::Matrix<T, ROWS, 1>& undefined_value);
828 void WriteFieldData(
const std::string& name, std::vector<T> data);
830 template <
class DATA>
833 template <
int ROWS,
class T>
835 const Eigen::Matrix<T, ROWS, 1>& in);
838template <
class MESH_FUNCTION,
class>
840 const MESH_FUNCTION& mesh_function) {
845 auto dim_mesh =
mesh_->DimMesh();
847 Eigen::Matrix<double, 0, 1> origin;
849 if constexpr (std::is_same_v<T, unsigned char> || std::is_same_v<T, char> ||
850 std::is_same_v<T, unsigned> || std::is_same_v<T, int> ||
851 std::is_same_v<T, float> ||
852 std::is_same_v<T, double>) {
859 for (
const auto* n :
mesh_->Entities(dim_mesh)) {
860 data.data[
mesh_->Index(*n)] = mesh_function(*n, origin)[0];
863 for (
int codim =
static_cast<int>(dim_mesh - 1);
864 codim >=
static_cast<char>(
codim_); --codim) {
865 for (
const auto* e :
mesh_->Entities(codim)) {
866 auto ref_el = e->RefEl();
870 auto values = mesh_function(*e,
aux_nodes_[ref_el.Id()]);
873 data.data[offset + i] = values[i];
878 }
else if constexpr (base::is_eigen_matrix<T>) {
879 static_assert(T::ColsAtCompileTime == 1,
880 "The MeshFunction must return row-vectors");
882 T::RowsAtCompileTime == Eigen::Dynamic ||
883 (T::RowsAtCompileTime > 1 && T::RowsAtCompileTime < 4),
884 "The Row vectors returned by the MeshFunction must be either dynamic "
885 "or must have 2 or 3 rows (at compile time).");
886 using Scalar =
typename T::Scalar;
888 std::is_same_v<double, Scalar> || std::is_same_v<float, Scalar>,
889 "The RowVectors returned by the MeshFunction must be either double "
896 for (
const auto* n :
mesh_->Entities(dim_mesh)) {
897 PadWithZeros<T::RowsAtCompileTime, Scalar>(data.data[
mesh_->Index(*n)],
898 mesh_function(*n, origin)[0]);
901 for (
int codim =
static_cast<int>(dim_mesh - 1);
902 codim >=
static_cast<char>(
codim_); --codim) {
903 for (
const auto* e :
mesh_->Entities(codim)) {
904 auto ref_el = e->RefEl();
908 auto values = mesh_function(*e,
aux_nodes_[ref_el.Id()]);
910 for (
unsigned long i = 0; i < values.size(); ++i) {
911 PadWithZeros<T::RowsAtCompileTime, Scalar>(data.data[offset + i],
919 "MeshFunction values must be one of: unsigned char, char, "
920 "unsigned, int, float, double, Eigen::Vector<double, ...> "
921 "or Eigen::Vector<float, ...>");
925template <
class MESH_FUNCTION,
class>
927 const MESH_FUNCTION& mesh_function) {
932 std::vector<Eigen::VectorXd> barycenters(5);
941 if constexpr (base::is_eigen_array<T> || base::is_eigen_matrix<T>) {
942 static_assert(T::ColsAtCompileTime == 1,
943 "The MeshFunction must return row-vectors");
945 T::RowsAtCompileTime == Eigen::Dynamic ||
946 (T::RowsAtCompileTime > 1 && T::RowsAtCompileTime < 4),
947 "The Row vectors returned by the MeshFunction must be either dynamic "
948 "or must have 2 or 3 rows (at compile time).");
949 using Scalar =
typename T::Scalar;
951 std::is_same_v<double, Scalar> || std::is_same_v<float, Scalar>,
952 "The RowVectors returned by the MeshFunction must be either double "
957 constexpr int rows = T::RowsAtCompileTime;
959 this->PadWithZeros<rows, Scalar>(
960 data.data[
mesh_->Index(*p)],
961 mesh_function(*p, barycenters[p->RefEl().Id()])[0]);
969 data.data[
mesh_->Index(*e)] =
970 mesh_function(*e, barycenters[e->RefEl().Id()])[0];
978 const std::string& name) {
979 if (std::find_if(data.begin(), data.end(), [&](
auto& d) {
980 return boost::apply_visitor([&](auto&& d2) { return d2.name; }, d) ==
984 "There is already another Point/Cell Attribute Set with the "
988 if (name.find(
' ') != std::string::npos) {
990 "The name of the attribute set cannot contain spaces!");
994template <
int ROWS,
class T>
995void VtkWriter::PadWithZeros(Eigen::Matrix<T, 3, 1>& out,
996 const Eigen::Matrix<T, ROWS, 1>& in) {
997 if constexpr (ROWS == 2) {
998 out.template block<2, 1>(0, 0) = in;
1000 }
else if constexpr (ROWS == 3) {
1002 }
else if constexpr (ROWS == Eigen::Dynamic) {
1003 LF_ASSERT_MSG(in.rows() == 2 || in.rows() == 3,
1004 "VtkWriter can only write out 2d or 3d vectors.");
1005 if (in.rows() == 2) {
1007 out.topRows(2) = in;
A simple, general purpose exception class that is thrown by LehrFEM++ if something is wrong.
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
constexpr unsigned int Id() const
Return a unique id for this reference element.
const Eigen::MatrixXd & NodeCoords() const
Get the coordinates of the nodes of this reference element.
static constexpr RefEl kPoint()
Returns the (0-dimensional) reference point.
static constexpr RefEl kTria()
Returns the reference triangle.
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
FieldDataArray(std::string name, std::vector< T > data)
Represents one set of attribute data (can be attached to points or cells)
ScalarData(std::string data_name, std::vector< T > data, std::string lookup_table="default")
std::vector< Eigen::Vector3f > points
std::vector< std::vector< size_type > > cells
std::vector< CellType > cell_types
VectorData(std::string name, std::vector< Eigen::Matrix< T, 3, 1 > > data)
std::vector< Eigen::Matrix< T, 3, 1 > > data
Representation of a VTK file (only relevant) features (advanced usage)
std::vector< boost::variant< FieldDataArray< int >, FieldDataArray< float >, FieldDataArray< double > > > FieldData
std::string header
The Vtk Header, at most 256 characters, no new lines characters!
UnstructuredGrid unstructured_grid
Describes the nodes + cells.
std::vector< boost::variant< ScalarData< char >, ScalarData< unsigned char >, ScalarData< short >, ScalarData< unsigned short >, ScalarData< int >, ScalarData< unsigned int >, ScalarData< long >, ScalarData< unsigned long >, ScalarData< float >, ScalarData< double >, VectorData< float >, VectorData< double > > > Attributes
Format format
The format of the file.
Write a mesh along with mesh data into a vtk file.
void setBinary(bool binary)
Determines whether the Vtk file is written in binary or ASCII mode (default).
VtkWriter(VtkWriter &&)=delete
void WriteScalarPointData(const std::string &name, const mesh::utils::MeshDataSet< T > &mds, T undefined_value)
VtkWriter(const VtkWriter &)=delete
void WriteCellData(const std::string &name, const mesh::utils::MeshDataSet< unsigned char > &mds, unsigned char undefined_value=0)
Add a new unsigned char attribute dataset that attaches data to the cells of the mesh (i....
~VtkWriter()
Destructor, writes everything into the file and closes it.
void WriteScalarCellData(const std::string &name, const mesh::utils::MeshDataSet< T > &mds, T undefined_value)
VtkWriter & operator=(VtkWriter &&)=delete
std::array< mesh::utils::CodimMeshDataSet< unsigned int >, 2 > aux_node_offset_
static void PadWithZeros(Eigen::Matrix< T, 3, 1 > &out, const Eigen::Matrix< T, ROWS, 1 > &in)
void WriteFieldData(const std::string &name, std::vector< T > data)
VtkWriter & operator=(const VtkWriter &)=delete
void WriteGlobalData(const std::string &name, std::vector< int > data)
Write global data into the vtk file that is not related to the mesh at all.
void WriteVectorPointData(const std::string &name, const mesh::utils::MeshDataSet< Eigen::Matrix< T, ROWS, 1 > > &mds, const Eigen::Matrix< T, ROWS, 1 > &undefined_value)
void WriteVectorCellData(const std::string &name, const mesh::utils::MeshDataSet< Eigen::Matrix< T, ROWS, 1 > > &mds, const Eigen::Matrix< T, ROWS, 1 > &undefined_value)
void CheckAttributeSetName(const DATA &data, const std::string &name)
std::shared_ptr< const mesh::Mesh > mesh_
std::array< Eigen::MatrixXd, 5 > aux_nodes_
void WritePointData(const std::string &name, const mesh::utils::MeshDataSet< unsigned char > &mds, unsigned char undefined_value=0)
Add a new unsigned char attribute dataset that attaches data to the points/nodes of the mesh.
Interface that specifies how data is stored with an entity.
unsigned int dim_t
type for dimensions and co-dimensions and numbers derived from them
unsigned int size_type
general type for variables related to size of arrays
Mesh input (from file) and output (in various formats) facilities.
void WriteToFile(const VtkFile &vtk_file, const std::string &filename)
internal::VectorElement_t< internal::MeshFunctionReturnType_t< R > > MeshFunctionReturnType
Determine the type of objects returned by a MeshFunction.