Conversation
|
5 minute Kaibel MINLP reformulation campaign after the Hull vapor-pressure evaluation fix. Command: /home/bernalde/.pixi/bin/pixi run gdplib-benchmark run --cases-file /tmp/kaibel_issue68_minlp_5min.csv --run-id issue68_kaibel_minlp_5min_after_hullfix_20260512 --no-skip-existing --no-summaryCampaign result: 6 result rows, 0 benchmark failures. This is the main improvement from the latest fix: the Hull reformulations no longer fail in Pyomo/GAMS expression evaluation.
Model sizes from the result JSON:
Bottom line: the Hull expression-evaluation blocker is fixed, so all three Hull solver settings now run through the benchmark path. It does not yet push the best feasible incumbent forward in 5 minutes. The only clear feasible integer incumbent in this campaign is Big-M/DICOPT at Generated artifacts were left under ignored benchmark output paths:
|
|
5 minute GDPOpt campaign for Kaibel after the Hull/GAMS expression fixes, excluding complete enumeration. Command: /home/bernalde/.pixi/bin/pixi run gdplib-benchmark run --cases-file /tmp/kaibel_issue68_gdpopt_no_enum_5min.csv --run-id issue68_kaibel_gdpopt_no_enum_5min_20260512 --no-skip-existing --no-summaryCase file used the local GDPOpt GAMS role stack:
Campaign result: 4 result rows, 0 benchmark failures.
Bottom line: yes, GDPOpt helps this instance. Without enumeration, LOA/RIC pushed the best feasible incumbent to Generated artifacts were left under ignored benchmark output paths:
|
|
Follow-up on the GDPOpt benchmark interpretation: the The contradiction is real:
For a minimization problem, a feasible incumbent at What appears to be happening:
Corrected interpretation of the no-enumeration GDPOpt run:
|
|
Follow-up on the GDPOpt/GLOA contradiction: I instrumented the 5-minute Kaibel GLOA run to map the generated affine cut that caused the premature certificate. Findings:
Conclusion: the GLOA |
|
Follow-up on whether Pyomo/pyomo#3939 explains the Kaibel GLOA failure: Yes, it appears to address the invalid GLOA certificate we observed here. The failing Kaibel row was a generated GLOA convex affine cut: Default GLOA produced the false certificate: That happened after the discrete master declared the generated affine cut infeasible and GDPOpt exited through "bounds have converged or crossed." I ran a local control monkeypatch matching the fix proposed in Pyomo #3939: build the concave lower cut with This does not make Kaibel globally solved in 5 minutes. It changes the result from an invalid certificate to a conservative open-gap result. The best 5-minute feasible incumbent from the no-enumeration GDPOpt campaign remains the LOA/RIC point: So for this PR, the Kaibel model fix is still valid, but the GLOA benchmark should be interpreted as affected by upstream Pyomo GLOA cut generation until Pyomo #3939 is fixed. |
9dfc324 to
43c235c
Compare
|
Heads up from PR #102: while wrapping up the pandemic PR after the base update, I ran the repository Black check/fix and it touched Relevant commits on #102: This may be relevant when rebasing or reviewing this Kaibel PR so the formatting noise is not mistaken for part of the Kaibel model fix. |
bernalde
left a comment
There was a problem hiding this comment.
Maintainer review of head 43c235c.
The math is equivalence-preserving. Multiplying the Raoult constraints through by P (with P in [1.05, 1.2] > 0) and expressing the 1.5 power as tc_gap*sqrt(tc_gap) with new bounded auxiliaries Tr and TcGap is algebraically equivalent to the base form, and the bounds are exact interval images of monotone maps over T in [Tlo, Tup], so nothing feasible is cut. Physically the sqrt singularity at 0 is unreachable: min TC = 512.6 K (methanol) against Tup ≈ 415–420 K keeps TcGap's lower bound ≈ 0.17. The new tests/test_kaibel.py is genuine — the hull/GAMS-writer test zeroes disaggregated variables and evaluates every active constraint body, which raises on base (TC/T division at T=0) and passes at head.
Findings:
Question: feasible-region widening — total_flow_max = max(flow_max, max Ltotal0, max Vtotal0) raises the Vtotal/Ltotal upper bound from 1000 to 1600 mol/s so the initialization fits inside bounds. This enlarges the feasible region relative to the published benchmark, so optimal objectives may not be comparable across gdplib versions. Was relaxing the bound intended, versus scaling the initial totals down to respect the original flow_max? If intended, record it in the model README or module docstring.
Nonblocking: stale size report — gdplib/kaibel/model_size_report.md is untouched but now stale: the PR adds 800 continuous variables (Tr, TcGap: 2 x 4 sections x 25 trays x 4 components) and 800 constraints. Regenerate the per-model size report (and the root README table row) with generate_model_size_report.py.
Nonblocking: naming/docs — m.Tr is documented as "Reduced temperature term" but is TC/T, the inverse reduced temperature; and the model-level constraint names _reduced_temperature_term/_critical_temperature_gap carry leading underscores, unconventional for public Pyomo components. Fix the docstrings at minimum; renaming the components is optional.
Nonblocking: xor no-op wording — xor=True is Pyomo's default; the body presents "declares tray disjunctions as XOR" as part of the fix, which overstates a no-op. Keep the explicitness, correct the narrative.
Issue linkage: issue #68's seven-strategy checklist is unchecked and the issue targets the defunct benchmark_zd branch. This PR fixes the hull/GAMS-writer blocker with smoke coverage but does not demonstrate the full matrix; treat "Closes #68" as Refs #68 unless the remaining checklist is explicitly superseded.
Summary — Blocking: 0. Nonblocking: 3. Questions: 1. Tests: static verification of the algebra, bound images, and physical data ranges; CI is green at this head (6/6 checks). Merge-ready once the size report is regenerated and the bound-widening question is answered. Posting as COMMENT (author account); the main ruleset requires one approving review from another maintainer.
|
Addressed the review of head 43c235c in commit 73a98f0:
Note on the edit hygiene: the model file has mixed line endings on main; the address commit preserves the original per-line endings, so the diff is the 12-line semantic change only. Issue linkage reminder from the review stands: treat Tests: |
|
Correction to the previous address pass (supersedes the regeneration claim in the comment above): the first regeneration ran on this branch's pre-pandemic checkout, so it reproduced the old README table format and made the PR CONFLICTING against main's rewritten table — the exact hand-merge trap flagged on PR #140. Fixed in commits 7e3373f (append-only merge of origin/main) and 9c62d3f: the table is now regenerated on the merged tree, so the kaibel columns update inside main's current table with the pandemic/grid/multiperiod_blending columns preserved. |
Summary
Tests run
pixi run pytest tests/test_kaibel.py -v --tb=short-> 5 passedpixi run pytest tests/test_module_imports.py -v --tb=short-> 68 passedpixi run test-> 289 passed, 1 skippedpixi run lint-> exit 0; Black clean, critical flake8 count 0, broader flake8 statistics are existing exit-zero findings, typos cleangit diff --checkandgit diff --cached --check-> passedpixi run gdplib-benchmark run --cases-file /tmp/kaibel_issue68_hull_eval_fix.csv --run-id issue68_kaibel_hull_eval_fix2_20260512 --no-skip-existing --no-summary-> 1 result row, 0 failures;gdp.hull/gams-local/DICOPT reached GAMS and returnedintermediateNonIntegerunder the 60 s limit with objective/upper bound151820.17183655952Notes
pixi.lockwas left unstaged as environment churn.Closes #68