Withstand ← Back

Whitepaper · 22 August 2026

What a data-center dynamic model can be identified from

Roughly three quarters of operating data-center load reaches the transmission planner with no explicit dynamic model. As that changes, the binding question stops being which model to submit and becomes which of its parameters the available records can actually support. This note measures that, on synthetic records with known ground truth, and reports one result that is unflattering to the method: a full-rank sensitivity matrix does not mean the answer is right.

1 · The gap

NERC's March 2026 aggregated report covers 33,282 MW of operating data-center load. Of that, 25,504 MW, about 77 percent, was submitted with no explicit dynamic load model or a blank response, relying on inherent ZIP behaviour. Only 137 MW used a user-defined model such as PERC1. The report also found that almost all respondents lacked a process to update models after design changes or observed events. NERC Level 2 aggregated report, March 2026

The deficiency there is not file format. It is that a dynamic model asserts specific behaviour: how much load rides through a sag, when it ceases, and how it comes back. Those assertions have to come from somewhere. When they come from a library default, nobody can say whether they describe the facility. When they come from a fit, the question becomes whether the record used for the fit could distinguish them at all.

2 · Method

We take a PERC1 aggregate load model at a 318 MW / 42 Mvar study point, set a truth parameter vector distinct from the baseline, and drive the truth model forward over records with different content. The resulting active and reactive power become the measurements handed back to the calibrator, which starts from the baseline and knows nothing of the truth. Because the truth is known, we can report what the calibrator claims: rank of the sensitivity matrix, condition number, and whether it declares the fit submission-ready. We can also report whether it in fact recovered the parameters.

Switching settings are locked throughout, so the optimiser cannot explain a trace by moving protection thresholds. Cease is at 0.70 pu with a 16.7 ms timer; reconnect at 0.85 pu after 5 s with a 15 s ramp. Every fit is scored against a held-out record of the same disturbance class at a different depth. Rank is computed on the Gauss-Newton normal matrix of normalised residuals; a parameter contributing no distinguishable direction does not count toward it.

3 · Identifiability is a property of the record

The clearest result needs only two parameters: Kdroop, the frequency droop gain, and Kvp, the voltage-active-power gain. The fit set is held constant and only the record changes.

RecordRankConditionVerdict
Shallow sag (V → 0.85, no cease)1 / 2n/arefused
Deep sag (V → 0.55, load ceases)1 / 2n/arefused
Frequency excursion, voltage flat1 / 2n/arefused
Both together2 / 249.5accepted

Neither voltage record identifies Kdroop, because the frequency never leaves nominal and a droop gain multiplied by zero deviation leaves no trace in the output. The frequency record does not identify Kvp for the mirrored reason. Only the record containing both excitations supports both parameters, and it does so at a condition number of 49.5, a comfortable result.

This is worth stating plainly because it inverts the intuition that a bigger event is a better one. The question a record answers is not "how severe was this disturbance" but "which distinguishable directions did it excite."

4 · Sample rate and severity both cost you

Next, we widen the fit to the six continuous parameters a settings-locked fit normally exposes: Kvp, Tvp, Kvq, Tvq, nP, and nQ. We then vary both the record and its rate:

RecordRateSamplesRankConditionVerdict
Shallow sag200 sps1,2016 / 6331accepted
Shallow sag30 sps1816 / 6350accepted
Deep sag200 sps6,0016 / 63.88 × 10⁶refused
Deep sag30 sps9014 / 6n/arefused
Frequency only200 sps1,2010 / 6n/arefused
Both together200 sps1,2016 / 6648accepted

Two things happen here. Decimating the deep sag from 200 to 30 samples per second (the difference between a disturbance recorder and typical PMU data) drops the rank from six of six to four of six. The event is unchanged; the record simply stops resolving two of the directions.

More surprising is that the deep sag is far worse conditioned than the shallow one, by four orders of magnitude, despite being the more violent event. The mechanism is the cease logic. Once terminal voltage crosses 0.70 pu the load disconnects, and a disconnected load reports nothing about its own continuous response. The severe event spends most of its duration telling you about the protection settings you already locked, and comparatively little about the dynamics you are trying to fit.

5 · Full rank is necessary, not sufficient

The results above are all the calibrator's own claims. To test whether those claims are correct we ran a control in which the truth model differs from the baseline in exactly the two parameters being fitted, with everything else identical.

RecordRateConditionKvp errorTvp error
Shallow sag200 sps4.40.0 %0.0 %
Shallow sag30 sps4.80.0 %0.0 %
Deep sag200 sps1680.0 %0.0 %
Deep sag30 sps6.33 × 10³0.0 %0.0 %

Recovery is exact to four decimal places in every case, including the badly conditioned deep sag at PMU rate. When the fit set covers what actually differs, the method works and the conditioning numbers are honest. The deep sag is genuinely 38 times worse than the shallow one at 200 sps, and it still lands on the right answer.

Now the unflattering part. In the main matrix, where the truth differed in parameters the fit set held fixed, the deep sag fitting Kvp and Tvp reported rank two of two, passed its held-out check, declared itself submission-ready, and returned a Tvp roughly fifteen times its true value. The rank test was not wrong. It measured what it measures: whether the record can distinguish the parameters you chose to fit. It cannot see a parameter you wrongly held fixed, and the optimiser will quietly absorb that error into whatever it is allowed to move.

The held-out record did not catch it either, and the reason matters. Our holdout was the same disturbance class at a different depth, so the misspecification biased training and holdout identically. A holdout only tests what it varies. Drawn from the same family as the training event, it certifies reproducibility rather than correctness.

6 · What follows for a submission

Check excitation before fitting. If the frequency channel never leaves nominal, no amount of data supports a droop claim, and the honest output is "not identifiable from this record" plus the test that would fix it. If terminal voltage never approaches the cease threshold, the record cannot substantiate cease behaviour regardless of how clean it looks.

Prefer the disturbance that excites without disconnecting. A sag that stays above cease is worth more for calibration than one that trips the load, which is the opposite of how records are usually triaged.

Hold out a different disturbance class, not a different instance of the same one. And treat rank as a necessary condition. A fit that reaches full rank has shown only that the record separates the parameters in play; establishing that the set is the right one is a modelling judgement that no sensitivity matrix will make for you.

7 · Limitations

These are synthetic records generated by the same PERC1 implementation used to fit them, so they carry no measurement noise, no clock error, no channel-mapping mistake, and no structural mismatch between the model and a real facility. They isolate the identifiability question and nothing else. Real records degrade every result here, and the ordering of effects on real data is not established by this note. The rank threshold is a numerical judgement rather than a statistical test, so it carries no confidence level. Finally, PERC1 semantics here follow public documentation, which is not sufficient on its own to assert equivalence with any licensed tool's implementation; establishing that requires replay against a licensed installation, which we have not done.

8 · Method, in full

Every figure above is engine output. Records were generated by driving a truth model forward and handing its active and reactive power back to the calibrator as measurements. The sensitivity spectrum, condition number, and gradient self-audit appear in each run's JSON report alongside the values quoted here.

run       <truth>    --event events/drive.csv --dt 0.001
calibrate <baseline> --event events/meas.csv \
    --holdout events/meas_holdout.csv --fit Kvp,Tvp,Kvq,Tvq,nP,nQ --dt 0.001

The compute engine runs server-side and is never distributed, so these are the operations rather than a local command line. Both are reachable from the client against an authorised account; the parameter vectors and record profiles are listed in full above, so the experiment can be rebuilt independently by anyone with a PERC1 implementation.

If you have a real record and want to know what it supports before committing to a fit, tell us about the facility.