API Reference

Core Pipeline

Shared evaluation pipeline.

Stages: applicability → evaluate → uncertainty → rank → confidence → explain → report.

htcie.core.pipeline.run_evaluation(state, registry)[source]

Run the full evaluation pipeline and return a serializable HtcieReport.

Applies applicability filters, evaluates each eligible correlation, computes per-correlation uncertainty bands, ranks results, computes confidence, builds explanation, and packages the result as a complete audit object.

Parameters:
Returns:

HtcieReport if at least one method is applicable, else None.

Return type:

HtcieReport | None

Canonical engineering state models and derived dimensionless groups.

class htcie.core.state.BoundaryConditions(*, boundary_type, wall_temperature=None, bulk_temperature=None)[source]

Thermal boundary conditions at the heat-transfer surface.

The boundary_type distinguishes between isothermal (UWT) and isoflux (UHF) conditions, which affects the fully-developed Nusselt number for laminar flow (3.66 vs 4.36) and the exponent n in Dittus-Boelter (0.3 vs 0.4). Providing wall_temperature and bulk_temperature allows the Dittus-Boelter exponent to be selected automatically based on heating or cooling.

Parameters:
  • boundary_type (Literal['constant_wall_temperature', 'constant_heat_flux'])

  • wall_temperature (float | None)

  • bulk_temperature (float | None)

boundary_type: Literal['constant_wall_temperature', 'constant_heat_flux']
bulk_temperature: float | None
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

wall_temperature: float | None
class htcie.core.state.EngineeringState(*, fluid, geometry, boundary, flow)[source]

Canonical engineering state for a single-phase forced-convection problem.

This is the single object passed through every layer of the pipeline. It combines fluid properties, geometry, boundary conditions, and flow state, and exposes all derived dimensionless groups as computed fields so that domain evaluators never recompute them independently.

Computed fields (read-only):

  • reynolds: \(Re = \rho V L / \mu\) (\(L\) = hydraulic_diameter if set, else characteristic_length)

  • prandtl: \(Pr = c_p \mu / k\)

  • relative_roughness: \(\varepsilon / D_h\), or None if hydraulic_diameter is absent

  • graetz: \(Gz = Re \cdot Pr \cdot (D_h / L)\), or None if developing_length is absent

  • entry_length_ratio: \(x/D = L_{dev} / D_h\), or None

  • pitch_ratio_transverse: \(S_T / D\), or None for non-tube-bank geometries

  • pitch_ratio_longitudinal: \(S_L / D\), or None for non-tube-bank geometries

Parameters:
boundary: BoundaryConditions
property entry_length_ratio: float | None

Dimensionless entry length \(x/D = L_{dev} / D_h\).

flow: FlowState
fluid: FluidProperties
geometry: Geometry
property graetz: float | None

Graetz number \(Gz = Re \cdot Pr \cdot (D_h / L)\) for thermally developing flow.

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property pitch_ratio_longitudinal: float | None

Longitudinal pitch ratio \(S_L / D\) = pitch_longitudinal / characteristic_length.

property pitch_ratio_transverse: float | None

Transverse pitch ratio \(S_T / D\) = pitch_transverse / characteristic_length.

property prandtl: float

Prandtl number \(Pr = c_p \mu / k\).

property relative_roughness: float | None

Relative roughness \(\varepsilon / D_h\) = roughness / hydraulic_diameter.

Returns None when hydraulic_diameter is not specified. Used by the Petukhov friction-factor formula (smooth tube assumed when absent).

property reynolds: float

Reynolds number \(Re = \rho V L / \mu\).

Uses hydraulic_diameter as the length scale when set, falling back to characteristic_length. This matches the convention used by all internal and external convection correlations in the registry.

validate_tube_bank_fields()[source]
Return type:

EngineeringState

class htcie.core.state.FlowState(*, velocity, mass_flow_rate=None, developing_length=None)[source]

Flow conditions at the inlet or representative cross-section.

velocity is the bulk mean (average) velocity used to compute Re. For tube-bank problems it represents the maximum velocity in the narrowest cross-section. developing_length enables Graetz-number and entry-length corrections in laminar correlations (Shah, Churchill-Ozoe).

Parameters:
  • velocity (float)

  • mass_flow_rate (float | None)

  • developing_length (float | None)

developing_length: float | None
mass_flow_rate: float | None
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

velocity: float
class htcie.core.state.FluidProperties(*, density, viscosity, thermal_conductivity, heat_capacity, wall_viscosity=None)[source]

