Bembel
 
Loading...
Searching...
No Matches
VTKDomainExport.hpp
1// This file is part of Bembel, the higher order C++ boundary element library.
2//
3// Copyright (C) 2022 see <http://www.bembel.eu>
4//
5// It was written as part of a cooperation of J. Doelz, H. Harbrecht, S. Kurz,
6// M. Multerer, S. Schoeps, and F. Wolf at Technische Universitaet Darmstadt,
7// Universitaet Basel, and Universita della Svizzera italiana, Lugano. This
8// source code is subject to the GNU General Public License version 3 and
9// provided WITHOUT ANY WARRANTY, see <http://www.bembel.eu> for further
10// information.
11
12#ifndef BEMBEL_SRC_IO_VTKDOMAINEXPORT_HPP_
13#define BEMBEL_SRC_IO_VTKDOMAINEXPORT_HPP_
14
15namespace Bembel {
16
17// This class provides the possibilty to generate a vtk-visualization.
19 public:
24 VTKDomainExport(const Eigen::VectorXd &x_vec, const Eigen::VectorXd &y_vec,
25 const Eigen::VectorXd &z_vec) {
26 init_VTKDomainExport(x_vec, y_vec, z_vec);
27 }
28 inline void init_VTKDomainExport(const Eigen::VectorXd &x_vec,
29 const Eigen::VectorXd &y_vec,
30 const Eigen::VectorXd &z_vec) {
31 x_vec_ = x_vec;
32 y_vec_ = y_vec;
33 z_vec_ = z_vec;
34 x_num = x_vec_.rows() - 1;
35 y_num = y_vec_.rows() - 1;
36 z_num = z_vec_.rows() - 1;
37 max_size_ = x_vec_.rows() * y_vec_.rows() * z_vec_.rows();
38 return;
39 }
40 // One can add data to visualize via the addDataSet methods. They accept a
41 // std::function object of different types, and generate the data needed for
42 // the vtk file. Allowed formats are:
43 // std::function<double(Eigen::Vector3d)>
44 // std::function<Eigen::Vector3d(Eigen::Vector3d)>
45 inline void addDataSet(const std::string &name,
46 std::function<double(const Eigen::Vector3d &)> fun) {
47 Eigen::MatrixXd data(max_size_, 1);
48 for (int z_idx = 0; z_idx < z_vec_.rows(); ++z_idx)
49 for (int y_idx = 0; y_idx < y_vec_.rows(); ++y_idx)
50 for (int x_idx = 0; x_idx < x_vec_.rows(); ++x_idx) {
51 const uint32_t i = (x_vec_.rows() * y_vec_.rows() * z_idx) +
52 (x_vec_.rows() * y_idx) + x_idx;
53 data(i) =
54 fun(Eigen::Vector3d(x_vec_(x_idx), y_vec_(y_idx), z_vec_(z_idx)));
55 }
56 addDataSet_(name, data);
57 return;
58 }
59 inline void addDataSet(
60 const std::string &name,
61 std::function<Eigen::Vector3d(const Eigen::Vector3d &)> fun) {
62 Eigen::MatrixXd data(max_size_, 3);
63 for (int z_idx = 0; z_idx < z_vec_.rows(); ++z_idx)
64 for (int y_idx = 0; y_idx < y_vec_.rows(); ++y_idx)
65 for (int x_idx = 0; x_idx < x_vec_.rows(); ++x_idx) {
66 const uint32_t i = (x_vec_.rows() * y_vec_.rows() * z_idx) +
67 (x_vec_.rows() * y_idx) + x_idx;
68 data.row(i) =
69 fun(Eigen::Vector3d(x_vec_(x_idx), y_vec_(y_idx), z_vec_(z_idx)))
70 .transpose();
71 }
72 addDataSet_(name, data);
73 return;
74 }
75 inline void writeToFile(const std::string &filename) {
76 std::ofstream output;
77 output.open(filename);
78 output << "<VTKFile type=\"StructuredGrid\" version=\"0.1\" "
79 "byte_order=\"LittleEndian\">\n"
80 "<StructuredGrid WholeExtent=\""
81 << "0 " << x_num << " 0 " << y_num << " 0 " << z_num
82 << "\">\n"
83 "<Piece Extent= \""
84 << "0 " << x_num << " 0 " << y_num << " 0 " << z_num
85 << "\">\n"
86 "<Points>\n"
87 "<DataArray type=\"Float32\" NumberOfComponents=\"3\" "
88 "format=\"ascii\">\n";
89
90 for (int z_idx = 0; z_idx < z_vec_.rows(); ++z_idx)
91 for (int y_idx = 0; y_idx < y_vec_.rows(); ++y_idx)
92 for (int x_idx = 0; x_idx < x_vec_.rows(); ++x_idx)
93 output << x_vec_(x_idx) << " " << y_vec_(y_idx) << " "
94 << z_vec_(z_idx) << "\n";
95 output << "</DataArray>\n"
96 "</Points>\n"
97 "<PointData>\n";
98 for (auto d : additionalData) output << d;
99 output << "</PointData>\n"
100 "</Piece>\n"
101 "</StructuredGrid>\n"
102 "</VTKFile>\n";
103 output.close();
104 return;
105 }
106 // can be used to clear the additional Data.
107 inline void clearData() {
108 additionalData = {};
109 additionalData.shrink_to_fit();
110 }
111
112 private:
113 // This routine turns the data of the above DataSet-routines into a string and
114 // stores it.
115 inline void addDataSet_(const std::string &name, const Eigen::MatrixXd &mat) {
116 assert(mat.cols() == 1 || mat.cols() == 3);
117
118 const int cols = mat.cols();
119 std::string data_ascii = "<DataArray type=\"Float32\" Name=\"" + name +
120 "\" NumberOfComponents=\"" +
121 std::to_string(mat.cols()) +
122 "\" format=\"ascii\">\n";
123 std::ostringstream out;
124 out.precision(6);
125 for (int i = 0; i < mat.rows(); ++i) {
126 for (int j = 0; j < cols; ++j) {
127 out << std::scientific << mat(i, j);
128 data_ascii.append(std::move(out).str() + " ");
129 out.str("");
130 out.clear();
131 }
132 data_ascii.append("\n");
133 }
134 data_ascii.append("</DataArray>\n");
135 additionalData.push_back(data_ascii);
136 }
137 int max_size_;
138 int x_num;
139 int y_num;
140 int z_num;
141 Eigen::VectorXd x_vec_;
142 Eigen::VectorXd y_vec_;
143 Eigen::VectorXd z_vec_;
144 std::vector<std::string> additionalData;
145};
146
147} // namespace Bembel
148
149#endif // BEMBEL_SRC_IO_VTKDOMAINEXPORT_HPP_
VTKDomainExport(const Eigen::VectorXd &x_vec, const Eigen::VectorXd &y_vec, const Eigen::VectorXd &z_vec)
Provides export routines to the VTK file format.
Routines for the evalutation of pointwise errors.
constexpr int getFunctionSpaceOutputDimension()