fix HeatExchangerNetwork cache_network: keep stored order, match units by identity - #253
Open
sarangbhagwat wants to merge 1 commit into
Open
fix HeatExchangerNetwork cache_network: keep stored order, match units by identity#253sarangbhagwat wants to merge 1 commit into
sarangbhagwat wants to merge 1 commit into
Conversation
…s by identity `cache_network=True` was silently broken in two independent ways in `HeatExchangerNetwork._cost()`: 1. It never fired when auxiliary heat exchangers share IDs (the norm in biorefineries: several 'condenser'/'reboiler' units). The cache-hit test compared `sorted(hxs, key=ID)` of the current utilities (unit order) with the stored list (duty-sorted synthesis order); ties keep input order, so the two lists differed and the network was always re-synthesized. 2. When it did fire (unique IDs), it rebuilt `hxs` in unit order and paired `hxs[i]` with `stream_life_cycles[i]`, which `synthesize_network` built for the duty-sorted list. Each life cycle was seeded with the wrong stream. The final consistency check compared against the same wrongly paired unit, so it passed: every HXprocess ended with Q = 0, the heat utility ratio went to 1.0 and the incremental HX cost collapsed, with no warning (doctest system: 0.82 -> 1.00). Fix: treat the stored synthesis order as the source of truth. The cache-hit test compares identity sets of units (HeatUtility objects are recreated on every simulation, so the unit is the only stable key), and the cached branch iterates `self.original_heat_exchangers` in stored order, looking up each unit's live HeatUtility. All downstream index-based pairing is then correct by construction. Also: the bare `except:` around the cache consistency check now catches `AssertionError` and reports the reason, and `_energy_balance_error_contributions` no longer raises TypeError when `ignored is None`. Validation: new tests/test_hxn.py (cache fires and matches fresh synthesis on the doctest system, after a 1% feed perturbation, and with duplicate auxiliary IDs; `ignored=None` smoke test). On the sugarcane biorefinery with all 10 utility streams the cached HXN now runs in 0.11 s vs 0.31 s with identical results. Class doctest output unchanged. Full suite: same pre-existing failures as the recorded baseline plus test_tire_modeling, which fails identically on unmodified master (thermosteam-clone drift). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 23, 2026
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.
Problem
cache_network=TrueonHeatExchangerNetworkwas silently broken in two independent ways inHeatExchangerNetwork._cost():condenser/reboilerunits). The cache-hit test comparedsorted(hxs, key=ID)of the current utilities (unit order) with the stored list (duty-sorted synthesis order); ties keep input order, so the two lists differed and the network was re-synthesized every simulation.hxsin unit order and pairedhxs[i]withstream_life_cycles[i], whichsynthesize_networkbuilt for the duty-sorted list. Each life cycle was seeded with the wrong stream. The final consistency check compared against the same wrongly paired unit, so it passed: everyHXprocessended with Q = 0, the heat-utility ratio went to 1.0, and the incremental HX cost collapsed — with no warning (class doctest system: 0.82 → 1.00).Fix
Treat the stored synthesis order as the source of truth. The cache-hit test compares identity sets of units (
HeatUtilityobjects are recreated on every simulation, so the unit is the only stable key), and the cached branch iteratesself.original_heat_exchangersin stored order, looking up each unit's liveHeatUtility. All downstream index-based pairing is then correct by construction.Also:
except:around the cache consistency check now catchesAssertionErrorand reports the reason;_energy_balance_error_contributionsno longer raisesTypeErrorwhenignored is None.Validation
tests/test_hxn.py: the cache fires and matches fresh synthesis on the doctest system, after a 1 % feed perturbation, and with duplicate auxiliary IDs;ignored=Nonesmoke test.HeatExchangerNetworkclass doctest output unchanged.pytest . --disable-numba=1 -m "not slow"): same pre-existing failure set as on unmodifiedmaster(thermosteam/biorefineries stack drift, missing optional deps, tutorial notebooks); nothing new.🤖 Generated with Claude Code