Skip to content

Select condensed species by phase component - #169

Merged
djbower merged 1 commit into
mainfrom
djbower/phase_components
Oct 27, 2026
Merged

djbower merged 1 commit into
mainfrom
djbower/phase_components

Conversation

@djbower

@djbower djbower commented Oct 27, 2026

Copy link
Copy Markdown
Collaborator

Stage 2 of the species-naming work, following #168. This adds a way to select condensed species by phase component (in the Holland and Powell sense: the gas, liquid or mineral that a set of data refers to). The old interface (_s species, PurePhase.from_species, create_condensed(..., state=...)) is unchanged. Migrating usages (stage 3) and removing the old interface (stage 4) will follow in separate PRs.

New interface

components_of("SiO2")  # ("quartz-alpha", "quartz-beta", "cristobalite-beta", "liquid")

PurePhase.from_formula("SiO2")      # O2Si_cd: all condensed phase components, stitched in order of temperature
PurePhase.from_components(("quartz-alpha", "quartz-beta"), name="quartz")   # O2Si_quartz
PurePhase.from_component("cristobalite-beta")       # O2Si_cristobalite-beta
PurePhase.from_component("liquid", formula="H2O")   # H2O_l ("liquid" is shared, so the formula is needed)
PurePhase.from_component("diamond")                 # C_diamond

Each method takes an optional database=; without it, the default database is used. The logic lives on DataBase (condensed_from_formula, condensed_from_components, condensed_from_component and components_of), and the PurePhase methods call it.

Rules

Stitching is done on demand with stitch_glenn_properties from #168.

  • Only condensed phase components can be stitched. The gas raises an error.
  • All phase components must be of one formula. A mineral fixes the formula, so formula= is needed only for a set of shared names such as liquid.
  • Temperature ranges may not overlap or leave a gap. With the current data this affects only Fe2O3 (haematite overlaps the liquid), which waits on the source of the data.
  • Several phase components can be stitched only if they all come from a data file (packaged, or GlennDataBase.from_file) and have no volume model. A single phase component can come from anywhere, including add_species, and keeps its volume model. So from_formula("C") gives graphite with its volume, and diamond can only be selected on its own.

Implementation

  • The reader builds a table keyed by Hill formula and then phase component: read_glenn_phase_components and glenn_phase_components. The name-keyed data are made from the same table, so existing lookups are unchanged.
  • DataBase keeps this table, plus a table of the phase components added with add_species.
  • The default database now gives C_graphite the graphite volume, as default_properties already does.
  • A custom DataBase subclass must call super().__init__().

Tests

test_phase_components (tests/test_database.py) checks:

  • O2Si_cd matches O2Si_s at 1000 K and O2Si_l at 2500 K.
  • C_cd matches C_s at 10⁴ bar, including the volume.
  • The database without the graphite volume gives a different result.
  • The names that each method gives.
  • Each rule raises.

Full suite: 243 passed. Pyright and the docs build (-W) pass.

🤖 Generated with Claude Code

The reader builds the data of each phase component, keyed by Hill formula and then phase
component, and the name-keyed data are made from it. DataBase keeps this table, plus the
phase components added with add_species, and creates condensed species from them:

- condensed_from_formula: all condensed phase components from a data file, stitched in order
  of temperature (e.g. O2Si_cd, quartz to cristobalite to liquid)
- condensed_from_components: a chosen set stitched, named with a required suffix
- condensed_from_component: one phase component, which keeps any volume model
- components_of: the condensed phase components of a formula from a data file

PurePhase.from_formula, from_components and from_component wrap these, with an optional
database (the default database otherwise). Only phase components from a data file can be
stitched together; added ones (e.g. diamond) are selected on their own. The default database
now also gives C_graphite its volume. A custom DataBase subclass calls super().__init__().

The old interface (_s, from_species) is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.83333% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
atmodeller/database.py 94.44% 4 Missing ⚠️
atmodeller/thermodata/janaf.py 96.96% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@djbower
djbower merged commit 1fb22b2 into main Oct 27, 2026
5 checks passed
@djbower
djbower deleted the djbower/phase_components branch October 27, 2026 11:25
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.

1 participant