Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Dynamics and DYR

Representation decision

PSS/E .dyr is a dynamic-model file, not a power-flow network. PowerIO keeps that distinction explicit: .raw is parsed by powerio::parse to a PioValue::BalancedNetwork, while .dyr is parsed by powerio::parse_dyr to a standalone DynamicCase. Pair the two with DynamicStudy; do not insert dynamic records into BalancedNetwork or treat the raw model key as a typed generator reference.

This separate Rust API is intentional. It establishes a stable boundary for loss-preserving DYR records and generic bus association without prematurely committing the cross-language PioValue, PowerIO IR, C ABI, Julia, or Python representations to an incomplete dynamic-model schema.

Parse and pair

The example below is compiled as the dynamic_study Cargo example. Run it in a directory containing case.raw and case.dyr with cargo run -p powerio --example dynamic_study.

use powerio::{DynamicStudy, PioValue, parse, parse_dyr};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let raw = parse("case.raw")?;
    let PioValue::BalancedNetwork(network) = raw.value() else {
        return Err("case.raw did not produce a balanced network".into());
    };

    let dyr_text = std::fs::read_to_string("case.dyr")?;
    let dynamics = parse_dyr(&dyr_text)?;
    let study = DynamicStudy::new(network.clone(), dynamics);

    for unresolved in study.unresolved_buses() {
        eprintln!(
            "line {}: {} references missing bus {}",
            unresolved.line, unresolved.model_name, unresolved.bus_id
        );
    }
    Ok(())
}

DynamicCase::records() returns records in source order. Each record exposes its bus ID, raw model name, optional device key, ordered parameter tokens, source line, and record spelling. DynamicCase::to_dyr_string() returns the original text exactly, including comments and formatting. parse_dyr_bytes rejects invalid UTF-8 rather than replacing bytes.

Linking guarantees and limitations

DynamicStudy::unresolved_buses() verifies only whether each generic DYR bus ID occurs in the paired network. It does not assert that the optional device_id refers to a generator, load, or other particular equipment: the meaning of that field and the association rule depend on the model family. Unknown and user-defined models are preserved rather than rejected or silently dropped. Parameters remain strings until a schema-backed model view exists.

Not implemented yet: typed machine/exciter/governor/stabilizer models, model-aware device association, DYR-to-DYD/SWI/PowerWorld AUX conversion, transient simulation, and dynamics exposure through PowerIO IR, C ABI, Julia, or Python. This is the initial public API boundary, not a claim that those features are complete.