Thermophysical properties of the working fluid at bulk conditions.

All properties are assumed constant (evaluated at bulk temperature) unless wall_viscosity is provided, in which case the viscosity-ratio correction can be applied by eligible correlations (Sieder-Tate, Žukauskas).

Parameters:
density: float
heat_capacity: float
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

thermal_conductivity: float
viscosity: float
wall_viscosity: float | None
class htcie.core.state.Geometry(*, geometry_type, characteristic_length, hydraulic_diameter=None, roughness=0.0, pitch_transverse=None, pitch_longitudinal=None, arrangement=None)[source]

Geometric description of the heat-transfer surface.

The characteristic_length drives the Reynolds number when hydraulic_diameter is not provided. For circular tubes, set both characteristic_length and hydraulic_diameter to the inner diameter D. For tube banks, pitch fields are required to determine the inline/staggered arrangement.

Parameters:
  • geometry_type (Literal['circular_tube', 'cylinder_crossflow', 'flat_plate', 'tube_bank'])

  • characteristic_length (float)

  • hydraulic_diameter (float | None)

  • roughness (float)

  • pitch_transverse (float | None)

  • pitch_longitudinal (float | None)

  • arrangement (Literal['inline', 'staggered'] | None)

arrangement: Literal['inline', 'staggered'] | None
characteristic_length: float
geometry_type: Literal['circular_tube', 'cylinder_crossflow', 'flat_plate', 'tube_bank']
hydraulic_diameter: float | None
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

pitch_longitudinal: float | None
pitch_transverse: float | None
roughness: float

Correlation metadata loading and validation.

class htcie.core.registry.CorrelationMetadata(*, key, family, title, output, formula_latex='', flow_regime='all', boundary_conditions=<factory>, required_inputs=<factory>, validity=<factory>, literature_uncertainty_pct=None, assumptions=<factory>, source=<factory>, notes=<factory>)[source]

Metadata for a single heat-transfer correlation loaded from a YAML file.

Variables:
  • key (str) – Dot-namespaced identifier, e.g. "internal.gnielinski".

  • family (str) – Domain family, e.g. "convection_internal".

  • title (str) – Human-readable name including author and year.

  • output (str) – Physical quantity produced (typically "Nu").

  • formula_latex (str) – LaTeX string of the primary correlation formula.

  • flow_regime (str) – Applicable regime: "laminar", "turbulent", "transitional_turbulent", or "all".

  • boundary_conditions (list[str]) – List of applicable boundary condition types, e.g. ["constant_wall_temperature", "constant_heat_flux"].

  • required_inputs (list[str]) – Dimensionless groups or inputs required by the correlation, e.g. ["Reynolds", "Prandtl"].

  • validity (dict[str, Any]) – Dict of bounds used for applicability filtering, e.g. {"re_min": 3000, "re_max": 5000000, "geometry_type": "circular_tube"}.

  • literature_uncertainty_pct (float | None) – Stated accuracy from the source publication, in percent, or None if not reported.

  • assumptions (list[str]) – List of stated assumptions (smooth tube, fully developed flow, etc.) for traceability.

  • source (dict[str, Any]) – Bibliographic reference dict with keys authors, year, title, journal, doi.

  • notes (list[str]) – List of implementation or usage notes for this correlation.

Parameters:
assumptions: list[str]
boundary_conditions: list[str]
family: str
flow_regime: str
formula_latex: str
key: str
literature_uncertainty_pct: float | None
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

notes: list[str]
output: str
required_inputs: list[str]
source: dict[str, Any]
title: str
validity: dict[str, Any]
class htcie.core.registry.CorrelationRegistry[source]

In-memory store of correlation metadata loaded from YAML files.

Load the registry once at startup via load_from_dir(), then pass it to the pipeline or individual engines. The registry is intentionally stateless after loading — all correlation definitions live in data/correlations/ YAML files, not in Python code.

all()[source]

Return all loaded correlations in insertion order.

Return type:

list[CorrelationMetadata]

by_family(family)[source]

Return all correlations in the given family.

Parameters:

family (str)

Return type:

list[CorrelationMetadata]

families()[source]

Return sorted list of unique families.

Return type:

list[str]

get(key)[source]

Return metadata for key, raising KeyError if not found.

Parameters:

key (str)

Return type:

CorrelationMetadata

load_from_dir(path)[source]

