Skip to content

Test drying energy rate basis#116

Merged
bernalde merged 4 commits into
fix/issue-21-drying-gas-mass-ratefrom
fix/issue-48-drying-energy-rate-basis
Jul 16, 2026
Merged

Test drying energy rate basis#116
bernalde merged 4 commits into
fix/issue-21-drying-gas-mass-ratefrom
fix/issue-48-drying-energy-rate-basis

Conversation

@Mazhar331

@Mazhar331 Mazhar331 commented Jul 13, 2026

Copy link
Copy Markdown

Summary

  • Add a focused Drying unit_model regression that drives the real energy-balance call path.
  • Verify molar drying rates are converted component-wise to mass rates before the gas sensible-heat and condensed latent-heat terms consume them.
  • Pin independently derived gas and condensed temperature-rate results while leaving issue High: [Drying] Condensed-phase energy balance doubles latent heat #24's separate latent-heat multiplier unchanged.

Refs #21, #24, #48, #108.

Acceptance Criteria

Dimensional Analysis

  • get_drying_rate: mol/m^3/s.
  • PR Fix drying gas mass-rate balance #108 conversion: (mol/m^3/s) * (kg/mol) = kg/m^3/s.
  • Sensible term: (J/kg/K) * K * (kg/m^3/s) = J/m^3/s.
  • Latent term: (kg/m^3/s) * (J/kg) = J/m^3/s.

Coordination Notes

Tests

  • conda run -n pharmapy python -m pytest tests/test_drying_model.py tests/test_drying_energy_rate_basis.py -q — 5 passed.
  • conda run -n pharmapy python -m pytest tests/ -m "not assimulo" — 33 passed, 12 deselected.
  • conda run -n pharmapy python -m pytest tests/ -m assimulo — 12 passed, 33 deselected.
  • Red check on exact origin/master (1a3ab31) — failed as expected: gas energy rates were about 27 times the mass-basis expectations.

Branch Hygiene

@Mazhar331 Mazhar331 marked this pull request as ready for review July 13, 2026 16:13

@Mazhar331 Mazhar331 left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Maintainer review. I am the PR author, so GitHub only allows a COMMENT review from this account; this is not a formal approval. mergeStateStatus is CLEAN and reviewDecision is empty (the branch has no protection reporting a review gate), so no maintainer approval is being demanded by live GitHub state.

The change is a single new focused regression test (tests/test_drying_energy_rate_basis.py, +99), no production code touched. It is correct, well-scoped, and genuinely guards issue #48.

