programming
Table of Contents
C
Language server
For C programming in emacs, clangd is available on debian and can be installed via:
apt install clangd
Or with a specific version number as:
apt install clangd-19
If a library header is not found by clangd, one can define it in the
.clangd file placed in the root directory of the project. For
example, to include glib.h on debian:
CompileFlags: Add: - "-I/usr/include/glib-2.0" - "-I/usr/lib/x86_64-linux-gnu/glib-2.0/include"
Tricks
From Klemens (2014):
go_libs="-lm" go_flags="-g -Wall -include monster.h -O3" alias go_c="cc -xc - $go_libs $go_flags"
with monster.h being, for example:
#include <math.h> #include <stdio.h> #include <stdlib.h>
Example usage:
go_c << "XXXX" int main(){ printf("Hello, world.\n"); } XXXX
HDF5
h5ls prints information about a file or dataset.
h5ls <fname.h5> h5dump
h5dump displays HDF5 file contents.
It’s helpful to inspect the headers of a HDF5 file first. This can
be done using the --header flag:
h5dump --header <fname.h5>
Suppose this gives you something like follows:
HDF5 "<fname.h5>" { GROUP "/" { ATTRIBUTE "time" { DATATYPE H5T_IEEE_F64LE DATASPACE SCALAR } DATASET "darcy_velocity.cell.0" { DATATYPE H5T_IEEE_F64LE DATASPACE SIMPLE { ( 894740, 1 ) / ( 894740, 1 ) } } DATASET "darcy_velocity.cell.1" { DATATYPE H5T_IEEE_F64LE DATASPACE SIMPLE { ( 894740, 1 ) / ( 894740, 1 ) } } DATASET "darcy_velocity.cell.2" { DATATYPE H5T_IEEE_F64LE DATASPACE SIMPLE { ( 894740, 1 ) / ( 894740, 1 ) } } }
To display an attribute (such as time), we use the flag -a:
h5dump -a /time <fname.h5>
This gives:
HDF5 "<fname.h5>" { ATTRIBUTE "time" { DATATYPE H5T_IEEE_F64LE DATASPACE SCALAR DATA { (0): 4.7952e+07 } } }
Datasets can be displayed with the -d flag:
h5dump -d /darcy_velocity.cell.0 <fname.h5>
This will return something like:
DATASET "/darcy_velocity.cell.0" {
DATATYPE H5T_IEEE_F64LE
DATASPACE SIMPLE { ( 894740, 1 ) / ( 894740, 1 ) }
DATA {
(0,0): 7.05594e-08,
(1,0): 4.07452e-09,
(2,0): 1.41819e-09,
(3,0): 1.10755e-09,
(4,0): 1.01312e-09,
(5,0): 9.20153e-10,
...
We can use the --start and --count flags to look at a slice of
the data. For example, to print the first 3 entries of a dataset:
h5dump -d /darcy_velocity.cell.0 --start="1,0" --count="3,1" <fname.h5>
Gives:
HDF5 "<fname.h5>" { DATASET "/darcy_velocity.cell.0" { DATATYPE H5T_IEEE_F64LE DATASPACE SIMPLE { ( 894740, 1 ) / ( 894740, 1 ) } SUBSET { START ( 1, 0 ); STRIDE ( 1, 1 ); COUNT ( 3, 1 ); BLOCK ( 1, 1 ); DATA { (1,0): 4.07452e-09, (2,0): 1.41819e-09, (3,0): 1.10755e-09 } } } }
See also the man page of h5dump.
Creating HDF5 files with C++
A problem when working with multidimensional arrays is that ISO C++ does not allow runtime initialization of the length. The obvious solution is to dynamically allocate memory for these arrays. However, HDF5 requires continuous chunks of memory that can be directly dumped into the file. Using pointers to pointers does not guarantee this.
Hence, we are stuck with one-dimensional arrays. When flattening a three-dimensional array, we need to do indexing work. This can be done as follows:
Suppose the dimensions of the array A are given by nx, ny,
nz. Then, the entry at i, j, k can be accessed by:
A(i, j, k) = A[i + nx * (j + ny * k)]
Note that this is just computing offsets. Given an entry at i,
j, we skip to the entry at i, j+1 by skipping nx * j
entries. Now, to skip in a three-dimensional matrix from i, j,
k to i, j + 1, k + 1, the offset is nx * j + nx * ny *
k. This can be manipulated to give the expression above.
Calling gnuplot from C
Define GNUPLOT as
#define GNUPLOT "gnuplot -persist"
Plot with gnuplot as
FILE *fp; fp = popen(GNUPLOT, "w"); fprintf(fp, "plot ';-' w p lt -1 pt 6 title 'e and z'\n"); for (int i = 0; i < N * (ngp + 2); i ++) { fprintf(fp, "%f %f\n", x[i], e[i]); fprintf(fp, "\033"); fflush(fp); fclose(fp); }
gnuplot specifics
Specify the delimiter character:
set datafile separator "<char>"
Specify comment character:
set datafile commentschar "<char>"
The terminal determines how the plot is displayed. I like the
terminals dumb, qt, and png. Specify the terminal:
set term dumb # plots to shell set term qt # graphical output set term png # plot to image file
The font can be specified through the term. For example
set term qt font "Times, 12"
or
set term pngcairo font "monospace"
Allows to plot several graphs in one figure, in a vertically or horizontally stacked way:
set multiplot layout 2,1 rowsfirst set title 'surface flow' plot '1.0e-06/surface_outlet_flux.dat'; u 1:2 w l title 'i = 1.0e-06 m/s' set title 'subsurface flow' plot '1.0e-06/subsurface_outlet_flux.dat' u 1:2 w l title 'i = 1.0e-06 m/s' unset multiplot
Use this for plotting three-dimensional data:
splot "<file>" u 1:2:3 w l
SERGHEI
Compiling SERGHEI on Debian Trixie
I have pnetcdf installed via package manager. Verify through apt
search pnetcdf. It should return something like:
libnetcdf-pnetcdf-22/stable,now 1:4.9.3-2 amd64 [Installiert,automatisch] Schnittstelle für den Zugriff auf wissenschaftliche Daten libnetcdf-pnetcdf-dev/stable,now 1:4.9.3-2 amd64 [installiert] creation, access, and sharing of array-oriented scientific data libpnetcdf-dev/stable,now 1.14.0-2 amd64 [installiert] Development files for the parallel netCDF library libpnetcdf6/stable,now 1.14.0-2 amd64 [Installiert,automatisch] Libraryfor reading and writing parallel NetCDF files pnetcdf-bin/stable 1.14.0-2 amd64 Programs for reading and writing parallel NetCDF files
Follow the README and compile Kokkos:
bash buildKokkos [GPU_ARCHITECTURE]
A good way to discover cmake configuration flags is as follows:
mkdir build
cd build
cmake ..
cmake -LAH
In the build folder, the integrated surface–subsurface solver in
SERGHEI can be compiled using:
cmake -S ../ -DPnetCDF_C_LIBRARY=/usr/lib/x86_64-linux-gnu/libpnetcdf.so -DPnetCDF_C_INCLUDE_DIR=/usr/include -DSERGHEI_SWE_RE=ON -DSERGHEI_ENABLE_TESTS=ON
Note that if you want to run the test cases, you must enable centred
friction discretisation. This requires the flag
-DSERGHEI_FRICTION_CENTERED=ON. If no errors are thrown, complete
the install:
cmake --build . -j$(nproc)
$(nproc) uses all available CPUs for parallel compilation.