Recursively load all *.yaml files from path into the registry.

Files are processed in sorted order so loading is deterministic. Each file must contain a single YAML document that validates against CorrelationMetadata.

Parameters:

path (str | Path) – Root directory containing correlation YAML files (may be nested in subdirectories).

Raises:

pydantic.ValidationError – If a YAML file fails schema validation.

Return type:

None

Deterministic ranking and scoring v1 for correlation candidates.

class htcie.core.ranking.RankedCandidate(key, score, breakdown, weights_version)[source]

A scored, ranked correlation candidate.

Variables:
  • key (str) – Correlation key (e.g. “internal.gnielinski”).

  • score (float) – Total weighted score (higher = better recommendation).

  • breakdown (dict[str, float]) – Per-factor scores before weighting.

  • weights_version (str) – ScoringWeightsV1.version used.

Parameters:
breakdown: dict[str, float]
key: str
score: float
weights_version: str
class htcie.core.ranking.RankingEngine(weights=None)[source]

Scores and ranks applicable correlation candidates using scoring v1.

Parameters:

weights (ScoringWeightsV1 | None)

rank(state, methods)[source]

Return methods sorted by descending score.

Parameters:
Return type:

list[RankedCandidate]

class htcie.core.ranking.ScoringWeightsV1(*, version='v1.1', validity=0.3, geometry=0.2, regime=0.15, boundary=0.1, corrections=0.1, pedigree=0.0, uncertainty=0.15, extrapolation=0.3)[source]

Versioned scoring weights for htcie ranking v1.1.

All factor weights sum to 1.0 (excluding extrapolation which is a penalty subtracted from the total).

v1.1 changes vs v1:

  • uncertainty raised from 0.05 to 0.15 — primary source-quality signal.

  • pedigree lowered from 0.10 to 0.00 — redundant when uncertainty is properly weighted. The _pedigree() function is retained for potential future reactivation with a non-year-based signal.

Parameters:
boundary: float
corrections: float
extrapolation: float
geometry: float
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

pedigree: float
regime: float
uncertainty: float
validity: float
version: str

Uncertainty, confidence, and extrapolation heuristics.

class htcie.core.uncertainty.UncertaintyEngine[source]

Computes per-correlation uncertainty bands from stated literature uncertainty.

The band is a flat ±p% interval around the computed heat transfer coefficient h, where p = literature_uncertainty_pct from the YAML metadata. The band is suppressed (h_low=None, h_high=None) when operating outside the correlation’s validity range, when the stated uncertainty is not physically meaningful, or when the evaluated value is non-positive.

compute(state, evaluations, methods)[source]

Return one UncertaintyResult per evaluation, in the same order.

Parameters:
  • state (EngineeringState) – Current engineering state.

  • evaluations (list[EvaluationResult]) – Evaluated correlation results.

  • methods (list[CorrelationMetadata]) – Correlation metadata for applicable correlations.

Returns:

List of UncertaintyResult objects, length equals len(evaluations).

Return type:

list[UncertaintyResult]

class htcie.core.uncertainty.UncertaintyResult(key, value, h, uncertainty_pct, h_low, h_high, extrapolated, note)[source]

Per-correlation uncertainty band result.

Variables:
  • key (str) – Correlation key matching EvaluationResult.key.

  • value (float) – Evaluated Nu (same as EvaluationResult.value).

  • h (float) – Heat transfer coefficient Nu × k / L_char [W/m²·K].

  • uncertainty_pct (float | None) – Stated literature uncertainty in percent, or None.

  • h_low (float | None) – h × (1 - pct/100), or None when band is suppressed.

  • h_high (float | None) – h × (1 + pct/100), or None when band is suppressed.

  • extrapolated (bool) – True when Re or Pr is outside the validity range.

  • note (str) – Empty string when band is valid; reason string when suppressed or clamped.

Parameters:
extrapolated: bool
h: float
h_high: float | None
h_low: float | None
key: str
note: str
uncertainty_pct: float | None
value: float
htcie.core.uncertainty.confidence_class(spread_summary, extrapolation_warnings=None)[source]

Classify confidence as ‘high’, ‘medium’, or ‘low’.

Parameters:
  • spread_summary (dict) – Output of summarize_spread().

  • extrapolation_warnings (list[str] | None) – Optional list of extrapolation warning strings. Warnings produced by extrapolation_status() embed the ratio as ‘ratio X.XX’; ratios >= 1.2 indicate significant extrapolation.

