22#define PHARE_DIAGNOSTIC_DETAIL_VTK_H5_TYPE_WRITER_HPP
33
44
5+ #include " core/utilities/types.hpp"
56#include " core/utilities/box/box.hpp"
67#include " core/utilities/algorithm.hpp"
78#include " core/utilities/mpi_utils.hpp"
89#include " core/data/tensorfield/tensorfield.hpp"
910
10- #include " core/utilities/types.hpp"
1111#include " diagnostic/diagnostic_writer.hpp"
1212
1313#include " hdf5/detail/h5/h5_file.hpp"
1414
1515#include < string>
16- #include < stdexcept>
1716#include < unordered_map>
1817
1918
@@ -35,12 +34,13 @@ using namespace hdf5::h5;
3534template <typename Writer>
3635class H5TypeWriter : public PHARE ::diagnostic::TypeWriter
3736{
38- using FloatType = float ; // Writer::FloatType;
37+ using FloatType = float ;
3938 std::string static inline base = " /VTKHDF/" ;
4039 std::string static inline level_base = base + " Level" ;
4140 std::string static inline step_level = base + " Steps/Level" ;
4241 using physical_quantity_type = Writer::ModelView::Field::physical_quantity_type;
4342
43+
4444public:
4545 static constexpr auto dimension = Writer::dimension;
4646 using GridLayout = Writer::GridLayout;
@@ -49,11 +49,14 @@ class H5TypeWriter : public PHARE::diagnostic::TypeWriter
4949 H5TypeWriter (Writer& h5Writer)
5050 : h5Writer_{h5Writer}
5151 {
52- if constexpr (dimension < 2 )
53- throw std::runtime_error (" VTK Diagnostics do not support 1D" );
5452 }
5553
5654protected:
55+ // data is duplicated in lower dimensions to fit a 3d view
56+ // so 2d data is * 2
57+ // and 1d data is * 4
58+ constexpr static auto X_TIMES = std::array{4 , 2 , /* 3d noop */ 1 }[dimension - 1 ];
59+
5760 auto static flatten_boxes (auto const & boxes)
5861 {
5962 std::vector<std::array<int , dimension * 2 >> data (boxes.size ());
@@ -77,13 +80,6 @@ class H5TypeWriter : public PHARE::diagnostic::TypeWriter
7780 // Mostly gridlayout and box info
7881 struct VTKFileFieldInfo ;
7982
80- // Writes fields to HDF5 in VTK format
81- struct VTKFileFieldWriter ;
82-
83- // Writes tensor fields to HDF5 in VTK format
84- template <std::size_t rank>
85- struct VTKFileTensorFieldWriter ;
86-
8783 auto & getOrCreateH5File (DiagnosticProperties const & diagnostic)
8884 {
8985 if (!fileData_.count (diagnostic.quantity ))
@@ -103,112 +99,17 @@ struct H5TypeWriter<Writer>::VTKFileFieldInfo
10399{
104100 auto static constexpr primal_qty = physical_quantity_type::rho;
105101
106- VTKFileFieldInfo (auto const & lyout)
107- : lvl{std::to_string (lyout.levelNumber ())}
108- , layout{lyout}
102+ VTKFileFieldInfo (auto const & layout)
103+ : lvl{std::to_string (layout.levelNumber ())}
109104 , ghost_box{layout.AMRGhostBoxFor (primal_qty)}
110105 , local_box{layout.AMRToLocal (core::grow (ghost_box, -1 * layout.nbrGhosts ()))}
111106 {
112107 }
113108
114-
115109 std::string lvl;
116- GridLayout const & layout;
117110 Box_t const ghost_box;
118111 core::Box<std::uint32_t , dimension> const local_box;
119- std::uint32_t const primal_row_len = local_box.shape(dimension - 1 );
120- std::string const path = level_base + lvl + " /PointData/data" ;
121- };
122-
123-
124-
125- template <typename Writer>
126- struct H5TypeWriter <Writer>::VTKFileFieldWriter
127- {
128- void write2D (auto const & field)
129- {
130- auto ds = fw->h5file .getDataSet (finfo.path );
131- auto const lcl_box = finfo.local_box ;
132- auto const size = lcl_box.size ();
133- auto const write = [&]() {
134- ds.select ({data_offset, 0 }, {size, 1 }).write_raw (field.data ());
135- data_offset += size;
136- };
137- write ();
138- write ();
139- }
140-
141-
142- void write3D (auto const & field)
143- {
144- auto ds = fw->h5file .getDataSet (finfo.path );
145- auto const lcl_box = finfo.local_box ;
146- auto const size = lcl_box.size ();
147- ds.select ({data_offset, 0 }, {size, 1 }).write_raw (field.data ());
148- data_offset += size;
149- }
150-
151-
152- void operator ()(auto const & field)
153- {
154- auto & tmp = fw->typewriter ->h5Writer_ .modelView ().tmpField ();
155- auto const frimal = core::convert_to_fortran_primal (tmp, field, finfo.layout );
156- if constexpr (dimension == 2 )
157- write2D (frimal);
158- if constexpr (dimension == 3 )
159- write3D (frimal);
160- }
161-
162- VTKFileWriter* fw;
163- VTKFileFieldInfo finfo;
164- std::size_t & data_offset = fw->data_offset; // NOT OWNED HERE
165- };
166-
167- template <typename Writer>
168- template <std::size_t rank>
169- struct H5TypeWriter <Writer>::VTKFileTensorFieldWriter
170- {
171- auto static constexpr N = core::detail::tensor_field_dim_from_rank<rank>();
172-
173- void write2D (auto const & tf)
174- {
175- auto ds = fw->h5file .getDataSet (finfo.path );
176- auto const lcl_box = finfo.local_box ;
177- auto const size = lcl_box.size ();
178- auto const write = [&]() {
179- for (std::uint32_t c = 0 ; c < N; ++c)
180- ds.select ({data_offset, c}, {size, 1 }).write_raw (tf[c].data ());
181- data_offset += size;
182- };
183- write ();
184- write ();
185- }
186-
187-
188- void write3D (auto const & tf)
189- {
190- auto ds = fw->h5file .getDataSet (finfo.path );
191- auto const lcl_box = finfo.local_box ;
192- auto const size = lcl_box.size ();
193- for (std::uint32_t c = 0 ; c < N; ++c)
194- ds.select ({data_offset, c}, {size, 1 }).write_raw (tf[c].data ());
195- data_offset += size;
196- }
197-
198-
199- void operator ()(auto const & tf)
200- {
201- auto & tmp = fw->typewriter ->h5Writer_ .modelView ().template tmpTensorField <rank>();
202- auto const frimal = core::convert_to_fortran_primal (tmp, tf, finfo.layout );
203- if constexpr (dimension == 2 )
204- write2D (frimal);
205- if constexpr (dimension == 3 )
206- write3D (frimal);
207- }
208-
209- VTKFileWriter* fw;
210- VTKFileFieldInfo finfo;
211- std::size_t & data_offset = fw->data_offset; // NOT OWNED HERE
112+ std::string const path = level_base + lvl + " /PointData/data" ;
212113};
213114
214115
@@ -223,6 +124,7 @@ struct H5TypeWriter<Writer>::VTKFileWriter
223124 , typewriter{tw}
224125 , h5file{tw->getOrCreateH5File (prop)}
225126 {
127+ // set global per file attributes and datasets
226128 {
227129 initDSDefault (base + " /Steps/Values" );
228130 auto steps_group = h5file.file ().getGroup (base + " /Steps" );
@@ -267,13 +169,34 @@ struct H5TypeWriter<Writer>::VTKFileWriter
267169
268170 void writeField (auto const & field, auto const & layout)
269171 {
270- VTKFileFieldWriter{this , {layout}}(field);
172+ VTKFileFieldInfo const finfo{layout};
173+ auto const frimal = core::convert_to_fortran_primal (
174+ typewriter->h5Writer_ .modelView ().tmpField (), field, layout);
175+ auto ds = h5file.getDataSet (finfo.path );
176+ auto const size = finfo.local_box .size ();
177+ for (std::uint16_t i = 0 ; i < X_TIMES; ++i)
178+ {
179+ ds.select ({data_offset, 0 }, {size, 1 }).write_raw (frimal.data ());
180+ data_offset += size;
181+ }
271182 }
272183
273184 template <std::size_t rank = 2 >
274185 void writeTensorField (auto const & tf, auto const & layout)
275186 {
276- VTKFileTensorFieldWriter<rank>{this , {layout}}(tf);
187+ auto static constexpr N = core::detail::tensor_field_dim_from_rank<rank>();
188+
189+ VTKFileFieldInfo const finfo{layout};
190+ auto const frimal = core::convert_to_fortran_primal (
191+ typewriter->h5Writer_ .modelView ().template tmpTensorField <rank>(), tf, layout);
192+ auto ds = h5file.getDataSet (finfo.path );
193+ auto const size = finfo.local_box .size ();
194+ for (std::uint16_t i = 0 ; i < X_TIMES; ++i)
195+ {
196+ for (std::uint32_t c = 0 ; c < N; ++c)
197+ ds.select ({data_offset, c}, {size, 1 }).write_raw (frimal[c].data ());
198+ data_offset += size;
199+ }
277200 }
278201
279202 template <typename T = FloatType>
@@ -327,36 +250,28 @@ struct H5TypeWriter<Writer>::VTKFileWriter
327250 }
328251 }
329252
330- void initFieldFileLevel (int const level, auto & boxes)
253+ template <std::size_t N = 1 >
254+ void initAnyFieldLevel (int const level, auto & boxes)
331255 {
332256 auto const path = level_base + std::to_string (level) + " /PointData/data" ;
333- h5file.template create_chunked_data_set <FloatType>(
334- path, std::vector<hsize_t >{detail::CHUNK_SIZE, 1 },
335- HighFive::DataSpace ({0 , 1 }, {HighFive::DataSpace::UNLIMITED, 1 }));
336- resize (level, boxes);
337- }
338-
339- template <std::size_t rank = 2 >
340- void initTensorFieldFileLevel (auto const level, auto & boxes)
341- {
342- auto constexpr N = core::detail::tensor_field_dim_from_rank<rank>();
343- auto const path = level_base + std::to_string (level) + " /PointData/data" ;
344257 h5file.template create_chunked_data_set <FloatType>(
345258 path, std::vector<hsize_t >{detail::CHUNK_SIZE, N},
346259 HighFive::DataSpace ({0 , N}, {HighFive::DataSpace::UNLIMITED, N}));
347260 resize<N>(level, boxes);
348261 }
349262
263+ void initFieldFileLevel (int const level, auto & boxes) { initAnyFieldLevel (level, boxes); }
264+
265+ template <std::size_t rank = 2 >
266+ void initTensorFieldFileLevel (int const level, auto & boxes)
267+ {
268+ initAnyFieldLevel<core::detail::tensor_field_dim_from_rank<rank>()>(level, boxes);
269+ }
350270
351271
352272 template <std::size_t N = 1 >
353273 void resize_data (auto const ilvl, auto const & boxes)
354274 {
355- // data is per face of a cube (cell)
356- // so 2d data is * 2
357- // and 1d data is * 4
358- constexpr static auto X_TIMES = std::array{4 , 2 , /* 3d noop */ 1 }[dimension - 1 ];
359-
360275 auto const lvl = std::to_string (ilvl);
361276 auto const data_path = level_base + lvl + " /PointData/data" ;
362277 auto point_data_ds = h5file.getDataSet (data_path);
@@ -392,8 +307,8 @@ struct H5TypeWriter<Writer>::VTKFileWriter
392307 ds.select ({old_size}, {1 }).write (total_boxes);
393308 }
394309
395- auto amrbox_ds = h5file.getDataSet (level_base + lvl + " /AMRBox" );
396- box_offset = amrbox_ds.getDimensions ()[0 ];
310+ auto amrbox_ds = h5file.getDataSet (level_base + lvl + " /AMRBox" );
311+ auto box_offset = amrbox_ds.getDimensions ()[0 ];
397312
398313 {
399314 auto ds = h5file.getDataSet (step_level + lvl + " /AMRBoxOffset" );
@@ -410,6 +325,7 @@ struct H5TypeWriter<Writer>::VTKFileWriter
410325 amrbox_ds.select ({box_offset, 0 }, {boxes.size (), dimension * 2 }).write (vtk_boxes);
411326 }
412327
328+
413329 template <std::size_t N = 1 >
414330 void resize (auto const ilvl, auto & boxes)
415331 {
@@ -423,7 +339,7 @@ struct H5TypeWriter<Writer>::VTKFileWriter
423339 DiagnosticProperties& diagnostic;
424340 H5TypeWriter<Writer>* typewriter;
425341 HighFiveFile& h5file;
426- std::size_t box_offset = 0 , data_offset = 0 ;
342+ std::size_t data_offset = 0 ;
427343};
428344
429345
0 commit comments