bloc.core#
Bloc runtime — CLI, converter, and runner.
Submodules#
Classes#
Cantera converter pre-loaded with Bloc Design* reactors and hooks. |
|
Orchestrator for the full YAML-to-SimulationResult pipeline, Bloc flavour. |
Functions#
|
Entry point for the |
Package Contents#
- bloc.core.main(argv=None)#
Entry point for the
blocconsole script.
- class bloc.core.BlocConverter(mechanism=None, plugins=None)#
Bases:
boulder.cantera_converter.DualCanteraConverterCantera converter pre-loaded with Bloc Design* reactors and hooks.
- Parameters:
mechanism – Raw mechanism name/path (not yet path-resolved). Resolution is performed by
resolve_mechanismduring construction.plugins – Optional pre-built plugin container. Bloc solver plugins are registered into this container (idempotent) regardless of whether it is provided or freshly created.
- SCRIPT_EMITTER_CLASS#
- post_build(config)#
Run post-build hooks, but fail-fast on equipment-envelope violations.
Boulder’s default
post_build()downgrades every hook exception to a warning (tolerant to optional hooks). Bloc keeps that tolerance but re-raisesPBR100EnvelopeErrorso a supplier model configured outside its nameplate envelope hard-fails the build instead of silently degrading.
- resolve_mechanism(name)#
Resolve name using Bloc’s mechanism search hierarchy.
Called from every site that turns a mechanism string into a
ct.Solution— both the top-level default mechanism (in__init__) and per-node mechanism overrides (in_get_gas_for_mech). Ifget_mechanism_pathcannot locate the file, returns name unchanged so Cantera can handle bare built-in names (e.g."gri30.yaml").
- script_load_lines(config_path, plan=None)#
Emit a Bloc-aware Cantera-native staged-solve script.
The generated file uses module-level
reactors/connections/wallsregistries, directDesign*construction, and namednetwork_<stage>.advance(...)calls — noBlocConvertershell.
- mechanism = 'gri30.yaml'#
- plugins#
- reactors: Dict[str, cantera.ReactorBase]#
- reactor_meta: Dict[str, Dict[str, Any]]#
- connections: Dict[str, cantera.FlowDevice]#
- walls: Dict[str, Any]#
- network: cantera.ReactorNet | None = None#
- code_lines: List[str] = []#
- last_network: cantera.ReactorNet | None = None#
- parse_composition(comp_str)#
Parse a
"species:value,species:value,..."composition string.A handful of real mechanisms (e.g.
n-heptane-NUIG-2016.yaml) have species names that themselves contain a literal comma (C6H101-3,3), so naively splitting on every,before every:misparses them. Values are always plain floats, so a fragment is only a complete entry once the text after its last:parses as one; until then the next comma-separated fragment is folded into the same (comma-bearing) name.
- set_reactor_volume(reactor, props, reactor_id)#
Set reactor volume if specified in properties.
- create_reactor_from_node(node, gas_for_node)#
Instantiate a Cantera reactor from a normalized node dict.
Uses the plugin reactor builder registry when the type matches a registered custom builder; otherwise falls back to the standard Cantera reactor types.
- Parameters:
node – Normalized node dict with
id,type, andproperties.gas_for_node – The
Solutioncarrying the initial state.
- Returns:
The newly created reactor (not yet added to any network).
- Return type:
ct.Reactor
- build_connection(conn)#
Create and register one Cantera flow device or wall from a connection dict.
The connection is added to
self.connections(forFlowDevicesubtypes) orself.walls(forWall).- Parameters:
conn – Normalized connection dict with
id,type,source,target, andproperties.
- apply_flow_conservation()#
Resolve unset MFC flow rates via mass conservation, then reset tracking state.
Called after all connections for a network (or sub-network stage) have been built. MFCs without an explicit
mass_flow_ratein the YAML config are resolved by enforcing steady-state mass conservation at each non-Reservoir reactor node. Resolved values are also appended tocode_linesso the--downloadscript reflects the actual flow rates.- Raises:
ValueError – Propagated from
resolve_unset_flow_rates()if any flow rate cannot be uniquely determined.
- build_isolated_reactor(node)#
Build a single reactor from one node, with no surrounding network.
Resolves the node’s mechanism, sets the gas state from its initial properties (
temperature/pressure/composition/mass_composition, either top-level or underinitial:), and delegates tocreate_reactor_from_node()so thatenergy,clone,volumeand any other recognised properties are honoured exactly as in a full network build. This is the single source of truth for reactor construction for callers (e.g. parametric τ-sweeps) that drive their ownReactorNetinstead of the staged solver.Property values may be unit strings (
"1273.15 K","1 bar") or plain numbers; temperature/pressure are coerced to SI.- Parameters:
node – A node dict with
id,type, andproperties(the normalised form; STONEKind: {...}blocks must be converted totype/propertiesby the caller first).- Returns:
The constructed reactor and the
Solutioncarrying its initial state.- Return type:
(reactor,gas)
- build_sub_network(stage_nodes, stage_connections, stage_mechanism, inlet_states, stage_id='', stage=None, pre_solve_hook=None)#
Build (and solve) a
ReactorNetfor one stage.Reactors whose IDs appear in inlet_states are initialised from the provided
Solution(upstream outlet, already mechanism-switched) instead of from the YAML properties.- Parameters:
stage_nodes – Normalized node dicts for this stage only.
stage_connections – Intra-stage normalized connection dicts.
stage_mechanism – Default kinetic mechanism for the stage.
inlet_states –
{node_id: ct.Solution}mapping inlet conditions for reactors that receive inter-stage flow.stage_id – For logging/error messages.
stage –
Stagedataclass; used to set the solve directive (advance_to_steady_statevsadvance).pre_solve_hook – Optional callback invoked with
selfafterself.reactors/self.connectionsare populated for this stage but before the solve dispatch runs. This is the only correct place to wire causal-layer bindings (e.g.apply_bindings_block) — calling them after this method returns means the solve already ran to completion with no schedule callbacks registered.
- Returns:
networkis the solvedReactorNet.stage_reactorsis a{node_id: ct.ReactorBase}dict for this stage (a subset ofself.reactors).- Return type:
(network,stage_reactors)
- build_viz_network(all_connections, built_conn_ids=None)#
Build a visualization-only
ReactorNet.Uses all reactor objects already in
self.reactors(which carry converged states after a staged solve) and adds any inter-stage connections that were not built during the per-stage solve.The returned network is initialized with
advance(0.0)so flow-device properties (mass_flow_rate) are ready for downstream reporting.- Parameters:
all_connections – The full list of normalized connection dicts (including inter-stage ones).
built_conn_ids – Set of connection IDs already built (intra-stage). Inter-stage connections not in this set will be created now.
- Return type:
ct.ReactorNet
- build_network(config, progress_callback=None)#
Build and solve the Cantera network through the staged solver.
normalize_configguarantees that the config has a top-levelgroupssection (synthesising a singledefaultgroup when the YAML does not declare one), so this method always delegates tosolve_staged(). It builds one sub-ReactorNetper stage, solves each according to itssolve_directiveand returns a visualization ReactorNet with all reactors in their converged state. The Lagrangian trajectory is stored onself._staged_trajectory.- Parameters:
config – Normalised and validated configuration dict.
progress_callback – Optional
(stage_id: str, n_done: int, n_total: int) -> Nonecalled after each stage completes. Forwarded tosolve_staged().
- run_streaming_simulation(simulation_time=10.0, time_step=1.0, progress_callback=None, config=None)#
Run simulation with streaming progress updates.
- finalize_results(times, reactors_series)#
Finalize simulation results with post-processing.
- build_network_and_code(config)#
Build+solve the network and return
(network, results, code_str).build_networknow solves the whole network through the staged solver, soresultsonly reports what the staged path already produced: the converged per-reactor states (as a single-time-point SolutionArray) and any scalars stored by post-build hooks.
- class bloc.core.BlocRunner(config, *, plugins=None, config_path=None)#
Bases:
boulder.runner.BoulderRunnerOrchestrator for the full YAML-to-SimulationResult pipeline, Bloc flavour.
Differences from
BoulderRunner:Uses
BlocConverteras the converter.normalizerejects deprecatedmechanism_reac/mechanism_torchkeys.report_metadataandschema_entryensure Bloc reactor schemas are registered in Boulder’s global_SCHEMA_REGISTRYbefore lookup.
- converter_class#
- classmethod load(path)#
Load raw config with Bloc
from:inheritance resolved.Bloc YAML files may use a
from: <parent>.yamlkey for STONE overlay inheritance. Boulder’sload_config_fileis a plainyaml.safe_loadand passes the raw dict (includingfrom:) straight tonormalize_config, which then rejectsfrom: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 afrom:key are loaded identically to the base implementation.
- classmethod normalize(cfg)#
Normalise config and inject Bloc-specific defaults.
Extends Boulder’s
normalize_configby:Rejecting deprecated
mechanism_reac/mechanism_torchfields inphases.gas(removed in the STONE architecture).Defaulting
metadata.gui_app_titleto"Bloc"andmetadata.gui_app_versionto the installed version so the GUI header shows the version once (title + version chip) rather than twice. Explicitly set values are 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_REGISTRYbefore delegating toboulder.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=toget_report_metadata_for_config).
- classmethod schema_entry(kind)#
Return the
ReactorSchemaEntryfor 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 columnst(seconds) andvalue.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
iddoes not appear as asourcein any entry of thebindings:block.Returns a
dict[signal_id, signal_spec]where each value is the raw spec dict from thesignals:block. Returns an empty dict if no signals are declared or ifbuild()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.fmiwould use. SeeFMI_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 callingsolve_staged()on the full plan.- Parameters:
plan – Full execution plan (needed for mechanism-switch target lookup).
stage – The
Stageto 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
SolutionArraysegments.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 bybuild()._stream_conns_by_stage – Pre-built mapping
{stage_id: [conn_dict, ...]}. Populated bybuild().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
ReactorNetfrom all converged states.Connects all inter-stage connections into one ReactorNet (not solved again — just for visualization and Sankey generation). Sets
self.networkandtrajectory.viz_network.- Parameters:
plan – Execution plan (provides inter-stage connection list).
trajectory – Updated in place:
trajectory.viz_networkis set.stream_reservoirs – When
True(default), the original inter-stage connection IDs are added tobuilt_conn_idsso thatbuild_viz_networkdoes 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 incombustor.py:while combustor.T > 500: sim.solve_steady() inlet.mass_flow_rate *= 0.9
- Parameters:
continuation –
Parsed
continuation:dict from the STONE YAML. WhenNonethe method readsself.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.networkis 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, andbuild_viz_network()— the same sequence emitted in the downloadable Python script.Returns
selffor chaining. After this call:self.converteris theDualCanteraConverter.self.networkis a raw visualizationReactorNet(upgraded to theStagedReactorNetfacade aftersolve()is called).self.codeis the generated standalone Python script string.
- solve()#
Build (if not done) and produce a typed
SimulationResult.After this call
self.resultis aSimulationResultandself.networkis the sameStagedReactorNetfacade asself.result.network— i.e.self.network is self.result.network.Returns
selffor 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 --downloadCLI flow. CustomBoulderRunnersubclasses 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
Trueandend_timeis set, runrun_streaming_simulationto append the time-advance section to the generated code.end_time – Simulation end time in seconds (from
settings.end_timein the YAML).dt – Simulation time step in seconds (from
settings.dtin the YAML).