diff --git a/src/amr/data/electromag/electromag_initializer.hpp b/src/amr/data/electromag/electromag_initializer.hpp index f8dc7d8b1..3dab99726 100644 --- a/src/amr/data/electromag/electromag_initializer.hpp +++ b/src/amr/data/electromag/electromag_initializer.hpp @@ -1,8 +1,6 @@ #ifndef _PHARE_AMR_DATA_ELECTROMAG_ELECTROMAG_INITIALIZER_HPP_ #define _PHARE_AMR_DATA_ELECTROMAG_ELECTROMAG_INITIALIZER_HPP_ -// #include "core/data/electromag/electromag.hpp" - #include "core/data/vecfield/vecfield_initializer.hpp" #include "amr/data/field/initializers/samrai_hdf5_field_initializer.hpp" #include "initializer/data_provider.hpp" diff --git a/src/amr/data/field/initializers/samrai_hdf5_field_initializer.hpp b/src/amr/data/field/initializers/samrai_hdf5_field_initializer.hpp index 43af05546..f94d59553 100644 --- a/src/amr/data/field/initializers/samrai_hdf5_field_initializer.hpp +++ b/src/amr/data/field/initializers/samrai_hdf5_field_initializer.hpp @@ -40,12 +40,64 @@ class SamraiHDF5FieldInitializer // no virtual classes needed (yet) }; - template void SamraiHDF5FieldInitializer::load(Field_t& field, GridLayout const& layout) const { - PHARE_LOG_LINE_STR("SamraiHDF5FieldInitializer::loadParticles"); + bool static constexpr c_ordering = false; + + auto const local_cell = [&](auto const& box, auto const& point) { + core::Point localPoint; + auto localStart = layout.physicalStartIndex(core::QtyCentering::dual, core::Direction::X); + for (std::size_t i = 0; i < dimension; ++i) + localPoint[i] = point[i] - (box.lower[i] - localStart); + return localPoint; + }; + + PHARE_LOG_LINE_STR("SamraiHDF5FieldInitializer::load"); + + auto const& dest_box = grow(layout.AMRBox(), GridLayout::nbrGhosts()); + auto const& overlaps = SamraiH5Interface::INSTANCE().box_intersections(dest_box); + + PHARE_LOG_LINE_STR(layout.AMRBox()); + for (auto const& [h5FilePtr, pdataptr] : overlaps) + { + auto& h5File = *h5FilePtr; + auto& pdata = *pdataptr; + PHARE_LOG_LINE_STR(pdata.box); + auto const src_box = grow(pdata.box, GridLayout::nbrGhosts()); + + std::vector data; + std::string const fieldpath + = pdata.base_path + "/" + field.name() + "##default/field_" + field.name(); + h5File.file().getDataSet(fieldpath).read(data); + + core::Box const lcl_src_box{ + core::Point{core::ConstArray()}, + core::Point{ + core::for_N([&](auto i) { + return static_cast(src_box.upper[i] - src_box.lower[i] + 1); + })}}; + + auto data_view = core::make_array_view(data.data(), *lcl_src_box.shape()); + auto dst_iter = dest_box.begin(); + auto src_iter = src_box.begin(); + for (; src_iter != src_box.end(); ++src_iter) + { + if (isIn(core::Point{*src_iter}, dest_box)) + { + while (*dst_iter != *src_iter) + ++dst_iter; + field(local_cell(dest_box, *dst_iter)) = data_view(local_cell(src_box, *src_iter)); + + PHARE_LOG_LINE_STR(*src_iter); + PHARE_LOG_LINE_STR(*dst_iter); + + PHARE_LOG_LINE_STR(field(local_cell(dest_box, *dst_iter))); + PHARE_LOG_LINE_STR(data_view(local_cell(src_box, *src_iter))); + } + } + } } diff --git a/src/amr/data/initializers/samrai_hdf5_initializer.hpp b/src/amr/data/initializers/samrai_hdf5_initializer.hpp index f2211b6c5..a139b266a 100644 --- a/src/amr/data/initializers/samrai_hdf5_initializer.hpp +++ b/src/amr/data/initializers/samrai_hdf5_initializer.hpp @@ -25,33 +25,32 @@ namespace PHARE::amr { -/* -example paths +template +struct SamraiH5PatchDataInfo +{ + using Box_t = core::Box; -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/protons##default/d_box -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/protons##default/d_ghost_box -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/protons##default/d_ghosts -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/protons##default/d_timestamp -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/protons##default/domainParticles_charge -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/protons##default/domainParticles_delta -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/protons##default/domainParticles_iCell -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/protons##default/domainParticles_v -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/protons##default/domainParticles_weight + SamraiH5PatchDataInfo(Box_t const& b, std::string const& p) + : box{b} + , base_path{p} + { + } -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/EM_B_y##default/d_box -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/EM_B_x##default/field_EM_B_x -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/EM_B_y##default/field_EM_B_y -/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/EM_B_z##default/field_EM_B_z -*/ + Box_t const box; + std::string const base_path; +}; + -template +template class SamraiH5Interface { - struct SamraiHDF5File; // : PHARE::hdf5::h5::HighFiveFile; + struct SamraiHDF5File; public: + using Box_t = core::Box; + static SamraiH5Interface& INSTANCE() { static SamraiH5Interface i; @@ -69,6 +68,18 @@ class SamraiH5Interface + "/proc." + SAMRAI::tbox::Utilities::processorToString(rank); } + auto box_intersections(Box_t const& box) + { + using Pair = std::pair const* const>; + std::vector overlaps; + for (auto const& h5File : restart_files) + for (auto const& patch : h5File->patches) + if (auto const intersection = box * patch.box) + overlaps.emplace_back(h5File.get(), &patch); + return overlaps; + } + private: @@ -76,11 +87,10 @@ class SamraiH5Interface std::unordered_map box2dataset; }; -template -struct SamraiH5Interface::SamraiHDF5File : public hdf5::h5::HighFiveFile +template +struct SamraiH5Interface::SamraiHDF5File : public hdf5::h5::HighFiveFile { using Super = hdf5::h5::HighFiveFile; - using Box_t = core::Box; SamraiHDF5File(std::string const& filepath) : Super{filepath, HighFive::File::ReadOnly, /*para=*/false} @@ -119,6 +129,8 @@ struct SamraiH5Interface::SamraiHDF5File : public hdf } */ + + struct BoxData { std::int32_t dim; @@ -149,43 +161,38 @@ struct SamraiH5Interface::SamraiHDF5File : public hdf assert(boxes.size() == 1); // auto const& bx = boxes[0]; - // return Box_t{core::as_sized_array(bx.lo0, bx.lo1, bx.lo2), - // core::as_sized_array(bx.hi0, bx.hi1, bx.hi2)}; + // return Box_t{core::as_sized_array(bx.lo0, bx.lo1, bx.lo2), + // core::as_sized_array(bx.hi0, bx.hi1, bx.hi2)}; - return Box_t{core::sized_array(boxes[0].lo), - core::sized_array(boxes[0].hi)}; + return Box_t{core::sized_array(boxes[0].lo), + core::sized_array(boxes[0].hi)}; } + + std::vector> patches; }; -template -void SamraiH5Interface::populate_from(std::string const& dir, - int const& idx, - int const& mpi_size) + +template +void SamraiH5Interface::populate_from(std::string const& dir, int const& idx, + int const& mpi_size) { + Box_t const mock{{0}, {99}}; for (int rank = 0; rank < mpi_size; ++rank) { auto const hdf5_filepath = getRestartFileFullPath(dir, idx, mpi_size, rank); - - hdf5::h5::HighFiveFile h5File{hdf5_filepath, HighFive::File::ReadOnly, /*para=*/false}; - - PHARE_LOG_LINE_STR("SamraiH5Interface::populate_from"); - - auto groups = h5File.scan_for_groups({"level_0000", "domainParticles_charge"}); - - for (auto const& g : groups) + auto& h5File = *restart_files.emplace_back(std::make_unique(hdf5_filepath)); + for (auto const& group : h5File.scan_for_groups({"level_0000", "field_EM_B_x"})) { - PHARE_LOG_LINE_STR(g); + auto const em_path = group.substr(0, group.rfind("/")); + h5File.patches.emplace_back(mock, em_path.substr(0, em_path.rfind("/"))); } - - restart_files.emplace_back(std::make_unique(hdf5_filepath)); } } - } // namespace PHARE::amr diff --git a/src/amr/data/particles/initializers/particle_initializer_factory.hpp b/src/amr/data/particles/initializers/particle_initializer_factory.hpp index e6b68db6c..48681fdb7 100644 --- a/src/amr/data/particles/initializers/particle_initializer_factory.hpp +++ b/src/amr/data/particles/initializers/particle_initializer_factory.hpp @@ -94,8 +94,7 @@ namespace amr int const mpi_size = dict["mpi_size"].template to(); // scan restart files for later use - SamraiH5Interface::INSTANCE().populate_from(dir, index, - mpi_size); + SamraiH5Interface::INSTANCE().populate_from(dir, index, mpi_size); return std::make_unique>(); } diff --git a/src/amr/data/particles/initializers/samrai_hdf5_particle_initializer.hpp b/src/amr/data/particles/initializers/samrai_hdf5_particle_initializer.hpp index 94c5158a8..d1ec3e2f7 100644 --- a/src/amr/data/particles/initializers/samrai_hdf5_particle_initializer.hpp +++ b/src/amr/data/particles/initializers/samrai_hdf5_particle_initializer.hpp @@ -6,6 +6,10 @@ #include #include +#include "core/def.hpp" +#include "core/logger.hpp" +#include "core/utilities/box/box.hpp" + #include "core/data/grid/gridlayoutdefs.hpp" #include "core/hybrid/hybrid_quantities.hpp" #include "core/utilities/types.hpp" @@ -13,13 +17,12 @@ #include "core/data/particles/particle.hpp" #include "initializer/data_provider.hpp" #include "core/utilities/point/point.hpp" -#include "core/def.hpp" -#include "core/logger.hpp" -#include "hdf5/detail/h5/h5_file.hpp" +#include "hdf5/detail/h5/h5_file.hpp" -#include "SAMRAI/hier/PatchDataRestartManager.h" +#include "core/data/particles/particle_packer.hpp" +#include "amr/data/field/initializers/samrai_hdf5_field_initializer.hpp" namespace PHARE::amr @@ -48,7 +51,38 @@ template void SamraiHDF5ParticleInitializer::loadParticles( ParticleArray& particles, GridLayout const& layout, std::string const& popname) const { + using Packer = core::ParticlePacker; PHARE_LOG_LINE_STR("SamraiHDF5ParticleInitializer::loadParticles"); + PHARE_LOG_LINE_SS(popname << " " << layout.AMRBox()); + + auto const& dest_box = layout.AMRBox(); + + auto const& overlaps = SamraiH5Interface::INSTANCE().box_intersections(dest_box); + for (auto const& [h5FilePtr, pdataptr] : overlaps) + { + auto& h5File = *h5FilePtr; + auto& pdata = *pdataptr; + std::string const poppath = pdata.base_path + "/" + popname + "##default/domainParticles_"; + core::ContiguousParticles soa{0}; + + { + std::size_t part_idx = 0; + core::apply(soa.as_tuple(), [&](auto& arg) { + auto const datapath = poppath + Packer::keys()[part_idx++]; + PHARE_LOG_LINE_STR("SamraiHDF5ParticleInitializer::loadParticles"); + PHARE_LOG_LINE_STR(datapath); + h5File.file().getDataSet(datapath).read(arg); + PHARE_LOG_LINE_STR("SamraiHDF5ParticleInitializer::loadParticles"); + }); + } + + for (std::size_t i = 0; i < soa.size(); ++i) + if (auto const p = soa.copy(i); core::isIn(core::Point{p.iCell}, dest_box)) + particles.push_back(p); + + PHARE_LOG_LINE_STR("SamraiHDF5ParticleInitializer::loadParticles"); + PHARE_LOG_LINE_STR(particles.size()); + } } diff --git a/src/core/data/grid/gridlayout.hpp b/src/core/data/grid/gridlayout.hpp index 59bd1ef8b..d0f076f0a 100644 --- a/src/core/data/grid/gridlayout.hpp +++ b/src/core/data/grid/gridlayout.hpp @@ -826,7 +826,7 @@ namespace core * This method only deals with **cell** indexes. */ template - NO_DISCARD auto AMRToLocal(Box AMRBox) const + NO_DISCARD auto AMRToLocal(Box const& AMRBox) const { static_assert(std::is_integral_v, "Error, must be MeshIndex (integral Point)"); auto localBox = Box{}; diff --git a/src/hdf5/detail/h5/group_scanner.hpp b/src/hdf5/detail/h5/group_scanner.hpp index a876a62bb..f62a3daee 100644 --- a/src/hdf5/detail/h5/group_scanner.hpp +++ b/src/hdf5/detail/h5/group_scanner.hpp @@ -28,7 +28,8 @@ struct GroupScanner auto& scan(std::string const& from = "/") { - scan(h5.file().getGroup(from), from); + // prevent double / at start of full path + scan(h5.file().getGroup(from), from == "/" ? "" : from); return groups; } void scan(HighFive::Group const& group, std::string const& path) diff --git a/tests/simulator/test_samrai_restarts_parser.py b/tests/simulator/test_samrai_restarts_parser.py index 37a1076af..79bca7a3f 100644 --- a/tests/simulator/test_samrai_restarts_parser.py +++ b/tests/simulator/test_samrai_restarts_parser.py @@ -84,27 +84,27 @@ def tearDown(self): ph.global_vars.sim = None def test_restart_parser(self): - h5_filepath = "phare_outputs/restarts/test/test_restarts_1/1/1/1/00000.00400/restore.000000/nodes.0000001/proc.0000000" - - h5 = H5Content(h5_filepath) - print( - h5.file[ - "/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/EMAvg_B_x##default/d_ghost_box" - ][:] - ) - for k in h5.data: - print(k) - - print( - "h5.file[]", - h5.file[ - "/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/EM_B_y##default/d_box" - ][:], - ) - - # sim = ph.Simulation(**dup()) - # model = setup_model() - # Simulator(sim).initialize() + # h5_filepath = "phare_outputs/restarts/test/test_restarts_1/1/1/1/00000.00400/restore.000000/nodes.0000001/proc.0000000" + + # h5 = H5Content(h5_filepath) + # print( + # h5.file[ + # "/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/EMAvg_B_x##default/d_ghost_box" + # ][:] + # ) + # for k in h5.data: + # print(k) + + # print( + # "h5.file[]", + # h5.file[ + # "/PHARE_hierarchy/level_0000/level_0000-patch_0000000-block_0000000/EM_B_y##default/d_box" + # ][:], + # ) + + sim = ph.Simulation(**dup()) + model = setup_model() + Simulator(sim).initialize() if __name__ == "__main__":