Read and exhaustively validate every appended value in a generated VTS file.
23{
25 char line[1024];
26 char footer[128];
27 char expected_extent[128];
28 PetscBool saw_pressure = PETSC_FALSE;
29 PetscBool saw_velocity = PETSC_FALSE;
30 PetscBool saw_qcrit = PETSC_FALSE;
31 PetscBool saw_extent = PETSC_FALSE;
32 uint32_t block_size = 0;
33 PetscInt npoints = mx * my * mz;
34 PetscScalar *coords = NULL;
35 PetscScalar *pressure = NULL;
36 PetscScalar *velocity = NULL;
37 PetscScalar *qcrit = NULL;
38 size_t footer_size = 0;
39 PetscBool valid = PETSC_FALSE;
40
41 file = fopen(path,
"rb");
42 if (!file) return PETSC_FALSE;
43 snprintf(expected_extent, sizeof(expected_extent),
44 "WholeExtent=\"0 %d 0 %d 0 %d\"", (int)(mx - 1), (int)(my - 1), (int)(mz - 1));
45
46 while (fgets(line, sizeof(line), file)) {
47 if (strstr(line, "Name=\"P_nodal\"")) saw_pressure = PETSC_TRUE;
48 if (strstr(line, "Name=\"Ucat_nodal\"")) saw_velocity = PETSC_TRUE;
49 if (strstr(line, "Name=\"Qcrit\"")) saw_qcrit = PETSC_TRUE;
50 if (strstr(line, expected_extent)) saw_extent = PETSC_TRUE;
51 if (strstr(line, "<AppendedData encoding=\"raw\">")) break;
52 }
53 if (!saw_pressure || !saw_velocity || !saw_qcrit || !saw_extent || fgetc(file) != '_') goto cleanup;
54
55
56 if (fread(&block_size, sizeof(block_size), 1, file) != 1 ||
57 block_size != (uint32_t)(3 * npoints * (PetscInt)sizeof(PetscScalar))) goto cleanup;
58 coords = malloc((size_t)(3 * npoints) * sizeof(*coords));
59 if (!coords ||
60 fread(coords, sizeof(PetscScalar), (size_t)(3 * npoints), file) != (size_t)(3 * npoints)) goto cleanup;
61
62
63 if (fread(&block_size, sizeof(block_size), 1, file) != 1 ||
64 block_size != (uint32_t)(npoints * (PetscInt)sizeof(PetscScalar))) goto cleanup;
65 pressure = malloc((size_t)npoints * sizeof(*pressure));
66 if (!pressure ||
67 fread(pressure, sizeof(PetscScalar), (size_t)npoints, file) != (size_t)npoints) goto cleanup;
68
69
70 if (fread(&block_size, sizeof(block_size), 1, file) != 1 ||
71 block_size != (uint32_t)(3 * npoints * (PetscInt)sizeof(PetscScalar))) goto cleanup;
72 velocity = malloc((size_t)(3 * npoints) * sizeof(*velocity));
73 if (!velocity ||
74 fread(velocity, sizeof(PetscScalar), (size_t)(3 * npoints), file) != (size_t)(3 * npoints)) goto cleanup;
75
76
77 if (fread(&block_size, sizeof(block_size), 1, file) != 1 ||
78 block_size != (uint32_t)(npoints * (PetscInt)sizeof(PetscScalar))) goto cleanup;
79 qcrit = malloc((size_t)npoints * sizeof(*qcrit));
80 if (!qcrit ||
81 fread(qcrit, sizeof(PetscScalar), (size_t)npoints, file) != (size_t)npoints) goto cleanup;
82
83 for (PetscInt k = 0; k < mz; ++k) {
84 for (PetscInt j = 0; j < my; ++j) {
85 for (PetscInt i = 0; i < mx; ++i) {
86 const PetscInt point = (k * my + j) * mx + i;
87 const PetscReal base = (PetscReal)(10000 * k + 100 * j + i);
88
89 if (!
ScalarMatches(coords[3 * point + 0], (PetscReal)i / (PetscReal)mx) ||
90 !
ScalarMatches(coords[3 * point + 1], (PetscReal)j / (PetscReal)my) ||
91 !
ScalarMatches(coords[3 * point + 2], (PetscReal)k / (PetscReal)mz) ||
97 }
98 }
99 }
100
101 footer_size = fread(footer, 1, sizeof(footer) - 1, file);
102 footer[footer_size] = '\0';
103 if (!strstr(footer, "</AppendedData>") || !strstr(footer, "</VTKFile>")) goto cleanup;
104
105 valid = PETSC_TRUE;
106
107cleanup:
108 fclose(file);
109 free(coords);
110 free(pressure);
111 free(velocity);
112 free(qcrit);
113 return valid;
114}
static PetscBool ScalarMatches(PetscScalar actual, PetscReal expected)
Compare one scalar from the raw VTK payload with its deterministic truth.