From 9bc6e6159f483a66b929cf0e05fe2479b50ea26a Mon Sep 17 00:00:00 2001 From: mattloulou Date: Fri, 30 Aug 2024 00:15:30 -0400 Subject: [PATCH] Implemented HDF5 output --- .../include/Neon/core/tools/io/ioToHDF5.h | 42 +++++++++--------- .../include/Neon/domain/interface/FieldBase.h | 12 +++-- .../Neon/domain/interface/FieldBase_imp.h | 44 +++++++++++++++++-- .../Neon/domain/interface/GridBaseTemplate.h | 5 +++ .../domain/interface/GridBaseTemplate_imp.h | 33 ++++++++++++++ 5 files changed, 108 insertions(+), 28 deletions(-) diff --git a/libNeonCore/include/Neon/core/tools/io/ioToHDF5.h b/libNeonCore/include/Neon/core/tools/io/ioToHDF5.h index 56480d6d..2af22dcc 100644 --- a/libNeonCore/include/Neon/core/tools/io/ioToHDF5.h +++ b/libNeonCore/include/Neon/core/tools/io/ioToHDF5.h @@ -30,7 +30,7 @@ namespace Neon { /** * Namespace for this tool */ -namespace ioToNanoVDBns { +namespace ioToHDF5ns { /** * Implicit function that defines the data stores by a user fields @@ -79,8 +79,8 @@ namespace helpNs { } // namespace helpNs template -void ioToNanoVDB(const ioToNanoVDBns::UserFieldInformation& fieldData /*! User data that defines the field */, - ioToNanoVDBns::UserFieldAccessMask mask /*! Stores a mask for which indices in the field should be outputted*/, +void ioToHDF5(const ioToHDF5ns::UserFieldInformation& fieldData /*! User data that defines the field */, + ioToHDF5ns::UserFieldAccessMask mask /*! Stores a mask for which indices in the field should be outputted*/, const std::string& filename /*! File name */, const Neon::Integer_3d& dim /*! Dimension of the field */, [[maybe_unused]] double spacingScale = 1.0 /*! Spacing, i.e. size of a voxel */, @@ -90,17 +90,19 @@ void ioToNanoVDB(const ioToNanoVDBns::UserFieldInformation& { if (fieldData.m_cardinality != 1) { - std::string msg = std::string("Too many components specified during attempt at creating hdf5 output. It currently only supports 1 component."); - NeonException exception("ioToNanoVDB"); + std::string msg = std::string("Too many components specified during attempt at creating HDF5 output. It currently only supports 1 component."); + NeonException exception("ioToHDF5"); exception << msg; NEON_THROW(exception); } + // create the dataset HighFive::File file(filename, HighFive::File::ReadWrite | HighFive::File::Create | HighFive::File::Truncate); HighFive::DataSetCreateProps props; props.add(HighFive::Chunking(std::vector{chunking.x, chunking.y, chunking.z})); HighFive::DataSet dataset = file.createDataSet(filename, HighFive::DataSpace({dim.x, dim.y, dim.z}), props); + // write the values to the dataset for (int i = origin.x; i < origin.x + dim.x; ++i) { for (int j = origin.y; j < origin.y + dim.y; ++j) { for (int k = origin.z; k < origin.z + dim.z; ++k) { @@ -112,24 +114,24 @@ void ioToNanoVDB(const ioToNanoVDBns::UserFieldInformation& } } -} // namespace ioToNanoVDBns +} // namespace ioToHDF5ns template -struct ioToNanoVDB +struct ioToHDF5 { - ioToNanoVDB(const std::string& filename /*! File name */, + ioToHDF5(const std::string& filename /*! File name */, const Neon::Integer_3d& dim /*! IoDense dimension of the field */, const std::function&, int componentIdx)>& fun /*! Implicit defintion of the user field */, const nComponent_t card /*! Field cardinality */, const double scalingData = 1.0 /*! Spacing, i.e. size of a voxel */, const Neon::Integer_3d& origin = Neon::Integer_3d(0, 0, 0) /*! Minimum Corner && Origin */, const Neon::Integer_3d& chunking = Neon::Integer_3d(10, 10, 10) /*1 Chunking size of the output file */, - const Neon::ioToNanoVDBns::UserFieldAccessMask mask = [](const Neon::index_3d& idx){return (idx.x == idx.x) ? true: false;}) /*! Used for sparce matrices; returns true for indices that should be stored in vdb output */ + const Neon::ioToHDF5ns::UserFieldAccessMask mask = [](const Neon::index_3d& idx){return (idx.x == idx.x) ? true: false;}) /*! Used for sparce matrices; returns true for indices that should be included in the output */ : m_filename(filename), m_dim(dim), m_scalingData(scalingData), m_origin(origin), - m_field(ioToNanoVDBns::UserFieldInformation(fun, card)), + m_field(ioToHDF5ns::UserFieldInformation(fun, card)), m_chunking(chunking), m_mask(mask) { @@ -137,7 +139,7 @@ struct ioToNanoVDB out << "dim: " << m_dim.x << " " << m_dim.y << " " << m_dim.z << std::endl; } - virtual ~ioToNanoVDB() + virtual ~ioToHDF5() { } @@ -152,8 +154,8 @@ struct ioToNanoVDB std::string s = ss.str(); filename = m_filename + s; } - filename = filename + ".nvdb"; - ioToNanoVDBns::ioToNanoVDB(m_field, + filename = filename + ".h5"; + ioToHDF5ns::ioToHDF5(m_field, m_mask, filename, m_dim, @@ -176,13 +178,13 @@ struct ioToNanoVDB private: - std::string m_filename /*! File name */; - Neon::Integer_3d m_dim /*! IoDense dimension of the field */; - double m_scalingData = 1.0 /*! Spacing, i.e. size of a voxel */; - Neon::Integer_3d m_origin = Neon::Integer_3d(0, 0, 0) /*! Origin */; - Neon::Integer_3d m_chunking = Neon::Integer_3d(10, 10, 10) /*! Chunking */; - ioToNanoVDBns::UserFieldInformation m_field /*! Field data*/; - ioToNanoVDBns::UserFieldAccessMask m_mask; + std::string m_filename /*! File name */; + Neon::Integer_3d m_dim /*! IoDense dimension of the field */; + double m_scalingData = 1.0 /*! Spacing, i.e. size of a voxel */; + Neon::Integer_3d m_origin = Neon::Integer_3d(0, 0, 0) /*! Origin */; + Neon::Integer_3d m_chunking = Neon::Integer_3d(10, 10, 10) /*! Chunking */; + ioToHDF5ns::UserFieldInformation m_field /*! Field data*/; + ioToHDF5ns::UserFieldAccessMask m_mask; int m_iteration = -1; }; diff --git a/libNeonDomain/include/Neon/domain/interface/FieldBase.h b/libNeonDomain/include/Neon/domain/interface/FieldBase.h index cdbc782f..4a377ba2 100644 --- a/libNeonDomain/include/Neon/domain/interface/FieldBase.h +++ b/libNeonDomain/include/Neon/domain/interface/FieldBase.h @@ -141,12 +141,16 @@ class FieldBase bool isNodeSpace = false) const -> void; template - auto ioToNanoVDB(const std::string& fileName, - bool isNodeSpace = false) const -> void; + auto ioToNanoVDB(const std::string& fileName) const -> void; template - auto ioDomainToNanoVDB(const std::string& fileName, - bool isNodeSpace = false) const -> void; + auto ioDomainToNanoVDB(const std::string& fileName) const -> void; + + template + auto ioToHDF5(const std::string& fileName) const -> void; + + template + auto ioDomainToHDF5(const std::string& fileName) const -> void; private: diff --git a/libNeonDomain/include/Neon/domain/interface/FieldBase_imp.h b/libNeonDomain/include/Neon/domain/interface/FieldBase_imp.h index 27cd00fd..0b1ff57a 100644 --- a/libNeonDomain/include/Neon/domain/interface/FieldBase_imp.h +++ b/libNeonDomain/include/Neon/domain/interface/FieldBase_imp.h @@ -3,6 +3,7 @@ #include "Neon/domain/interface/FieldBase.h" #include "Neon/domain/tools/IOGridVTK.h" #include "Neon/core/tools/io/ioToNanoVDB.h" +#include "Neon/core/tools/io/ioToHDF5.h" namespace Neon::domain::interface { @@ -321,8 +322,7 @@ auto FieldBase::ioToVtk(const std::string& fileName, template template -auto FieldBase::ioToNanoVDB(const std::string& fileName, - bool isNodeSpace) const -> void +auto FieldBase::ioToNanoVDB(const std::string& fileName) const -> void { Neon::ioToNanoVDB io(fileName, this->getDimension(), @@ -340,8 +340,7 @@ auto FieldBase::ioToNanoVDB(const std::string& fileName, template template -auto FieldBase::ioDomainToNanoVDB(const std::string& fileName, - bool isNodeSpace) const -> void +auto FieldBase::ioDomainToNanoVDB(const std::string& fileName) const -> void { Neon::ioToNanoVDB io(fileName, this->getDimension(), @@ -358,6 +357,43 @@ auto FieldBase::ioDomainToNanoVDB(const std::string& fileName, return; } +template +template +auto FieldBase::ioToHDF5(const std::string& fileName) const -> void +{ + Neon::ioToHDF5 io(fileName, + this->getDimension(), + [&](Neon::Integer_3d idx, int card) -> HDF5ExportType { + return (*this)(idx, card); + }, + this->getCardinality(), + 1.0, + Neon::Integer_3d(0, 0, 0)); + + + io.flush(); + return; +} + +template +template +auto FieldBase::ioDomainToHDF5(const std::string& fileName) const -> void +{ + Neon::ioToHDF5 io(fileName, + this->getDimension(), + [&](const Neon::index_3d& idx, int) { + HDF5ExportType setIdx = HDF5ExportType(getBaseGridTool().getSetIdx(idx)); + return setIdx; + }, + 1, + 1.0, + Neon::Integer_3d(0, 0, 0)); + + + io.flush(); + return; +} + template auto FieldBase::getClassName() const -> const std::string& { diff --git a/libNeonDomain/include/Neon/domain/interface/GridBaseTemplate.h b/libNeonDomain/include/Neon/domain/interface/GridBaseTemplate.h index 5741911f..d2cbe2ab 100644 --- a/libNeonDomain/include/Neon/domain/interface/GridBaseTemplate.h +++ b/libNeonDomain/include/Neon/domain/interface/GridBaseTemplate.h @@ -36,6 +36,11 @@ class GridBaseTemplate : public GridBase * Exporting the domain active voxel to nanoVDB */ auto ioDomainToNanoVDB(const std::string& fileName) const -> void; + + /** + * Exporting the domain active voxel to HDF5 + */ + auto ioDomainToHDF5(const std::string& fileName) const -> void; }; } // namespace Neon::domain::interface diff --git a/libNeonDomain/include/Neon/domain/interface/GridBaseTemplate_imp.h b/libNeonDomain/include/Neon/domain/interface/GridBaseTemplate_imp.h index f859fc3c..2d444d12 100644 --- a/libNeonDomain/include/Neon/domain/interface/GridBaseTemplate_imp.h +++ b/libNeonDomain/include/Neon/domain/interface/GridBaseTemplate_imp.h @@ -2,6 +2,7 @@ #include "Neon/core/tools/io/ioToVTK.h" #include "Neon/core/tools/io/ioToNanoVDB.h" +#include "Neon/core/tools/io/ioToHDF5.h" namespace Neon::domain::interface { @@ -65,4 +66,36 @@ auto GridBaseTemplate::ioDomainToNanoVDB(const std::string& fileNa io2.flush(); return; } + +template +auto GridBaseTemplate::ioDomainToHDF5(const std::string& fileName) const -> void +{ + ioToHDF5 io1(fileName + "_domain", + this->getDimension(), + [&](const Neon::index_3d& idx, int) { + bool isActiveVox = isInsideDomain(idx); + return isActiveVox; + }, + 1, + 1.0, + Neon::Integer_3d(0, 0, 0)); + + ioToHDF5 io2(fileName + "_partition", + this->getDimension(), + [&](const Neon::index_3d& idx, int) { + const auto& cellProperties = this->getProperties(idx); + if (!cellProperties.isInside()) { + return -1; + } + auto setIdx = cellProperties.getSetIdx(); + return setIdx.idx(); + }, + 1, + 1.0, + Neon::Integer_3d(0, 0, 0)); + + io1.flush(); + io2.flush(); + return; +} } // namespace Neon::domain::interface