Returns:

spread < 5% AND no extrapolation warnings. ‘medium’: spread < 15% OR mild extrapolation (max ratio < 1.2). ‘low’: spread >= 15% OR significant extrapolation (max ratio >= 1.2).

Return type:

‘high’

htcie.core.uncertainty.extrapolation_status(state, method)[source]

Return extrapolation details for one method vs. the current state.

Parameters:
Returns:

  • extrapolated: True if Re or Pr is outside the valid range.

  • re_fraction: ratio measuring how far Re is outside range — re/re_max if above, re_min/re if below, 1.0 if within. None when the correlation has no Re bounds.

  • pr_fraction: same logic for Pr. None when no Pr bounds.

  • warnings: human-readable warning strings, one per violated bound.

Return type:

dict with keys

htcie.core.uncertainty.summarize_spread(results)[source]

Compute inter-method spread statistics over a set of evaluation results.

Returns:

  • count: number of results

  • mean: arithmetic mean of the output values

  • stdev: population standard deviation \(\sigma\)

  • relative_spread: \(\sigma / \bar{x}\) (coefficient of variation), or None if mean is zero

Return type:

dict with keys

Parameters:

results (list[EvaluationResult])

Structured explanation builder for htcie evaluation results.

class htcie.core.explain.Explanation(best_method, best_score, score_breakdown, why_applicable, why_others_excluded, key_assumptions, confidence_class, extrapolation_warnings, recommendation_note)[source]

Structured explanation of an htcie evaluation result.

Variables:
  • best_method (str) – Key of the top-ranked correlation.

  • best_score (float) – Numeric score of the top-ranked correlation.

  • score_breakdown (dict[str, float]) – Per-factor scores for the best method.

  • why_applicable (list[str]) – Reasons why the best method was applicable. Currently a single-item list populated by build_explanation() with a generic sentence covering Re, Pr, and geometry.

  • why_others_excluded (list[tuple[str, str]]) – List of (key, reason) tuples for excluded methods.

  • key_assumptions (list[str]) – Key assumptions of the best method.

  • confidence_class (str) – “high”, “medium”, or “low”.

  • extrapolation_warnings (list[str]) – List of extrapolation warning strings.

  • recommendation_note (str) – One-sentence recommendation summary.

Parameters:
best_method: str
best_score: float
confidence_class: str
extrapolation_warnings: list[str]
key_assumptions: list[str]
recommendation_note: str
score_breakdown: dict[str, float]
to_text()[source]

Return a human-readable multi-line explanation.

Sections are rendered in this order:

  1. Recommended method name and score

  2. Per-factor score breakdown (always present)

  3. Confidence class

  4. Extrapolation warnings (omitted when empty)

  5. Key assumptions (omitted when empty)

  6. Excluded methods with reasons (omitted when empty)

  7. One-sentence recommendation note

Returns:

Newline-joined string suitable for printing or embedding in a Markdown code block.

Return type:

str

why_applicable: list[str]
why_others_excluded: list[tuple[str, str]]
htcie.core.explain.build_explanation(best, best_meta, excluded, confidence, extrapolation_warnings)[source]

Build a structured Explanation from pipeline evaluation components.

Parameters:
Returns:

Populated Explanation including the recommendation note and up to three key assumptions from the best method’s metadata.

Return type:

Explanation

htcie.core.explain.explain_recommendation(best)[source]

Return a plain-text summary of the top-ranked candidate.

This is a lightweight alternative to build_explanation() for callers that only need the method key, total score, and factor breakdown as text — without constructing an Explanation object. Used by api/main.py and cli/main.py where the full structured explanation is not required.

Parameters:

best (RankedCandidate) – Top-ranked candidate from RankingEngine.

Returns:

Multi-line string with the method key, total score, and per-factor breakdown.

Return type:

str

Reports

HtcieReport — the full audit object for one evaluation run.

HtcieReport is the single output of run_evaluation. It captures every decision made by the pipeline so the result is fully reproducible and auditable without re-running the engine.

Use HtcieReport.to_dict() to obtain a JSON-serialisable dict, or pass the report to the serializer helpers in htcie.reports.serializers to write JSON, Markdown, or HTML files.

class htcie.reports.schema.HtcieReport(*, engine_version=<factory>, timestamp=<factory>, input_state, derived, applicable, excluded, evaluations, ranking, spread, confidence, warnings=<factory>, explanation, scoring_weights_version)[source]

