sandbox/acastillo/output_fields/tests_spectra/test_spectra_hdf5.c
The HDF5 spectrum file
Three blocks appended along the time axis, then read back in C –
which keeps the checker on the standard library and gives it the stored
values rather than a transcription. As in test_spectra_ascii.c the fields are
scaled by z and the mode moves between
blocks, so (nt, nz, nk) is checked by its contents. Only
the vector file’s shapes are read.
#include "utils.h"
#include "acastillo/output_fields/spectra/spectra.h"
#define ML 5
#define NZ 4
#define NT 3
#ifdef HAVE_HDF5
// Peak bin, its energy, and the total, for one (block, plane) spectrum.
static void summarise (FILE * fp, const char * name, const double * E,
const double * z, int nt, int nz, int nk)
{
for (int it = 0; it < nt; it++)
for (int iz = 0; iz < nz; iz++) {
const double * s = E + ((size_t) it*nz + iz)*nk;
double sum = 0., peak = -1.;
int bpeak = -1;
for (int b = 0; b < nk; b++) {
sum += s[b];
if (s[b] > peak)
peak = s[b], bpeak = b;
}
fprintf (fp, "peak %s %d %d %d %.17g %.17g %.17g\n",
name, it, iz, bpeak, peak, sum, z[(size_t) it*nz + iz]);
}
}
static void readback (const char * filename, const char * vecfile)
{
FILE * fp = fopen ("spectra_hdf5.asc", "w");
hid_t file = H5Fopen (filename, H5F_ACC_RDONLY, H5P_DEFAULT);
double L0f;
int mf, nzf, nkf;
H5LTget_attribute_double (file, ".", "L0", &L0f);
H5LTget_attribute_int (file, ".", "m", &mf);
H5LTget_attribute_int (file, ".", "nz", &nzf);
H5LTget_attribute_int (file, ".", "nk", &nkf);
fprintf (fp, "attr %.17g %d %d %d\n", L0f, mf, nzf, nkf);
hsize_t dt[3], dz[3], de[3], dk[3];
H5LTget_dataset_info (file, "/t", dt, NULL, NULL);
H5LTget_dataset_info (file, "/z", dz, NULL, NULL);
H5LTget_dataset_info (file, "/kphys", dk, NULL, NULL);
H5LTget_dataset_info (file, "/E/a", de, NULL, NULL);
fprintf (fp, "shape t %d\n", (int) dt[0]);
fprintf (fp, "shape z %d %d\n", (int) dz[0], (int) dz[1]);
fprintf (fp, "shape kphys %d\n", (int) dk[0]);
fprintf (fp, "shape E %d %d %d\n", (int) de[0], (int) de[1], (int) de[2]);
int nt = dt[0], nz = dz[1], nk = de[2];
double * tv = malloc (nt*sizeof(double));
double * zv = malloc ((size_t) nt*nz*sizeof(double));
double * kv = malloc (nk*sizeof(double));
double * Ev = malloc ((size_t) nt*nz*nk*sizeof(double));
H5LTread_dataset_double (file, "/t", tv);
H5LTread_dataset_double (file, "/z", zv);
H5LTread_dataset_double (file, "/kphys", kv);
for (int it = 0; it < nt; it++)
fprintf (fp, "t %d %.17g\n", it, tv[it]);
// the bin axis is fixed, so one residual against 2 pi k / L0 says enough
double dkmax = 0.;
for (int b = 0; b < nk; b++)
dkmax = max (dkmax, fabs (kv[b] - 2.*pi*b/L0));
fprintf (fp, "kphys %.17g\n", dkmax);
H5LTread_dataset_double (file, "/E/a", Ev);
summarise (fp, "a", Ev, zv, nt, nz, nk);
H5LTread_dataset_double (file, "/E/b", Ev);
summarise (fp, "b", Ev, zv, nt, nz, nk);
free (tv), free (zv), free (kv), free (Ev);
H5Fclose (file);
// the vector file goes through the same writer; check that it is there
hid_t vfile = H5Fopen (vecfile, H5F_ACC_RDONLY, H5P_DEFAULT);
const char * comp[3] = {"/E/v.x", "/E/v.y", "/E/v.z"};
for (int k = 0; k < 3; k++) {
hsize_t d[3] = {0, 0, 0};
H5LTget_dataset_info (vfile, comp[k], d, NULL, NULL);
fprintf (fp, "shape %s %d %d %d\n", comp[k] + 3,
(int) d[0], (int) d[1], (int) d[2]);
}
H5Fclose (vfile);
fclose (fp);
}
#endif // HAVE_HDF5
int main()
{
L0 = 2.*pi;
X0 = Y0 = Z0 = -L0/2.;
int m = 1 << ML;
init_grid (m);
scalar a[], b[];
vector v[];
// three times, with a widening zone so the heights move between blocks
for (int step = 0; step < NT; step++) {
t = 0.1*step;
double Lz = 0.5 + 0.25*step;
foreach() {
a[] = (1. + z)*cos ((5. + step)*x); // bin 5 + step
b[] = 3. + step + z; // bin 0
v.x[] = a[], v.y[] = b[], v.z[] = cos (3.*y);
}
spectrum_scalar_stack ({a, b}, "spec.h5", -Lz, Lz, NZ, m,
X0, X0 + L0, Y0, Y0 + L0, "a", SPECTRA_HDF5);
spectrum_vector_stack (v, "spec_u.h5", -Lz, Lz, NZ, m,
X0, X0 + L0, Y0, Y0 + L0, "a", SPECTRA_HDF5);
}
#ifdef HAVE_HDF5
if (pid() == 0) {
readback ("spec.h5", "spec_u.h5");
system ("python3 ../test_spectra.py hdf5 spectra_hdf5.asc 1>&2");
}
#else
if (pid() == 0)
fprintf (stderr, "HDF5 not available\n");
#endif
}