#ifndef FESA_IO_HDF5_HDF5_PRIMITIVES_H_ #define FESA_IO_HDF5_HDF5_PRIMITIVES_H_ #include #include #include #include #include #include #include #include #include "fesa/core/source_identity.h" #include "fesa/core/status.h" #include "fesa/model/domain.h" #include "io/hdf5/hdf5_raii.h" namespace fesa::hdf5_internal { inline constexpr std::size_t kDofsPerNode = 6U; inline constexpr std::size_t kEndpointCount = 2U; inline constexpr std::size_t kGaussPointCount = 2U; inline constexpr std::size_t kEndActionComponentCount = 6U; inline constexpr std::size_t kGeneralizedComponentCount = 4U; inline constexpr std::size_t kShellNodeCount = 4U; inline constexpr std::size_t kShellLocationCount = 4U; inline constexpr std::size_t kShellGeneralizedComponentCount = 8U; inline constexpr std::size_t kShellSectionPositionCount = 3U; inline constexpr std::size_t kShellStressComponentCount = 3U; inline constexpr const char* kStepName = "Step-1"; inline constexpr std::size_t kFrameIndex = 0U; inline constexpr const char* kStepRoot = "/steps/Step-1/frames/0"; using AxisSet = std::array; /// @brief Owns model values derived before candidate-file creation. struct WriterModelData { std::vector beam_local_axes; std::vector constraint_mask; std::vector prescribed_displacement; }; /// @brief Describes one backend-neutral float64 result dataset. struct DoubleDatasetPlan { std::string path; std::vector dimensions; std::vector values; std::string component_names; std::string component_units; std::string coordinate_system; std::string location; }; /// @brief Owns the fully validated model and result write plan. struct WriterPlan { WriterModelData model_data; std::vector result_datasets; }; /// @brief Creates one structured output failure. Status OutputFailure(const std::string& code, const std::string& message); /// @brief Tests exact preserved source identity. bool SameIdentity(const SourceEntityId& left, const SourceEntityId& right); /// @brief Tests a fixed component record for finite values. template bool IsFinite(const std::array& values) { for (const double value : values) { if (!std::isfinite(value)) { return false; } } return true; } /// @brief Validates UTF-8 without accepting overlong or surrogate encodings. bool IsValidUtf8(const std::string& value); /// @brief Identifies the schema-v0 shell variant. bool IsShellDomain(const Domain& domain) noexcept; /// @brief Returns the preserved shell source element type spelling. const char* ShellSourceTypeName(ShellSourceElementType type); /// @brief Computes a checked size product. bool SizeProductFits(std::size_t left, std::size_t right, std::size_t& product); /// @brief Returns a normalized absolute UTF-8 path string. std::string NormalizedPathString(const std::filesystem::path& path); /// @brief Returns schema-v0 source path and content identity metadata. std::string SourceInputIdentity(const Domain& domain); Hdf5Handle MakeUtf8StringType(); void WriteStringAttribute(hid_t object, const char* name, const std::string& value); void WriteUint64Attribute(hid_t object, const char* name, std::uint64_t value); void WriteUint8Attribute(hid_t object, const char* name, std::uint8_t value); void WriteDoubleAttribute(hid_t object, const char* name, double value); Hdf5Handle CreateGroup(hid_t file, const char* path); Hdf5Handle CreateDatasetSpace(const std::vector& dimensions); void WriteResultAttributes(hid_t dataset, const std::string& component_names, const std::string& component_units, const std::string& coordinate_system, const std::string& location); Hdf5Handle WriteDoubleValues(hid_t file, const std::string& path, const std::vector& dimensions, const double* values, std::size_t value_count); void WriteDoubleDataset(hid_t file, const std::string& path, const std::vector& dimensions, const double* values, std::size_t value_count, const std::string& component_names, const std::string& component_units, const std::string& coordinate_system, const std::string& location); void WriteModelDoubleDataset(hid_t file, const std::string& path, const std::vector& dimensions, const double* values, std::size_t value_count, const std::string& component_names, const std::string& component_units, const std::string& coordinate_system, const std::string& location); void WriteUint8Dataset(hid_t file, const std::string& path, const std::vector& dimensions, const std::uint8_t* values, std::size_t value_count); Hdf5Handle WriteCompoundDataset(hid_t file, const char* path, std::size_t row_count, hid_t file_type, hid_t memory_type, const void* rows); } // namespace fesa::hdf5_internal #endif // FESA_IO_HDF5_HDF5_PRIMITIVES_H_