Follow-up to #1821. src/simulation/m_ibm.fpp is now 2220 lines, and about 400 of them are a surface-chemistry Newton solver that has nothing to do with immersed boundaries.
The seam
The surface-chemistry block (m_ibm.fpp:1822-2218) is:
| routine |
lines |
what it does |
s_solve_surface |
151 |
damped Newton with backtracking |
s_solve_surface_linear_system |
67 |
dense LU with partial pivoting |
s_surface_species_residual |
41 |
per-species flux balance |
s_blend_ghost_state |
34 |
bounded ghost reconstruction |
s_surface_residual |
27 |
residual assembly |
s_surface_energy_residual |
18 |
surface energy balance |
s_pick_bath_species |
14 |
sum-constraint closure |
Its interface to the immersed boundary is narrow: given (pres, T_IP, T_wall, d, Ys_IP, W_species, thermal_bc) it returns (Ys_s, T_s, mdot_s, converged). Nothing in it knows what a ghost point is. Only the ~70-line branch in s_ibm_correct_state is genuinely IB coupling.
Note s_blend_ghost_state is arguably the exception — it is about the ghost state — but it belongs with the solver whose clamps it exists to preserve, and it takes no IB arguments either.
Performance: this costs nothing
The concern with splitting device code is offload and inlining. It does not apply here:
m_ibm already makes 11 cross-module device calls from inside the ghost-point GPU_PARALLEL_LOOP (into m_thermochem and m_surface_thermochem).
- 8+ modules already host
GPU_ROUTINE(parallelism='[seq]') helpers called from parallel loops (m_collisions, m_igr, m_thinc, m_riemann_state, m_compute_levelset, …).
A new m_surface_chemistry.fpp is the pattern the code already depends on.
The real payoff is testability
Codecov on #1821 reports 56.97% patch coverage, 55 uncovered lines in m_ibm.fpp. The Newton solve is currently reachable only by running a 2-D reacting IB simulation and comparing a golden — which is also why its one regression test is sensitive to the compiler (see #1821, cold-wall golden).
Extracted, it can be tested directly: feed a known surface equilibrium, assert the residual converges to zero; feed a singular Jacobian, assert converged = .false.; assert sum(Ys_s) = 1 holds exactly; assert the ghost blend never returns a negative mass fraction or a temperature outside [T_surface_min, T_surface_max]. None of that needs CFD.
Scope
Pure move plus tests — no behaviour change, so the existing goldens must not shift.
Tracked in #1893.
Follow-up to #1821.
src/simulation/m_ibm.fppis now 2220 lines, and about 400 of them are a surface-chemistry Newton solver that has nothing to do with immersed boundaries.The seam
The surface-chemistry block (
m_ibm.fpp:1822-2218) is:s_solve_surfaces_solve_surface_linear_systems_surface_species_residuals_blend_ghost_states_surface_residuals_surface_energy_residuals_pick_bath_speciesIts interface to the immersed boundary is narrow: given
(pres, T_IP, T_wall, d, Ys_IP, W_species, thermal_bc)it returns(Ys_s, T_s, mdot_s, converged). Nothing in it knows what a ghost point is. Only the ~70-line branch ins_ibm_correct_stateis genuinely IB coupling.Note
s_blend_ghost_stateis arguably the exception — it is about the ghost state — but it belongs with the solver whose clamps it exists to preserve, and it takes no IB arguments either.Performance: this costs nothing
The concern with splitting device code is offload and inlining. It does not apply here:
m_ibmalready makes 11 cross-module device calls from inside the ghost-pointGPU_PARALLEL_LOOP(intom_thermochemandm_surface_thermochem).GPU_ROUTINE(parallelism='[seq]')helpers called from parallel loops (m_collisions,m_igr,m_thinc,m_riemann_state,m_compute_levelset, …).A new
m_surface_chemistry.fppis the pattern the code already depends on.The real payoff is testability
Codecov on #1821 reports 56.97% patch coverage, 55 uncovered lines in
m_ibm.fpp. The Newton solve is currently reachable only by running a 2-D reacting IB simulation and comparing a golden — which is also why its one regression test is sensitive to the compiler (see #1821, cold-wall golden).Extracted, it can be tested directly: feed a known surface equilibrium, assert the residual converges to zero; feed a singular Jacobian, assert
converged = .false.; assertsum(Ys_s) = 1holds exactly; assert the ghost blend never returns a negative mass fraction or a temperature outside[T_surface_min, T_surface_max]. None of that needs CFD.Scope
Pure move plus tests — no behaviour change, so the existing goldens must not shift.
Tracked in #1893.