Repository navigation
Source term method for preferential diffusion - #2970
joshkellyjak wants to merge 6 commits into
Conversation
…te fixes Adds the resolved Eq. (14) preferential diffusion flux formulation (model B2 of Schepers & van Oijen, C&F 280 (2025) 114332) to the flamelet scalar transport, alongside the existing beta correction, and fixes two defects that left the existing model inert or wrong. Model - PREFERENTIAL_DIFFUSION_METHOD selects BETA_CORRECTION (default, unchanged) or SOURCE_TERM. - PREFERENTIAL_DIFFUSION_MAJOR_SPECIES names the species carrying the resolved flux. The manifold variables (Res_<cv>, Y-<sp>, D_<cv>_<sp>, DT_<cv>) are composed from the configured controlling variable and species names. - The Eq. (14) fluxes are a new branch of CScalarFlux_Flamelet, driven by the CFD-resolved gradients of the major species and of temperature. Explicit, with a stabilising self-diffusion added to the Jacobian alone so the converged solution is unchanged. - The Eq. (16) closure sources are gated on manifold validity only. Fixes - nAuxVar was never set, so SetAuxVar_Gradient_* looped zero times and every beta gradient stayed zero. The beta term then evaluated grad(beta) - grad(phi) as -grad(phi), cancelling the ordinary diffusion of the controlling variables rather than correcting it. - LEAST_SQUARES fell through the auxiliary gradient switch, with the same effect. - Soret coefficients are zeroed on viscous walls, where the manifold carries no quench layer data. - A collective in the volume output ran behind an "iPoint == 0" test inside the per point loop; a rank owning no points would have hung the others. Moved to a new per write COutput::PrepareVolumeData hook. - The cached preferential diffusion source is cleared at off manifold nodes, and the Newton non convergence message is rank guarded. Diagnostics - FLAME_QUALITY volume group, hull miss deviations, FLAMELET_VERBOSE_MISSES, and per location probe history files. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…le gradient The stabilising diffusivity is a bound on the Eq. (14) flux recast as a self diffusion, |J| <= D_stab |grad phi|, so it has to be divided by the controlling variable's own gradient. Without that division D_stab sits at the raw coefficient magnitude everywhere, which damps the update far more than the explicit flux warrants: on the burner case every stabilised run plateaued near rms[h] = -2.45 whatever the CFL, so the higher ceiling bought no convergence. With the division restored, CFL 2 reaches -2.530 against -2.528 at CFL 1, and the ceiling moves from (1, 2) without the term to (2, 3) with it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| coefficient D^T_{phi_k}. ---*/ | ||
| if (source_term_active) { | ||
| pd_terms_per_cv = FlameletPDTermsPerCV(flamelet_config_options.n_pd_major_species); | ||
| pd_flux_coeff.resize(nPoint, flamelet_config_options.n_control_vars * pd_terms_per_cv) = su2double(0.0); |
…spaces) (#2935) ## Proposed Changes `SU2_PY/SU2/run/interface.py` builds the command as `os.path.join(SU2_RUN, "SU2_CFD") + " config_CFD.cfg"` and runs it with `shell=True`. The executable path is quoted only on Windows (`quote = '"' if sys.platform == "win32" else ""`), so on Linux/macOS any SU2_PY script (shape_optimization.py, parallel_computation.py, ...) fails if `SU2_RUN` contains a space. This PR moves the quoting into `build_command`: the first word of the command is joined with `SU2_RUN` and quoted (`shlex.quote` on POSIX, double quotes on Windows as before), the callers pass plain `"SU2_CFD config_CFD.cfg"` strings. The quoted path is then inserted into the MPI template as before (`mpirun -n %i %s`, `srun`, `SU2_MPI_COMMAND`). The module-level `quote` variable is removed; it was not used outside `interface.py`. Reproduction on macOS, `SU2_RUN=".../su2 bin"`, `shape_opt_euler_py` from serial_regression.py: ``` before: Command = /.../su2 bin/SU2_CFD config_CFD.cfg SU2 process returned error '127' /bin/sh: /.../su2: No such file or directory after: Command = '/.../su2 bin/SU2_CFD' config_CFD.cfg optimization runs to the end ``` With the change and `SU2_RUN` containing a space, `history_project.csv` and the optimizer output of `shape_opt_euler_py` are identical to develop with a `SU2_RUN` without spaces. The MPI path was checked with `NUMBER_PART=2`: `mpirun -n 2 '/.../su2 bin/SU2_CFD' config_CFD.cfg` runs with 2 ranks. The Windows branch produces the same string as before. ## Related Work None found. Separate from #2934 (also SU2_PY). ## PR Checklist - [X] I am submitting my contribution to the develop branch. - [X] My contribution generates no new compiler warnings (try with --warnlevel=3 when using meson). - [X] My contribution is commented and consistent with SU2 style (https://su2code.github.io/docs_v7/Style-Guide/). - [X] I used the pre-commit hook to prevent dirty commits and used `pre-commit run --all` to format old commits. - [X] I have added a test case that demonstrates my contribution, if necessary. — Not necessary: the change only affects how the executable path is quoted; `shape_opt_euler_py` passes unchanged, and the reproduction above (SU2_RUN with a space) fails before and passes after. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. — Not necessary: no user-facing option changed. Co-authored-by: Nijso <bigfootedrockmidget@hotmail.com>
This is the correct behavior as described in Everts thesis, the ordinary diffusion should be cancelled, leaving only the beta correction term. |
This description is wrong the beta correction side is unchanged from develop other than the nAuxVar fix |
|
OK, I checked what was really going on with the nAuxvar fix. This bug actually puts the cross-diffusion term of the gradient of beta to zero. On orthogonal meshes this nAuxvar contribution is zero. |
|
OK, so I checked the paper of Stijn. So it's an extension of Nithin's paper for mixture averaged diffusion (instead of constant Lewis per species) and he adds Soret diffusion. And Stijn uses only major species and then has some truncation source term. |
Yes, as the forthcoming PR to DataMiner will show, when you have a PV definition with non-major species you end up with some additional conservation term, relatively small to all other contributions but necessary for conservation |
|
https://eprints.soton.ac.uk/id/eprint/494934/1/1-s2.0-S1540748924003894-main.pdf From Heinz's group also good for validation study |
Proposed Changes
Adds the resolved Eq. (14) preferential diffusion flux formulation (model B2 of
Schepers & van Oijen, C&F 280 (2025) 114332) to the flamelet scalar transport,
alongside the existing beta correction, and fixes two defects that leave the
current preferential diffusion model not merely inert but actively wrong.
Two fixes that affect
developtoday.CSpeciesFlameletVariablesizesAuxVarandGrad_AuxVarto the four beta terms but never setsnAuxVar, soSetAuxVar_Gradient_GG/LSloop zero times and every beta gradient stays zero.The FGM model drives the diffusive flux of the controlling variables by
grad(beta) rather than by their own gradient (Bunschoten, Eqs. 2.8-2.10); the
solver reaches that from the generic scalar base class by adding
div(D grad(beta - phi)) to the ordinary div(D grad phi), which sums to
div(D grad beta). With the beta gradients zero that sum is zero, so the
controlling variables are left with no diffusion at all. Separately,
LEAST_SQUARESfalls through the auxiliary gradient switch, with the sameconsequence for anyone not on Green-Gauss.
New model.
PREFERENTIAL_DIFFUSION_METHODselectsBETA_CORRECTION(default, unchanged) or
SOURCE_TERM.PREFERENTIAL_DIFFUSION_MAJOR_SPECIESnames the species carrying the resolved flux; the manifold variables
(
Res_<cv>,Y-<sp>,D_<cv>_<sp>,DT_<cv>) are composed from theconfigured controlling variable and species names rather than hard-coded, so one
set of strings describes the table on both sides. The Eq. (14) fluxes are a new
branch of
CScalarFlux_Flamelet, driven by the CFD-resolved gradients of themajor species and of temperature — the point of tabulating a coefficient per
species instead of pre-contracting them against the one-dimensional flamelet
gradients. They are applied explicitly, with a stabilising self-diffusion added
to the Jacobian alone so the converged solution is untouched. The Eq. (16)
closure sources are gated on manifold validity only.
Also fixed. Soret coefficients are zeroed on viscous walls, where the
manifold carries no quench-layer data. A collective in the volume output ran
behind an
iPoint == 0test inside the per-point loop, so a rank owning nopoints would have hung every other rank; it moves to a new per-write
COutput::PrepareVolumeDatahook, where an empty partition contributes theMIN/MAX identity elements instead of not participating. The cached preferential
diffusion source is cleared at off-manifold nodes, and the Newton
non-convergence message is rank-guarded.
Diagnostics.
FLAME_QUALITYvolume group (C+, chi_C, Da), hull-missdeviations,
FLAMELET_VERBOSE_MISSES, and per-location probe history files.Validation
Laminar premixed H2 burner against an OpenFOAM FGM reference, on a manifold
whose progress variable is defined on the major species only.
four equations; Temperature and Density agree with the reference
implementation to 5-6 significant figures.
figures at CFL 1); CFL ceiling moves from (1, 2) without it to (2, 3) with it;
misses hold at 1-2 across that range, against 1 -> 7 -> 49 without.
A chemical-activity gate on the closure sources was removed:
fmax(0, .)clipping meant it only closed where the tabulated source wasnegative, so it closed at 320 preheat-zone nodes (304-567 K) while staying open
across 21k gradient-free bulk nodes — the inverse of its stated purpose.
Caveats
nAuxVarfix changes results for every existingBETA_CORRECTIONuser, including regression case 07, which runs the default method.
Baselines will move. The fix is correct, but the new behaviour still needs
validating on a manifold built for the beta formulation — on the
SOURCE_TERM-oriented manifold used here,
BETA_CORRECTIONdiverges.heat flux by up to 1.2% and wall temperature by 0.4 K, decaying to nothing
within 0.5 mm. Justified by manifold support, not impermeability: the wall
face carries no Eq. (14) flux in any case, since only interior edges are
visited. What it changes is the near-wall interior edges, through the
coefficient averaging.
restart on this burner, with a coarse ladder (1, 2, 3). Treat ~1.5x as
indicative, not a precise factor.
different manifolds and two different flux discretizations). Retained as
insurance against a poorly matched table, but unexercised.
Related Work
This work was developed on a branch that predates the rewrite of the flamelet
scalar transport into
CScalarFlux_Flamelet/EdgeFluxResidual, and the fluxassembly was ported onto that framework rather than carried over. The port is
validated by reproducing the pre-port implementation's residuals to the digit
with the stabiliser disabled.
PR Checklist
pre-commit run --allto format old commits.