Skip to content

feat: #1030 - Add GasData conversion utilities from_species() and to_species()#1036

Merged
Gorkowski merged 2 commits intouncscode:mainfrom
Gorkowski:issue-1030-adw-1955660d
Feb 3, 2026
Merged

feat: #1030 - Add GasData conversion utilities from_species() and to_species()#1036
Gorkowski merged 2 commits intouncscode:mainfrom
Gorkowski:issue-1030-adw-1955660d

Conversation

@Gorkowski
Copy link
Collaborator

Target Branch: main

Fixes #1030 | Workflow: 1955660d

Summary

Adds bidirectional conversion utilities between the existing GasSpecies class and the new GasData container. This enables gradual migration from the behavior-rich GasSpecies to the data-only GasData representation, supporting multi-box CFD simulations while maintaining backward compatibility.

The key challenge addressed is unit conversion: GasSpecies stores concentration in kg/m³ while GasData uses molecules/m³, requiring Avogadro's number for conversion.

What Changed

New Components

  • particula/gas/gas_data.py - Added from_species() and to_species() conversion functions (~175 LOC)

Modified Components

  • particula/gas/__init__.py - Exported from_species and to_species in __all__

Tests Added/Updated

  • particula/gas/tests/gas_data_test.py - Added 13 comprehensive test cases across 3 test classes:
    • TestFromSpecies (4 tests): single/multi-species conversion, n_boxes replication, unit conversion verification
    • TestToSpecies (6 tests): single/multi-species conversion, box_index selection, error handling for strategy mismatch, out-of-range box_index, and mixed partitioning
    • TestRoundTrip (3 tests): single/multi-species round-trip preservation, different partitioning values

How It Works

The conversion utilities bridge the gap between GasSpecies (with vapor pressure strategies) and GasData (data-only):

┌─────────────────┐                      ┌─────────────────┐
│   GasSpecies    │                      │    GasData      │
│  (with vapor    │    from_species()    │  (data-only,    │
│   pressure      │ ──────────────────▶  │   batched)      │
│   strategies)   │                      │                 │
│                 │    to_species()      │  concentration: │
│ concentration:  │ ◀────────────────── │  molecules/m³   │
│ kg/m³           │  + vapor_pressure    │  (n_boxes,      │
│                 │    strategies        │   n_species)    │
└─────────────────┘                      └─────────────────┘

Unit Conversion (Avogadro's Number):
─────────────────────────────────────
from_species: molecules/m³ = (kg/m³ ÷ kg/mol) × Avogadro
to_species:   kg/m³ = (molecules/m³ × kg/mol) ÷ Avogadro

from_species(species, n_boxes=1):

  • Extracts name, molar_mass, concentration, partitioning from GasSpecies
  • Converts concentration from kg/m³ → molecules/m³
  • Handles both single-species (scalars) and multi-species (arrays)
  • Replicates concentration across n_boxes for multi-box simulations

to_species(data, vapor_pressure_strategies, box_index=0):

  • Recreates GasSpecies from GasData for a single box
  • Requires vapor pressure strategies (GasData is data-only)
  • Validates strategy count matches n_species
  • Validates box_index is in range
  • Validates uniform partitioning (GasSpecies limitation)
  • Converts concentration from molecules/m³ → kg/m³

Implementation Notes

  • Why separate functions: Keeps GasData as a pure data container without behavior dependencies
  • TYPE_CHECKING imports: Used to avoid circular imports while maintaining type hints
  • Partitioning limitation: to_species() raises ValueError for mixed partitioning because GasSpecies.append() requires uniform partitioning across all species
  • Multi-species construction: Uses += operator to build multi-species GasSpecies, matching existing API patterns

Testing

  • Unit tests: 13 new tests covering all acceptance criteria
  • Round-trip verification: Confirms data preservation within floating-point precision (rtol=1e-10)
  • Error handling: Tests for ValueError (strategy mismatch, mixed partitioning) and IndexError (invalid box_index)
  • Manual verification: Pytest passes with all 508 tests in gas_data_test.py

Add from_species() and to_species() functions for converting between
GasSpecies and GasData containers:

- from_species(): Converts GasSpecies to GasData with batch dimension
  support, transforming concentration from kg/m³ to molecules/m³
- to_species(): Converts GasData back to GasSpecies for a single box,
  requiring vapor pressure strategies since GasData is data-only

Key features:
- Handle both single and multi-species conversions
- Support n_boxes replication in from_species()
- Validate strategy count and box_index in to_species()
- Error on mixed partitioning (GasSpecies requires uniform)

Includes 13 comprehensive tests covering:
- Single/multi-species conversions
- Unit conversion verification
- Box index selection
- Error handling for mismatched inputs
- Round-trip data preservation

Closes uncscode#1030

ADW-ID: 1955660d
- Fixed line length violations (E501) in error messages
- Fixed mypy type errors for names variable type inference
- Extracted f-string expressions to local variables for line length

This commit fixes validation gaps found in issue uncscode#1030.

Closes uncscode#1030

ADW-ID: 1955660d
@Gorkowski Gorkowski added agent Created or managed by ADW automation blocked Blocked - review required before ADW can process labels Feb 3, 2026
@Gorkowski Gorkowski merged commit b85bc37 into uncscode:main Feb 3, 2026
7 checks passed
@Gorkowski Gorkowski deleted the issue-1030-adw-1955660d branch February 3, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Created or managed by ADW automation blocked Blocked - review required before ADW can process

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[E3-F2-P3] Add GasData conversion utilities from_species() and to_species()

1 participant