bloc.runner#

BlocRunner — BoulderRunner subclass with Bloc-specific normalisation.

All Bloc Python code that previously called Boulder free functions directly now goes through BlocRunner. This means:

  • Mechanism normalisation and deprecated-key rejection live in one place.

  • Mechanism path resolution lives on BlocConverter.resolve_mechanism.

  • Schema lookups (report_metadata, schema_entry) trigger registration of Bloc reactor kinds into Boulder’s global _SCHEMA_REGISTRY on demand.

Classes#

BlocRunner

Orchestrator for the full YAML-to-SimulationResult pipeline, Bloc flavour.

Module Contents#

class bloc.runner.BlocRunner(config, *, plugins=None, config_path=None)#

Bases: boulder.runner.BoulderRunner

Orchestrator for the full YAML-to-SimulationResult pipeline, Bloc flavour.

Differences from BoulderRunner:

  • Uses BlocConverter as the converter.

  • normalize rejects deprecated mechanism_reac / mechanism_torch keys.

  • report_metadata and schema_entry ensure Bloc reactor schemas are registered in Boulder’s global _SCHEMA_REGISTRY before lookup.

converter_class#
classmethod load(path)#

Load raw config with Bloc from: inheritance resolved.

Bloc YAML files may use a from: <parent>.yaml key for STONE overlay inheritance. Boulder’s load_config_file is a plain yaml.safe_load and passes the raw dict (including from:) straight to normalize_config, which then rejects from: as an unknown top-level key.

This override resolves the full inheritance chain via load_yaml_with_inheritance() before handing the merged dict to Boulder’s normaliser. Files without a from: key are loaded identically to the base implementation.

classmethod normalize(cfg)#

Normalise config and inject Bloc-specific defaults.

Extends Boulder’s normalize_config by:

  1. Rejecting deprecated mechanism_reac / mechanism_torch fields in phases.gas (removed in the STONE architecture).

  2. Defaulting metadata.gui_app_title to "Bloc" so the browser tab and GUI header show Bloc instead of Boulder when opened via the bloc CLI. An explicitly set value is never overwritten.

classmethod report_metadata(config, *, explicit_kind=None)#

Return Calculation-Note reporting metadata for config.

Ensures Bloc’s reactor schemas are registered in Boulder’s global _SCHEMA_REGISTRY before delegating to boulder.schema_registry.get_report_metadata_for_config().

Parameters:
  • config – Normalised config dict.

  • explicit_kind – Override the reactor kind used for schema lookup (forwarded as explicit_kind= to get_report_metadata_for_config).

classmethod schema_entry(kind)#

Return the ReactorSchemaEntry for kind.

Ensures Bloc’s reactor schemas are registered before lookup.

config#
config_path = None#
plugins = None#
converter: boulder.cantera_converter.DualCanteraConverter | None = None#
network: boulder.staged_network.StagedReactorNet | cantera.ReactorNet | None = None#
results: Dict[str, Any] | None = None#
code: str | None = None#
result: boulder.simulation_result.SimulationResult | None = None#
property scopes: Dict[str, Any]#

Return scope data as a dict[str, pandas.DataFrame].

Each key is a scope variable path (e.g. nodes.r1.T); each value is a DataFrame with columns t (seconds) and value.

Returns an empty dict if no scopes were declared or if build() has not been called yet.

property exposed_inputs: Dict[str, Any]#

Return signals that are not bound to any internal network target.

These are the FMI-friendly input variables — signals that a co- simulation master (FMU) could override at each doStep.

A signal is considered exposed (unbound) if its id does not appear as a source in any entry of the bindings: block.

Returns a dict[signal_id, signal_spec] where each value is the raw spec dict from the signals: block. Returns an empty dict if no signals are declared or if build() has not been called yet.

Note

This is the Phase E FMU data-shape contract. No FMU code is generated here; this property just exposes the data structure that boulder.fmi would use. See FMI_FMU_EXPORT.md.

classmethod from_yaml(path)#

Load, normalise, and validate a YAML file, returning a runner instance.

classmethod validate(cfg)#

Validate a normalised config, raising on schema errors.

build_stage_graph()#

Parse the config into a topologically-sorted StageExecutionPlan.

