openswmm_gymnasium.spaces#

openswmm_gymnasium.spaces#

Action-space factories. Plan §3.

Each factory is a small class exposing:

  • A name property naming its key in the runtime/design Dict.

  • A space property returning the gymnasium.spaces.Space the factory contributes.

  • A bind(adapter) method called once after SolverAdapter.open to resolve symbolic IDs (link names, node names) to engine indices.

  • An apply(adapter, value) method that writes the sampled action value into the engine.

Runtime (RTC) factories live in openswmm_gymnasium.spaces.runtime and are applied B{every step}.

Design (CIP) factories live in openswmm_gymnasium.spaces.design and are applied B{once per episode} between SolverAdapter.open and SolverAdapter.initialize.

author:

Caleb Buahin

copyright:

Copyright (c) 2026 Caleb Buahin

license:

MIT

class openswmm_gymnasium.spaces.DesignActionFactory(*args, **kwargs)[source]#

Bases: Protocol

Interface every CIP factory must satisfy.

Same shape as openswmm_gymnasium.spaces.runtime.OrificeSetting — the difference is B{when} the env calls apply: design factories are applied once at gymnasium.Env.reset, between SolverAdapter.open and SolverAdapter.initialize.

apply(adapter, value)[source]#
Parameters:
Return type:

None

bind(adapter)[source]#
Parameters:

adapter (SolverAdapter)

Return type:

None

name: str#
property space: gymnasium.spaces.Space#
class openswmm_gymnasium.spaces.LinkDiameter(link_ids, low, high, name='link_diameter')[source]#

Bases: object

Cross-section primary geometry parameter (geom1) for each link.

For a CIRCULAR conduit this is the diameter; for other shapes it is the first dimension per the engine’s openswmm.engine.CrossSection.geom_labels. The shape itself is B{preserved} — the factory reads the existing cross-section at bind time and rewrites only geom1 on apply, leaving shape, geom2, geom3, geom4 unchanged.

@ivar name: Action-space key, default "link_diameter".

Parameters:
  • link_ids (Sequence[str])

  • low (float)

  • high (float)

  • name (str)

apply(adapter, value)[source]#
Parameters:
Return type:

None

bind(adapter)[source]#
Parameters:

adapter (SolverAdapter)

Return type:

None

property space: gymnasium.spaces.Box#
class openswmm_gymnasium.spaces.LinkLength(link_ids, low, high, name='link_length')[source]#

Bases: object

Conduit length for each link.

@ivar name: Action-space key, default "link_length".

Parameters:
  • link_ids (Sequence[str])

  • low (float)

  • high (float)

  • name (str)

apply(adapter, value)[source]#
Parameters:
Return type:

None

bind(adapter)[source]#
Parameters:

adapter (SolverAdapter)

Return type:

None

property space: gymnasium.spaces.Box#
class openswmm_gymnasium.spaces.LinkRoughness(link_ids, low, high, name='link_roughness')[source]#

Bases: object

Manning’s n for each link.

@ivar name: Action-space key, default "link_roughness".

Parameters:
  • link_ids (Sequence[str])

  • low (float)

  • high (float)

  • name (str)

apply(adapter, value)[source]#
Parameters:
Return type:

None

bind(adapter)[source]#
Parameters:

adapter (SolverAdapter)

Return type:

None

property space: gymnasium.spaces.Box#
class openswmm_gymnasium.spaces.NodeMaxDepth(node_ids, low, high, name='node_max_depth')[source]#

Bases: object

Maximum allowable depth at each node.

Used as a CIP proxy for storage capacity: tank-like nodes whose max_depth grows can hold more water before surcharging / flooding. The factory delegates to openswmm.engine.Nodes.set_max_depth.

@ivar name: Action-space key, default "node_max_depth".

Parameters:
  • node_ids (Sequence[str])

  • low (float)

  • high (float)

  • name (str)

apply(adapter, value)[source]#
Parameters:
Return type:

None

bind(adapter)[source]#
Parameters:

adapter (SolverAdapter)

Return type:

None

property space: gymnasium.spaces.Box#
class openswmm_gymnasium.spaces.OrificeSetting(link_ids, name='orifice_setting')[source]#

Bases: object

Box action over the control setting of one or more links.

The setting is a real number in [0, 1], where 0 = fully closed and 1 = fully open. Applied via openswmm.engine.Controls.set_link_setting.

Although the name reflects the primary use case, the underlying engine call accepts any controllable link (orifices, weirs, pumps, and conduits with the LINK_OFFSETS option set appropriately).

@ivar _link_ids: Symbolic link IDs supplied at construction. :type _link_ids: list[str] @ivar _name: Action-space key under which this factory’s component

appears in the env’s runtime Dict.

Parameters:
  • link_ids (Sequence[str])

  • name (str)

@ivar _link_idxs: Engine link indices, resolved by bind. :type _link_idxs: list[int] or None

apply(adapter, value)[source]#

Push the sampled action value into the engine.

Parameters:
  • adapter (SolverAdapter) – Adapter wrapping the running solver.

  • value (numpy.ndarray) – 1-D float array of length len(link_ids).

Raises:

RuntimeError – If bind was not called first.

Return type:

None

bind(adapter)[source]#

Resolve symbolic link IDs to engine indices.

Must be called after SolverAdapter.open (so the engine knows about the model’s links) and before apply.

Parameters:

adapter (SolverAdapter) – Adapter wrapping the open solver.

Return type:

None

property name: str#

Action-space key for this factory.

Return type:

str

property space: gymnasium.spaces.Box#

Per-link setting in [0, 1].

Return type:

gymnasium.spaces.Box