Skip to content

Fix VaporPhase mass-basis latent heat weighting - #100

Merged
bernalde merged 1 commit into
masterfrom
fix/issue-18-vapor-enthalpy-mass-basis
Jul 8, 2026
Merged

Fix VaporPhase mass-basis latent heat weighting#100
bernalde merged 1 commit into
masterfrom
fix/issue-18-vapor-enthalpy-mass-basis

Conversation

@andres9403

Copy link
Copy Markdown
Collaborator

Summary

  • Fix VaporPhase.getEnthalpy(basis="mass") so the per-species J/kg latent heat term is weighted by mass fractions.
  • Preserve the existing mole-basis weighting and the total_h=False per-species return path.
  • Add a regression test with two species of very different molecular weights that verifies mass-basis/mole-basis consistency.

Closes #18

Tests

  • pytest tests/test_phases_vapor_enthalpy.py
  • pytest tests/ -m "not assimulo"
  • pytest tests/ --collect-only -q
  • git -c core.whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol diff --cached --check

Assimulo-marked integration tests were not run locally because Assimulo is not installed in this environment; the CI workflow runs that marker group separately.

Branch Hygiene

  • Base branch: master
  • Source branch point: origin/master at 1c3a046fceb5c4da8b5fdb6e8b254f657d6e3cc7
  • Upstream status: origin/master includes upstream/master at 400e1e13ad4ecd3ba202d5fae8c70ec73bdf9c3e
  • Stacked status: not stacked; no prerequisite PRs
  • Note: an old remote branch named fix-issue18-latent-heat-weighting exists at an ancestor of current origin/master and has no PR; this PR uses a fresh focused branch.

@andres9403
andres9403 marked this pull request as ready for review July 7, 2026 17:51

@andres9403 andres9403 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainer review — PR #100 (VaporPhase mass-basis latent heat weighting)

Reviewed at head 56c6835. The change correctly resolves issue #18: in VaporPhase.getEnthalpy, the per-species J/kg latent-heat term is now weighted by mass fractions when basis='mass' and by mole fractions otherwise, instead of using mole_frac unconditionally.

What I verified

  • Fix matches the diagnosis. PharmaPy/Phases.py:732-733 selects frac = mass_frac if basis == 'mass' else mole_frac, exactly the fix recommended in the issue audit and the independent Codex verification. mass_frac/mole_frac are both resolved earlier (lines 687-693), so the mass branch is always defined.
  • Mole-basis path unchanged. The else branch still uses mole_frac; the total_h=False per-species path (hVap = hSens + deltaVap) is untouched. All existing callers in Evaporators.py/Extractors.py pass basis='mole' explicitly and are unaffected.
  • Regression test is meaningful. tests/test_phases_vapor_enthalpy.py uses two species of disparate MW (18 vs 100), equimolar, and independently recomputes the expected mass- and mole-basis mixture enthalpies plus the basis-invariance identity h_mass == h_mole * 1000 / mw_av, and checks the per-species path for both bases. I confirmed it is genuinely red on the pre-fix code shape (1.51e6 vs expected 9.46e5 J/kg) and green after the fix — it locks in the behavior rather than passing vacuously.
  • Docstring cleanup fixes the he default is True typo and documents the basis parameter, consistent with the signature default ('mass').

Tests run locally (Python 3.10, numpy 1.26.4)

  • pytest tests/test_phases_vapor_enthalpy.py → 1 passed
  • pytest tests/ -m "not assimulo" → 28 passed, 6 deselected
  • Temporary revert of the one-line fix → target test fails as expected, then restored
  • Working tree clean; no stray artifacts. Assimulo-marked tests not run (Assimulo not installed locally; CI runs that marker group).

Findings

Nonblocking — pre-existing multi-temperature mass-basis shape mismatch (out of scope).
Not introduced by this PR, but adjacent to the changed line: in getHeatVaporization the basis='mass' branch reindexes deltahvap to only the subcritical columns (deltahvap[:, idx] / self.mw[idx]), reducing its second dimension from num_comp to len(idx). When any species is supercritical, the subsequent np.dot(deltaVap, frac) in getEnthalpy would then mismatch the full-length frac vector. The tests here keep all species subcritical (350 K), so this path isn't exercised. Worth a follow-up issue; no change requested in this PR.

Merge-readiness

  • No blocking findings. Fix is correct, minimal, and covered by a regression test that fails without it.
  • mergeStateStatus: CLEAN.
  • This review is a COMMENT because I am the PR author — GitHub does not accept an APPROVE from the author account. If branch protection requires a formal approval, another eligible maintainer will need to provide it; live state does not currently report a REVIEW_REQUIRED gate.

@andres9403

Copy link
Copy Markdown
Collaborator Author

Addressed the review pass for PR #100.

Commits pushed:

  • None; the branch was already up to date at 56c68351166867a09d3cdae8eb11cf029303c61f.

Main changes made:

Verification:

  • Reproduced the follow-up behavior: getHeatVaporization(np.array([660.0, 680.0]), basis="mass") returns shape (2, 1) while the mole-basis path returns (2, 2), and getEnthalpy(..., basis="mass") raises ValueError: shapes (2,1) and (2,) not aligned.
  • pytest tests/test_phases_vapor_enthalpy.py -> 1 passed.

Comments intentionally not addressed in this PR:

Remaining gates:

  • Current PR head remains 56c68351166867a09d3cdae8eb11cf029303c61f.
  • No formal approval is present yet; the existing maintainer review is a COMMENT by the PR author account.

@andres9403

Copy link
Copy Markdown
Collaborator Author

Review-resolution verification — no further review round needed

Verified at head 56c6835 (read-only pass).

  • Inline review threads: none.
  • Review-body findings: one finding (multitemp-mass-getheatvap-shape), explicitly nonblocking and out of scope for this PR; correctly deferred to tracking issue High: [Phases] Multi-temperature VaporPhase mass-basis latent heat drops component columns #101 (OPEN). Not a declined blocking comment.
  • Core PR fix confirmed present at head: Phases.py still selects frac = mass_frac if basis == "mass" else mole_frac; regression test tests/test_phases_vapor_enthalpy.py present. No later commit reverted the fix.
  • CI: Core tests pass, Assimulo integration tests pass; mergeStateStatus: CLEAN.

Another review round is NOT justified — the only finding was nonblocking and deferred by the reviewer, and no behavior changed beyond the commented lines. No further agent review needed.

Remaining gate (governance, not a review comment): reviewDecision is empty — the only review is a COMMENT from the PR author account, so a formal APPROVE from a second eligible maintainer may be required if branch protection demands one.

@andres9403
andres9403 requested a review from bernalde July 7, 2026 19:34
@bernalde
bernalde merged commit 4098d77 into master Jul 8, 2026
2 checks passed
@bernalde
bernalde deleted the fix/issue-18-vapor-enthalpy-mass-basis branch July 8, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Critical: [Phases] VaporPhase mass-basis enthalpy weights latent heat by mole fraction

2 participants