bloc.chem.solid_carbon_threshold#

Mechanism-aware resolution of n_C_min, the solid-carbon carbon-count threshold.

The problem. bloc.chem.species.get_solid_carbon_species() decides whether a species counts as “solid carbon” two ways: by name (C(s), C(soot), …) OR by carbon count (n_C >= n_C_min). The right criterion depends entirely on which Cantera mechanism is loaded, and it isn’t always a plain carbon-count number:

  • A CRECK sectional-soot mechanism represents soot as BIN1, BIN2, … species with doubling carbon counts (20/40/80/160/…) – the threshold is really “which BIN index counts as solid”, which happens to translate to a carbon count once you know that mechanism’s bin sizes.

  • A small PAH-growth mechanism (KAUST, ABF/Khrabry, Caltech) has a genuine carbon-count cutoff with no BIN structure.

  • A mechanism with no PAH growth chemistry at all (Fincke_GRC, Kassel, Holmen) has no count-based rule whatsoever – only its named solid species (C(s), C(soot), …) are ever solid, however few carbons they carry.

Historically this was hand-typed per model YAML (settings.get_carbon_yield.n_C_min), and every place in the codebase that needed a value when it wasn’t set fell back to its own inconsistent hardcoded guess (80 in some places, 300 in others) – see issue #292 (spark-cleantech-l3/bloc#292), “n_C_min should be evaluated automatically from the Mechanism used”.

The fix. resolve_n_c_min() is the single entry point that replaces all of that guessing with one lookup, in order of precedence:

  1. An explicit override in the config always wins (an engineer’s deliberate choice for this run).

  2. A lookup by mechanism name in _SOLID_CARBON_RULES_BY_MECHANISM below – a plain dict of mechanism basename -> already-validated rule, one entry per mechanism file in data/mechanisms/. Each rule states its own kind of criterion explicitly (see _SOLID_CARBON_RULES_BY_MECHANISM’s docstring) instead of forcing everything through a single carbon-count number. This is just a dict; most calls resolve here.

  3. If the mechanism isn’t in the dict yet (a brand-new or not-yet-validated mechanism), auto_n_c_min() returns one conservative fallback value – and always warns that it’s a guess, so it gets noticed and someone adds a real entry to the dict above.

Why isn’t this just the dict, then? Two reasons the plain lookup alone doesn’t cover:

  • A brand-new mechanism has no dict entry yet. Without a fallback, every caller downstream would need its own “mechanism not found” handling (which is exactly the inconsistent-hardcoded-guess situation this module exists to remove). The fallback keeps that guess in one place, and loud enough that it doesn’t go unnoticed.

  • The explicit config override has to win over both. That precedence rule belongs in one function, not re-implemented at every call site.

So in practice this module is “a dict, plus a documented, visible answer for what happens on a dict miss” – not a fundamentally different kind of thing.

See PR#182 (spark-cleantech-l3/bloc#182), which set the CRECK convention (BIN3, i.e. n_C_min=80) this registry formalizes.

Classes#

NCMinResult

A resolved solid-carbon criterion for one mechanism, for traceability.

Functions#

registered_mechanisms()

Return a copy of the mechanism-basename -> resolved-criterion registry.

auto_n_c_min(*[, warn_on_guess])

Return the single conservative fallback for a mechanism not in the registry.

resolve_n_c_min([gas, config, mechanism, warn_on_guess])

Resolve the solid-carbon criterion to use, in order of precedence.

Module Contents#

class bloc.chem.solid_carbon_threshold.NCMinResult#

A resolved solid-carbon criterion for one mechanism, for traceability.

Parameters:
  • n_c_min (int or None) – Count-based threshold: any species with n_C >= n_c_min counts as solid, in addition to solid_species_names. None means there is no count-based rule at all for this mechanism – only solid_species_names matters (true for mechanisms with no PAH/soot continuum, e.g. Fincke_GRC: it has C(s)/C(soot) but nothing else worth calling “solid” by carbon count).

  • solid_species_names (tuple of str) – Named species that always count as solid, regardless of carbon count. Defaults to the same list bloc.chem.species.get_solid_carbon_species() itself defaults to; only overridden when a mechanism’s actual solid species differ (e.g. the Kassel/Holmen family only has C(s), not C(soot)).

  • source (str) – One of "explicit_override", "registry_basename", "structural_fallback".

  • note (str, optional) – Human-readable justification (empty for an explicit override, which needs no justification beyond “the engineer set it”).

Examples

See PAH size-dependent melting vs. mechanism solid-carbon thresholds., which overlays every registered mechanism’s resolved n_c_min against a PAH melting-point-vs-size phase diagram.

n_c_min: int | None#
source: str#
note: str = ''#
solid_species_names: tuple[str, Ellipsis] = ('C(s)', 'C(soot)', 'CSOLID', 'C(gr)')#
bloc.chem.solid_carbon_threshold.registered_mechanisms()#

Return a copy of the mechanism-basename -> resolved-criterion registry.

For introspection/reporting – e.g. comparing every registered mechanism’s threshold against reference data – without reaching into this module’s private _REGISTRY_BY_BASENAME.

Examples

Used by PAH size-dependent melting vs. mechanism solid-carbon thresholds. to overlay every registered mechanism’s threshold against a PAH melting-point-vs-size phase diagram.

bloc.chem.solid_carbon_threshold.auto_n_c_min(*, warn_on_guess=True)#

Return the single conservative fallback for a mechanism not in the registry.

Only reached when the mechanism isn’t in _SOLID_CARBON_RULES_BY_MECHANISM (see resolve_n_c_min()) – always warns that this is an unvalidated guess, so it gets noticed and someone adds a real, verified entry to the registry instead. This is a deliberately conservative fallback, not a substitute for registering a real mechanism.

Parameters:

warn_on_guess (bool, optional) – Set False to silence the “unvalidated guess” warning.

Return type:

NCMinResult

Examples

See PAH size-dependent melting vs. mechanism solid-carbon thresholds. for how the resolved threshold compares to a PAH melting-point-vs-size phase diagram.

bloc.chem.solid_carbon_threshold.resolve_n_c_min(gas=None, *, config=None, mechanism=None, warn_on_guess=True)#

Resolve the solid-carbon criterion to use, in order of precedence.

  1. An explicit settings.get_carbon_yield.n_C_min in config (dict-like or attrs-style) always wins – an engineer’s deliberate override.

  2. A registry hit by mechanism basename (mechanism, or gas.source).

  3. auto_n_c_min()’s single conservative fallback, loudly warned as an unvalidated guess – covers both an unregistered mechanism and a call with nothing to resolve against at all.

Parameters:
  • gas – A live Cantera Solution/SolutionArray to classify, if one is already built (avoids constructing one just to resolve a threshold).

  • config – A STONE config (dict or attrs-style) that may declare settings.get_carbon_yield.n_C_min.

  • mechanism – A bare mechanism name/path, used for registry lookup when gas isn’t available yet, or as a fallback identity when gas is given but its own .source doesn’t resolve to a recognized basename.

  • warn_on_guess – Passed through to auto_n_c_min(); set False to silence the “unvalidated guess” warning (e.g. in a tight loop that already warned once).

Return type:

NCMinResult

Examples

See PAH size-dependent melting vs. mechanism solid-carbon thresholds., which overlays every registered mechanism’s resolved n_C_min against a PAH melting-point-vs-size phase diagram.