bloc.cfd_pathlines#

CFD pathline post-processing: RTD, temperature histories, chemistry replay, and particle analysis.

Submodules#

Classes#

ChemistryReplay

Replay chemical kinetics along CFD temperature-time histories.

PathlineDataset

CFD pathline dataset loaded from a comment-annotated CSV file.

Functions#

plot_particles(replay, nobili_diameters_csv[, ...])

Post-process a Nobili mechanism replay to produce particle figures.

plot_rtd(dataset[, ax, bins, kde, color])

Plot the residence time distribution of the CFD pathlines.

plot_temperature_histories(dataset[, ax, path_ids, ...])

Plot temperature vs. time for all (or selected) pathlines.

Package Contents#

class bloc.cfd_pathlines.ChemistryReplay(dataset, mechanism, label='')#

Replay chemical kinetics along CFD temperature-time histories.

Parameters:
  • dataset – Loaded pathline dataset. The initial species composition at step=0 of each path is used as the inlet condition.

  • mechanism – Path to a Cantera YAML mechanism file.

  • label – Human-readable label for this replay (used in plots).

Raises:

FileNotFoundError – If the mechanism file does not exist.

label#
run()#

Integrate kinetics for every path.

The Cantera Solution, Reactor, and ReactorNet are created once and reused across all paths — only the gas state is reset between paths, avoiding repeated mechanism parsing and preconditioner setup.

Returns:

Per-path DataFrames with columns time_s, T_K, and X_<species> for every species in the mechanism.

Return type:

dict[int, pd.DataFrame]

classmethod from_csv(dataset, mechanism, csv_dir, label='')#

Load replay results from previously saved CSV files instead of running.

Expects one path_{pid}.csv file per path in csv_dir, as written by save_results().

Parameters:
  • dataset – The pathline dataset this replay belongs to (used for metadata).

  • mechanism – Path to the Cantera mechanism file (used for labelling and species lookup in plots).

  • csv_dir – Directory containing the path_{pid}.csv files.

  • label – Human-readable label. Defaults to the mechanism stem.

Returns:

Instance with results already populated — no need to call run().

Return type:

ChemistryReplay

Raises:

FileNotFoundError – If csv_dir does not exist or contains no path_*.csv files.

save_results(output_dir)#

Write per-path replay results to CSV files.

One file per path, named path_{pid}.csv, placed in output_dir (created if it does not exist). Each file has the same columns as the DataFrames returned by run(): time_s, T_K, and X_<species> for every species in the mechanism.

Parameters:

output_dir – Directory to write CSV files into.

Returns:

Paths of the written files, sorted by path id.

Return type:

list[Path]

Raises:

RuntimeError – If run() has not been called yet.

property results: dict[int, pandas.DataFrame]#

Replay results; call run() first.

Raises:

RuntimeError – If run() has not been called yet.

plot_species_comparison(cfd_dataset, species, path_ids=None, figsize=None)#

Plot CFD mole fractions vs. replayed mole fractions per species.

Each path gets a distinct color from the tab20 colormap. CFD curves use solid lines; replay curves use dashed lines. One subplot per species.

Parameters:
  • cfd_dataset – The source pathline dataset (CFD values).

  • species – Species names to compare (Cantera names, no X_ prefix).

  • path_ids – Subset of path ids to include. Defaults to all.

  • figsize – Figure size override.

Raises:

RuntimeError – If run() has not been called yet.

class bloc.cfd_pathlines.PathlineDataset(path)#

CFD pathline dataset loaded from a comment-annotated CSV file.

The CSV header contains # key: value lines that carry simulation metadata (solver, pressure, mechanism, …). The body holds one row per (path_id, step) with columns: time_s, T_K, r_mm, velocity components, and X_<species> mole fractions.

Parameters:

path – Path to the pathline CSV file.

Raises:

ValueError – If required metadata fields are missing or n_paths in the header does not match the number of unique path ids in the data.

property metadata: dict[str, str]#

Raw metadata parsed from the # key: value header lines.

property cfd_mechanism: str#

Mechanism name reported by the CFD simulation.

property pressure_Pa: float#

Operating pressure [Pa].

property uniform_distribution: bool#

Whether pathlines represent a statistically uniform inlet sample.

property n_paths: int#

Number of particle paths.

property species_names: list[str]#

Species names extracted from X_* columns (Cantera-compatible).

property paths: dict[int, pandas.DataFrame]#

Per-path DataFrames, keyed by path_id.

get_path(path_id)#

Return the DataFrame for a single path.

Parameters:

path_id – Integer path identifier.

Raises:

KeyError – If path_id does not exist in the dataset.

exit_times()#

Return the exit times for each path.

bloc.cfd_pathlines.plot_particles(replay, nobili_diameters_csv, residence_times_s=None, path_ids=None)#

Post-process a Nobili mechanism replay to produce particle figures.

Converts mole fractions from replay to number concentrations [#/cm³] using the ideal gas law, then calls bloc.chem.nobili functions to compute particle size distributions and aggregate statistics.

Three figures are returned:

  • "avg_diameter": number-weighted average primary particle diameter vs. time for each path.

  • "psd_aggregate": aggregate particle size distribution dN/dlogD at each requested residence time.

  • "npp_per_aggregate": average number of primary particles per aggregate vs. time.

Parameters:
  • replay – A completed ChemistryReplay (run() must have been called). The mechanism must be a Nobili-compatible one (BIN species present).

  • nobili_diameters_csv – Path to Nobili2024_particle_diameters.csv, which contains the bin, Dpp_m, npp, dcollision_m, and mass_kg columns used by bloc.chem.nobili.

  • residence_times_s – Specific residence times [s] at which to evaluate the aggregate particle size distribution. Defaults to the median exit time.

  • path_ids – Subset of path ids to include. Defaults to all paths in the replay.

Returns:

Keyed by "avg_diameter", "psd_aggregate", "npp_per_aggregate".

Return type:

dict[str, plt.Figure]

Raises:
  • RuntimeError – If replay.run() has not been called.

  • FileNotFoundError – If nobili_diameters_csv does not exist.

bloc.cfd_pathlines.plot_rtd(dataset, ax=None, bins=20, kde=True, color='#2196F3')#

Plot the residence time distribution of the CFD pathlines.

Each path’s residence time is taken as its final time_s value. When uniform_distribution is False in the dataset metadata, a warning annotation is added stating that the sample is not statistically representative of the inlet.

Parameters:
  • dataset – Loaded pathline dataset.

  • ax – Existing axes to draw on. A new figure is created when None.

  • bins – Number of histogram bins.

  • kde – Overlay a kernel density estimate when True.

  • color – Bar and KDE line color.

Returns:

The matplotlib figure.

Return type:

plt.Figure

bloc.cfd_pathlines.plot_temperature_histories(dataset, ax=None, path_ids=None, alpha_individual=0.6)#

Plot temperature vs. time for all (or selected) pathlines.

Each path is drawn in the same tab20 color used by chemistry replay plots so paths can be identified across figures.

Parameters:
  • dataset – Loaded pathline dataset.

  • ax – Existing axes to draw on. A new figure is created when None.

  • path_ids – Subset of path ids to plot. Defaults to all paths.

  • alpha_individual – Opacity for individual path lines.

Returns:

The matplotlib figure.

Return type:

plt.Figure