Turbulent Channel Flow with NekRS + Ginkgo#
Simulates turbulent channel flow at $Re_\tau = 590$ using NekRS for the spectral element discretization and time stepping, with Ginkgo replacing NekRS’s built-in PCG for the pressure Poisson solve at every time step.
Compatible with NekRS v26+.
Integration Overview#
This example extends the NekRS Poisson example to a
full time-dependent simulation. The Ginkgo solver is called at every time
step within NekRS’s operator-splitting scheme. The same NekRSOperator
wrapper from nekrs/nekrs_ginkgo.hpp is reused.
Key Integration Points#
Setup#
void UDF_Setup()
{
auto* pSolver = nrs->fluid->ellipticSolverP;
if (pSolver) {
std::cout << "[Ginkgo] Turbulent channel flow setup" << std::endl;
std::cout << "[Ginkgo] Pressure DOFs: " << pSolver->fieldOffset()
<< std::endl;
}
}
Per-Timestep Solve#
Ginkgo’s CG replaces NekRS’s built-in PCG at every time step:
void UDF_ExecuteStep(double time, int tstep)
{
auto* pSolver = nrs->fluid->ellipticSolverP;
if (!pSolver || tstep == 0) return;
auto o_rhs = nrs->fluid->o_explicitTerms("pressure");
auto o_sol = nrs->fluid->o_solution("pressure");
nekrs_ginkgo_solve(pSolver, static_cast<occa::memory&>(o_rhs),
static_cast<occa::memory&>(o_sol));
ginkgo_solve_count++;
if (tstep % 500 == 0) {
std::cout << "[Ginkgo] Step " << tstep << ", time = " << time
<< ", total Ginkgo solves: " << ginkgo_solve_count
<< std::endl;
}
}
Building#
NekRS UDFs compile as shared libraries (plugins):
cmake -S . -B build --preset default \
-DNEKRS_DIR=/path/to/nekrs \
-DGinkgo_DIR=/path/to/ginkgo
cmake --build build
Running#
Note: Running has not been tested end-to-end. The code compiles against the NekRS v26 API, validating the integration pattern, but actually executing it requires a full NekRS case setup.
To run, copy the built shared library into a NekRS turbulent channel
case directory (e.g., the channel example bundled with NekRS):
cp -r /path/to/nekrs/examples/channel /tmp/test-channel
cp build/libturbulent_channel.so /tmp/test-channel/
cd /tmp/test-channel && mpirun -np 4 nekrs --setup channel
As with the Poisson example, a production integration would need to disable NekRS’s built-in pressure solve and route it through Ginkgo.
Expected Output (approximate)#
[Ginkgo] Turbulent channel flow setup
[Ginkgo] Pressure DOFs: 262144
[Ginkgo] Step 500, time = 1.0, total Ginkgo solves: 500
[Ginkgo] Step 1000, time = 2.0, total Ginkgo solves: 1000