name: gfm-validation description: "Use when validating a grid-forming inverter Simulink or Simscape model against a gfm-design parameter struct or analytical prediction. Triggers include running sim(), checking logged P/Q/f/V/I signals, comparing simulation results to gfm_predict_steady_state, building validation reports, defining nominal/load-step/frequency/voltage/LVRT/FRT scenarios, and reviewing whether a GFM simulation supports the design assumptions. Companion to gfm-design; use this only after a model, logs, or explicit simulation-validation request exists."
GFM Validation
Overview
Validate a grid-forming inverter Simulink/Simscape model against the analytical design produced by the companion gfm-design skill. This skill may call sim() only when the user explicitly asks for simulation validation and provides a model or captured simulation output.
Keep the boundary sharp:
gfm-design: choose/tune the control law, creategfm_params.m, predict steady state and small-signal poles. It does not callsim().gfm-validation: run or inspect simulations, compare logged behavior against the design prediction, and produce a validation report. It does not retune the controller unless the user explicitly redirects back to design.
Workflow
- Confirm the validation target: model name/path, parameter source, scenario, stop time, and whether the user wants a live
sim()run or analysis of existingSimulink.SimulationOutput/logs. - Run the pre-flight convention audit before
sim(): readreferences/pre-flight-convention-audit.md, query SPS source-block parameters, scan controller chart for hardcoded literals, verify the IC is not at a saddle. This is a static inspection — it reads the model without running it. Most "wrong amplitude" / "doesn't settle" reports trace back to issues this audit catches in under a minute. - Identify which depth tier the scenario lives in (steady-state, small-signal, large-signal) — see
gfm-design/references/gfm-test-scenarios.md. Tier-1 amplitude/sign sanity checks apply to every run; small-signalgfm_smallsignalcomparisons apply only at Tier 2; pre-event settled-window verification matters most at Tier 3. - Load the model logging contract before running: read
references/model-logging-contract.mdwhen signal names, logging, orlogsoutare unclear. - Run the no-event baseline before layering any disturbance: read
references/baseline-first-checks.md. Strip scenario events (lock breakers closed, disable programmable variations, bypass fault blocks), confirm the controller block's sample time matches the algorithm's hardcodeddt, and verify the model settles to a correct steady state. This is the dynamic counterpart to step 2 — it separates "is the controller doing its job" from "is the event handled correctly." A baseline that does not settle invalidates every event-response conclusion built on top of it. - Use
Simulink.SimulationInputfor live runs. Setpfrom the providedgfm_paramssource, apply the scenario, and callsim()without saving or structurally editing the model unless the user asks. - Extract logged signals: P, Q, PCC frequency, PCC voltage, current, and modulation index when available.
- Compare the settled simulation window against
gfm_predict_steady_stateor a supplied prediction. Treat current limiting, modulation saturation, missing logs, and fault periods as validation findings, not tuning results. - Write artifacts under
runs/or another ignored output directory. Do not claim grid-code or protection compliance; report simulation evidence only.
Resource map
References are organized by scope. Read essential ones for every validation run; read plus ones only when the scenario calls for them.
Essential — General (every validation run)
| Reference | Purpose |
|---|---|
references/pre-flight-convention-audit.md |
Pre-sim() audit: SPS source-block parameter strings, controller-chart literals, block-swap port topology, baseline regression. Catches sqrt(2)/sqrt(3) / sign / IC-saddle failures before they look like tuning bugs. |
references/baseline-first-checks.md |
Strip events (locked breakers, disabled programmable variations, bypassed fault blocks), verify the controller block's actual sample time matches the algorithm's hardcoded dt, then check steady-state metrics before layering disturbances. |
references/model-logging-contract.md |
Expected signals, units, sign conventions, amplitude cross-check (` |
references/scenario-contract.md |
Scenario classes, pre/post-event windows, what each scenario can and cannot prove. |
references/companion-boundary.md |
Division of responsibility between gfm-design and gfm-validation. |
references/common-measurement-pitfalls.md |
Cross-cutting failure patterns that lead to wrong conclusions about the controller: dropped signals after a structural model edit (an edit problem, not a gain problem), measuring power angle at the wrong electrical boundary, moving-average causality around step events, quasi-static back-calculation limits during transients, and a small set of stable MATLAB API traps. Read FIRST when a validation result looks suspicious before retuning anything. |
Essential — Tier definitions (cross-reference)
| Reference | Lives in | Use when |
|---|---|---|
gfm-test-scenarios.md |
gfm-design |
Decide whether the scenario is Tier 1 (steady-state), Tier 2 (small-signal), or Tier 3 (large-signal). Linear predictions only apply at Tiers 1–2. |
Scripts
| Script | Purpose |
|---|---|
scripts/gfm_validate_sim.m |
Top-level runner. Accepts a model or existing sim output, resolves parameters/prediction, extracts logs, compares metrics, and writes a report. |
scripts/gfm_extract_sim_signals.m |
Extracts canonical signals from logsout, SimulationOutput, or simple structs. |
scripts/gfm_compare_logs_to_prediction.m |
Computes settled-window metrics and pass/fail checks against a prediction. |
scripts/gfm_write_validation_report.m |
Writes a concise Markdown validation report. |
scripts/test_gfm_validation_helpers.m |
Smoke test for helper scripts using synthetic logs; does not call sim(). |
Minimal Usage
From MATLAB, with both skills on disk:
addpath('D:\AI\gfm-validation-skill\scripts');
addpath('D:\AI\gfm-design-skill\scripts');
p = gfm_params(); % or pass 'paramsFcn','gfm_params'
result = gfm_validate_sim( ...
'model', 'my_gfm_model', ...
'p', p, ...
'gfmDesignPath', 'D:\AI\gfm-design-skill\scripts', ...
'scenarioName', 'nominal_load_step', ...
'tStop', 1.5);
For already captured logs:
pred = gfm_predict_steady_state(p, 'verbose', false);
result = gfm_validate_sim( ...
'simOutput', simOut, ...
'prediction', pred, ...
'runSim', false);
Output Expectations
End with:
- The model/scenario and whether
sim()actually ran. - A pass/fail table for settled P, Q, frequency, voltage, current, and modulation checks, noting missing signals.
- The report path and any generated run artifacts.
- A boundary note: simulation evidence is not grid-code compliance, certification, protection proof, or field qualification.
If the logs disagree with the design prediction, first check signal names/units, steady-state window, limiter activity, saturation, and scenario timing before recommending controller retuning. For the recurring failure patterns — near-zero output after a model edit, P-δ steady state stuck at 0°, pre-step operating point showing transient values, missing trajectory discontinuity at grid steps, or unexplained set_param/whos API errors — read references/common-measurement-pitfalls.md first; most of these are mechanical, not physical.