Register SURFACE_SPECIES_VARIANCE as a coefficient in the Python history map - #2930
Closed
ManasBagul23 wants to merge 61 commits into
Closed
ManasBagul23 wants to merge 61 commits into
ManasBagul23 wants to merge 61 commits into
Conversation
* allow fsi+cht * Apply suggestions from code review Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> * set regression values * back to develop
…#2806) * Reduce redundant CUDA Jacobian uploads * Move CUDA Jacobian upload into CSysMatrixVectorProduct * Defer CUDA matrix upload to first matvec use
This reverts commit ee4de5c.
* flexible BC for flamelet equations * add jacobian of the split source terms, rename FLAMELET->FLAME * add python wrapper to flamelet enthalpy --------- Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com>
su2code#2815) * allow adjoin-only, fix residual and objective reporting in single and multizone solvers * save main recording for functions that don't need it * update ref
…tion for ARM (su2code#2819) * add option * define single precision type, mpi, avoid repeated instantiations in mixed precision * use correct tecplot function * option 1 to handle double precision literals: replace min/max with fmin/fmax * Revert "option 1 to handle double precision literals: replace min/max with fmin/fmax" This reverts commit 4e4d9e1. * option 2: overload std::min/max for float/double mix, handle blas and lapack functions, fix some FPEs * fix some FPEs * vectorization for floats * arm vectorization * arm fix and use cpu arch for arm, fix some pass by value warnings * remove commented code * remove debug stuff * update regressions
Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com>
Base early exit on proper residual fix some implicit line agglomeration add more debugging info --------- Co-authored-by: Pedro Gomes <pcarruscag@gmail.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* Change nested classes to friend classes * Include discrete adjoint multizone driver in python wrapper * Re-define AdjointProduct and Identity as template classes * address comments --------- Co-authored-by: Pedro Gomes <pcarruscag@gmail.com>
* do not compute vorticity when it's not necessary * fix * fix restarts
… T <= 0 (su2code#2830) * detect temperature outliers * non simd too * fix * fix AD OMP build * avoid zero-ing the whole matrix * update regressions * file diffs
… preconditioners (su2code#2838) * ldu * orientation not necessary * sort to simplify edge map * apply to ILU, cleanup * cleanup * cleanup * cleanup pastix wrapper * avoid two copies in pastix wrapper * missing ZONE_SCOPED * fix UB * update regressions * fix tests * Apply suggestion from @pcarruscag * last update
* Implemented the reading of a binary SU2 format * Ran pre-commit * Addressing issues * Forgot to run pre-commit * Addressing comments * Set up the infrastructure for the writing of a binary grid file * Made sure to save these changes * review * writer and test * Added the number of DOFs per element when writing the file of the Jacobian matrix * fix --------- Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> Co-authored-by: Pedro Gomes <pcarruscag@gmail.com>
…u2code#2844) * bounded scalar for compressible * tests * fix windows build, update tests
…code#2846) * Move BC_Riemann definition from CTurbSolver to CScalarSolver This allows BC_Riemann to be used with all scalar solvers, particularily the species solver. * Add Riemann boundary check to CSpeciesSolver::SetUniformInlet * Add regression test for species transport with Riemann BC
…ion (su2code#2829) * Enable viscous flux contribution at supersonic outlet boundary condition The viscous flux contribution in BC_Supersonic_Outlet was previously commented out due to reported convergence issues. However, for viscous NS simulations this omission is physically incorrect and causes severe convergence problems at outlet boundary cells, which also prevents the use of second-order MUSCL reconstruction. For supersonic flows, downstream disturbances cannot propagate upstream, so the outlet state can be safely extrapolated from the domain interior. Using SetPrimitive(V_domain, V_domain) instead of (V_domain, V_outlet) resolves the convergence problems that motivated the original commenting. * Fix: declare Point_Normal in BC_Supersonic_Outlet viscous section * Add laminar flat plate test case config (Ma=4.0, Re=1.2e4) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove test case files from PR Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add supersonic flat plate test case configuration (Ma=4.0, Re=1.2e4) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add flatplate_supersonic to parallel regression tests Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update TestCases/navierstokes/flatplate/flatplate_supersonic.cfg Co-authored-by: Nijso <nijso@hotmail.com> * Update TestCases/navierstokes/flatplate/flatplate_supersonic.cfg Co-authored-by: Nijso <nijso@hotmail.com> * Update TestCases/navierstokes/flatplate/flatplate_supersonic.cfg Co-authored-by: Nijso <nijso@hotmail.com> * Update TestCases/navierstokes/flatplate/flatplate_supersonic.cfg Co-authored-by: Nijso <nijso@hotmail.com> * Update supersonic flat plate config * Apply suggestion from @bigfooted * Apply suggestion from @bigfooted * Add Yilun Tan to AUTHORS.md --------- Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> Co-authored-by: Nijso <bigfootedrockmidget@hotmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Nijso <nijso@hotmail.com>
…ions (su2code#2836) * int8 quantization * [skip ci] * [skip ci] * full crazy * micro optimize * compress more [skip ci] * consistency [skip ci] * productize quantization as a new preconditioner * cleanup * cleanup overloads * reduce potential incompatibility with quantization * typedef int type * address more compatibility * final fixes for non-simd numerics * heat solver fix * need to check da_sp_pinArray_cht_2d_dp_hf * add comp and incomp tests * unit test * unit tests + updates * updates * multizone bin test * fix binary reader * fix * fix * again
## Proposed Changes This PR adds an end-to-end CUDA linear solve path: the Krylov solvers keep their host control flow, and `CSysVector` operations, the SpMV and the Jacobi preconditioner are dispatched to CUDA kernels when `ENABLE_CUDA=YES`. Transfers are explicit and owned by the object responsible for the data, with no coherency or dirty-flag tracking in `CSysVector` / `CSysMatrix`: - `CSysMatrixVectorProduct` uploads the matrix on construction - the preconditioner uploads its data in `Build()` - `CSysSolve` uploads `b` and `x` and downloads `x` in `HandleTemporariesIn/Out`, which is also where device evaluation is switched on and off - preconditioners without a device implementation (ILU, LU-SGS, Linelet, PaStiX) download the input, apply on the host, and upload the result A solve is therefore fully device resident for Identity and Jacobi preconditioners: **2 uploads and 1 download per linear system**, independent of the Krylov subspace size. Implementation notes: - `cuBLAS` for `dot` / `norm`, custom kernels for the block-LDU SpMV, the Jacobi apply, and `CSysVector` expression assignment - `CSysVector` operands are captured in expressions by value, so an arbitrary expression tree is trivially copyable into the assignment kernel; the required expression shapes are explicitly instantiated in `CSysVectorGPU.cu`, consistent with how `CSysMatrix` is instantiated - device work is issued by a single thread with the OpenMP team synchronized around it, so the GPU path is usable from inside the existing parallel regions; this is internal to the linear algebra layer - the CUDA translation units are only linked into the primal libraries, since they cannot be compiled with the CoDiPack defines; device dispatch is compiled out of the AD builds - adds `LINEAR_SOLVER_PREC= NONE` (identity) ## Related Work Follows the review direction in su2code#2822 (show a working end-to-end GPU linear solve before splitting out infrastructure) and the implementation preferences in su2code#2816. ## Validation - CPU vs GPU on inviscid NACA0012, 25 iterations, RTX 4070 Ti SUPER (sm_89), for FGMRES + `JACOBI`, FGMRES + `NONE`, FGMRES + `ILU` (host preconditioner path) and BCGSTAB. Results agree to the printed precision in double, and to ~6 significant figures in mixed precision. BCGSTAB agrees exactly once the linear system is converged (`LINEAR_SOLVER_ERROR=1e-10`); at loose tolerances the two paths diverge through BCGSTAB's own sensitivity, not a difference in the algebra. - Mixed, normal and single precision builds all compile and run; device dispatch confirmed live in each (kernel launch counts track the subspace size). - `OMP_NUM_THREADS=1` and `4` give bit-identical results on the GPU path. - Builds verified: primal, primal + AD + directdiff, `enable-cuda` + `with-omp`, mixed / normal / single precision. - Transfer counts measured per solve: 2 H2D + 1 D2H + 1 matrix upload for Jacobi and `NONE`, plus one download/upload pair per preconditioner application for ILU. Earlier validation of the original design (6 representative cases, `nsys` / `ncu` profiling) predates the rework of the transfer and dispatch model and should be repeated. ## 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. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Pedro Gomes <pcarruscag@gmail.com>
…e#2738) (su2code#2855) ## Proposed Changes The QCR2000 quadratic constitutive relation (Spalart, *Int. J. Heat and Fluid Flow*, 2000) modifies the turbulent (Boussinesq) stresses, but `CNumerics::AddQCR` was applied to the total stress tensor at all call sites: laminar + eddy in the viscous fluxes (scalar and SIMD paths), and the **purely laminar** tensor in `Friction_Forces`, where the eddy viscosity is zero and the correction should vanish identically. For a pure-shear wall state this injects spurious normal stresses of ±0.6·τ_wall into the wall traction, which redistributes drag between the pressure and friction components while leaving total drag nearly unchanged — the exact signature reported in su2code#2738. This PR scales the correction by the turbulent fraction of the viscosity used to build the tensor, `mu_t / (mu_l + mu_t)`, which recovers the turbulent-only correction exactly because the stress tensor is linear in the viscosity (SA carries no turbulent-kinetic-energy term). The wall-force site passes a zero fraction on smooth walls. A unit test covers both properties (zero correction at `mu_t = 0`; scaled-total ≡ separate-turbulent-tensor). **Validation** (Ubuntu 24.04, source build at `de8c5015`, the su2code#2738 reporter's Joukowski R2 grid, 12000 iters, rms[Rho] ≈ −11): | run | CDp | CDv | CD | |---|---|---|---| | SA | 0.003180 | 0.004735 | 0.007915 | | SA-QCR2000, before | 0.003482 | 0.004432 | 0.007914 | | SA-QCR2000, after | 0.003183 | 0.004716 | 0.007898 | | SA on patched build | 0.003179 | 0.004735 | 0.007915 | Before the change, QCR2000 shifts CDp +9.5% / CDv −6.4%; after it, the split returns to within 0.1% of SA, consistent with CFL3D/FUN3D/Fluent behavior for this attached flow ([HiFi CFD verification workshop references](https://highfidelitycfdverificationworkshop.github.io/papers/rans.pdf)). With QCR disabled the patched build is behaviorally unchanged. Note: the `turb_SA_QCR_RAE2822` reference values in `parallel_regression.py` shift by 1e-4…4e-3 (verified on a same-platform before/after pair); I will update them from this PR's CI output, since reference values are runner-specific. Opening as a draft until then. ## Related Work Fixes su2code#2738. ## 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. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Boateng Opoku-Yeboah <bigboateng@users.noreply.github.com>
## Proposed Changes Currently, the species solver crashes when restarting a multi-grid simulation due to mismatched grid levels in two calls in `CSpeciesSolver::LoadRestart`. This PR fixes that, and modifies a test to exercise this code path. It'd be great if someone could also double-check whether this code makes sense. Given this bug, I suspect these lines have never been run since they were committed 5 years ago. ## Related Work I'll send an accompanying PR for the new restart file needed for the test case. ## 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. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Nijso <bigfootedrockmidget@hotmail.com>
## 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. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…de#2641) ## Proposed Changes Implements variable density treatment for unsteady incompressible flow simulations. Currently, SU2 uses constant density in transient simulations, which is inaccurate for combustion cases where density varies significantly due to heat release and species composition changes. This contribution enables proper density updates during time-stepping for flamelet-based combustion modeling. For now, only 1st order time marching is implemented ## Related Work Related to incompressible flow solver and flamelet combustion modeling. No specific issue linked yet. ## 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. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Tahsin Berk Kiymaz <tberk@int6.local.snellius.surf.nl> Co-authored-by: Tahsin Berk Kiymaz <tberk@int5.local.snellius.surf.nl> Co-authored-by: Nijso <bigfootedrockmidget@hotmail.com> Co-authored-by: Cristopher Morales <98025159+Cristopher-Morales@users.noreply.github.com> Co-authored-by: bigfooted <nijso@hotmail.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Nijso Beishuizen <nijso.beishuizen@nlr.nl> Co-authored-by: Tahsin Berk Kiymaz <tberk@tcn222.local.snellius.surf.nl> Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> Co-authored-by: Berk Kıymaz <tkiymaz@berks-air.home> Co-authored-by: Berk Kıymaz <tkiymaz@Berks-MacBook-Air.local> Co-authored-by: Berk Kıymaz <tkiymaz@berks-macbook-air.home>
…nditioner on GPU and CUDA Unified preconditiong matrix) (su2code#2843) ## Proposed Changes This PR introduces improves the GPU implementation of the multiDot product between Krylov vectors used in the FGMRES solver. It moves from a looped instantiation of pairwise dot products to a batched one-time kernel launch. A custom CUDA kernel and the batched gemm using cublas<t>gemm are benchmarked, the latter being eventually selected. ## Original proposal for the GSoC This PR introduces CUDA Unified memory and Managed memory allocation, and memory management for the CSysVector class and the preconditioning matrix inside the Jacobi preconditioner. This allows for a benchmark between the two memory strategies within the FGMRES solver. Also, this draft PR extends the section of GPU execution inside the FGMRES solver Custom CUDA kernels are implemented for the preconditioning matrix, the multi dot product and the linear combination (inside the Modified Gram-Schmidt orthogonalization), and the vector norm calculation. Unary vector-scalar operations based on templates are also offloaded to GPU through a generic kernel. Moreover, abstract Syntax Tree are deployed to offload vector-vector binary operations to the GPU through a generic kernel based on a runtime evaluation of the tree. The solver logic is not modified, and the GPU path is hidden inside the specific methods. ### Unified memory approach su2code@5fe25b8 A custom data() method recovers the CSysVector Unified pointer inside the CUDA logic, cleaning the logic from the double host/device pointers. All memory explicit memory copies are also removed from the CUDA logic, but explicit device synchronizations are introduced around MPI calls and at the end of the CUDA section. ### Managed memory approach su2code@4b43fa0 Operators accessing the CSysVector on Host after GPU operations demand synchronization, which is introduced explicitly in each. ## Performance evaluation (on-going) For the considered test-case (rae2822), the CPU execution expresses an **Avg. s/iter: 0.198681**. The GPU execution with Unified memory expresses an **Avg. s/iter: 0.238953**. The GPU execution with Managed memory expresses an **Avg. s/iter: 0.372046**. The CPU is a Intel(R) Xeon(R) E-2276M CPU @ 2.80GHz with 12 cores. The GPU is a Quadro P620. Tests on more advanced hardware are ongoing. Profiling results comparing the Unified Memory (left column) against the Managed Memory (right column) are available in the attached pdf: [SU2_ra2822_GPU_MA_vs_UM_nsys_prof.pdf](https://github.com/user-attachments/files/30520807/SU2_ra2822_GPU_MA_vs_UM_nsys_prof.pdf) ## Asynchronous pre-fetching: The Jacobi preconditioner calculations are performed on GPU through a new custom CUDA kernel under the preconditioner abstraction. The preconditioning matrix is selected to test CUDA Unified Memory asynchronous prefetching to the GPU. For simplicity, the double CPU/GPU pointer is still maintained in the current logic, although the device pointer reduces to an alias for the Unified Memory pointer when this kind of allocation is adopted. **This strategy introduces a simple context to test the CUDA Unified Memory usage and study the possibility of overlapping memory transfers and calculations without the need to introduce CUDA streams.** Concretely, this PR: - introduces new CUDA Unified Memory allocation methods and asynchronous prefetching; - introduces the GPU logic for the Jacobi preconditioner; - introduces the GPU logic for the multi dot product and the linear combination (Modified Gram-Schmidt orthogonalization); - introduces the GPU logic for the vector norm operation; - introduces the GPU logic for generic scalar-vector unary operations through templates and generic vector/scalar-vector binary operations through Abstract Syntax Tree evaluated at runtime; - finally falls back to CUDA Managed memory as highlighted in the following discussion. This introduces the need for explicity synchronization in all the custom setter/getter methods of the CSysVector. This work is part of my ongoing contribution during the Google Summer of Code 2026 program. ## Validation Validated locally with: - serial CUDA build compilation - serial CPU build compilation - CPU/GPU numerical comparison on 1 representative case (rae2822) tested with LINEAR_SOLVER_PREC=JACOBI with both CUDA Unified and Managed memory approaches. Nsys profiling was performed to confirm the asynchronous prefetching of the CUDA Unified Memory preconditioning matrix on my local GPU. Partial prefetching is observed, although page faults were reported during the preconditioner CUDA kernel, indicating that the calculations were slowed down by the prefetching matrix still being transferred to the GPU. This overlap is expected to largely improve on more modern hardware; tests are ongoing in the cloud. ## Related Work The Jacobi preconditioner kernels come from the PR su2code#2825. ## Observed Issues Some issues were observed during this first period of GSoC: - PR su2code#2825 compiles with CUDA 13.3 but CUSPARSE calls raise an unknown operation at the first matrix-vector product. - the build.meson file has a hard-coded CUDA arch. - the HAVE_MPI flag is not being passed to the nvcc compiler in the develop branch. This raises a linking error if MPI operations are included within the *.cu files. That is not the case in the master branch. ## Next steps I propose to continue working on the following steps: - [X] extend the CUDA Unified Memory allocation to the CSysVector class - [X] evaluate if it might be of interest to extend the CUDA Unified Memory allocation to the CSysMatrix class; Update: discussion with mantainer indicates preference for Managed Memory approach; - [X] benchmark the multiDot approached: looped vs custom kernel batched vs cublas<t>gemm batched: batched approaches are convenient due to just one kernel launch overhead, cublas implementation shows moderate speed-up (0.01s) against the custom CUDA kernel on local P620 but ensures less code complexity, thus it is selected. ## 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. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Pedro Gomes <pcarruscag@gmail.com>
## Proposed Changes Also compatible with GPU ## 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. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
## Proposed Changes Fix type comparison error introduced by turbo adjoints ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.* - [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. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> Co-authored-by: Josh Kelly <J.Kelly7@liv.ac.uk>
## Proposed Changes The original trapezoidal map implementation needs excessive memory for large lookup tables (LUT) (e.g., 300+ MB for tables with ~80k points). This PR introduces a new memory-efficient trapezoidal map implementation (LUT_FAST) for Flamelet-Generated Manifold (FGM) lookup tables, based on LUT algorithm of Pedro Gomes. The new implementation reduces memory usage while maintaining query performance. A new unit test is created and all tests are passed. ## Related Work This code is an implementation of https://github.com/pcarruscag/LUT to SU2. ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.* - [ 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). - [ ] My contribution is commented and consistent with SU2 style (https://su2code.github.io/docs_v7/Style-Guide/). - [ ] 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. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: tkiymaz <berkmetume@gmail> Co-authored-by: Nijso <bigfootedrockmidget@hotmail.com> Co-authored-by: Berk Kıymaz <tkiymaz@berks-air.home> Co-authored-by: Berk Kıymaz <tkiymaz@berks-macbook-air.home>
## Proposed Changes This is a split from su2code#2863 to clean up the different implementations. This PR does not really improve convergence, it merely implements some configuration options and makes it work robustly. An improvement comes from the CFL ramping: every level of the startup phase in FMG gets its own scaled CFL, then for this level CFL increases from the max CFL of the previous level to the new CFL of this level over MG_STARTUP_ITER iterations. This does mean some CFL jumps when you converge early. Also, when you exit the startup phase and enter the final v-cycle phase, you immediately jump to CFL_NUMBER, no ramping here. The real future improvement is probably stepping away from the piecewise constant interpolation. At the moment there is no improvement because the coarser levels do not result in a better starting point for the final v-cycle. Implementation details: MG_STARTUP_ITER= 100 %Full multigrid iterations per level for the warmup phase. MG_CFL_SCALING= 0.5, 0.5, 0.5 %Full multigrid now has CFL scaling for the coarser levels during warmup phase MG_STARTUP_CONVERGENCE= -2 %Full multigrid now exits the current level during the warmup phase when convergence dropped. MG_STARTUP_STAGNATION_ITER= 0.99 %Full multigrid now exits the current level during the warmup phase when the level residual stalls. MG_STARTUP_STAGNATION_ITER= 5 % 5 consecutive iteration of stagnation before exiting. ## Related Work su2code#2863 ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.* - [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. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com>
This PR ports the LU-SGS preconditioner to GPU ## Proposed Changes This PR introduces a build phase for the LU-SGS preconditioner where the inverse of the diagonal D is calculated to facilitate the compute phase. Then, forward and backward sweeps are implemented through custom CUDA kernels matching the logic of the CPU section (except for the inverse of D, which is directly multiplied in the GPU logic). These kernels are managed by the compute method on GPU which maintains the MPI communications. ## Related Work This PR follows the discussion of su2code#2843 . Kernel level dependencies are managed as for the ILU preconditioner proposed in su2code#2858 . ## Validation CPU and GPU implementations of the LU-SGS preconditioner are compared for validation of this PR on the rae2822 test-case. After one iteration, the first, preconditioned Krylov vector is compared finding matching results down to machine precision. Residuals are compared after 100 iterations finding matching results. ## TO-DO - [X] complete with the quantized_mode option path; - [ ] run benchmarks on modern GPUs. Current evaluations on a P620 are inconclusive; - [ ] profiling of the custom kernels; ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.* - [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. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Nijso <bigfootedrockmidget@hotmail.com>
…u2code#2721) ## Proposed Changes Continuation of su2code#2442. ## Related Work - General improvements - Adds the zone number to tags so that more mismatches/errors can occur whenever a dependency is wrong or is not behaving as expected ## 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. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary.
…ients (su2code#2886) ## Proposed Changes Fall back to no reconstruction for variables that are not stored. ## 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. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary.
…ock in Newton-Krylov (su2code#2887) ## Proposed Changes All in the title. ## 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. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…u2code#2880) ## Proposed Changes `CSU2TCLib` validates the user-supplied freestream composition with `if (mf != 1.0)`, an exact floating-point equality on an accumulated sum, at four gas-model sites (ARGON, N2, AIR-5, AIR-7). A physically exact composition need not sum to bit-exact unity in double precision. For example ``` GAS_COMPOSITION= ( 0.999, 0.00025, 0.00025, 0.00025, 0.00025 ) ``` sums to `1 - 1.1e-16` and is rejected with *"Intial gas mass fractions do not sum to 1!"*, which reads to the user as a typo in a composition that visibly sums to one. Any case seeding trace species can hit this. This PR compares against a `1e-10` roundoff tolerance and reports the offending sum in the message. The tolerance sits about six orders above the roundoff in the example (`1.1e-16`) and four orders below the `1.e-6` already used for the same "is this roundoff?" question in `Common/src/fem/fem_geometry_structure.cpp`, so genuine input errors are still rejected. The constant is `constexpr passivedouble` per the convention in `option_structure.hpp`, and the message uses `SU2_TYPE::GetValue` so the change is safe under AD builds. The sum is printed with 16 significant digits through a small static helper shared by the four sites, because `to_string` would print `1.000000` for any sum that fails the tolerance by less than `5e-7`; a composition off by `3e-7` now reports `sum = 0.9999997` and a real typo reports `sum = 0.99`. The pre-existing "Intial" typo is corrected in the same lines. Verification with actual solver launches on the public viscous-cone mesh (`ITER= 0`, exit code as the verdict): the roundoff-unity AIR-5 and AIR-7 compositions are now accepted; exact compositions for ARGON, N2, AIR-5 and AIR-7 remain accepted; real typos such as `( 0.75, 0.24, 0, 0, 0 )` remain rejected for every gas model. The regression baselines are unchanged, serial and MPI, so no regression vectors are modified. The contributor entry is added to `AUTHORS.md`. A dedicated constructor unit test was removed in response to maintainer review; the acceptance/rejection matrix above exercises the behavior through actual solver launches. ## Related Work The confusing failure mode may account for some reports of NEMO setup difficulty; it surfaces whenever trace species are seeded rather than left at exact zero. No open issue or PR is known to cover it. ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These a guide for you to know what the reviewers will be looking for in your contribution.* - [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] A dedicated unit test is not included at maintainer request; actual solver launches cover accepted roundoff and rejected invalid compositions. - [x] Documentation is not applicable; this corrects input validation and its diagnostic without changing a configuration keyword or public API. --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: BlueChips RunPod Integration <runpod-integration@bluechips.local>
…ion of the code (su2code#2889) ## Proposed Changes The 4th int of the header was written as 0 and never read, it now holds the size in bytes of the floating point data, so single and double precision builds can read each other's restart files. Files written before this field existed have a 0 there and were always double. The MPI-IO read paths were hardcoded to MPI_DOUBLE, which is redefined to MPI_FLOAT in single precision builds and was therefore consistent within a build but not across builds. They now describe the payload as blocks of bytes of the size given by the header, and convert to the precision of the build when the two differ. ## 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. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## Proposed Changes Bit of a hack to make it compile, but I think it's ok since no adjoint code is done on GPU, just the linear systems in plain types. Also fixes an issue with adjoint Krylov and OpenMP. ## 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. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary.
…rupted runs (su2code#2881) ## Proposed Changes Interrupt-driven termination is not limited to a user's Ctrl-C. SIGTERM is the normal way batch schedulers terminate a job at its wall-clock limit: SLURM sends SIGTERM when a job reaches its `TimeLimit` and on `scancel` (waiting `KillWait` before SIGKILL), and PBS/Torque and LSF behave equivalently. Today every SU2 job that exhausts its allocation on a cluster ends with a log stating "All convergence criteria satisfied." directly above a Solver Exit table whose every criterion reads "No". Any parameter sweep or optimization loop that classifies runs by scraping that banner silently admits timed-out, unconverged runs as converged, and a human skimming the log is misled the same way. That population is far larger than the manual-interrupt case. Mechanism: on SIGTERM the signal handler sets `STOP`, and `COutput::ConvergenceMonitoring` forces `convergence = true` so the run stops and saves. Both `CSinglezoneDriver::Monitor` and `CMultizoneDriver::Monitor` then read that flag as `InnerConvergence` and print the satisfied banner. Fix: a new `convergenceInterrupted` member of `COutput` records that the stop came from the interrupt path rather than from the criteria. It is propagated across ranks in the existing convergence Allreduce as a count-2 element-wise `MPI_MAX` (SU2's serial MPI stub does not define `MPI_BOR`, and the AD layer maps only SUM/MIN/MAX/PROD), exposed through `GetConvergenceInterrupted()`, and both drivers print ``` Interrupt signal received, exiting before the convergence criteria were satisfied. ``` on that path. Stop-and-save behavior, exit code 0, and the genuine-convergence and maximum-iteration messages are unchanged. Files: `SU2_CFD/include/output/COutput.hpp`, `SU2_CFD/src/output/COutput.cpp`, `SU2_CFD/src/drivers/CSinglezoneDriver.cpp`, `SU2_CFD/src/drivers/CMultizoneDriver.cpp` (+29/-8). Verification (QuickStart `inv_NACA0012.cfg`, serial release build of develop `07aa46b1`): - SIGTERM sent to the exact `SU2_CFD` process about 8 s into the run: the new interrupt message is printed, the satisfied banner does not appear, restart and solution files are written, exit code 0. - Run to genuine convergence and run to maximum iterations: output byte-identical to the unpatched build (checked when the change was first made on develop `81ce6a68f9`). - Touched files re-checked with `-Wall -Wextra`: no new warnings. ## Related Work The defect is present at v8.5.0 and at the current develop tip. I found no existing upstream issue or PR that addresses it. The change is independent of the other NEMO-related PRs from the same qualification campaign; it touches only the output and driver exit path. ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.* - [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. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
## Proposed Changes `CSU2FileWriter` takes its header from `dataSorter->GetRequiredFieldNames()` but reads data columns by positional index, so the sorter it's handed must be the one whose layout those names describe. The `RESTART_BINARY` branch directly below already does this correctly with `volumeDataSorterCompact` but for ASCII restarts where the user has specified `VOLUME_OUTPUT` fields outside the compact set, the columns become shifted and the outputted values are wrong. ## Related Work N/A ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.* - [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. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Josh Kelly <J.Kelly7@liv.ac.uk>
Simulations of flames in large domains is difficult because volumetric source terms blow up in large cells, causing the species solver to diverge. I implemented a damping term which scales the species source terms and diffusion in cells with a length scale above a user-defined threshold. This allows for the flame to propagate through regions of the domain with large cells (such as in the far-field) without the solver diverging, while the source terms in refined regions remain unaffected. Co-authored-by: Nijso <bigfootedrockmidget@hotmail.com>
## Related Work su2code#2893 ## 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. - [X] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary.
## Proposed Changes *Give a brief overview of your contribution here in a few sentences.* continuation of su2code#2891 SURFACE_CSV still has a compact restart issue. Since surface_csv is not a restart file, we do not apply compactness to it. ## Related Work *Resolve any issues (bug fix or feature request), note any related PRs, or mention interactions with the work of others, if any.* ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.* - [x] I am submitting my contribution to the develop branch. - [ ] My contribution generates no new compiler warnings (try with --warnlevel=3 when using meson). - [ ] My contribution is commented and consistent with SU2 style (https://su2code.github.io/docs_v7/Style-Guide/). - [ ] I used the pre-commit hook to prevent dirty commits and used `pre-commit run --all` to format old commits. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary.
## Proposed Changes In some cases we use relative frame for rotor zone to perform URANS, e.g., in aeroelasticity analysis, we want the grid movement comes only from blade deformation. The problem is that the sliding plane in SU2 works only for absolute frame. In relative frame, the grid is not rotating, so the interpolation at sliding interface is not changed as time step is marching. The proposed changes rotate the sliding interface in accordance with physical time steps to perform interpolation. This function is activated only for relative frame. The grid itself is not rotating. Currently, this is only implemented in CNearestneighbor class, other interpolation method should be changed as well in the near future. ## Related Work *Resolve any issues (bug fix or feature request), note any related PRs, or mention interactions with the work of others, if any.* ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.* - [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. - [x] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: chuanxiang yan <yancx20@mails.tsinghua.edu.cn> Co-authored-by: Nijso <bigfootedrockmidget@hotmail.com> Co-authored-by: Pedro Gomes <pcarruscag@gmail.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
### Proposed Changes
Fixes two defects in `SU2_PY/SU2/io/data.py`. Both make documented
public API paths of `SU2.io` raise immediately on any input.
**1. `save_data(..., append=True)` raises `NameError`.**
The append branch calls `load(...)`, which does not exist in the module.
The function is `load_data()`. The stale end-of-function markers (`#:
def load()`, `#: def save()`) suggest the functions were renamed at some
point and this internal call site was missed. `git log -S` dates it to
the v2.0.2 import.
Simply calling `load_data()` here is **not** a correct fix. `filelock`
is not reentrant (it is an `O_CREAT | O_EXCL` lock on a `.lock` sidecar
file), and `save_data` makes this call from inside its own `with
filelock(file_name)` block. The naive change therefore swaps an instant
`NameError` for a 10 second stall followed by `FileLockException`, which
is strictly worse.
Instead the lock-free read body is extracted into a private
`_read_data()` helper. `load_data()` wraps it in the filelock, and
`save_data()` calls it directly under the lock it already holds. This
keeps the read-modify-write atomic, rather than hoisting the read
outside the lock and introducing a TOCTOU race.
**2. `load_data(var_names=...)` raises `RuntimeError`.**
The filter deletes keys while iterating `input_data.keys()`. This was
safe on Python 2, where `.keys()` returned a list copy, and has been
broken since the Python 3 migration. It only triggers when at least one
key is actually dropped, which is why a single-key call appears to work.
Fixed by iterating a copy of the keys.
Both fixes sit in the same pair of functions and share one root cause,
namely leftovers from a rename and from the Python 2 to 3 migration, so
I have kept them in a single PR. Happy to split them if reviewers
prefer.
Also removes a `scipy` import probe in `load_data()` that becomes dead
once the read moves into the helper, and corrects the two stale marker
comments.
## Related Work
No open issue.
No in-tree caller currently passes `append=True` or `var_names`, so
there is no regression risk to the optimization drivers. These are
broken paths in a documented public API rather than a live crash in the
design loop.
Out of scope, flagged for a possible follow-up: the matlab (`.mat`) path
of `save_data` fails with `TypeError: 'method' object does not support
item assignment` inside `mat_bunch`. I verified this behaves identically
before and after this change, and did not touch it, in order to keep
this PR to one thing.
Could a maintainer please add the `changelog:fix` label.]
## Verification
`SU2_PY` has no Python test harness (`UnitTests/` is C++/Catch2 only),
so no test file is added. The following reproduces both failures on
`develop` and passes on this branch:
```python
import sys, os, tempfile
sys.path.insert(0, "SU2_PY")
os.environ.setdefault("SU2_RUN", tempfile.mkdtemp())
from SU2.io.data import save_data, load_data
os.chdir(tempfile.mkdtemp())
save_data("z.pkl", {"DRAG": 0.1, "LIFT": 0.9, "MOMENT_Z": 0.02})
save_data("z.pkl", {"CD": 1.0}, append=True) # was NameError
print(sorted(load_data("z.pkl"))) # ['CD', 'DRAG', 'LIFT', 'MOMENT_Z']
print(load_data("z.pkl", var_names="DRAG")) # was RuntimeError
```
Before and after on `develop`:
| Call | Before | After |
| --- | --- | --- |
| `save_data(append=True)` | `NameError` | OK |
| `load_data(var_names="DRAG")` | `RuntimeError` | OK |
| `load_data(var_names=["DRAG", "LIFT"])` | `RuntimeError` | OK |
| `load_data()` plain (regression check) | OK | OK |
`pre-commit run --files SU2_PY/SU2/io/data.py` passes.
## PR Checklist
- [x] I am submitting my contribution to the develop branch.
- [ ] My contribution generates no new compiler warnings (try with
--warnlevel=3 when using meson). *(N/A, Python only)*
- [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.
- [ ] I have added a test case that demonstrates my contribution, if
necessary. *(No Python test harness exists in the repo; a runnable
reproduction is included above.)*
- [ ] I have updated appropriate documentation (Tutorials, Docs Page,
config_template.cpp), if necessary. *(N/A, internal bug fix with no
user-facing API change.)*
Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com>
## Proposed Changes
The current work (part of GSoC) provides a working version of a
pressure-based algorithm for the incompressible flow solver as an
alternative to the existing Density-based solver. Below, the reader may
find the algorithm which has been implemented, as well as the current
progress of the code and challenges. All the way at the bottom one can
find performance comparisons between the DB and PB solvers for some test
cases.
### Algorithm
A lot of versions of pressure-based algorithms exist, and many different
versions can be implemented. Here, we opt for versions of the original
SIMPLE/PISO algorithm, it is briefly defined here for clarity.
First, the momentum equations are solved, starting from the previous
time step's velocity $\vec{u}^{(0)}$, pressure $p^{(0)}$, and face
velocity $\vec{u}_f^{(0)}$. The resulting momentum is the predicted
momentum, here its discretized form is shown, as its coefficients are
used in the subsequent equations
$A_p(\rho\vec{u})_p^{(1)}+\sum_n A_n (\rho\vec{u})_n^{(1)}=-V\nabla
p^{(0)}+S_m$
The subsequent momentum is not necessarily incompressible, the pressure
correction equation can be derived by rewriting it as follows, using a
term often called H by A
$(\rho\vec{u})_p^{(1)}=-\frac{\sum_n A_n
(\rho\vec{u})_n^{(1)}}{A_p}-\frac{V}{A_p}\nabla
p+S_m=\frac{H((\rho\vec{u})^{(1)})}{A}-\frac{V}{A_p}\nabla p^{(0)}+S_m$
$(\rho\vec{u})_p^{(2)}=\frac{H((\rho\vec{u})^{(1)})}{A}-\frac{V}{A_p}\nabla
p^{(1)}+S_m$
Note how a simplification is used here where the HbyA term is neglected.
Subtracting these two equations yields the first pressure correction
equation for $p'$ as
$\nabla \cdot \left( \frac{V}{A_p}\nabla p'\right)=\nabla \cdot \left(
\rho \vec{u}^{(1)}\right)$
Make note that for the divergence here, we require the face mass fluxes,
which are computed using Rhie-Chow interpolation to avoid odd-even
decoupling. After the equation is solved, using the pressure correction
$p'$, the pressure and momentum are corrected according to
$p^{(1)} = p^{(0)} + p' ,\quad (\rho u)^{(2)} = (\rho u)^{(1)}+(\rho
u)'.\quad (\rho u)'= -\frac{V}{A_p}\nabla p'$
So far, this is equal to a pseudo-transient version of the SIMPLE
algorithm. This algorithm however suffers from a very tight stability
condition on the time-step size. Therefore, multiple pressure
corrections can be applied, which for two corrections is originally
called the PISO algorithm.
The second pressure correction does not neglect the HbyA term, which
then results in the equation
$\nabla \cdot \left( \frac{V}{A_p}\nabla p'\right)=\nabla \cdot \left(
\rho \vec{u}^{(2)}\right)+\nabla\cdot\left(\frac{H((\rho
u)')}{A}\right)$
And the new correction equations are defined as
$p^{(2)} = p^{(1)} + p' ,\quad (\rho u)^{(3)} = (\rho u)^{(2)}+(\rho
u)'.\quad (\rho u)'= \frac{H((\rho u)')}{A}-\frac{V}{A_p}\nabla p'$
Note that HbyA here uses the previous velocity correction and is thus
the same quantity as the one used in the second pressure correction
equation. Later pressure correction equations follow analogously.
### Progress:
- Pressure-based solver added as alternative to density-based solver for
the incompressible flow equations.
- The pressure-based solver has only been tested for constant density
cases for basic Navier-Stokes and Euler flow.
- The pressure-based solver is implemented based on a pseudo
time-stepping approach to remain consistent with the other solvers in
SU2. The pressure-based solver is currently set to the SIMPLE algorithm
by default, with options for SIMPLEC and PISO available.
- The Poisson solver is a major bottleneck in the computation speed. To
account for this, an option was added to use a different linear solver
and preconditioner for the poisson solver.
- For details on the implementation of the algorithm and the
responsibility distribution please see the file CPBFluidIteration.cpp.
- A tutorial showcasing the different options of the PB solver for the
lid driven cavity flow problem has been added, please see
su2code/Tutorials#86 and su2code/su2code.github.io#218
- Regression tests have been added.
### Future work:
#### Performance:
- The Poisson solver can sometimes struggle a lot due to high Reynolds
numbers and fine meshes, and thus require a ridiculous number of
iterations to converge reasonably. Possible fixes include adding
multigrid support or a DIC preconditioner (far less efficient).
Multigrid support is tricky as SU2 currently only considers multigrid
for the main (flow) solver and not for auxiliary solvers.
- Convergence issues with RANS (SA and SST) on fine meshes with high
Reynolds numbers. Tests have shown that cases such as flow over a flat
plate converges fine. However, external aerodynamic cases such as the
naca0012 RANS test case do not converge well at all. The convergence
does slightly improve when we switch out the mesh for a more uniform
unstructured mesh without large aspect ratio cells in the wake of the
airfoil, although this only slightly helps. The flat plate turbulence
test case also uses large aspect ratio cells so this is not the sole
issue. The RANS solver also often requires many iterations of the
Poisson solver to converge reasonably, this is however not the reason
for the lack of convergence.
- Periodic boundary conditions have not been implemented/tested at all
as of yet.
- Any code related to adjoints has not been considered at all either.
#### Code:
- Parallelization with OMP gives wrong results due to a unknown issue in
the Poisson solver, MPI however does work as expected.
- The restart solution currently does not write the edge mass fluxes
which are used by the pressure-based solver. Therefore restarted
solutions have to estimate these mass fluxes based on the average of the
nodal solutions. This results in the restarted solutions starting from
slightly different residuals. A fix for this issue can be to let the
edge mass fluxes be stored in the restart file.
- Support for the energy equation is added trough both the enthalpy
equation as well as trough the weakly coupled heat solver. This support
has however not yet been verified trough actual test cases.
- The numerics class for the convective residuals write the continuity
parts of the flux and jacobians. This will allow for a coupled solver in
the future, but as it stands now this code is _not_ used.
### TODO list
- Fix issues mentioned above (left for future work)
## Related Work
This work is based on earlier attempts by Nitish Anand (2024) and Akshay
Koodly (2021), see feature branches feature_PBFlow_V8 and
feature_Pressure_based respectively. Also see PR su2code#2210
## 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.
- [x] I have updated appropriate documentation (Tutorials, Docs Page,
config_template.cpp), if necessary.
## Result showcase
### Inviscid Hydrofoil
<img
src="https://github.com/user-attachments/assets/2178b449-557d-4ec5-89b6-0d49ace6b612"
width="600">
*Convergence history of the inviscid flow around a hydrofoil at a 5
degree aoa.*
<img
src="https://github.com/user-attachments/assets/cd28de03-1c0a-4927-a5a3-567c454eb5c2"
width="600">
*The pressure coefficient along the surface of the hydrofoil at a 5
degree aoa and the corresponding lift coefficients, X-FOIL predicts
C_L=0.6.*
### Lid Driven Cavity
<img
src="https://github.com/user-attachments/assets/0433d13c-b76d-4b9d-ac2c-615539877c9e"
width="600">
*Convergence history of the lid driven cavity problem, note that CFL=60
is the highest stable CFL for the PB solver, whereas the DB solver does
not have this CFL related stability issue.*
### Flatplate RANS
<img
src="https://github.com/user-attachments/assets/b8db128d-e919-46a5-9b9d-aa17c1b94219"
width="600">
*The skin friction coefficient for turbulent flow over a (rough) flat
plate with SA.*
---------
Co-authored-by: Pedro Gomes <pcarruscag@gmail.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com>
… edge assembly (su2code#2885) ## Proposed Changes The gradient-corrected NEMO viscous routine returns the right Jacobian block twice, and the solver assembles viscous Jacobians with additive signs despite subtracting the flux at node i and adding it at node j. This patch returns the distinct left and right blocks and uses `UpdateBlocksSub` for the matching assembly signs. The residual equations are unchanged. For the controlled constant density and viscosity momentum test, Newtonian stress gives raw flux derivatives of -8/15 at i and +8/15 at j. The opposite signs inside numerics come from the velocity difference; they do not include the residual assembly sign. The assembled blocks must therefore be `(-Ji, -Jj, +Ji, +Jj)`. The general viscous Jacobian remains a TSL approximation. ## Tests - The numerics unit test checks the independently derived values and central differences of the returned momentum flux at both endpoints, using two perturbation sizes. The unused gradient reconstruction helper is removed. - The solver assembly test checks the signs and placement of the supplied blocks, with explicit finite checks. It is an integration test, not an independent proof of the full Jacobian. - The existing `ion_gy` regression now runs through iteration 99 using `test_iter`, the existing mesh and the same stored restart. Its residual threshold is lowered to prevent the previous stop at iteration 10. The duplicate case and config are removed, and the output restart has a separate filename so the input seed stays unchanged. - The installed unit-test container now gets the Mutation++ library path required by the new NEMO coverage. In the earlier captured two-rank comparison, the final log10 energy residual was 8.78 with the original code and 4.54 with the patch. The patched trajectory stayed bounded but still reported nonphysical states. This is regression stability evidence, not convergence or physical validation. The existing 0.01 tolerance is retained. In the [focused Linux run](https://github.com/babybluechips/SU2/actions/runs/34157605477), both MPI and NoMPI builds passed the full normal unit suite: 36 cases and 73,848 assertions each, including MLPCpp. `super_cat` passed, and both fresh two-rank `ion_gy` repeats passed at iteration 99 with identical printed rows and unchanged input seeds. Native checks also confirmed that restoring either original bug makes its relevant test fail. The cone references were refreshed from identical results in the fork and [upstream runs](https://github.com/su2code/SU2/actions/runs/34156557441), keeping the existing 1e-5 tolerance. The original regression comparisons failed only those stored cone references. The focused solver runs used `cd8a39d`; the final commit `50e3343` changes only the two reference arrays and the unit container's library path. Compiled source, unit tests and solver configs are identical. [Final upstream CI](https://github.com/su2code/SU2/actions/runs/34159628295) now passes the installed normal unit suite (36 cases, 73,848 assertions), AD/DD unit suites, and all 157 serial regression tests. The parallel cone, `super_cat`, and `ion_gy` at iteration 99 also pass; the rest of the parallel suite is still running. Both cone comparisons have zero printed difference. The overlapping `visc_cone`, `super_cat`, and `ion_gy` expectations must be refreshed if another NEMO PR merges first. ## Related Work Possibly relevant to su2code#2717. The inviscid case in su2code#2026 is outside this patch's scope. Earlier matched Mach 7.95 cone runs showed the original code aborting at iteration 1,406 and this patch completing 3,000 bounded iterations; those runs did not establish convergence. ## PR Checklist - [x] I am submitting my contribution to the develop branch. - [x] My contribution is commented and consistent with SU2 style. - [x] I have added a test case that demonstrates my contribution. - [x] Documentation is not applicable; no user-facing configuration option or API is added. - [x] Pre-commit formatting checks pass. - [x] The focused Linux checks and final upstream results listed above are verified. --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…bian (su2code#2883) Use `GeometryToolbox::Norm` instead of `SquaredNorm` when passing edge distance to the NEMO approximate viscous Jacobian. This corrects one production line; the physical flux calculation is unchanged. The duplicated fixture remains removed. ## Historical convergence comparison The published comparison tested head `b8504d8de172a20a0493391d3f3a3fd572b0cfbd` against base `07aa46b1868655ec01f534bf3ac84ba5fbb6b822`. Each Mach 2 and 2.5 pair used the same 37,192 point sphere mesh, identical settings and cold starts: AIR5, 6 Pa, T=Tve=220 K, first order AUSM, implicit Euler, an adiabatic noncatalytic wall, CFL1, MG1 with the default coarse CFL ratio of 0.25, and two MPI ranks per arm. | Condition | Base | Historical PR head | |---|---|---| | Mach 2 | Guard stopped at 34 rows; maximum 4 nonphysical points | Natural convergence in 1,341 rows; zero nonphysical points | | Mach 2.5 | Guard stopped at 23 rows; maximum 9 nonphysical points | Natural convergence in 1,243 rows; zero nonphysical points | Counts include row zero. Both patched runs met all ten log10 RMS residual limits ≤−6 and all three absolute CD/CL/HF Cauchy limits <1e−6 over a window of 100 samples, with clean natural exits before the 10,000 row cap. Each saved final field also passed a separate MG0 residual audit on the same mesh. Independent verification passed. The controls were stopped by the guard for nonphysical points. These two operating conditions on one geometry demonstrate improved robustness under the stated settings; they do not establish a speedup or improved physical accuracy. [Evidence ZIP with configs, mesh, logs, results, plots and reproduction instructions](https://github.com/user-attachments/files/31923042/PR2883-supersonic-reproduction-v1.zip). [Reply to Pedro](su2code#2883 (comment)). ## Validation after merging develop Source revision `a3a60bfa6d25f60066f2a892ea85841df986862d` includes develop `56df7491c9027fd28c83d8b09617c2852ccd078e` and su2code#2885. The historical convergence cases above were not rerun on this revision. [Supplemental Linux run](https://github.com/babybluechips/SU2/actions/runs/34925451837) tested that exact source on x86_64 and arm64, with separate serial and MPI builds. Full normal unit suites passed, including MLPCpp and Mutation++. Each selected regression ran twice from clean directories. The autotest configs change only `ITER` to `test_iter + 1`; all other settings and protected restart inputs are preserved. All 52 solver runs completed cleanly, repeated rows were identical, and the refreshed references accept every captured row under the original tolerances. Archive digests and all 680 sealed files for this PR were independently verified. Reference commit `c0519aa5f310f65f453da24bb7d955f65d6ee158` updates ten arrays from that evidence. The subsequent E221 cleanup changes only assignment spacing on 37 lines; the Python syntax trees and all numerical arrays are unchanged. **Head after the whitespace cleanup:** `dc81add7a6ba9a42dc4b18d2e41bda94451db9ee`. **Full upstream CI at that head:** [pending](https://github.com/su2code/SU2/actions/runs/34929371327). --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…2884) The total energy check was nested inside the species block, so it could never execute. This makes the energy check independent and applies the tighter species or total energy limit. The loop logic is now the small `ComputeUnderRelaxationFactor` helper requested in review. Its direct test with manufactured data covers small and excessive energy updates, opposing species updates, which limit wins, and cancellation for a tiny factor. ## Validation after the latest develop merge Updated with develop `8118ee0f507b5fb0fd70b819e6f1351c1b3c6d28` after su2code#2883 merged. The approved helper and its direct tests are unchanged. The [combined source validation](https://github.com/babybluechips/SU2/actions/runs/35018055822) tested merge commit `7e89cb6be1a869a61f9425bd069dc1ac6aa3d699` on Linux x86 and ARM with separate serial and MPI builds. All 52 solver runs completed, and every repeated row agreed within its architecture and build. All four full normal unit suites passed. Both MPI builds included Mutation++ support. That validation run failed its comparisons against the old cone references. Commit `53b8b75affdf3b1c29ff56691fc2333dd32cbd88` updates four cone arrays from the repeated results, with three residual entries changed in each. All 52 recorded rows pass the updated references under the original tolerances. Other references, configurations and restart inputs are unchanged. Full upstream CI on `53b8b75affdf3b1c29ff56691fc2333dd32cbd88` passed: [all 31 regression workflow jobs](https://github.com/su2code/SU2/actions/runs/35022817008), including unit tests and both sanitizer suites. Code Style, CodeQL, labels and CodeFactor also passed. ## 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. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary. --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…u2code#2900) addDoubleArrayOption expects a su2double*, but std::array::begin() returns a checked iterator type under the MSVC STL instead of decaying to a pointer as it effectively does with libstdc++. This broke native Windows builds with MSVC. Use .data() instead, which returns a raw pointer on every implementation. ## Proposed Changes *Give a brief overview of your contribution here in a few sentences.* ## Related Work *Resolve any issues (bug fix or feature request), note any related PRs, or mention interactions with the work of others, if any.* ## PR Checklist *Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.* - [ ] I am submitting my contribution to the develop branch. - [ ] My contribution generates no new compiler warnings (try with --warnlevel=3 when using meson). - [ ] My contribution is commented and consistent with SU2 style (https://su2code.github.io/docs_v7/Style-Guide/). - [ ] I used the pre-commit hook to prevent dirty commits and used `pre-commit run --all` to format old commits. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary.
[skip ci]
## Proposed Changes
In `SU2_PY/SU2_Nastran/pysu2_nastran.py`, the mesh summary prints
`"Number of points in the moving marker".format(len(...))`. The string
has no `{}` placeholder, so the count is computed but never shown. This
adds the missing placeholder.
Before: `Number of points in the moving marker`
After: `Number of points in the moving marker: 123`
Found with pyflakes (`'...'.format(...) has unused arguments at
position(s): 0`).
The exception for an unknown imposed motion type referenced `self.tipo`,
which does not exist, so it raised `AttributeError: 'ImposedMotionClass'
object has no attribute 'tipo'` instead of the intended message. It now
uses `self.typeOfMotion`.
## Related Work
None. This does not touch the SET1 parsing discussed in su2code#2313.
## 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.
- [ ] I have added a test case that demonstrates my contribution, if
necessary.
- [ ] I have updated appropriate documentation (Tutorials, Docs Page,
config_template.cpp), if necessary
[skip ci] ## Proposed Changes Eleven objectives that `CConfig::GetObjFunc_Extension` gives an adjoint file suffix were missing from `get_adjointSuffix` in `SU2_PY/SU2/io/tools.py`, so the Python scripts stop with `Unrecognized adjoint function name` when one of them is used: `INVERSE_DESIGN_HEATFLUX`, `AVG_TEMPERATURE`, `SURFACE_STATIC_TEMPERATURE`, `SURFACE_SPECIES_0`, `SURFACE_SPECIES_VARIANCE`, `REFERENCE_GEOMETRY`, `REFERENCE_NODE`, `VOLUME_FRACTION`, `TOPOL_DISCRETENESS`, `TOPOL_COMPLIANCE`, `STRESS_PENALTY` `INVERSE_DESIGN_HEATFLUX` was listed as `INVERSE_DESIGN_HEAT`, which is not an objective name in SU2, so that entry is renamed. The suffixes are the ones from `GetObjFunc_Extension`. After this change every objective with a suffix in CConfig is found by `get_adjointSuffix`. ## Related Work Complements su2code#2907, which corrects the suffixes of `TOTAL_PRESSURE_LOSS` and `KINETIC_ENERGY_LOSS`. The two PRs do not conflict. ## 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. - [ ] I have added a test case that demonstrates my contribution, if necessary. - [ ] I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary.
## Proposed Changes
Apply the design of the SIMD numerics to scalars (but without
vectorization because it does not pay off for scalars). Performance is
still about 2 times better.
Every transported-scalar equation (SA, SST, LM, species, flamelet, heat,
pressure correction) now gets its convective and diffusive flux from a
**single statically-sized inline kernel**, used by both the interior
edge loop and the boundary conditions. The old `CNumerics`-based scalar
convection/diffusion classes are deleted, along with their `CDriver`
registration.
Deleted: `scalar_convection.hpp`, `scalar_diffusion.hpp`,
`turb_convection.hpp`, `turb_diffusion.hpp`, `trans_convection.hpp`,
`trans_diffusion.hpp`, `species_convection.hpp`,
`species_diffusion.hpp`, `heat.hpp`.
Added: `numerics/util.hpp`, `numerics/scalar/scalar_edge_flux.hpp` and
one `*_edge_flux.hpp` per model.
### Key points of the architecture
**One class per model, a three-layer CRTP chain.** Convection and
diffusion are not separate objects; they accumulate into one residual
under one preaccumulation region.
| Layer | Written | Holds |
| --- | --- | --- |
| `CUpwScalarBase` | once | upwinding weights, MUSCL reconstruction,
preaccumulation region, both `ComputeFlux` overloads |
| `CUpwScalarFlux` / `CAvgGradScalarBase` | once | the generic
convective expression; the edge geometry, projected gradient,
contraction with the coefficient matrix and the TSL Jacobians |
| Model (`CScalarFlux_SA`, `_SST`, `_TransLM`, `_Species`, `_Flamelet`,
`_Heat`, `_Poisson`) | per model | `Conservative`, `DiagonalDiffusion`,
and one `coefficients()` function |
**Runtime flags, not separate instantiations.** `ScalarFluxOptions`
carries `convective`, `viscous`, `oneSided`, `muscl`, `implicit`,
`boundedScalar`, `dynamicGrid`, `correctGradient` and
`accurateJacobians`. They are loop-invariant and unswitched by the
compiler. They are built through named constructors (`Interior`,
`BoundaryConvective`, `BoundaryFull`, `BoundaryDiffusive`) so that no
flag is passed positionally. A boundary clears `viscous`; a solid zone
(heat) and the pressure correction clear `convective`.
**Boundaries use the same kernel through ghost containers.** `EdgeSide`
locates one endpoint (scalar nodes, flow nodes, coordinates, grid
velocity). The interior loop binds one `EdgeSide` as both endpoints; a
boundary binds the solver's containers for `i` and per-marker ghost
containers for `j` — a `CGhostFlowVariable` (same primitive layout as
the flow solver) plus an instance of the solver's own `VariableType`,
indexed by vertex. Each BC is a fill pass followed by the shared flux
pass; there is no boundary special case inside any kernel.
**Non-conservative diffusion is supported.** `EdgeResidual` carries two
independent row contributions (`flux_i`, `flux_j`) and four Jacobian
blocks (`ii`, `ij`, `ji`, `jj`). `CSysMatrix` gains a four-block
`SetBlocks` and a `SetOffDiagBlocks`, both quantization-aware, covered
by a new unit test
(`UnitTests/Common/linear_algebra/edge_residual_blocks_tests.cpp`).
**The value type is a template parameter.** `numerics_simd/util.hpp` was
promoted to `numerics/util.hpp` with its value and index types
parameterized (`CLaneTraits`, `CValueTraits`) and its alignment behind a
trait; the MUSCL helpers moved with it and are now shared by the flow
and scalar paths. The solvers bind `su2double` today; a SIMD binding
would be the same code with `simd::Array`.
**`nVar` is a template parameter, or `Dynamic`.** Species and flamelet
pass `Dynamic`: the static arrays are backed by `MaxScalarVar`, the
loops run to a count read from the solver, and reconstruction takes a
runtime width.
**Shared loops in `CScalarSolver`:** `EdgeFluxResidual` (both the
coloring and the reducer strategy, one loop for both terms — the solvers
no longer have a `Viscous_Residual`), `BoundaryFluxResidual`, and
`FluidInterfaceFluxResidual`.
### Adding a new scalar model
1. **Write the flux class** in `numerics/.../<model>_edge_flux.hpp`:
```cpp
template <class Double, class FlowIndices, int nDim, size_t nVar = 2>
class CScalarFlux_Foo final
: public CUpwScalarBase<Double, CScalarFlux_Foo<Double, FlowIndices, nDim, nVar>, FlowIndices, nDim, nVar> {
public:
static constexpr bool Conservative = true; // density-weighted transport
static constexpr bool DiagonalDiffusion = true; // vector of coefficients instead of a matrix
using Base = CUpwScalarBase<Double, CScalarFlux_Foo, FlowIndices, nDim, nVar>;
using Base::Base;
template <class VariableType>
FORCEINLINE CPair<Vector<Double, nVar>> coefficients(const FlowIndices& idx, Int iPoint,
const EdgeSide<VariableType>& side_i, Int jPoint, const EdgeSide<VariableType>& side_j,
const CPair<Double>& rho) const { ... }
};
```
That is the whole model in the common case. The optional hooks, each
inherited empty or generic, are:
- `finalizeFlux` — only if the convective term is not `a0*w_i*phi_i +
a1*w_j*phi_j` (SA overrides it for the backscatter equations).
- `coefficientJacobians` — extra Jacobian terms when the coefficients
depend on the transported variables (SA, SST).
- `extraDiffusionTerms` — extra gradients of synthesised states
(flamelet preferential diffusion).
- `DiffusionReadsDensity = true` — if the coefficients need the density
and the model is not `Conservative`; otherwise the density is never
gathered.
2. **Dispatch from the solver.** `CScalarSolver::DispatchScheme<Model,
nVarList...>(config, f)` resolves the flow indices
(compressible/incompressible), `nDim` and the equation count, and calls
a generic lambda with a type tag. There is nothing else to touch: no
`CDriver` registration and no `CNumerics` allocation.
```cpp
const auto opt = ScalarFluxOptions::Interior(*config, /*bounded*/ false);
DispatchScheme<CScalarFlux_Foo, 2>(config, [&](auto tag) {
EdgeFluxResidual<typename decltype(tag)::type>(geometry, solver_container, config, opt);
});
```
Use `Dynamic` in the `nVarList` for a runtime equation count, and list
several counts (SA uses `1, 4`) to instantiate variants.
3. **Boundaries.** Write the fill pass (ghost solution,
`SetGhostPrimitives`, `SetGhostGeometry`, `SetGhostDiffusionState` for
the diffusion sites, `ghostSkip` for vertices that contribute nothing),
then call `BoundaryFluxResidual` through the same `DispatchScheme`. Most
boundaries of the `CScalarSolver` family are already generic and need no
per-model code.
The instantiation cost is `regime x nDim x |nVarList|` per model.
### Behavior changes and fixes
- NEMO with a turbulence model is now rejected at configuration; the
dead NEMO scalar-numerics branches and instantiations are gone.
- SST and species had no `BC_Far_Field` of their own (crash on
`MARKER_FAR`); it is now inherited from `CScalarSolver`.
- `BC_Inlet_MixingPlane` / `BC_Inlet_Turbo` never applied the
bounded-scalar mass-flux correction.
- The heat solver gained far-field and fluid-interface boundaries, and
its diffusion coefficients are now visible to AD.
- SA-neg keeps its `fn`-corrected diffusion coefficient and frozen
Jacobians; exact turbulent Jacobians stay behind
`USE_ACCURATE_TURB_JACOBIANS`.
- The unused `CAvgGrad_Species` `visc_bound_term` allocation is deleted.
### Validation
Last-digit changes are expected: the two terms now accumulate in one
`EdgeResidual` and each Jacobian block is cast to `su2mixedfloat` once.
The reference values were refreshed from CI across the serial, parallel
and hybrid suites, the AD suites, `tutorials.py` and `vandv.py`; a
flamelet CFD case was added to `hybrid_regression.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.
- [X] I have updated appropriate documentation (Tutorials, Docs Page,
config_template.cpp), if necessary.
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
|
|
||
| #: if file_format | ||
|
|
||
| return input_data |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SURFACE_SPECIES_VARIANCEis registered in C++ asHistoryFieldType::COEFFICIENT, but its description string contains a comma, which brokeupdateHistoryMap.py's parsing: it readTYPEasDEFAULT, truncated the description at the comma, and never created the correspondingD_/TAVG_entries. As a result SU2_PY skipped the adjoint path for this field (gradients.py:96), skipped it in aerodynamics (functions.py:94), and left it out ofopt_names(functions.py:212).This was the only field across all 11 output files affected by this problem. Fixed by removing the comma from the description in
CFlowOutput.cpp:90and hand-adding the 4 corresponding history-map entries. Verified they are byte-identical to what the (fixed) generator emits, black-clean, and the surrounding key order is unchanged.Prepared with AI assistance; I reviewed the changes.