Transformer Control (Complex Tap, Outer Loop)
Concept
Sparlectra models transformer regulation within the existing branch PI model using a complex tap t = τ * exp(jφ) and without auxiliary nodes.
τ→ voltage controlφ→ active power flow control (PST behavior)
A combined transformer (“Schrägregler”) is represented by enabling both controls on one device.
Equations
With series admittance y, total shunt y_sh, and from-side tap t:
\[\begin{aligned} Y_{ff} &= \frac{y + 0.5\,y_{sh}}{\lvert t \rvert^2} \\ Y_{ft} &= -\frac{y}{\overline{t}} \\ Y_{tf} &= -\frac{y}{t} \\ Y_{tt} &= y + 0.5\,y_{sh} \end{aligned}\]
This matches the Sparlectra sign and conjugation convention.
Numerical Method
Transformer control is implemented as an outer loop around the power flow:
- Solve PF with current taps
- Evaluate control error
- Update tap(s) (continuous or discrete)
- Re-run PF
- Stop on convergence, limits, or iteration cap
No augmentation of the Newton system is performed.
Controller Resolution
Controllers are collected centrally via _tap_controllers(net) from PowerTransformerWinding.controls.
They are:
- deduplicated by identity
- used consistently for execution and reporting
- evaluated to determine if outer-loop control is required
Design Rationale
Tap control is intentionally kept outside the Newton solver:
- no extension of Jacobian/state vector
- simpler solver backends
- centralized control logic (deadbands, limits, discrete steps)
- deterministic post-processing between iterations
Taps are treated as supervisory control updates, not algebraic unknowns.
API
addPowerTransformerControl!(net;
trafo = "1",
mode = :voltage,
target_bus = "B5",
target_vm_pu = 1.01,
control_ratio = true,
control_phase = false,
is_discrete = true)Generic control framework integration
Transformer tap/phase control is implemented as an AbstractOuterController. Controllers are collected by collect_outer_controllers(net). When at least one controller is present, run_acpflow calls run_control! for outer-loop orchestration.
Advanced direct use:
result = run_control!(
net;
pf_config = powerflow_config(),
control_config = control_config(),
)
result.status
result.trace
latest_control_result(net)Preferred high-level solve path:
Result inspection
run_acpflow(net = net; show_results = false)
result = latest_control_result(net)
println(result.status)
println(result.outer_iterations)
println(result.powerflow_solves)
println(result.controllers)
println(result.trace)result.status is the outer control-loop terminal state. It is separate from numerical PF success/failure. result.trace is machine-readable and does not require parsing console output.
addPowerTransformerControl!(net;
trafo = "1",
mode = :branch_active_power,
target_branch = ("B1", "B2"),
p_target_mw = 250.0,
control_ratio = false,
control_phase = true,
is_discrete = true)addPowerTransformerControl!(net;
trafo = "1",
mode = :voltage_and_branch_active_power,
target_bus = "B5",
target_vm_pu = 1.01,
target_branch = ("B1", "B2"),
p_target_mw = 250.0,
control_ratio = true,
control_phase = true,
is_discrete = true)Discrete Tap Behavior
ratio:
tap_ratio_new = clamp(tap_ratio ± tap_step, tap_min, tap_max)phase:
phase_shift_deg_new = clamp(phase_shift_deg ± phase_step_deg, phase_min_deg, phase_max_deg)
Limits / Scope
- No auxiliary transformer nodes
- No coupling of tap variables into NR
- No coordinated multi-transformer control
Remote Voltage Control (Current vs. Complete)
Current capability
Sparlectra already supports basic remote voltage control:
- measurement:
target_bus - actuator: one transformer tap
- objective:
target_vm_pu ± deadband
This corresponds to a single-controller remote regulation.
What is missing for full remote voltage control
A complete implementation (as used in real grid control systems or CGMES-based models) typically requires:
multiple transformers controlling the same remote bus
coordination between controllers, e.g.:
- participation factors / weighting
- priority rules
limit handling with redistribution (when one transformer hits tap limits)
anti-hunting / stabilization mechanisms
deterministic group convergence logic
Key gap in Sparlectra
Currently:
- controllers operate independently
- no grouping or coordination exists
- no shared control objective across multiple transformers
Implication
Sparlectra implements:
→ single-actuator remote control
but not yet:
→ coordinated multi-actuator remote voltage control
Example: Inline Controller Definition
ctrl = PowerTransformerControl(
trafo = "",
mode = :voltage,
target_bus = "B5",
target_vm_pu = 1.01,
control_ratio = true,
control_phase = false,
)
addPIModelTrafo!(
net = net,
fromBus = "B1",
toBus = "B2",
r_pu = 0.01,
x_pu = 0.08,
b_pu = 0.0,
ratio = 1.0,
shift_deg = 0.0,
status = 1,
controls = [ctrl],
)Examples
See:
examples/tap_control_demo_grid.jl- Two-file configuration model:
examples/configuration.yaml(orSPARLECTRA_CONFIGURATION_YAML) for central solver/output/control-framework settings.examples/tap_control_demo_grid.yamlfor demo-specific transformer setpoints and tap parameters.
- Demonstrates all three control types in one lightweight network: OLTC voltage control, PST active-power control, and Schrägregler combined voltage + active-power control.
- Controller definitions are created programmatically by the example.
- Central
control.controllers: []remains reserved/future. - Optional classic output:
SPARLECTRA_TAP_DEMO_CLASSIC=1 julia --project=. examples/tap_control_demo_grid.jl - Optional raw result dump:
SPARLECTRA_TAP_DEMO_RAW=1 julia --project=. examples/tap_control_demo_grid.jl - Default output is compact and summarizes controller status, taps/phases, and trace size.
- Structured results are inspected via
latest_control_result(net)(controller rows and trace rows).
- Two-file configuration model:
for runnable setups.