158 lines
6.9 KiB
C++
158 lines
6.9 KiB
C++
#ifndef FESA_IO_HDF5_HDF5_PRIMITIVES_H_
|
|
#define FESA_IO_HDF5_HDF5_PRIMITIVES_H_
|
|
|
|
#include <hdf5.h>
|
|
|
|
#include <array>
|
|
#include <cmath>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <filesystem>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "fesa/core/source_identity.h"
|
|
#include "fesa/core/status.h"
|
|
#include "fesa/math/vector.h"
|
|
#include "fesa/model/domain.h"
|
|
#include "io/hdf5/hdf5_raii.h"
|
|
#include "math/finite_values.h"
|
|
|
|
namespace fesa::hdf5_internal {
|
|
|
|
using math_internal::IsFinite;
|
|
|
|
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<double, 9>;
|
|
|
|
/// @brief Owns model values derived before candidate-file creation.
|
|
struct WriterModelData {
|
|
std::vector<AxisSet> beam_local_axes;
|
|
std::vector<std::uint8_t> constraint_mask;
|
|
std::vector<double> prescribed_displacement;
|
|
};
|
|
|
|
/// @brief Describes one backend-neutral float64 result dataset.
|
|
struct DoubleDatasetPlan {
|
|
std::string path;
|
|
std::vector<std::size_t> dimensions;
|
|
std::vector<double> 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<DoubleDatasetPlan> 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 Appends source-ordered reference directors and a,b,d frame columns.
|
|
/// @note Callers retain allocation, schema, write/readback and failure ownership.
|
|
void AppendShellReferenceFrames(const Domain& domain,
|
|
std::vector<double>& directors,
|
|
std::vector<double>& frames);
|
|
|
|
/// @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);
|
|
|
|
/// @brief Copies validated vector values in their existing component order.
|
|
std::vector<double> CopyVectorValues(const Vector& source);
|
|
|
|
/// @brief Flattens global nodal A,B,D axes in stable node/axis/component order.
|
|
std::vector<double> FlattenNodalTriads(
|
|
const std::vector<std::array<std::array<double, 3>, 3>>& triads);
|
|
|
|
/// @brief Flattens global nodal directors in stable node/component order.
|
|
std::vector<double> FlattenNodalDirectors(
|
|
const std::vector<std::array<double, 3>>& directors);
|
|
|
|
/// @brief Preserves force rows and maps generalized moments to spatial moments.
|
|
/// @pre Both six-DOF vectors and node_count were validated by the typed writer.
|
|
/// @note Rotation entries are at offsets 3..5; conversion uses J^T m = q.
|
|
/// @throws std::runtime_error when the existing spatial-moment solve fails.
|
|
std::vector<double> SpatialReactionValues(const Vector& rotation,
|
|
const Vector& reaction,
|
|
std::size_t node_count);
|
|
|
|
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<hsize_t>& dimensions);
|
|
/// @brief Writes quantity identity attributes, without family/frame metadata.
|
|
void WriteQuantityAttributes(hid_t dataset, const std::string& component_names,
|
|
const std::string& component_units,
|
|
const std::string& coordinate_system,
|
|
const std::string& location);
|
|
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<hsize_t>& dimensions,
|
|
const double* values, std::size_t value_count);
|
|
void WriteDoubleDataset(hid_t file, const std::string& path,
|
|
const std::vector<hsize_t>& 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<hsize_t>& 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<hsize_t>& 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_
|