Skip to content

Commit 5d2cdb5

Browse files
committed
docs(condensation): update latent heat plan status
Mark E5-F3 P1 in progress across dev plan docs and update public docs/readme to mention the CondensationLatentHeat scaffold and strategy resolution behavior. Expand the CondensationLatentHeat docstrings to describe inputs and stubbed method expectations. Closes #1139 ADW-ID: 72bc5e5e
1 parent 37208c0 commit 5d2cdb5

File tree

7 files changed

+109
-16
lines changed

7 files changed

+109
-16
lines changed

adw-docs/dev-plans/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ and rollout.
7676
- [E5-F2: Non-Isothermal Mass Transfer Functions][e5-f2] — Status: Planning
7777
- Scope: Thermal resistance factor and non-isothermal mass transfer rate
7878
pure functions with energy tracking.
79-
- [E5-F3: CondensationLatentHeat Strategy Class][e5-f3] — Status: Planning
79+
- [E5-F3: CondensationLatentHeat Strategy Class][e5-f3] — Status: In Progress
80+
(P1, #1139)
8081
- Scope: New condensation strategy with latent heat correction and energy
8182
diagnostics.
8283
- [E5-F4: Builder, Factory, and Exports][e5-f4] — Status: Planning

adw-docs/dev-plans/epics/E5-non-isothermal-condensation.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
**Owners**: @Gorkowski
66
**Start Date**: 2026-03-02
77
**Target Date**: TBD
8-
**Last Updated**: 2026-03-02
8+
**Last Updated**: 2026-03-04
99
**Size**: Medium (7 features, ~22 phases)
1010

1111
## Vision
@@ -233,6 +233,7 @@ L -> 0 as T -> T_c. Used in engineering thermodynamics and EOS-based models.
233233
### Feature E5-F3: `CondensationLatentHeat` Strategy Class
234234

235235
- [ ] **E5-F3-P1**: Create `CondensationLatentHeat` class skeleton with tests
236+
- Issue: #1139 | Size: M (~80 LOC) | Status: In Progress
236237
- File: `particula/dynamics/condensation/condensation_strategies.py` (extend
237238
existing file, currently 1699 lines with `CondensationStrategy` ABC,
238239
`CondensationIsothermal`, and `CondensationIsothermalStaggered`)
@@ -253,7 +254,8 @@ L -> 0 as T -> T_c. Used in engineering thermodynamics and EOS-based models.
253254
- Tests: `particula/dynamics/condensation/tests/
254255
condensation_strategies_test.py` (extend existing, currently 1655 lines)
255256
- Tests: instantiation with all param combos, strategy resolution priority,
256-
fallback to isothermal when L=0, type errors for bad inputs
257+
fallback to isothermal when L=0, logging for array/negative latent heat,
258+
stub methods raise `NotImplementedError`
257259

258260
- [ ] **E5-F3-P2**: Implement `mass_transfer_rate()` and `rate()` with tests
259261
- `mass_transfer_rate()` follows `CondensationIsothermal.mass_transfer_rate()`
@@ -620,3 +622,4 @@ class CondensationLatentHeat(CondensationStrategy):
620622
|------|--------|--------|
621623
| 2026-03-02 | Initial epic creation | ADW |
622624
| 2026-03-02 | Split E5-F1-P3 into P3 (builders) + P4 (factory+exports); split E5-F3-P3 into P3 (particle-resolved step) + P4 (discrete+continuous) + P5 (data-only parity); added missing details: function signatures, file references, thermal conductivity source, vapor_pressure_surface parameter, test tolerances, literature targets | ADW |
625+
| 2026-03-04 | Noted E5-F3-P1 issue #1139 and logging expectations | ADW |

adw-docs/dev-plans/features/E5-F3-condensation-latent-heat-strategy.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Feature E5-F3: CondensationLatentHeat Strategy Class
22

33
**Parent Epic**: [E5: Non-Isothermal Condensation with Latent Heat](../epics/E5-non-isothermal-condensation.md)
4-
**Status**: Planning
4+
**Status**: In Progress
55
**Priority**: P1
66
**Owners**: @Gorkowski
7-
**Start Date**: TBD
7+
**Start Date**: 2026-03-04
88
**Target Date**: TBD
9-
**Last Updated**: 2026-03-02
9+
**Last Updated**: 2026-03-04
1010
**Size**: Large (5 phases)
1111

1212
## Summary
@@ -105,7 +105,7 @@ additions:
105105
## Phase Checklist
106106

107107
- [ ] **E5-F3-P1**: Create `CondensationLatentHeat` class skeleton with tests
108-
- Issue: TBD | Size: M (~80 LOC) | Status: Not Started
108+
- Issue: #1139 | Size: M (~80 LOC) | Status: In Progress
109109
- File: `particula/dynamics/condensation/condensation_strategies.py` (extend
110110
existing file, currently 1699 lines)
111111
- Extends `CondensationStrategy` (inherits all base methods including
@@ -118,11 +118,14 @@ additions:
118118
1. If `latent_heat_strategy` provided -> use it directly
119119
2. Else if `latent_heat > 0` -> wrap in `ConstantLatentHeat(latent_heat)`
120120
3. Else (both zero/None) -> store None, behave as isothermal
121+
4. If `latent_heat` is array-like, log warning and fall back to None
122+
5. If `latent_heat` is negative, log warning and fall back to None
121123
- Instance attribute: `last_latent_heat_energy: float = 0.0` (diagnostic)
122124
- Tests: `particula/dynamics/condensation/tests/
123125
condensation_strategies_test.py` (extend existing, currently 1655 lines)
124126
- Tests: instantiation with all param combos, strategy resolution priority,
125-
fallback to isothermal when L=0, type errors for bad inputs
127+
fallback to isothermal when L=0, logging for array/negative latent heat,
128+
stub methods raise `NotImplementedError`
126129

127130
- [ ] **E5-F3-P2**: Implement `mass_transfer_rate()` and `rate()` with tests
128131
- Issue: TBD | Size: M (~100 LOC) | Status: Not Started
@@ -237,3 +240,4 @@ additions:
237240
| Date | Change | Author |
238241
|------|--------|--------|
239242
| 2026-03-02 | Initial feature document created from E5 epic | ADW |
243+
| 2026-03-04 | Marked P1 in progress for issue #1139 | ADW |

adw-docs/dev-plans/features/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ work, typically ~100 LOC per phase, that deliver user-facing functionality.
2828
|----|------|--------|----------|--------|
2929
| E5-F1 | [Latent Heat Strategy Pattern](E5-F1-latent-heat-strategy.md) | In Progress | P1 | 4 |
3030
| E5-F2 | [Non-Isothermal Mass Transfer Functions](E5-F2-non-isothermal-mass-transfer.md) | Planning | P1 | 3 |
31-
| E5-F3 | [CondensationLatentHeat Strategy Class](E5-F3-condensation-latent-heat-strategy.md) | Planning | P1 | 5 |
31+
| E5-F3 | [CondensationLatentHeat Strategy Class](E5-F3-condensation-latent-heat-strategy.md) | In Progress | P1 | 5 |
3232
| E5-F4 | [Builder, Factory, and Exports](E5-F4-builder-factory-exports.md) | Planning | P1 | 2 |
3333
| E5-F5 | [Validation and Integration Tests](E5-F5-validation-integration-tests.md) | Planning | P1 | 2 |
3434
| E5-F6 | [Documentation and Examples](E5-F6-documentation-examples.md) | Planning | P2 | 3 |

docs/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ Whether you’re a researcher, educator, or industry expert, Particula is design
2929
- **Building gas-phase properties** with builder/factory patterns (vapor
3030
pressure and latent heat) that support unit-aware setters and exports.
3131
- **Supporting non-isothermal condensation** with thermal resistance,
32-
latent-heat mass transfer rate utilities, and latent-heat energy release
33-
bookkeeping.
32+
latent-heat mass transfer rate utilities, latent-heat energy release
33+
bookkeeping, and the `CondensationLatentHeat` strategy scaffold
34+
(latent-heat strategy resolution with a constant fallback).
3435
- **Interrogating your experimental data** to validate and expand your impact.
3536
- **Fostering open-source collaboration** to share ideas and build on each other’s work.
3637

particula/dynamics/condensation/condensation_strategies.py

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,13 @@ class CondensationLatentHeat(CondensationStrategy):
17061706
"""Condensation strategy with latent heat configuration.
17071707
17081708
This class mirrors the base condensation setup while deferring the
1709-
non-isothermal mass-transfer implementation to later phases.
1709+
non-isothermal mass-transfer implementation to later phases. It resolves
1710+
latent heat either from a provided strategy or a scalar fallback value.
1711+
1712+
Attributes:
1713+
latent_heat_strategy_input: Strategy input provided at initialization.
1714+
latent_heat_input: Raw latent heat value provided at initialization.
1715+
last_latent_heat_energy: Diagnostic latent heat energy tracker.
17101716
"""
17111717

17121718
# pylint: disable=R0913, R0917
@@ -1726,7 +1732,22 @@ def __init__(
17261732
latent_heat_strategy: LatentHeatStrategy | None = None,
17271733
latent_heat: float | NDArray[np.float64] = 0.0,
17281734
):
1729-
"""Initialize the CondensationLatentHeat strategy."""
1735+
"""Initialize the CondensationLatentHeat strategy.
1736+
1737+
Args:
1738+
molar_mass: Molar mass of the species [kg/mol].
1739+
diffusion_coefficient: Diffusion coefficient [m^2/s].
1740+
accommodation_coefficient: Mass accommodation coefficient.
1741+
update_gases: Whether to update gas concentrations on update.
1742+
skip_partitioning_indices: Species indices that should skip
1743+
partitioning.
1744+
activity_strategy: Activity strategy used for ParticleData inputs.
1745+
surface_strategy: Surface strategy used for ParticleData inputs.
1746+
vapor_pressure_strategy: Vapor pressure strategy used for GasData
1747+
inputs.
1748+
latent_heat_strategy: Optional latent heat strategy to use.
1749+
latent_heat: Scalar latent heat fallback [J/kg].
1750+
"""
17301751
super().__init__(
17311752
molar_mass=molar_mass,
17321753
diffusion_coefficient=diffusion_coefficient,
@@ -1750,6 +1771,19 @@ def _resolve_latent_heat_strategy(
17501771
latent_heat_strategy: LatentHeatStrategy | None,
17511772
latent_heat: float | NDArray[np.float64],
17521773
) -> LatentHeatStrategy | None:
1774+
"""Resolve the latent heat strategy from inputs.
1775+
1776+
Prefers an explicit strategy, otherwise converts scalar latent heat
1777+
values into a constant strategy. Array-like or negative latent heat
1778+
values log a warning and fall back to isothermal behavior.
1779+
1780+
Args:
1781+
latent_heat_strategy: Optional strategy to use directly.
1782+
latent_heat: Scalar or array-like latent heat input [J/kg].
1783+
1784+
Returns:
1785+
Resolved latent heat strategy, or None for isothermal fallback.
1786+
"""
17531787
if latent_heat_strategy is not None:
17541788
return latent_heat_strategy
17551789

@@ -1779,7 +1813,23 @@ def mass_transfer_rate(
17791813
pressure: float,
17801814
dynamic_viscosity: Optional[float] = None,
17811815
) -> Union[float, NDArray[np.float64]]:
1782-
"""Return the mass transfer rate (stub)."""
1816+
"""Return the mass transfer rate (stub).
1817+
1818+
Args:
1819+
particle: Particle representation providing radius and activity
1820+
information.
1821+
gas_species: Gas species supplying vapor properties and
1822+
concentrations.
1823+
temperature: System temperature in Kelvin.
1824+
pressure: System pressure in Pascals.
1825+
dynamic_viscosity: Optional dynamic viscosity override.
1826+
1827+
Returns:
1828+
Mass transfer rate per particle and per species in kg/s.
1829+
1830+
Raises:
1831+
NotImplementedError: Implemented in E5-F3-P2/P3.
1832+
"""
17831833
raise NotImplementedError("Implemented in E5-F3-P2/P3")
17841834

17851835
def rate(
@@ -1790,7 +1840,23 @@ def rate(
17901840
pressure: float,
17911841
dynamic_viscosity: Optional[float] = None,
17921842
) -> NDArray[np.float64]:
1793-
"""Return the condensation rate (stub)."""
1843+
"""Return the condensation rate (stub).
1844+
1845+
Args:
1846+
particle: Particle representation providing radius and activity
1847+
information.
1848+
gas_species: Gas species supplying vapor properties and
1849+
concentrations.
1850+
temperature: System temperature in Kelvin.
1851+
pressure: System pressure in Pascals.
1852+
dynamic_viscosity: Optional dynamic viscosity override.
1853+
1854+
Returns:
1855+
Condensation rate per particle and per species in kg/s.
1856+
1857+
Raises:
1858+
NotImplementedError: Implemented in E5-F3-P2/P3.
1859+
"""
17941860
raise NotImplementedError("Implemented in E5-F3-P2/P3")
17951861

17961862
def step(
@@ -1804,5 +1870,20 @@ def step(
18041870
) -> (
18051871
Tuple[ParticleRepresentation, GasSpecies] | Tuple[ParticleData, GasData]
18061872
):
1807-
"""Advance one condensation step (stub)."""
1873+
"""Advance one condensation step (stub).
1874+
1875+
Args:
1876+
particle: Particle representation to update.
1877+
gas_species: Gas species object providing vapor properties.
1878+
temperature: System temperature in Kelvin.
1879+
pressure: System pressure in Pascals.
1880+
time_step: Integration timestep in seconds.
1881+
dynamic_viscosity: Optional dynamic viscosity override.
1882+
1883+
Returns:
1884+
Tuple containing updated particle and gas species objects.
1885+
1886+
Raises:
1887+
NotImplementedError: Implemented in E5-F3-P2/P3.
1888+
"""
18081889
raise NotImplementedError("Implemented in E5-F3-P2/P3")

readme.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ particula/
9797
`particula.dynamics.get_thermal_resistance_factor`,
9898
`particula.dynamics.get_mass_transfer_rate_latent_heat`, and
9999
`particula.dynamics.get_latent_heat_energy_released`
100+
- **Condensation Strategies**`CondensationIsothermal` plus the
101+
`CondensationLatentHeat` scaffold (latent-heat strategy resolution with a
102+
constant fallback; rate/step implementation pending)
100103
- **Latent Heat Factories** — Build constant, linear, and power-law latent heat
101104
strategies via `particula.gas.LatentHeatFactory` with unit-aware builders and
102105
gas-phase exports for upcoming non-isothermal workflows

0 commit comments

Comments
 (0)