Expand description
Area interchange control: holding each control area’s net export at its scheduled value.
DistributedSlack drives one number to one
target — the slack’s output to its own schedule. Interconnected systems
schedule more than that: each control area agrees a net position with
its neighbours, and the area’s generators are dispatched to meet it. An
area importing 300 MW when it agreed to import 200 has every tie-line flow
around it wrong, for the same reason a single slack absorbing an unscheduled
few hundred megawatts does.
§The formulation
An area’s interchange is the active power leaving it across its own boundary branches, measured at its own side of each:
\[ X_a = \sum_{b \in \partial a} P_b^{(a\text{-side})} \]
and its mismatch is that against the schedule. The knob is the same one
distributed slack uses: the participating generators’ p_spec.
§One area’s position is dependent, and it has to be
The targets are not independent. Each area’s side of a tie line is measured at its own terminal, into the branch, so both ends of a tie contribute positively and their sum is what the tie dissipates:
\[ \sum_a X_a = +\ell_{\text{tie}} \]
— a quantity nobody knows before the solve. (The sign is easy to get backwards: it is not that one area’s export is the other’s import, because the loss falls between them and belongs to neither.) Targets that sum to zero, which is what a set of agreed net positions looks like, are therefore unachievable by exactly the tie losses. Counting it out: the knobs are each area’s aggregate participant schedule, \(N\) of them; the conditions wanted are \(N\) interchange targets plus the slack on its own schedule, \(N+1\). Over-determined by one, always.
So the area holding the slack is the dependent one: its own target is
not enforced, and its condition is that the slack produces its schedule
instead. Every other area’s position is met exactly, and the slack’s area
absorbs the tie losses — which is what a real interconnection does, and what
makes one area’s position a residual rather than an agreement.
AreaInterchangeReport::dependent names it, and its
residual entry reports how far its
nominal target was missed, so the number is visible rather than implied.
§Deriving the sign, which is the rest of the difficulty
For an area that is not the slack’s, an export above target means it should generate less, so the mismatch \(X_a - X_a^{target}\) is subtracted from the participants by weight.
For the slack’s area, write \(\delta_s\) for the slack’s excess over its
own schedule. Its participants must take that excess up — exactly
DistributedSlack’s move — so the quantity
subtracted is \(-\delta_s\).
Worth checking the degenerate case, because it is also a test
(area_interchange_with_one_area_is_distributed_slack): one area covering
the whole network is the slack’s area, so the only condition is
\(-\delta_s\), and the loop becomes distributed slack exactly. Area
interchange generalizes it rather than sitting beside it, which is why
powsybl-open-loadflow’s own AcAreaInterchangeControlOuterLoop constructs a
DistributedSlackOuterLoop as its no-area fallback and why the two must not
both be configured.
Structs§
- Area
Definition - Which buses belong to which control area, what each area is scheduled to export, and who adjusts to get there.
- Area
Interchange - Drives every area’s net export to its scheduled value, and the slack to its own schedule, by moving the participating generators.
- Area
Interchange Report - What
AreaInterchangedid.