Technically, Hexed is really two things. It is a C++ library, and it is an executable program. If you want to extend the functionality of Hexed or use it as a backend and develop your own UI, you should link with the C++ library libhexed.so
and you will have access to everything in the namespace hexed However, for most use cases, the executable should be sufficient. To distinguish it from the library and namespace, the command to execute hexed is hexecute
(sorry for my terrible sense of humor). It supports a text-based interface in the Hexed Interface Language.
To run a typical simulation, you should create a script and run it with something like hexecute your-script.hil
. A script should generally including the items below, in order. Note that some of the commands you include are Macros, which have to be invoked with $
, whereas others are Heisenberg variables for which you do not use $
.
- define basic input parameters
$start
$mesh
init_state
$run
Or if you're feeling lazy:
- define basic input parameters
$simulate
If you just want to generate a mesh for a different solver, then you can do:
- define input parameters
- If you're not running iterations, you don't have to define done, but you do still have to define freestream conditions, even though their value is irrelevant.
$start
$mesh
write_mesh
or export_polymesh
- If you want to be able to directly visualize the mesh for debugging, you can add:
init_state
visualize
A good example of a meshing-only case is the multi-element airfoil case. We currently do not have the physics necessary to obtain realistic results for this case, so we only generate the mesh.
A good example of a basic simulation is the oblique shock case located in samples/oblique_shock. In this directory, you should see two files—run.hil
is the input script (name and extension are arbitrary), and geom.csv
is a CSV file containing coordinates for a wedge geometry (see add_geom for more information). To run this case, just type hexecute run.hil
. You should see text output that looks something like:
Commencing simulation with Hexed version 0.3.0 (commit 978f29b66b5253dabde3dbaf300687ad518dfc2a) at 2024-08-01 05:38:17 UTC (1722490697 Unix Time).
meshing...
geometry-based refinement sweep 0... done
meshing complete with 953 elements
writing mesh... done
visualizing... done
iteration, normalized_residual, flow_time, time_step, art_visc_residual
1, 1.00000000e+00, 1.20000000e+01, 1.00000000e+00, 1.10943843e-05
100, 2.98452735e-01, 1.20000000e+03, 1.00000000e+00, 6.17622986e-03
200, 2.66107709e-01, 2.40000000e+03, 1.00000000e+00, 3.64504543e-03
300, 1.65974680e-01, 3.60000000e+03, 1.00000000e+00, 4.37872854e-03
400, 1.01426129e-01, 4.80000000e+03, 1.00000000e+00, 2.77442455e-03
500, 6.65615325e-02, 6.00000000e+03, 1.00000000e+00, 2.19205513e-03
600, 4.67136703e-02, 7.20000000e+03, 1.00000000e+00, 1.67800684e-03
700, 3.31224820e-02, 8.40000000e+03, 1.00000000e+00, 1.02986015e-03
800, 2.43242348e-02, 9.60000000e+03, 1.00000000e+00, 5.49477349e-04
900, 1.75576328e-02, 1.08000000e+04, 1.00000000e+00, 4.15321491e-04
1000, 1.19670482e-02, 1.20000000e+04, 1.00000000e+00, 2.35965203e-04
writing mesh... done
writing state... done
writing status... done
visualizing... done
1100, 7.78303221e-03, 1.32000000e+04, 1.00000000e+00, 1.73218054e-04
1200, 4.91702287e-03, 1.44000000e+04, 1.00000000e+00, 1.32606350e-04
... etc. The iteration
column tells you what iteration you're on (note that it doesn't print output on every iteration) and the normalized_residual
column tells you the \( L^2 \) norm residual of the Navier-Stokes equations, normalized by the value after the first iteration. The art_visc_residual
gives you a measure of the residual of the auxiliary PDEs used to determine the artificial viscosity coefficient. It will not appear if you run a simulation without artificial viscosity. If both of these residuals vanish, the simulation has reached iterative convergence. The flow_time
and time_step
variables are meaningless in this case because local time stepping is used, but for a simulation with global time stepping their meaning should be self-explanatory. As soon as you start the solver, a directory called hexed_out
will be created. In this directory will be a copy of the input file as well as a file output.txt
with a copy of the command line output. Also, each time you see visualizing...done
in the command line output, the solver will have written a new set of .h5
and .xmf
files to this directory. You can view these files in ParaView by opening the .xmf
(not .h5
) files and selecting "XDMF Reader T" as the reader. Each time you see writing mesh/state data...done
, the solver will have written a new set of mesh and state files that you can use to restart the simulation from where you left off with read_mesh and read_state. Unlike many solvers, Hexed saves new mesh and state data files every time instead of overwriting old ones. In my experience, worrying about overwriting important restart files can be a bit of a headache, and avoiding that problem is worth a little extra disk space. Finally, the hexed_out
directory will also contain an empty runtime_cmd.hil
. Every time the solver prints output, it will execute the contents of this file as HIL code and then overwrite it again with an empty file. Thus by writing HIL code to this file you can control the solver while it is running. I frequently use this to change the termination condition or the CFL constraint.
When the simulation is completed, you should see something like:
2100, 8.18880490e-05, 2.52000000e+04, 1.00000000e+00, 3.52859250e-06
simulation complete
wall clock time = 52.5361s = 0.875602min = 0.0145934hr
performance summary:
24015600 (element*update)s completed in 27.1849 s at 1.13197e-06 s / (element*update).
boundary conditions: 6554860 (boundary connection)*(time integration stage)s completed in 1.06117 s at 1.61891e-07 s / (boundary connection)*(time integration stage).
cartesian: 22327200 (element*update)s completed in 9.7943 s at 4.38671e-07 s / (element*update).
compute time step: 22327200 (element*update)s completed in 1.55241 s at 6.953e-08 s / (element*update).
local: 44673892 (element*(time integration stage))s completed in 5.17024 s at 1.15733e-07 s / (element*(time integration stage)).
neighbor: 131847492 (connection*(time integration stage))s completed in 1.79748 s at 1.3633e-08 s / (connection*(time integration stage)).
reconcile LDG flux: 22346692 (element*(time integration stage))s completed in 0.911592 s at 4.07931e-08 s / (element*(time integration stage)).
deformed: 1688400 (element*update)s completed in 2.27068 s at 1.34487e-06 s / (element*update).
compute time step: 1688400 (element*update)s completed in 0.249881 s at 1.47999e-07 s / (element*update).
local: 3378274 (element*(time integration stage))s completed in 0.852327 s at 2.52297e-07 s / (element*(time integration stage)).
neighbor: 17246832 (connection*(time integration stage))s completed in 0.60758 s at 3.52285e-08 s / (connection*(time integration stage)).
reconcile LDG flux: 1689874 (element*(time integration stage))s completed in 0.208913 s at 1.23626e-07 s / (element*(time integration stage)).
fix admis.: 0 (element*(fix admis. iter))s completed in 2.69817 s.
cartesian: 0 (element*update)s completed in 0 s.
compute time step: 0 (element*update)s completed in 0 s.
local: 0 (element*(time integration stage))s completed in 0 s.
neighbor: 0 (connection*(time integration stage))s completed in 0 s.
reconcile LDG flux: 0 (element*(time integration stage))s completed in 0 s.
check admis.: 48031200 (element*update)s completed in 2.54543 s at 5.29954e-08 s / (element*update).
deformed: 0 (element*update)s completed in 0 s.
compute time step: 0 (element*update)s completed in 0 s.
local: 0 (element*(time integration stage))s completed in 0 s.
neighbor: 0 (connection*(time integration stage))s completed in 0 s.
reconcile LDG flux: 0 (element*(time integration stage))s completed in 0 s.
prolong/restrict: 0 (element*(time integration stage))s completed in 1.65056 s.
set art visc: 2001300 (element*update)s completed in 8.91743 s at 4.45582e-06 s / (element*update).
advection: 2001300 (element*update)s completed in 2.78156 s at 1.38987e-06 s / (element*update).
BCs: 12007800 (element*(time integration stage))s completed in 0.0882994 s at 7.35351e-09 s / (element*(time integration stage)).
cartesian: 5581800 (element*update)s completed in 1.58364 s at 2.83714e-07 s / (element*update).
compute time step: 1860600 (element*update)s completed in 0.050125 s at 2.69402e-08 s / (element*update).
local: 11163600 (element*(time integration stage))s completed in 1.08116 s at 9.68471e-08 s / (element*(time integration stage)).
neighbor: 21961800 (connection*(time integration stage))s completed in 0.395914 s at 1.80274e-08 s / (connection*(time integration stage)).
deformed: 422100 (element*update)s completed in 0.376061 s at 8.90929e-07 s / (element*update).
compute time step: 140700 (element*update)s completed in 0.0159837 s at 1.13602e-07 s / (element*update).
local: 844200 (element*(time integration stage))s completed in 0.187484 s at 2.22085e-07 s / (element*(time integration stage)).
neighbor: 2872800 (connection*(time integration stage))s completed in 0.117219 s at 4.08031e-08 s / (connection*(time integration stage)).
setup: 2001300 (element*update)s completed in 0.369787 s at 1.84773e-07 s / (element*update).
update: 2001300 (element*(time integration stage))s completed in 0 s at 0 s / (element*(time integration stage)).
diffusion: 2001300 (element*update)s completed in 5.89477 s at 2.94547e-06 s / (element*update).
cartesian: 0 (element*update)s completed in 3.23632 s.
compute time step: 1860600 (element*update)s completed in 0.0420257 s at 2.25872e-08 s / (element*update).
local: 22327200 (element*(time integration stage))s completed in 1.66982 s at 7.47886e-08 s / (element*(time integration stage)).
neighbor: 87847200 (connection*(time integration stage))s completed in 0.623239 s at 7.09458e-09 s / (connection*(time integration stage)).
reconcile LDG flux: 22327200 (element*(time integration stage))s completed in 0.694877 s at 3.11225e-08 s / (element*(time integration stage)).
deformed: 0 (element*update)s completed in 1.15607 s.
compute time step: 140700 (element*update)s completed in 0.014102 s at 1.00227e-07 s / (element*update).
local: 1688400 (element*(time integration stage))s completed in 0.360147 s at 2.13307e-07 s / (element*(time integration stage)).
neighbor: 11491200 (connection*(time integration stage))s completed in 0.358313 s at 3.11815e-08 s / (connection*(time integration stage)).
reconcile LDG flux: 1688400 (element*(time integration stage))s completed in 0.219167 s at 1.29807e-07 s / (element*(time integration stage)).
initialize: 2001300 (element*update)s completed in 0.0335501 s at 1.67641e-08 s / (element*update).
writing mesh... done
writing state... done
writing status... done
visualizing... done
simulation complete
tells you that the user-specified termination condition was met (in this case, a bound on normalized_residual
; see done). Below, you will see the elapsed time for which the simulation was running as well as some data on the kernel performance. Thus, you have completed a successful simulation. See the other sample cases for examples of more complex usage.