|
Peano
|
Peano has introduced its own block-structured output format.
Its idea is that a mesh is dumped as an unstructured set of cell where each cell is uniquely identified through its offset and its size. The mesh data format lacks any topological information (connectivity). A cell always is a patch, i.e. holds a (topological) Cartesian mesh of dimensions \( k \times k \) or \( k \times k \times k \), respectively. If you work without patches, \( k=2 \). In this case, the block format obviously can yield a significant overhead.
This spec file specifies a simple grid that
identifier A and each entry (per vertex) comprises 58 double unknowns. The second set of unknowns per vertex is called time and is a scalar quantity.The header of every file carries a line format ASCII or format Binary. The two formats only differ in how the quantities of a patch are stored. Everything else, i.e. the header, the metadata, the mappings, offset and size of the patches and the begin/end markers, is text in both formats.
begin cell-values and end cell-values (or the vertex counterparts) holds the numbers as text.The number of bytes follows from number-of-unknowns, number-of-dofs-per-axis and dimensions of the metadata block. A reader therefore never has to search for the end of the raw data, which may contain any byte value.
Binary files are smaller, faster to write and hold the doubles bit-exact. ASCII files can be read by humans and by any tool. ExaHyPE's plotters and checkpoints write binary files by default (argument binary). Meta files, i.e. the files which only link to snapshot files, are always plain text. The C++ readers tarch::reader::PeanoTextPatchFileReader and tarch::reader::PeanoBinaryPatchFileReader read the two formats, and tarch::reader::PeanoTextPatchFileReader::readHeader() tells which one to use. The Python scripts in tarch.plotter.api, e.g. render.py, probe.py and merge.py, handle both.
cell-values.vertex-values or cell-values section in the header of the file, i.e. not embedded into a patch, may have a sectionIf no mapping is present, our code dumps a regular subgrid (patch) per patch region. If a mapping is present, the mapping has exactly \( (6+1)
\cdot (6+1) \cdot (6+1) \) entries in the example from the previous section. Each entry is a 3d coordinate relative to the unit cube and specifies how the topologially regular grid prescribed within a patch is to be mapped. You might for example plot points of the topologically regular grid with Gauss-Legendre spacing.
Per snapshot (typically time step), the plotter adds on dataset entry. Each data set holds one data file per active rank. Each rank writes its actual data into a separate file.