18 @brief Read a real64 PETSc binary VecView payload.
19 @details The header's class id and count are PetscInt of `index_bytes`, the width of the
20 PETSc that wrote the file, which the file does not record. Either byte order is
21 accepted, with or without the class id; the file length must match exactly.
22 @param[in] path PETSc binary vector path.
23 @param[in] numpy The caller's numpy module.
24 @param[in] index_bytes Bytes of a PetscInt in the writing PETSc, 4 or 8.
25 @param[in] label How the caller names the file in errors.
26 @return NumPy array of scalar values.
28 if not os.path.isfile(path):
29 raise ValueError(f
"{label} not found: {path}")
30 data = open(path,
"rb").read()
31 word, code = index_bytes,
"i" if index_bytes == 4
else "q"
32 if len(data) < 2 * word:
33 raise ValueError(f
"{label} '{path}' is too short to be a PETSc Vec binary.")
35 for endian
in (
">",
"<"):
36 _class_id, vec_size = struct.unpack(endian + 2 * code, data[:2 * word])
37 if vec_size > 0
and len(data) == 2 * word + vec_size * 8:
38 candidates.append((endian, vec_size, 2 * word))
39 (vec_size_no_class,) = struct.unpack(endian + code, data[:word])
40 if vec_size_no_class > 0
and len(data) == word + vec_size_no_class * 8:
41 candidates.append((endian, vec_size_no_class, word))
44 f
"{label} '{path}' does not match a PETSc real64 Vec binary with "
45 f
"{index_bytes}-byte indices; a file from the other index width does not fit."
47 endian, vec_size, offset = candidates[0]
48 values = numpy.frombuffer(data, dtype=numpy.dtype(endian +
"f8"), count=vec_size, offset=offset)
49 return values.astype(float, copy=
False)