Complete, serializable audit record of one htcie evaluation.

Every field is included so the report is self-contained — no external state is required to re-interpret the output.

Complex field shapes:

  • derived — dimensionless groups computed from the state: reynolds, prandtl, graetz, entry_length_ratio, pitch_ratio_transverse, pitch_ratio_longitudinal. Fields that are not applicable for the geometry (e.g. graetz for external flow) are None.

  • evaluations — one entry per applicable correlation, each a dict with key, value (Nu), metadata, uncertainty_pct, h, h_low, h_high, and uncertainty_note.

  • excluded — one entry per filtered-out correlation: {"key": str, "reason": str}.

  • ranking — correlations sorted by descending score, each entry {"key": str, "score": float, "breakdown": dict[str, float]}.

  • spread — inter-method statistics: count, mean, stdev, relative_spread.

Parameters:
applicable: list[str]
confidence: str
derived: dict[str, Any]
engine_version: str
evaluations: list[dict[str, Any]]
excluded: list[dict[str, str]]
explanation: Explanation
input_state: EngineeringState
model_config = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

ranking: list[dict[str, Any]]
scoring_weights_version: str
spread: dict[str, Any]
timestamp: str
to_dict()[source]

Return a JSON-serialisable dict representation of this report.

The explanation sub-dict expands the Explanation dataclass inline. why_others_excluded is converted from a list of (key, reason) tuples to a list of {"key": ..., "reason": ...} dicts, and a rendered "text" key is added via to_text().

Return type:

dict[str, Any]

warnings: list[str]

Serialization helpers for writing an HtcieReport to disk.

Three formats are supported:

All three formats are derived from to_dict(). The to_dict() function is provided as a convenience alias for callers that want the dict without writing a file.

htcie.reports.serializers.dump_html_report(report, path)[source]

Render report as self-contained HTML and write it to path.

Delegates to save_html(). The renderer is imported lazily to avoid a circular import between the serializers and renderer modules.

Parameters:
Return type:

None

htcie.reports.serializers.dump_json_report(report, path)[source]

Write report as indented JSON to path.

Accepts either an HtcieReport (converted via to_dict()) or a plain dict (written as-is). The plain-dict path is useful when the caller has already called to_dict() and wants to add or strip fields before writing.

Parameters:
  • report (dict[str, Any] | HtcieReport) – Report object or pre-serialised dict.

  • path (str | Path) – Destination file path. Parent directory must exist.

Return type:

None

htcie.reports.serializers.dump_markdown_report(report, path)[source]

Render report as Markdown and write it to path.

Parameters:
Return type:

None

htcie.reports.serializers.to_dict(report)[source]

Return the JSON-serialisable dict for report.

Thin alias for to_dict() provided so callers can use a consistent functional style (to_dict(report)) alongside the three dump_* helpers without holding a method reference.

Parameters:

report (HtcieReport)

Return type:

dict[str, Any]

Jinja2-based HTML renderer for HtcieReport.

A single Jinja2 Environment (_ENV) is created once at module import time and reused for all render calls. The environment loads the report.html.j2 template from the templates/ directory co-located with this module and enables auto-escaping for HTML files.

The template receives the output of to_dict() — a plain dict — not the HtcieReport object itself. This keeps the template decoupled from the Pydantic model and ensures the rendered output matches exactly what dump_json_report would write.

htcie.reports.renderer.render_html(report, charts=None)[source]

Render report as a self-contained HTML string.

Calls to_dict() and passes the resulting plain dict to the report.html.j2 Jinja2 template. The output includes inline CSS and no external dependencies.

Parameters:
  • report (HtcieReport) – A fully populated HtcieReport.

  • charts (dict[str, str] | None) – Optional dict of pre-rendered Plotly HTML fragments keyed by "ranking" and "uncertainty". When provided, the charts are embedded in the report. Omit (or pass None) for chart-free output suitable for programmatic use.

Returns:

UTF-8 HTML string suitable for writing to a .html file.

Return type:

str

htcie.reports.renderer.save_html(report, path)[source]

Render report as HTML and write it to path.

Charts are not embedded — the output is equivalent to calling render_html(report, charts=None). To embed Plotly charts, call render_html() directly with a charts dict and write the returned string yourself.

Parameters:
  • report (HtcieReport) – A fully populated HtcieReport.

  • path (str | Path) – Destination file path. Parent directory must exist.

Return type:

None