diff --git a/docs/Tutorials/CCE.md b/docs/Tutorials/CCE.md index 5ebb8a37bab3..8e92cc02669b 100644 --- a/docs/Tutorials/CCE.md +++ b/docs/Tutorials/CCE.md @@ -205,6 +205,21 @@ values are the complex modes in m-varies-fastest format. That is, "Lapse_Re(2,0)", "Lapse_Im(2,0)", "Lapse_Re(2,-1)", "Lapse_Im(2,-1)", "Lapse_Re(2,-2)", "Lapse_Im(2,-2)" ``` +Each dataset in the file must also have an attribute named "Legend" which +is an ASCII-encoded null-terminated variable-length string. That is, the HDF5 +type is: +``` +DATATYPE H5T_STRING { + STRSIZE H5T_VARIABLE; + STRPAD H5T_STR_NULLTERM; + CSET H5T_CSET_ASCII; + CTYPE H5T_C_S1; +} +``` +This can be checked for a dataset by running +``` +h5dump -a DrLapse.dat/Legend CceR0150.h5 +``` The second format is Bondi-Sachs metric component data. This format is far more space-efficient (by around a factor of 4), and SpECTRE diff --git a/src/Evolution/Systems/Cce/BoundaryData.cpp b/src/Evolution/Systems/Cce/BoundaryData.cpp index cc2d8a83ab7c..01f8e6c70bb3 100644 --- a/src/Evolution/Systems/Cce/BoundaryData.cpp +++ b/src/Evolution/Systems/Cce/BoundaryData.cpp @@ -15,6 +15,7 @@ #include "DataStructures/Variables.hpp" #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp" #include "NumericalAlgorithms/Spectral/SwshDerivatives.hpp" +#include "Utilities/ErrorHandling/CaptureForError.hpp" #include "Utilities/Math.hpp" #include "Utilities/SetNumberOfGridPoints.hpp" @@ -484,6 +485,10 @@ void null_vector_l_and_derivatives( const tnsr::I& shift, const tnsr::I& worldtube_normal) { const size_t size = get(lapse).size(); + CAPTURE_FOR_ERROR(lapse); + CAPTURE_FOR_ERROR(dt_lapse); + CAPTURE_FOR_ERROR(shift); + CAPTURE_FOR_ERROR(dt_shift); // Allocation Variables, ::Tags::TempScalar<1>, @@ -507,6 +512,7 @@ void null_vector_l_and_derivatives( denominator -= spacetime_metric.get(i + 1, i + 1) * shift.get(i) * worldtube_normal.get(i); } + CAPTURE_FOR_ERROR(denominator); // buffer re-use because we won't need the uninverted denominator after this. DataVector& one_divided_by_denominator = get(get<::Tags::TempScalar<0>>(aggregated_buffer)); diff --git a/src/IO/H5/Helpers.cpp b/src/IO/H5/Helpers.cpp index a88387c7849a..c89d94ac5d8c 100644 --- a/src/IO/H5/Helpers.cpp +++ b/src/IO/H5/Helpers.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "DataStructures/BoostMultiArray.hpp" #include "DataStructures/DataVector.hpp" @@ -473,8 +474,25 @@ std::vector read_rank1_attribute( // Read the strings as arrays of characters std::vector temp(legend_dims[0]); const hid_t memtype = h5_type(); - CHECK_H5(H5Aread(attribute_id, memtype, static_cast(temp.data())), - "Failed to read attribute"); + const hid_t type_in_file = H5Aget_type(attribute_id); + CHECK_H5(type_in_file, + "Failed to read attribute type from file. Attribute name is '" + << name << "'"); + if (H5Tis_variable_str(type_in_file) < 0) { + char* type_name_ptr = H5Tget_tag(type_in_file); + const std::string type_name{type_name_ptr}; + ERROR("The attribute type should be a variable string but got " + << type_name); + free(type_name_ptr); // NOLINT + } + if (H5Tget_cset(type_in_file) != H5T_CSET_ASCII) { + ERROR("Expected ASCII-encoded string but got H5T_cset_t of value " + << H5Tget_cset(type_in_file) + << ". Likely the string is UTF8 encoded."); + } + CHECK_H5( + H5Aread(attribute_id, memtype, static_cast(temp.data())), + "Failed to read attribute: " << name << " with size " << legend_dims); std::vector result(temp.size()); std::transform(temp.begin(), temp.end(), result.begin(), diff --git a/src/IO/H5/Type.hpp b/src/IO/H5/Type.hpp index 0fbe9e4e255e..a90bf5fad681 100644 --- a/src/IO/H5/Type.hpp +++ b/src/IO/H5/Type.hpp @@ -86,6 +86,10 @@ SPECTRE_ALWAYS_INLINE hid_t h5_type() { #pragma GCC diagnostic ignored "-Wold-style-cast" CHECK_H5(H5Tset_size(datatype, H5T_VARIABLE), "Failed to set size of string."); + CHECK_H5(H5Tset_cset(datatype, H5T_CSET_ASCII), + "Failed to set string to ASCII encoding."); + CHECK_H5(H5Tset_strpad(datatype, H5T_STR_NULLTERM), + "Failed to set string to null terminate"); #pragma GCC diagnostic pop return datatype; }