Initial quality ([INITIAL_QUALITY])#

Note

Engine: OpenSWMM 6 — refactored.

solver.initial_quality is the row-based view over [INITIAL_QUALITY]: per-element starting concentrations for nodes and links. Rows are indexed 0 .. len-1 in file order and seed state at initialize().

Reference: openswmm_initial_quality.h.


Quickstart#

from openswmm.engine import Solver, InitialQuality

s = Solver("model.inp")
try:
    s.open()
    s.initial_quality.set("TSS", 12.5, node="J1")
    s.initial_quality.set("TSS", 3.0, link="C1")

    # Reserved species: hours (signed) and degC.
    s.initial_quality.set(InitialQuality.WATER_AGE, 6.0, node="J1")
    s.initial_quality.set(InitialQuality.TEMPERATURE, 14.2, node="J1")

    for row in s.initial_quality:
        print(row.is_link, row.elem_index, row.constituent, row.value)

    s.initial_quality.remove(0)     # later rows shift down
finally:
    s.close()
    s.destroy()

Warning

Mutation is BUILDING/OPENED only. Rows seed state at initialize(), so writing them mid-run would change nothing — the same contract as Pollutant.init_conc.


Rows are an upsert#

InitialQuality.set() is an upsert keyed on (is_link, elem_index, constituent). Writing the same triple twice updates the existing row rather than appending a duplicate, so an editor can change a value it just wrote.

Pass exactly one of node= or link=; either accepts an int index or a str id.

Operation

Behaviour

len(s.initial_quality)

Number of rows.

s.initial_quality[row_index]

One InitialQualityEntry — (is_link, elem_index, constituent, value).

for row in s.initial_quality:

Iterate rows in file order.

.set(constituent, value, *, node=..., link=...)

Upsert on the (is_link, elem_index, constituent) key.

.remove(row_index)

Delete by row index.

Warning

InitialQuality.remove() shifts every later row down by one, so a cached row index goes stale the moment anything before it is removed. Re-enumerate after removing, or remove from the highest index downward.

elem_index reads -1 when the row’s element could not be resolved.


Constituents#

The constituent is a name: either a [POLLUTANTS] pollutant, or one of two reserved species exposed as class attributes so you never have to spell the sentinel by hand.

Constituent

Units

Notes

A [POLLUTANTS] name

Pollutant’s own units

Concentration. Must be non-negative — a negative value is refused.

InitialQuality.WATER_AGE

hours

The literal "__WATER_AGE__". Signed — negative values are legal.

InitialQuality.TEMPERATURE

degC

The literal "__TEMPERATURE__". Signed.

An unknown constituent name, a bad element index, or a negative pollutant value is refused.

InitialQuality.WATER_AGE     # "__WATER_AGE__"
InitialQuality.TEMPERATURE   # "__TEMPERATURE__"

See also#

Sidecar provenance#

initial_quality.file_path preserves the authored CSV reference. Assign a path to record it, or None/an empty string to clear it. Assignment does not read the file: the engine loads it on the next open. is_file(row_index) identifies loaded sidecar rows and accepts negative sequence indices. Inline rows and sidecar rows retain their native save/provenance behavior.

Keys must be unique across inline and sidecar rows; duplicate element/species rows cause a parse error when opening the model.