feat: gate heavy solver JSON, field traceability API, GUI rod/export depth

- C: emit profiles/diagnostics/fourier only when enable flags are set; null otherwise
- API: fieldTraceability on case parse/default and solve; fix GET /solve/default options
- Tests: golden fingerprint, quality gates, C diagnostics invariants; cardQa mean empty guard
- Makefile: test-solver-sanitize ASan/UBSan target; README and COMPUTE_PLAN updates
- GUI: taper weight/MTS/guides/sinker round-trip, rod catalog, solver output toggles,
  results (profiles/diagnostics/Fourier/traceability), engineering checks and tabs
- Restore canonical WellName in base-case for regression; trace TaperGuidesCountArray

Made-with: Cursor
This commit is contained in:
2026-04-16 23:19:00 -06:00
parent 10f6ae1c2b
commit 64e9d31373
39 changed files with 1318 additions and 369 deletions

View File

@@ -173,6 +173,26 @@ static int test_zero_input_bounded(void) {
return 0;
}
/* Gas fraction and chamber pressure invariants after valve/gas stepping */
static int test_diagnostics_invariants(void) {
SolverInputs inputs;
fill_base_inputs(&inputs);
SolverOutputs outputs;
if (solver_run_fdm(&inputs, &outputs) != 0) {
return 1;
}
for (int i = 0; i < outputs.point_count; i++) {
const double g = outputs.gas_fraction[i];
if (g < -1e-6 || g > 1.0 + 1e-6) {
return 2;
}
if (!isfinite(outputs.chamber_pressure_pa[i])) {
return 3;
}
}
return 0;
}
/* FDM vs FEA peak polished load tolerance (regression gate) */
static int test_fdm_fea_peak_tolerance(void) {
SolverInputs inputs;
@@ -247,6 +267,12 @@ int main(void) {
return 1;
}
rc = test_diagnostics_invariants();
if (rc != 0) {
printf("test_diagnostics_invariants failed: %d\n", rc);
return 1;
}
printf("solver-c tests passed\n");
return 0;
}