1#ifndef TATOOINE_DETAIL_UNSTRUCTURED_SIMPLICIAL_GRID_TRIANGULAR_VTU_WRITER_H
2#define TATOOINE_DETAIL_UNSTRUCTURED_SIMPLICIAL_GRID_TRIANGULAR_VTU_WRITER_H
14template <
typename Grid, unsigned_integral HeaderType = std::uint64_t,
15 integral ConnectivityInt = std::int64_t,
16 integral OffsetInt = std::int64_t,
17 unsigned_integral CellTypesInt = std::uint8_t>
18requires(Grid::num_dimensions() == 2 ||
19 Grid::num_dimensions() == 3)
29 auto write(filesystem::path
const& path)
const {
30 auto file = std::ofstream{path};
31 if (!file.is_open()) {
32 throw std::runtime_error{
"Could open file " + path.string() +
35 auto offset = std::size_t{};
36 write_vtk_file(file, offset);
42 <<
" type=\"UnstructuredGrid\""
44 <<
" byte_order=\"LittleEndian\""
47 vtk::xml::to_data_type<HeaderType>())
49 write_unstructured_grid(file, offset);
50 write_appended_data(file);
55 file <<
" <UnstructuredGrid>\n";
56 write_piece(file, offset);
57 file <<
" </UnstructuredGrid>\n";
62 <<
" NumberOfPoints=\"" << m_grid.vertices().size() <<
"\""
63 <<
" NumberOfCells=\"" << m_grid.simplices().size() <<
"\""
65 write_points(file, offset);
66 write_cells(file, offset);
67 write_point_data(file, offset);
68 write_cell_data(file, offset);
69 file <<
" </Piece>\n";
73 file <<
" <PointData>\n";
74 for (
auto const& [name, prop] : m_grid.vertex_properties()) {
75 write_vertex_property_data_array<HeaderType, float,
vec2f,
vec3f,
vec4f,
78 name, *prop, file, offset);
80 file <<
" </PointData>\n";
84 file <<
" <CellData>\n";
85 file <<
" </CellData>\n";
88 auto write_points(std::ofstream& file, std::size_t& offset)
const {
91 <<
" format=\"appended\""
92 <<
" offset=\"" << offset <<
"\""
95 vtk::xml::to_data_type<typename Grid::real_type>())
96 <<
"\" NumberOfComponents=\"3\"/>\n"
98 auto const num_bytes = HeaderType(
sizeof(
typename Grid::real_type) * 3 *
99 m_grid.vertices().size());
100 offset += num_bytes +
sizeof(HeaderType);
103 auto write_cells(std::ofstream& file, std::size_t& offset)
const {
104 write_connectivity(file, offset);
105 write_offsets(file, offset);
106 write_cell_types(file, offset);
112 <<
" <DataArray format=\"appended\" offset=\"" << offset
115 vtk::xml::to_data_type<ConnectivityInt>())
116 <<
"\" Name=\"connectivity\"/>\n";
117 HeaderType num_bytes = m_grid.simplices().size() *
118 m_grid.num_vertices_per_simplex() *
119 sizeof(ConnectivityInt);
120 offset += num_bytes +
sizeof(HeaderType);
125 file <<
" <DataArray format=\"appended\" offset=\"" << offset
128 vtk::xml::to_data_type<OffsetInt>())
129 <<
"\" Name=\"offsets\"/>\n";
130 auto const num_bytes =
sizeof(OffsetInt) * (m_grid.simplices().size());
131 offset += num_bytes +
sizeof(HeaderType);
136 file <<
" <DataArray format=\"appended\" offset=\"" << offset
139 vtk::xml::to_data_type<CellTypesInt>())
140 <<
"\" Name=\"types\"/>\n";
141 file <<
" </Cells>\n";
142 auto const num_bytes=
143 sizeof(CellTypesInt) * m_grid.simplices().size();
144 offset += num_bytes +
sizeof(HeaderType);
148 file <<
" <AppendedData encoding=\"raw\">\n _";
149 write_appended_data_points(file);
150 write_appended_data_cells(file);
151 write_appended_data_point_data(file);
152 write_appended_data_cell_data(file);
153 file <<
"\n </AppendedData>\n";
157 using namespace std::ranges;
158 auto const num_bytes = HeaderType(
sizeof(
typename Grid::real_type) * 3 *
159 m_grid.vertices().size());
160 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(HeaderType));
161 if constexpr (Grid::num_dimensions() == 2) {
162 auto point_data = std::vector<vec<typename Grid::real_type, 3>>{};
163 point_data.reserve(m_grid.vertices().size());
164 auto position = [
this](
auto const v) ->
auto& {
return at(v); };
165 constexpr auto to_3d = [](
auto const& p) {
166 return vec{p.x(), p.y(),
typename Grid::real_type(0)};
168 for (
auto const v : m_grid.vertices()) {
169 point_data.push_back(to_3d(m_grid[v]));
172 file.write(
reinterpret_cast<char const*
>(point_data.data()), num_bytes);
173 }
else if constexpr (Grid::num_dimensions() == 3) {
174 file.write(
reinterpret_cast<char const*
>(m_grid.vertices().data()),
180 write_appended_data_cells_connectivity(file);
181 write_appended_data_cells_offsets(file);
182 write_appended_data_cells_types(file);
186 using namespace std::ranges;
187 auto connectivity_data = std::vector<ConnectivityInt>(
188 m_grid.simplices().size() * m_grid.num_vertices_per_simplex());
189 auto index = [](
auto const x) -> ConnectivityInt {
return x.index(); };
190 copy(m_grid.simplices().data_container() | views::transform(
index),
191 begin(connectivity_data));
192 HeaderType num_bytes = m_grid.simplices().size() *
193 m_grid.num_vertices_per_simplex() *
194 sizeof(ConnectivityInt);
195 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(HeaderType));
196 file.write(
reinterpret_cast<char const*
>(connectivity_data.data()),
201 auto offsets = std::vector<OffsetInt>(m_grid.simplices().size(),
202 m_grid.num_vertices_per_simplex());
203 for (std::size_t i = 1; i <
size(offsets); ++i) {
204 offsets[i] += offsets[i - 1];
206 auto const num_bytes =
sizeof(OffsetInt) * m_grid.simplices().size();
207 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(HeaderType));
208 file.write(
reinterpret_cast<char const*
>(offsets.data()), num_bytes);
212 auto cell_types = std::vector<CellTypesInt>(m_grid.simplices().size(), 5);
213 auto const num_bytes =
sizeof(CellTypesInt) * m_grid.simplices().size();
214 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(HeaderType));
215 file.write(
reinterpret_cast<char const*
>(cell_types.data()), num_bytes);
219 for (
auto const& [name, prop] : m_grid.vertex_properties()) {
220 write_vertex_property_appended_data<
228 template <
typename... Ts>
230 std::ofstream& file)
const {
233 if (prop.type() ==
typeid(Ts)) {
234 write_vertex_property_appended_data(
235 prop.template cast_to_typed<Ts>(), file);
241 template <
typename T>
244 if constexpr (tensor_rank<T> <= 1) {
245 auto data = std::vector<T>{};
246 for (
auto const v : m_grid.vertices()) {
247 data.push_back(prop[v]);
249 auto const num_bytes =
251 m_grid.vertices().size());
252 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(HeaderType));
253 file.write(
reinterpret_cast<char const*
>(data.data()), num_bytes);
254 }
else if constexpr (tensor_rank<T> == 2) {
255 auto const num_bytes =
257 m_grid.vertices().size() / tensor_dimension<T, 0>);
258 for (std::size_t i = 0; i < tensor_dimension<T, 1>; ++i) {
259 file.write(
reinterpret_cast<char const*
>(&num_bytes),
261 for (
auto const v : m_grid.vertices()) {
262 auto data_begin = &prop[v](0, i);
263 file.write(
reinterpret_cast<char const*
>(data_begin),
270 template <
typename... Ts>
274 std::size_t& offset)
const {
277 if (prop.type() ==
typeid(Ts)) {
278 if constexpr (tensor_rank<Ts> <= 1) {
279 file <<
" <DataArray"
280 <<
" Name=\"" << name <<
"\""
281 <<
" format=\"appended\""
282 <<
" offset=\"" << offset <<
"\""
287 <<
"\" NumberOfComponents=\""
288 << tensor_num_components<Ts> <<
"\"/>\n";
290 m_grid.vertices().size() *
sizeof(Ts) +
sizeof(HeaderType);
291 }
else if constexpr (tensor_rank<Ts> == 2) {
292 for (std::size_t i = 0; i < Ts::dimension(1); ++i) {
294 <<
" Name=\"" << name <<
"_col_" << i <<
"\""
295 <<
" format=\"appended\""
296 <<
" offset=\"" << offset <<
"\""
301 <<
"\" NumberOfComponents=\"" << Ts::dimension(0)
303 offset += m_grid.vertices().size() *
305 tensor_dimension<Ts, 0> +
Definition: edge_vtp_writer.h:12
auto size(simplex_container< Real, NumDimensions, SimplexDim > simplices)
Definition: simplex_container.h:89
auto begin(simplex_container< Real, NumDimensions, SimplexDim > simplices)
Definition: simplex_container.h:79
auto to_string(data_type const t) -> std::string_view
static auto constexpr to_data_type()
Definition: data_type.h:88
VecF< 3 > vec3f
Definition: vec_typedefs.h:40
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
mat44f mat4f
Definition: mat_typedefs.h:299
VecD< 3 > vec3d
Definition: vec_typedefs.h:51
mat22d mat2d
Definition: mat_typedefs.h:370
mat33d mat3d
Definition: mat_typedefs.h:371
mat33f mat3f
Definition: mat_typedefs.h:298
auto constexpr index(handle< Child, Int > const h)
Definition: handle.h:119
VecD< 2 > vec2d
Definition: vec_typedefs.h:50
VecF< 4 > vec4f
Definition: vec_typedefs.h:41
VecD< 4 > vec4d
Definition: vec_typedefs.h:52
mat22f mat2f
Definition: mat_typedefs.h:297
VecF< 2 > vec2f
Definition: vec_typedefs.h:39
Definition: triangular_vtu_writer.h:20
auto write_piece(std::ofstream &file, auto &offset) const
Definition: triangular_vtu_writer.h:60
auto write_cell_data(std::ofstream &file, std::size_t &) const
Definition: triangular_vtu_writer.h:83
auto write_cell_types(std::ofstream &file, std::size_t &offset) const
Definition: triangular_vtu_writer.h:134
auto write_offsets(std::ofstream &file, std::size_t &offset) const
Definition: triangular_vtu_writer.h:123
auto write_appended_data_cells_offsets(std::ofstream &file) const
Definition: triangular_vtu_writer.h:200
auto write_appended_data_point_data(std::ofstream &file) const
Definition: triangular_vtu_writer.h:218
auto write_appended_data_cell_data(std::ofstream &) const
Definition: triangular_vtu_writer.h:226
typename Grid::vertex_property_type vertex_property_type
Definition: triangular_vtu_writer.h:22
auto write_points(std::ofstream &file, std::size_t &offset) const
Definition: triangular_vtu_writer.h:88
auto write_unstructured_grid(std::ofstream &file, auto &offset) const
Definition: triangular_vtu_writer.h:54
auto write(filesystem::path const &path) const
Definition: triangular_vtu_writer.h:29
auto write_vertex_property_appended_data(typed_vertex_property_type< T > const &prop, std::ofstream &file) const
Definition: triangular_vtu_writer.h:242
auto write_appended_data_cells(std::ofstream &file) const
Definition: triangular_vtu_writer.h:179
auto write_cells(std::ofstream &file, std::size_t &offset) const
Definition: triangular_vtu_writer.h:103
typename Grid::template typed_vertex_property_type< T > typed_vertex_property_type
Definition: triangular_vtu_writer.h:25
auto write_connectivity(std::ofstream &file, std::size_t &offset) const
Definition: triangular_vtu_writer.h:109
Grid const & m_grid
Definition: triangular_vtu_writer.h:27
auto write_vertex_property_appended_data(vertex_property_type const &prop, std::ofstream &file) const
Definition: triangular_vtu_writer.h:229
auto write_appended_data_cells_types(std::ofstream &file) const
Definition: triangular_vtu_writer.h:211
auto write_appended_data_points(std::ofstream &file) const
Definition: triangular_vtu_writer.h:156
static auto constexpr num_dimensions()
Definition: triangular_vtu_writer.h:21
auto write_vtk_file(std::ofstream &file, auto &offset) const
Definition: triangular_vtu_writer.h:40
auto write_vertex_property_data_array(auto const &name, vertex_property_type const &prop, std::ofstream &file, std::size_t &offset) const
Definition: triangular_vtu_writer.h:271
auto write_point_data(std::ofstream &file, std::size_t &offset) const
Definition: triangular_vtu_writer.h:72
auto write_appended_data(std::ofstream &file) const
Definition: triangular_vtu_writer.h:147
auto write_appended_data_cells_connectivity(std::ofstream &file) const
Definition: triangular_vtu_writer.h:185