dragonfly_sim.core.turbulence_models

Turbulence closures for CompressibleRANSModel.

A model contributes n_vars conservative transported scalars rho*phi_k. They are appended after the mean flow in the state vector and solved fully coupled with it. The RANS model asks the closure for the following, all UFL expressions of the state U (mean flow in U[:n_mean], scalars after it):

eddy_viscosity(U, mu, n_mean) mu_t diffusive_fluxes(U, mu, n_mean) -> f(grad_phi, grad_rho), one

viscous-flux row per scalar

sources(U, grad_U, mu, d, n_mean, gamma) one source per scalar (right-hand side) freestream_values(fs) conservative rho*phi_inf per scalar wall_values(U, n_mean) conservative values on a no-slip wall limiter_scales(fs) a magnitude per scalar, for the MUSCL

limiter’s smoothing parameter

fs is a dict with the free stream: rho, p, c, M, speed (M c) and mu (a dolfinx Constant: mu_inf follows set_mach). Convection needs nothing from the closure: every scalar is carried with the mean flow, rho*phi*u (NS_utils.extended_flux), and upwinded with the mean flow’s wave speeds. A closure whose sources need the distance to the wall sets needs_wall_distance.

Laminar is the zero-equation case (pure Navier-Stokes). Adding a closure, k-omega SST say, is a new subclass with n_vars = 2 and names (“rho_k”, “rho_omega”). Nothing in CompressibleRANSModel changes: the state size, boundary values, limiter scales, the Jacobian and the adjoint all follow from this interface.

Classes

Laminar

No turbulence model: the laminar compressible Navier-Stokes equations.

SpalartAllmarasNeg

The negative Spalart-Allmaras model, SA-neg (Allmaras, Johnson & Spalart,

TurbulenceModel

Base class and interface (see the module docstring).

Module Contents

class dragonfly_sim.core.turbulence_models.Laminar

Bases: TurbulenceModel

No turbulence model: the laminar compressible Navier-Stokes equations.

class dragonfly_sim.core.turbulence_models.SpalartAllmarasNeg(chi_inf=3.0, ft2=False)

Bases: TurbulenceModel

The negative Spalart-Allmaras model, SA-neg (Allmaras, Johnson & Spalart, ICCFD7-1902, 2012), in the conservative compressible form

div(rho nu~ u) = rho (P - D)
  • (1/sigma) div[(mu + rho nu~ f_n) grad nu~]

  • (c_b2/sigma) rho |grad nu~|^2

  • (1/sigma) (nu + nu~ f_n) grad rho . grad nu~

For nu~ >= 0 this is standard SA (without the f_t2 term unless ft2=True), with the S~ modification that keeps S~ positive. For nu~ < 0 it switches to the negative-branch production, destruction and diffusion, which make a negative nu~ decay instead of growing. Under-resolved boundary-layer edges routinely undershoot below zero, which is why SA-neg is the usual choice. mu_t is zero there.

The two branches meet continuously at nu~ = 0 (production and destruction both vanish), so the conditionals add kinks, not jumps.

Free stream: nu~_inf = chi_inf nu_inf, chi_inf = 3 (NASA TMR). Wall: nu~ = 0.

_nu_tilde(U, n_mean)
diffusive_fluxes(U, mu, n_mean)
eddy_viscosity(U, mu, n_mean)
fn(chi)
freestream_values(fs)
ft2_fn(chi)
fv1(chi)
fv2(chi)
fw(r)
production_destruction(nu_t, nu, Omega, d)

(P, D) per unit density, with both SA-neg branches. S~ is floored before it divides r, which only matters on the unselected branch.

s_tilde(Omega, nu_t, chi, d)
sources(U, grad_U, mu, d, n_mean, gamma)
wall_values(U, n_mean)
cb1 = 0.1355
cb2 = 0.622
chi_inf
cn1 = 16.0
ct3 = 1.2
ct4 = 0.5
cv1 = 7.1
cv2 = 0.7
cv3 = 0.9
cw1 = 3.2390678167757287
cw2 = 0.3
cw3 = 2.0
ft2 = False
kappa = 0.41
n_vars = 1
names = ('rho_nu_tilde',)
needs_wall_distance = True
r_lim = 10.0
sigma = 0.6666666666666666
class dragonfly_sim.core.turbulence_models.TurbulenceModel

Base class and interface (see the module docstring).

diffusive_fluxes(U, mu, n_mean)
eddy_viscosity(U, mu, n_mean)
freestream_values(fs)
limiter_scales(fs)

Default: 1000x the free-stream value, i.e. the scalar’s size in a boundary layer whose eddy viscosity is ~1e3 times the laminar one.

sources(U, grad_U, mu, d, n_mean, gamma)
wall_values(U, n_mean)
n_vars = 0
names = ()
needs_wall_distance = False