Pure config parsing — no Cantera objects are created. Stage IDs and node lists are available immediately after this call.

new_trajectory()#

Return a fresh, empty LagrangianTrajectory.

solve_stage(plan, stage, inlet_states, trajectory, stream_reservoirs=True, _stream_node_dicts=None, _stream_conns_by_stage=None, interface_reservoirs=None, _iface_node_dicts=None, _iface_conns_by_stage=None)#

Build and solve one stage, updating inlet_states and trajectory in place.

This is exactly one iteration of the solve_staged() loop body. Calling it once per stage in topological order is equivalent to calling solve_staged() on the full plan.

Parameters:
  • plan – Full execution plan (needed for mechanism-switch target lookup).

  • stage – The Stage to solve.

  • inlet_states – Mutable {node_id: ct.Solution} dict. Populated by upstream stages; consumed here to initialise inter-stage-inlet reactors. Updated in place with this stage’s outlet states.

  • trajectory – Accumulates per-stage SolutionArray segments.

  • stream_reservoirs – When True (default), use synthesised stream-point reservoirs and real MFCs on the downstream side of each stage boundary.

  • _stream_node_dicts – Pre-built mapping {stream_point_id: node_dict}. Populated by build().

  • _stream_conns_by_stage – Pre-built mapping {stage_id: [conn_dict, ...]}. Populated by build().

  • interface_reservoirs – Deprecated alias for stream_reservoirs.

  • _iface_node_dicts – Deprecated alias for _stream_node_dicts.

  • _iface_conns_by_stage – Deprecated alias for _stream_conns_by_stage.

Examples

build_viz_network(plan, trajectory, stream_reservoirs=True, interface_reservoirs=None)#

Assemble the full visualization ReactorNet from all converged states.

Connects all inter-stage connections into one ReactorNet (not solved again — just for visualization and Sankey generation). Sets self.network and trajectory.viz_network.

Parameters:
  • plan – Execution plan (provides inter-stage connection list).

  • trajectory – Updated in place: trajectory.viz_network is set.

  • stream_reservoirs – When True (default), the original inter-stage connection IDs are added to built_conn_ids so that build_viz_network does not create a direct source→target MFC that bypasses the stream-point reservoir.

  • interface_reservoirs – Deprecated alias for stream_reservoirs.

Examples

run_continuation(continuation=None)#

Execute a parameter continuation sweep as defined in continuation: STONE block.

Wraps solve_stage() in an outer loop, mutating the target parameter between solves and collecting the trajectory. Equivalent to the manual loop in combustor.py:

while combustor.T > 500:
    sim.solve_steady()
    inlet.mass_flow_rate *= 0.9
Parameters:

continuation

Parsed continuation: dict from the STONE YAML. When None the method reads self.config.get("continuation"). Structure:

parameter: connections.<id>.mass_flow_rate
update:
  multiply: 0.9          # or set: <val> or list: [...]
until:
  reactor_T_below: 500   # or reactor_T_above: <K>
  max_iters: 200

Returns:

For chaining. After this call self.network is the visualization network built from the last converged iteration.

Return type:

self

Raises:

ValueError – If continuation is missing required keys or parameter path cannot be resolved.

build()#

Instantiate the converter, build and solve the staged network.

Internally calls build_stage_graph(), solve_stage() for each stage, and build_viz_network() — the same sequence emitted in the downloadable Python script.

Returns self for chaining. After this call:

solve()#

Build (if not done) and produce a typed SimulationResult.

After this call self.result is a SimulationResult and self.network is the same StagedReactorNet facade as self.result.network — i.e. self.network is self.result.network.

Returns self for chaining.

run_headless(*, download_path=None, simulate=True, end_time=None, dt=None)#

Solve the network and optionally write a downloadable Python script.

This is the single source of truth for the --headless --download CLI flow. Custom BoulderRunner subclasses use the same method so the generated scripts stay on one code path (same converter wiring).

Parameters:
  • download_path – Path to write the standalone Python script. Skipped when None.

  • simulate – When True and end_time is set, run run_streaming_simulation to append the time-advance section to the generated code.

  • end_time – Simulation end time in seconds (from settings.end_time in the YAML).

  • dt – Simulation time step in seconds (from settings.dt in the YAML).