“I disagree strongly with whatever work this quote is attached to.” – Randall Munroe
One can argue that loading data is the most important part of a
postprocessing tool. In Postgkyl, it is handled by the
postgkyl.data.Data class (there is a
shortcut). It load data on initialization and serves as an input for
all the other parts of Postgkyl.
Examples are provided simultaneously for scripting and command line using output files of an electrostatic two-stream instability simulation [two-stream.lua].
Gkeyll files are loaded in Postgkyl by creating a new instance of the
Data class with the file name as the parameter.
import postgkyl as pg data = pg.Data('filename')
getValues() can be used to return the grid
and values as NumPy arrays. For structured meshes, the
return a Python
list of 1D NumPy arrays which represent the nodal
points of the grid in each dimension. Note that since these are nodal
points, these arrays will always have one more cell in each dimension
in comparison to the value array. Another important note is that the
value array always have one extra dimension for
components. Components can represent many things from vector
elements to discontinuous Galerkin expansion coefficients. As a rule,
this extra dimension is always retained even if there is just one
import postgkyl as pg data = pg.Data('two-stream_elc_0.bp') print(data.getGrid()) [array([-6.283185307179586 , -6.086835766330224 , -5.890486225480862 , -5.6941366846315 , -5.497787143782138 , -5.301437602932776 , -5.105088062083414 , -4.908738521234052 , -4.71238898038469 , -4.516039439535327 , -4.319689898685965 , -4.123340357836604 , -3.9269908169872414, -3.730641276137879 , -3.5342917352885173, -3.3379421944391554, -3.141592653589793 , -2.945243112740431 , -2.748893571891069 , -2.552544031041707 , -2.356194490192345 , -2.1598449493429825, -1.9634954084936211, -1.7671458676442588, -1.5707963267948966, -1.3744467859455343, -1.178097245096172 , -0.9817477042468106, -0.7853981633974483, -0.589048622548086 , -0.3926990816987246, -0.1963495408493623, 0. , 0.1963495408493623, 0.3926990816987246, 0.589048622548086 , 0.7853981633974483, 0.9817477042468106, 1.178097245096172 , 1.3744467859455343, 1.5707963267948966, 1.767145867644258 , 1.9634954084936211, 2.1598449493429825, 2.356194490192344 , 2.552544031041707 , 2.7488935718910685, 2.9452431127404317, 3.141592653589793 , 3.3379421944391545, 3.5342917352885177, 3.730641276137879 , 3.9269908169872423, 4.123340357836604 , 4.319689898685965 , 4.516039439535328 , 4.71238898038469 , 4.908738521234051 , 5.105088062083414 , 5.301437602932776 , 5.497787143782137 , 5.6941366846315 , 5.890486225480862 , 6.086835766330225 , 6.283185307179586 ]), array([-6. , -5.8125, -5.625 , -5.4375, -5.25 , -5.0625, -4.875 , -4.6875, -4.5 , -4.3125, -4.125 , -3.9375, -3.75 , -3.5625, -3.375 , -3.1875, -3. , -2.8125, -2.625 , -2.4375, -2.25 , -2.0625, -1.875 , -1.6875, -1.5 , -1.3125, -1.125 , -0.9375, -0.75 , -0.5625, -0.375 , -0.1875, 0. , 0.1875, 0.375 , 0.5625, 0.75 , 0.9375, 1.125 , 1.3125, 1.5 , 1.6875, 1.875 , 2.0625, 2.25 , 2.4375, 2.625 , 2.8125, 3. , 3.1875, 3.375 , 3.5625, 3.75 , 3.9375, 4.125 , 4.3125, 4.5 , 4.6875, 4.875 , 5.0625, 5.25 , 5.4375, 5.625 , 5.8125, 6. ])] print(data.getValues()) [[[ 1.6182154425614533e-127 2.2497634664678846e-136 2.1705614015952743e-127 ... 1.4466223559100639e-127 7.7862978418103503e-137 2.0112020871650523e-136] [ 7.2163320153412515e-118 1.0032681083505769e-126 9.6785762877207286e-118 ... 6.4497610162539372e-118 3.4719259660326997e-127 8.9669370964188083e-127] [ 1.3363156717841295e-108 1.8578453383418215e-117 1.7920360303344134e-108 ... 1.1940080895062958e-108 6.4284392330301674e-118 1.6599988152412963e-117] ... print(data.getGrid().shape) (65,) print(data.getGrid().shape) (65,) print(data.getValues().shape) (64, 64, 8)
It is also possible to create an empty instance and fill it using the
In the command line mode, a data file is loaded by simply adding it to
pgkyl script chain at any position.
Under the hood, Postgkyl calls a hidden
load command to load
the file. When provided string does not match any command but is
matching a file, the load command is invoked and the file name is
passed to it. The load command should not be called manually but
it can be used to access the help.
pgkyl load --help
Currently, Postgkyl supports
h5 file that were used in Gkeyll 1,
Gkeyll 2 ADIOS
bp files, and Gkeyll 0
gkyl binary files. Many
of the advanced functions like loading only partial data and some
quality of life features like storing the polynomial order of DG
representation are currently available only for the ADIOS
Loading multiple files in a script is straightforward; one creates more
instances of the
Data class. Postgkyl does naturally support loading
any number of files.
pgkyl two-stream_elc_0.bp two-stream_elc_1.bp
When batch application of commands is not the desired behavior, some data files can be loaded later in the chain, loaded dataset can be changed from active to inactive (activate/deactivate/pg_cmd_deactivate), or the command scope can be limmited by specifying tags. The Key concepts section provides examples where one desired behavior is achieved in multiple ways. It is left up to the user to chose the preferred one.
Postgkyl also allows for loading with a wild card characters:
While the quotes are entirely optional when loading a single file, they change behavior when used with wild card characters. With quotes, a single load command is performed and the wild card matching is done internally by Postgkyl. Without quotes, the wild card is replaced before calling Postgkyl which results in several load command calls. This leads to several key differences:
- With quotes, Postgkyl orders files correctly, i.e.,
file_2will be before
- With quotes, tags, labels, etc., are applied to all the matching files, not just the last one.
- Some wildcard characters like
[0-9]are not supported by every shell.
Using wild card characters might lead to unexpected situations. For
example in the two-stream case, the query
going to return
two-stream_elc_0.bp but also the moment files like
two-stream_elc_M0_0.bp. If we want to load just the distribution
functions, we can limit the query. For example:
This requires the first character to be a number between 0 and 9, which effectively eliminates all the outputs except for the distribution functions themselves.
Following are details on load parameters which alter the
behavior. Here, we would like to mention that these can be specified
individually for each file of as the global options of the
script itself. For example, the partial loading flag
bellow) can be applied to one file (
pgkyl file_0 --z0 0 file_1
Or it can be applied globally to all the files:
pgkyl --z0 0 file_0 file_1
This is analogous to:
pgkyl file_0 --z0 0 file_1 --z0 0
Gkeyll output files, especially the higher dimensional ones, can be
large. Therefore, Postgkyl allows to load just a smaller subsection of
each file. This is done with the optional
for coordinates and
comp for components. Each can be either an
integer number or a string in the form of
start:end. Note that
this does follow the Python convention so the last index is
1:5 will load only the indices/components 1, 2,
3, and 4. This functionality is supported both in the script mode and
the command line mode.
import postgkyl as pg data = pg.Data('two-stream_elc_0.bp', z1='1:3', comp=0)
pgkyl two-stream_elc_0.bp --z1 1:3 -c 0
Note that the select command has a similar use. In addition, it allows to specify a coordinate value instead of an index. However, it requires the whole file to be loaded into memory.
This feature was introduced in 1.6.7 and currently only works with
gkyl binary files.
Postgkyl supports the c2p mapping used in Gkeyll. The file with the
map can be specified using the
--c2p keyword. Following are two
plots where a Maxwellian particle distribution is evaluated in
cylindrical coordinates with and without c2p map provided to Postgkyl.
pgkyl rt_eval_on_nodes_f-ser.gkyl interpolate -bms -p2 plot -a
pgkyl rt_eval_on_nodes_f-ser.gkyl --c2p rt_eval_on_nodes_rtheta-ten.gkyl interpolate -bms -p2 plot -a
Gkeyll stores the c2p coordinate information as expansion coefficients
of a finite element representation independent of the representation of
the data itself. It is converted to plotting nodal points during the
interpolate command when the information about the data
is provided. However, the interpolate command is never
used when working with finite-volume data. For this instance, the
--fv flag is available which converts the expansion coefficients
to nodal values immediately after loading.
pgkyl euler_axis_sodshock-euler_0.gkyl --c2p euler_axis_sodshock-mapc2p.gkyl --fv select -c0 plot -a