1#ifndef TATOOINE_DETAIL_RECTILINEAR_GRID_VTR_WRITER_H
2#define TATOOINE_DETAIL_RECTILINEAR_GRID_VTR_WRITER_H
14template <
typename Gr
id,
unsigned_
integral HeaderType>
15requires(Grid::num_dimensions() == 2 || Grid::num_dimensions() == 3)
19 template <
typename T,
bool H>
25 auto write(filesystem::path
const& path)
const {
26 auto file = std::ofstream{path};
27 if (!file.is_open()) {
28 throw std::runtime_error{
"Could open file " + path.string() +
31 auto offset = std::size_t{};
32 write_vtk_file(file, offset);
38 <<
" type=\"RectilinearGrid\""
40 <<
" byte_order=\"LittleEndian\""
43 tatooine::vtk::xml::to_data_type<HeaderType>())
45 write_rectilinear_grid(file, offset);
46 write_appended_data(file);
51 file <<
" <RectilinearGrid WholeExtent=\"" << 0 <<
" "
52 << m_grid.template size<0>() - 1 <<
" " << 0 <<
" "
53 << m_grid.template size<1>() - 1;
54 if constexpr (num_dimensions() >= 3) {
55 file <<
" " << 0 <<
" " << m_grid.template size<2>() - 1;
57 file <<
" " << 0 <<
" " << 0;
60 write_piece(file, offset);
61 file <<
" </RectilinearGrid>\n";
65 file <<
" <Piece Extent=\"" << 0 <<
" " << m_grid.template size<0>() - 1
66 <<
" " << 0 <<
" " << m_grid.template size<1>() - 1 <<
" ";
67 if constexpr (num_dimensions() >= 3) {
68 file << 0 <<
" " << m_grid.template size<2>() - 1;
70 file << 0 <<
" " << 0;
74 write_point_data(file, offset);
75 write_cell_data(file, offset);
76 write_coordinates(file, offset);
78 file <<
" </Piece>\n";
82 file <<
" <PointData>\n";
83 for (
auto const& [name, prop] : m_grid.vertex_properties()) {
87 name, *prop, file, offset);
89 file <<
" </PointData>\n";
93 file <<
" <CellData>\n";
94 file <<
" </CellData>\n";
98 file <<
" <Coordinates>\n";
99 write_dimension_data_array(m_grid.template
dimension<0>(),
"x_coordinates",
101 write_dimension_data_array(m_grid.template
dimension<1>(),
"y_coordinates",
103 if constexpr (num_dimensions() >= 3) {
104 write_dimension_data_array(m_grid.template
dimension<2>(),
105 "z_coordinates", file, offset);
107 write_dimension_data_array(std::vector<typename Grid::real_type>{0},
108 "z_coordinates", file, offset);
110 file <<
" </Coordinates>\n";
113 template <
typename T>
115 std::string
const& name, std::ofstream& file,
116 std::size_t& offset)
const {
117 file <<
" <DataArray"
121 <<
" Name=\"" << name <<
"\""
122 <<
" format=\"appended\""
123 <<
" offset=\"" << offset <<
"\""
125 offset += dim.size() *
sizeof(T) +
sizeof(HeaderType);
128 template <
typename T, std::
size_t N>
130 std::string
const& name, std::ofstream& file,
131 std::size_t& offset)
const {
132 file <<
" <DataArray"
136 <<
" Name=\"" << name <<
"\""
137 <<
" format=\"appended\""
138 <<
" offset=\"" << offset <<
"\""
140 offset += N *
sizeof(T) +
sizeof(HeaderType);
143 template <
typename T>
145 std::string
const& name, std::ofstream& file,
146 std::size_t& offset)
const {
147 file <<
" <DataArray"
151 <<
" Name=\"" << name <<
"\""
152 <<
" format=\"appended\""
153 <<
" offset=\"" << offset <<
"\""
156 offset += dim.
size() *
sizeof(T) +
sizeof(HeaderType);
160 file <<
" <AppendedData encoding=\"raw\">\n _";
161 write_appended_data_point_data(file);
162 write_appended_data_cell_data(file);
163 write_appended_data_coordinates(file);
164 file <<
"\n </AppendedData>\n";
168 for (
auto const& [name, prop] : m_grid.vertex_properties()) {
169 write_vertex_property_appended_data<
178 write_dimension_appended_data(m_grid.template
dimension<0>(), file);
179 write_dimension_appended_data(m_grid.template
dimension<1>(), file);
180 if constexpr (num_dimensions() >= 3) {
181 write_dimension_appended_data(m_grid.template
dimension<2>(), file);
183 write_dimension_appended_data(std::vector{
typename Grid::real_type(0)},
188 template <
typename T>
190 std::ofstream& file)
const {
191 auto const num_bytes = HeaderType(
sizeof(T) * dim.size());
192 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(HeaderType));
193 file.write(
reinterpret_cast<char const*
>(dim.data()), num_bytes);
196 template <
typename T, std::
size_t N>
198 std::ofstream& file)
const {
199 auto const num_bytes = HeaderType(
sizeof(T) * N);
200 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(HeaderType));
201 file.write(
reinterpret_cast<char const*
>(dim.data()), num_bytes);
204 template <
typename T>
206 std::ofstream& file)
const {
207 auto data = std::vector<T>(dim.
size());
208 std::ranges::copy(dim,
begin(data));
209 auto const num_bytes = HeaderType(
sizeof(T) * data.size());
210 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(HeaderType));
212 file.write(
reinterpret_cast<char const*
>(data.data()), num_bytes);
216 template <
typename... Ts>
218 std::ofstream& file)
const {
220 if (prop.type() ==
typeid(Ts)) {
221 write_vertex_property_appended_data(prop.template cast_to_typed<Ts>(),
227 template <
typename T,
bool H>
230 std::ofstream& file)
const {
231 if constexpr (tensor_rank<T> <= 1) {
232 auto data = std::vector<T>{};
233 m_grid.vertices().iterate_indices(
234 [&](
auto const... is) { data.push_back(prop(is...)); });
235 auto const num_bytes =
237 m_grid.vertices().size());
238 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(HeaderType));
239 file.write(
reinterpret_cast<char const*
>(data.data()), num_bytes);
240 }
else if constexpr (tensor_rank<T> == 2) {
241 auto const num_bytes =
243 m_grid.vertices().size() / tensor_dimension<T, 0>);
244 for (std::size_t i = 0; i < tensor_dimension<T, 1>; ++i) {
245 file.write(
reinterpret_cast<char const*
>(&num_bytes),
247 m_grid.vertices().iterate_indices([&](
auto const... is) {
248 auto data_begin = &prop(is...)(0, i);
249 file.write(
reinterpret_cast<char const*
>(data_begin),
256 template <
typename... Ts>
260 std::size_t& offset)
const {
262 if (prop.type() ==
typeid(Ts)) {
263 if constexpr (tensor_rank<Ts> <= 1) {
265 <<
" Name=\"" << name <<
"\""
266 <<
" format=\"appended\""
267 <<
" offset=\"" << offset <<
"\""
269 << tatooine::vtk::xml::to_string(
270 tatooine::vtk::xml::to_data_type<tatooine::value_type<Ts>>())
271 <<
"\" NumberOfComponents=\""
272 << tensor_num_components<Ts> <<
"\"/>\n";
273 offset += m_grid.vertices().size() * sizeof(Ts) + sizeof(HeaderType);
274 }
else if constexpr (tensor_rank<Ts> == 2) {
275 for (std::size_t i = 0; i < Ts::dimension(1); ++i) {
277 <<
" Name=\"" << name <<
"_col_" << i <<
"\""
278 <<
" format=\"appended\""
279 <<
" offset=\"" << offset <<
"\""
283 <<
"\" NumberOfComponents=\"" << Ts::dimension(0) <<
"\"/>\n";
285 tensor_dimension<Ts, 0> +
Definition: dimension.h:9
Definition: cell_container.h:15
auto begin(vertex_container< Dimensions... > const &c)
Definition: vertex_container.h:137
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
constexpr auto invoke(invocable auto &&...funcs)
Definition: functional.h:8
mat33f mat3f
Definition: mat_typedefs.h:298
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: vtr_writer.h:16
auto write_vertex_property_appended_data(vertex_property_type const &prop, std::ofstream &file) const
Definition: vtr_writer.h:217
auto write_appended_data(std::ofstream &file) const
Definition: vtr_writer.h:159
auto write_dimension_appended_data(tatooine::linspace< T > const &dim, std::ofstream &file) const
Definition: vtr_writer.h:205
auto write_dimension_data_array(std::array< T, N > const &, std::string const &name, std::ofstream &file, std::size_t &offset) const
Definition: vtr_writer.h:129
auto write_dimension_data_array(std::vector< T > const &dim, std::string const &name, std::ofstream &file, std::size_t &offset) const
Definition: vtr_writer.h:114
auto write_dimension_appended_data(std::array< T, N > const &dim, std::ofstream &file) const
Definition: vtr_writer.h:197
auto write_coordinates(std::ofstream &file, std::size_t &offset) const
Definition: vtr_writer.h:97
auto write_appended_data_cell_data(std::ofstream &) const
Definition: vtr_writer.h:175
auto write_vtk_file(std::ofstream &file, auto &offset) const
Definition: vtr_writer.h:36
auto write_dimension_data_array(tatooine::linspace< T > const &dim, std::string const &name, std::ofstream &file, std::size_t &offset) const
Definition: vtr_writer.h:144
Grid const & m_grid
Definition: vtr_writer.h:23
typename Grid::vertex_property_type vertex_property_type
Definition: vtr_writer.h:18
auto write_dimension_appended_data(std::vector< T > const &dim, std::ofstream &file) const
Definition: vtr_writer.h:189
static auto constexpr num_dimensions()
Definition: vtr_writer.h:17
auto write_rectilinear_grid(std::ofstream &file, auto &offset) const
Definition: vtr_writer.h:50
auto write_appended_data_coordinates(std::ofstream &file) const
Definition: vtr_writer.h:177
typename Grid::template typed_vertex_property_interface_type< T, H > typed_vertex_property_interface_type
Definition: vtr_writer.h:21
auto write_piece(std::ofstream &file, auto &offset) const
Definition: vtr_writer.h:64
auto write_vertex_property_data_array(auto const &name, vertex_property_type const &prop, std::ofstream &file, std::size_t &offset) const
Definition: vtr_writer.h:257
auto write(filesystem::path const &path) const
Definition: vtr_writer.h:25
auto write_vertex_property_appended_data(typed_vertex_property_interface_type< T, H > const &prop, std::ofstream &file) const
Definition: vtr_writer.h:228
auto write_appended_data_point_data(std::ofstream &file) const
Definition: vtr_writer.h:167
auto write_point_data(std::ofstream &file, std::size_t &offset) const
Definition: vtr_writer.h:81
auto write_cell_data(std::ofstream &file, std::size_t &) const
Definition: vtr_writer.h:92
Definition: linspace.h:26
constexpr auto size() const
Definition: linspace.h:91