|
| 1 | +#ifndef PHARE_DIAGNOSTIC_DETAIL_VTK_TYPES_FLUID_HPP |
| 2 | +#define PHARE_DIAGNOSTIC_DETAIL_VTK_TYPES_FLUID_HPP |
| 3 | + |
| 4 | +#include "core/utilities/box/box.hpp" |
| 5 | +#include "diagnostic/detail/vtkh5_type_writer.hpp" |
| 6 | +#include "core/numerics/interpolator/interpolator.hpp" |
| 7 | + |
| 8 | +#include "core/data/vecfield/vecfield_component.hpp" |
| 9 | +#include <string> |
| 10 | + |
| 11 | +namespace PHARE::diagnostic::vtkh5 |
| 12 | +{ |
| 13 | +/* |
| 14 | + * It is assumed that each patch has equal number of populations |
| 15 | + * |
| 16 | + * Possible outputs |
| 17 | + * |
| 18 | + * /t#/pl#/p#/ions/density |
| 19 | + * /t#/pl#/p#/ions/bulkVelocity/(x,y,z) |
| 20 | + * /t#/pl#/p#/ions/pop_(1,2,...)/density |
| 21 | + * /t#/pl#/p#/ions/pop_(1,2,...)/bulkVelocity/(x,y,z) |
| 22 | + */ |
| 23 | +template<typename H5Writer> |
| 24 | +class FluidDiagnosticWriter : public H5TypeWriter<H5Writer> |
| 25 | +{ |
| 26 | +public: |
| 27 | + using Super = H5TypeWriter<H5Writer>; |
| 28 | + using Attributes = Super::Attributes; |
| 29 | + using GridLayout = H5Writer::GridLayout; |
| 30 | + using FloatType = H5Writer::FloatType; |
| 31 | + using Super::fileData_; |
| 32 | + using Super::h5Writer_; |
| 33 | + |
| 34 | + static constexpr auto dimension = GridLayout::dimension; |
| 35 | + static constexpr auto interp_order = GridLayout::interp_order; |
| 36 | + |
| 37 | + |
| 38 | + FluidDiagnosticWriter(H5Writer& h5Writer) |
| 39 | + : Super{h5Writer} |
| 40 | + { |
| 41 | + } |
| 42 | + void write(DiagnosticProperties&) override; |
| 43 | + void compute(DiagnosticProperties&) override; |
| 44 | + |
| 45 | + |
| 46 | +private: |
| 47 | + auto static isActiveDiag(DiagnosticProperties const& diagnostic, std::string const& tree, |
| 48 | + std::string const& var) |
| 49 | + { |
| 50 | + return diagnostic.quantity == tree + var; |
| 51 | + }; |
| 52 | +}; |
| 53 | + |
| 54 | + |
| 55 | + |
| 56 | +template<typename H5Writer> |
| 57 | +void FluidDiagnosticWriter<H5Writer>::compute(DiagnosticProperties& diagnostic) |
| 58 | +{ |
| 59 | +} |
| 60 | + |
| 61 | + |
| 62 | +template<typename H5Writer> |
| 63 | +void FluidDiagnosticWriter<H5Writer>::write(DiagnosticProperties& diagnostic) |
| 64 | +{ |
| 65 | + auto constexpr static box_dim = dimension * 2; |
| 66 | + std::string static base = "/VTKHDF/"; |
| 67 | + std::string static level_base = base + "Level"; |
| 68 | + std::string static step_level = base + "Steps/Level"; |
| 69 | + |
| 70 | + auto& h5Writer = this->h5Writer_; |
| 71 | + auto& modelView = h5Writer.modelView(); |
| 72 | + auto& ions = modelView.getIons(); |
| 73 | + auto const minLvl = this->h5Writer_.minLevel; |
| 74 | + auto const maxLvl = this->h5Writer_.maxLevel; |
| 75 | + std::vector<std::vector<int>> boxes(this->h5Writer_.maxLevel + 1); |
| 76 | + std::size_t item_offset = 0, data_offset = 0; |
| 77 | + |
| 78 | + for (auto const& pop : ions) |
| 79 | + { |
| 80 | + std::string const tree{"/ions/pop/" + pop.name() + "/"}; |
| 81 | + this->checkCreateFileFor_(diagnostic, fileData_, tree, "density", "charge_density", "flux", |
| 82 | + "momentum_tensor"); |
| 83 | + } |
| 84 | + std::string const tree{"/ions/"}; |
| 85 | + this->checkCreateFileFor_(diagnostic, fileData_, tree, "charge_density", "mass_density", |
| 86 | + "bulkVelocity", "momentum_tensor"); |
| 87 | + auto& h5file = Super::h5FileForQuantity(diagnostic); |
| 88 | + |
| 89 | + auto const initDS = [&]<typename T = FloatType>(auto const& path, auto const& ds) { |
| 90 | + h5file.template create_chunked_data_set<FloatType>( // |
| 91 | + path, std::vector<hsize_t>{2}, ds); |
| 92 | + }; |
| 93 | + auto const initDSDefault = [&]<typename T = FloatType>(auto const& path) { |
| 94 | + initDS.template operator()<T>(path, |
| 95 | + HighFive::DataSpace({2}, {HighFive::DataSpace::UNLIMITED})); |
| 96 | + }; |
| 97 | + auto const doLevel = [&](std::string const lvl) { |
| 98 | + initDSDefault(level_base + lvl + "/PointData/data"); |
| 99 | + initDSDefault.template operator()<int>(level_base + lvl + "/AMRBox"); |
| 100 | + initDSDefault(step_level + lvl + "/AMRBoxOffset"); |
| 101 | + initDSDefault(step_level + lvl + "/NumberOfAMRBox"); |
| 102 | + initDSDefault(base + "/Steps/Values"); |
| 103 | + }; |
| 104 | + |
| 105 | + auto const setup = [&](auto& layout, auto const& patchID, auto const iLevel) { |
| 106 | + doLevel(std::to_string(iLevel)); |
| 107 | + for (std::size_t i = 0; i < dimension; ++i) |
| 108 | + boxes[iLevel].emplace_back(layout.AMRBox().lower[i]); |
| 109 | + for (std::size_t i = 0; i < dimension; ++i) |
| 110 | + boxes[iLevel].emplace_back(layout.AMRBox().upper[i]); |
| 111 | + }; |
| 112 | + modelView.visitHierarchy(setup, minLvl, maxLvl); |
| 113 | + |
| 114 | + auto const writeDS = [&](auto const& path, auto& field, auto const& layout) { |
| 115 | + auto const ilvl = layout.levelNumber(); |
| 116 | + auto const lvl = std::to_string(ilvl); |
| 117 | + auto const primal_box = core::grow(layout.AMRGhostBoxFor(field), -1 * layout.nbrGhosts()); |
| 118 | + { // data |
| 119 | + auto ds = h5file.getDataSet(level_base + lvl + "/PointData/data"); |
| 120 | + auto const new_size = data_offset + primal_box.size(); |
| 121 | + ds.resize({new_size}); |
| 122 | + // write physical rows |
| 123 | + ds.select({data_offset}, {primal_box.size()}) |
| 124 | + .write_raw(field.data() + layout.nbrGhosts()); |
| 125 | + data_offset += new_size; |
| 126 | + } |
| 127 | + { // boxes |
| 128 | + auto ds = h5file.getDataSet(level_base + lvl + "/AMRBox"); |
| 129 | + ds.resize({item_offset + boxes[ilvl].size()}); |
| 130 | + ds.select({item_offset}, {boxes[ilvl].size()}).write_raw(boxes[ilvl].data()); |
| 131 | + item_offset += boxes[ilvl].size(); |
| 132 | + } |
| 133 | + }; |
| 134 | + auto const write = [&](auto& layout, auto const& patchID, auto const iLevel) { |
| 135 | + if (isActiveDiag(diagnostic, tree, "charge_density")) |
| 136 | + writeDS("charge_density", ions.chargeDensity(), layout); |
| 137 | + }; |
| 138 | + |
| 139 | + modelView.visitHierarchy(write, minLvl, maxLvl); |
| 140 | +} |
| 141 | + |
| 142 | + |
| 143 | + |
| 144 | +} // namespace PHARE::diagnostic::vtkh5 |
| 145 | + |
| 146 | +#endif /* PHARE_DIAGNOSTIC_DETAIL_VTK_TYPES_FLUID_H */ |
0 commit comments