What I verified

  • Changed-file set matches gh pr diff --name-only (one new test file). Merge-base is beb53e4, exactly the base tip / PR #108 head.
  • Expected values are independent literals, hand-checked against the code, not recomputations of production expressions:
    • mass conversion mol/m^3/s * (MW/1000) = kg/m^3/s → rates [0.036, 0, 0.184], [0.054, 0, 0.230].
    • gas sensible cpg*(Tg-295)*sum(m_dot) = [1100, 3408]; denom_gas = cvg*eps*rho = [450, 1100]dTg/dt = [1100/450, 3408/1100].
    • condensed latent sum(m_dot_i * L_i * 2) = [512000, 676000]; denom_cond = 900000dTcond/dt = [-512000/900000, -676000/900000].
  • Mutation check: deleting the _drying_rate_mass_basis call in unit_model (the pre-#108 / issue #48 defect) makes the test fail — gas rate 66.67 vs expected 2.44 (≈27×), matching the PR's "about 27 times" red-check claim. The test is a real regression guard, not vacuously green.
  • Test lanes reproduce the PR body exactly: -m "not assimulo" → 33 passed, 12 deselected; -m assimulo → 12 passed, 33 deselected; targeted test_drying_model.py + test_drying_energy_rate_basis.py → 5 passed.
  • The * 2 latent factor is pinned and documented as owned by #24; the test correctly characterizes current behavior rather than changing it. Keeping this a focused unit test (rather than an end-to-end run that would assert #24's unstable multiplier) is the right call.
  • Working tree clean after runs; only gitignored .pyc artifacts generated.

Nonblocking

  • The production fix for #48 (the dry_rate * MW / 1000 conversion at Drying_Model.py:287) lives in PR #108, which is the base of this stacked PR — this PR's own diff contains only the test. Closes #48 therefore only takes effect once the stack reaches master, and #48 is not actually "resolved with regression coverage" from #116's diff alone. The body already documents the stacking and the manual-close caveat, so this is fine as-is; just confirm the intended close ownership between #108 (fix) and #116 (test) so #48 is neither closed prematurely by #108 nor left dangling.
  • The fixture uses number_nodes == num_volatiles == 2. In energy_balance the latent term broadcasts latent_heat (per-node in the real model) against dry_rate[:, idx_volatiles] (per-volatile columns); with both dims equal to 2 the test cannot distinguish per-node from per-component latent semantics. This does not weaken the #48 guard (the mutation check moves both gas and condensed rates ≈27×, and the sensible term via dry_rate.sum is unambiguous), and the underlying broadcasting shape in energy_balance:410 is pre-existing and out of scope here. Worth a note only if a future change makes nodes ≠ volatiles.

Summary

  • Blocking: none.
  • Nonblocking: Closes #48 close-ownership across the #108/#116 stack; nodes == volatiles == 2 fixture coincidence in the latent term.
  • Questions: none.
  • Tests run: targeted drying tests (5 passed), not assimulo lane (33 passed), assimulo lane (12 passed), and a mutation check confirming the test fails without the mass conversion. All green.
  • Merge-readiness: content is ready on the merits. It targets the non-default base fix/issue-21-drying-gas-mass-rate and is stacked on PR #108, so #108 must land (and this PR be retargeted to master) before merge and before #48 auto-closes. This author COMMENT does not satisfy any branch-protection approval that may apply after those gates clear.

@Mazhar331

Copy link
Copy Markdown
Author

Addressed the review feedback for head d02a597.

Changes made:

Commits pushed: none. This was a metadata-only correction; repository content and head SHA are unchanged.

Verification on the unchanged head:

  • Core tests: pass.
  • Assimulo integration tests: pass.
  • Prior local checks remain applicable: 5 focused drying tests, 33 core tests, and 12 Assimulo-marked tests passed.

Intentionally not changed:

No unresolved inline threads exist, so no thread replies were required. reviewDecision remains empty; the remaining merge dependency is PR #108.

@Mazhar331

Copy link
Copy Markdown
Author

Addressed the latent-heat fixture-shape review note on head cb18bc6.

Changes made:

  • Added commit cb18bc6 (Clarify drying energy test shape).
  • Changed tests/test_drying_energy_rate_basis.py from 2 nodes / 2 volatiles to 3 nodes / 2 volatiles.
  • Kept latent_heat as a length-2 vector and added a short comment that those values are per volatile component, not per node.
  • Updated the third row's hand-computed expected gas and condensed temperature rates.

Why this is OK for the current PR:

Verification:

  • conda run -n pharmapy python -m pytest tests/test_drying_energy_rate_basis.py -q -> 1 passed.
  • conda run -n pharmapy python -m pytest tests/test_drying_model.py tests/test_drying_energy_rate_basis.py -q -> 5 passed.
  • conda run -n pharmapy python -m pytest tests/ -m "not assimulo" -> 33 passed, 12 deselected.
  • conda run -n pharmapy python -m pytest tests/ -m assimulo -> 12 passed, 33 deselected.
  • GitHub Actions on cb18bc6: Core tests and Assimulo integration tests both passed.

No unresolved inline review threads exist. reviewDecision remains empty and mergeStateStatus is CLEAN; the remaining stack dependency is still PR #108.

@Mazhar331

Copy link
Copy Markdown
Author

Coordination follow-up for the latent-heat shape note:

@Mazhar331

Copy link
Copy Markdown
Author

Read-only resolution check of my earlier maintainer review (COMMENT on head d02a597), now re-verified against current head cb18bc6 and cross-checked with the coordination notes on this PR and on #101.

Both review findings addressed

Verification performed (read-only)

  • test_drying_energy_rate_basis.py at head cb18bc6 → 1 passed; test_drying_model.py + test_drying_energy_rate_basis.py → 5 passed.
  • Re-ran the mutation check at the 3-node head (scratch copy, real checkout untouched): deleting the _drying_rate_mass_basis conversion makes the test fail with gas rates [66.7, 87.3, 96.4] vs expected [2.44, 3.10, 3.54] (≈27×). The test still genuinely guards issue High: [Drying] Energy terms multiply molar drying rates by mass-basis heat quantities #48 after the fixture change.
  • No approval gate: master is unprotected (protection endpoint 404), reviewDecision empty, mergeStateStatus: CLEAN. No inline review threads exist. The only remaining merge dependency is PR Fix drying gas mass-rate balance #108 (currently CHANGES_REQUESTED against master).

Coordination notes are consistent and technically accurate

The note on #101 (gh-coord:source-pr=116) and its backlink here are mutually cross-linked and correctly scoped. I verified its technical claim against the source:

One follow-up for #101 (not blocking #116)

This PR's getHeatVaporization stub is a 1-D per-component vector, which is a simplification of the real multi-temperature return (a 2-D (num_nodes, num_volatiles) array today, (num_nodes, num_components) after #101). When #101 changes the consumer to latent_heat[:, self.idx_volatiles], indexing this 1-D stub with [:, idx_volatiles] will raise, so #101's Drying-consumer audit should explicitly update this existing test's stub to 2-D, not only add a new nodes != volatiles case. Recording so the coupling isn't lost.

Assessment

All review feedback on #116 is resolved at head cb18bc6. The fixture change is test-only and stays within the exact scope my finding anticipated, so no new automated review round is warranted. Merge-readiness is unchanged: content is ready, gated only on PR #108 landing and this PR being retargeted to master.

@Mazhar331 Mazhar331 requested review from andres9403 and bernalde July 13, 2026 19:53
Comment thread tests/test_drying_energy_rate_basis.py
@Mazhar331

Copy link
Copy Markdown
Author

Addressed the latest review feedback on head cf940d9.

Changes made:

  • Added commit cf940d9 (Document drying energy test units).
  • Added a module-level description to tests/test_drying_energy_rate_basis.py explaining that the test is a compact synthetic Drying.unit_model regression, not a full solve_unit drying example.
  • Documented that no checked-in PharmaPy example currently constructs an end-to-end Drying run from full phase/cake classes.
  • Added bracketed unit annotations throughout the test fixture and assertions: dimensionless fractions/indices, pressure, length, heat capacity, viscosity, latent heat, drying rate, state layout, and expected temperature rates.

Verification:

  • conda run -n pharmapy python -m pytest tests/test_drying_energy_rate_basis.py -q -> 1 passed.
  • conda run -n pharmapy python -m pytest tests/test_drying_model.py tests/test_drying_energy_rate_basis.py -q -> 5 passed.
  • conda run -n pharmapy python -m pytest tests/ -m "not assimulo" -> 33 passed, 12 deselected.
  • conda run -n pharmapy python -m pytest tests/ -m assimulo -> 12 passed, 33 deselected.
  • GitHub Actions on cf940d9: Core tests and Assimulo integration tests both passed.

The inline review thread has been replied to. reviewDecision still reports CHANGES_REQUESTED until the reviewer updates or dismisses that review. The remaining stack dependency is still PR #108.

@Mazhar331

Copy link
Copy Markdown
Author

Addressed the corrected end-to-end Drying test rationale on head 0010799.

Changes made:

Why no full class-style solve_unit example is added here:

Verification:

  • conda run -n pharmapy python -m pytest tests/test_drying_energy_rate_basis.py -q -> 1 passed.
  • conda run -n pharmapy python -m pytest tests/test_drying_model.py tests/test_drying_energy_rate_basis.py -q -> 5 passed.
  • GitHub Actions on 0010799: Core tests and Assimulo integration tests both passed.

The inline review thread has been replied to. reviewDecision still reports CHANGES_REQUESTED until the reviewer updates or dismisses that review.

@Mazhar331

Copy link
Copy Markdown
Author

Read-only review-resolution check of @bernalde's CHANGES_REQUESTED review, verified against current head 0010799f (commits cf940d9, 0010799f).

Comment-by-comment status

@bernalde's inline thread on tests/test_drying_energy_rate_basis.py (still isResolved: false) had three asks:

What this pass did not change

reviewDecision is CHANGES_REQUESTED from @bernalde, a different reviewer than the PR author. GitHub does not clear that gate when the comments are addressed — it stays until @bernalde submits a new review or dismisses the prior one; the PR author cannot clear another reviewer's CHANGES_REQUESTED. @bernalde has not re-reviewed since the cf940d9/0010799f fixes. mergeStateStatus is CLEAN (no conflicts), but the review gate blocks merge.

The only substantively open item is the end-to-end example, which was deferred rather than added. The rationale is factually accurate (all cited blockers verified OPEN), but whether the documented deferral is acceptable — versus requiring an example in this PR — is @bernalde's decision, not something the author can self-resolve.

Assessment

  • Documentation asks: addressed at head.
  • End-to-end example: reasonably deferred with a sound, verifiable rationale; awaiting @bernalde's accept/reject.
  • No new automated review round is warranted (the fixes are documentation plus a semantically-inert fixture reformat, within the scope of the original comment).
  • Next step is a human one: @bernalde to re-review 0010799f and either accept the deferral (dismiss or submit a fresh review to release the gate) or state that an end-to-end example must land in this PR.

Verification-only pass; no code, reviews, or thread states were modified.

@Mazhar331 Mazhar331 requested a review from bernalde July 15, 2026 18:37
@bernalde bernalde merged commit 158213d into fix/issue-21-drying-gas-mass-rate Jul 16, 2026
2 checks passed
@bernalde bernalde deleted the fix/issue-48-drying-energy-rate-basis branch July 16, 2026 11:51
@Mazhar331

Copy link
Copy Markdown
Author

Coordination note from PR #119 / issue #81:

The end-to-end Drying example/test discussed on this PR should remain deferred until the open Drying correctness work is solved and merged. PR #119 fixes #81's gas-velocity, gas-source holdup, and single-node initialization defects, but a realistic Drying.solve_unit transient still depends on the rest of the drying correctness cluster.

Before turning the class/Purdue-style example into an integration assertion, wait for #21 / PR #108, #24, #28, #37, #42, #81 / PR #119, and #101 to land. Until then, PR #116's focused unit_model -> energy_balance regression is the right level of coverage for #48.

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.

2 participants