Audit every document in the repository, convert the non-markdown ones into markdown reports, and split current documentation from outdated material. docs/ — 31 markdown documents in seven numbered sections. Twenty are new reports generated from .docx / .pdf / .xlsx / .mlx / .m sources that were previously unreadable in the browser and undiffable in git. Each report carries a provenance block (source path, format, MD5) and links back to its original; all 13 recorded checksums verify against the files on disk. Machine-extraction losses (PDF table column interleaving, Word OMML equations, embedded figures) are called out explicitly rather than silently smoothed over. superseded/ — outdated material with a documented reason per entry: two byte-identical ClickUp re-exports, an older revision of the BIDMC/UCSD energy-flow doc (the retained copy adds the SoC Violation Rate KPI), a duplicate of Shift input data.docx, the May 2026 simulation plan, the root PV+Battery.md now covered by a fuller report, GitHub's stock demo-repository template, and a zero-byte placeholder. Its README also records what was deliberately NOT retired and why — the "Old Frameworks" and "Old Simulations" folders hold unique Simulink revisions, and "Big Ugly Folder" holds the only copy of framework revision 1.3. Findings worth flagging, all documented in the reports: - Simulink lineage recovered from each .slx's internal coreProperties.xml revision counter. The current model is Current Framework/Bobert0206_Initial_Simulation_Framework.slx (rev 2.7); the top-level copy is rev 1.3, five revisions behind. - Simulations/Constants.m is a truncated byte-prefix of the Current Framework copy, silently missing H2_leak, H2_cap and E_H2_vol_h. - The PEM electrolyser and fuel cell are unmodified MathWorks Simscape examples still at vendor defaults; the "10x bigger" sizing TODO recorded in Constants.m was never carried out. - controller-claude.m does not compile — undefined P_Electro_max, outputs unassigned on several paths. - The specification set uses two incompatible variable naming conventions and disagrees on action-space size (5 vs 16). - MA_hourly_load.csv (13.7 MB) is the same 35,040 rows as 89993-0.parquet (2.4 MB). - Clinical data is the MIMIC-IV *demo* (ODbL, 100 patients), not full MIMIC-IV — redistributable, but the licence and citation are unrecorded. Housekeeping: untrack 21 Simulink build artefacts (slprj/, *.slxc) and add ignore rules for them. Root README rewritten around the new layout. Recruitment notes naming individual candidates are excluded from version control via .gitignore rather than committed; the generic question template is kept in docs/07-team-and-operations/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
14 KiB
SHIFT Simulator — Input/Output Interface
Markdown report of a non-markdown source document.
Source docs/_originals/Simulator Interface Input-Output sheet.pdfFormat PDF, 10 pages, 556 kB MD5 0712f05593c39897abc8f651834bebdeOwner AI & Control Systems cluster Document status Draft v0.1 — living document, TBD items unresolved Report generated 2026-07-25
Note
Tables in the source PDF are rendered in a layout that machine extraction scrambles (symbol, name, unit and note columns interleave). The tables below are reconstructed — the content is the source's, the column alignment is this report's. Where a mapping was ambiguous it is flagged inline. Check against the original PDF before relying on any single row for implementation.
Purpose
Defines the contract between the SHIFT microgrid simulator and everything that talks to it:
- the AI/RL policy,
- the rule-based baseline,
- the validation/benchmark layer,
- the Economics team's downstream cost and CO₂ accounting.
It covers what the simulator consumes (configuration, exogenous time-series, control actions) and what it returns at every timestep.
"It is a living document — items flagged TBD need a decision from the cluster or whoever."
This document is the direct descendant of Shift Input Data — §1 explicitly refers to "the constants Robert's doc lists in bold."
0. Conventions
Timestep
Symbol: dt
Default assumption 1 hour — matches typical PV/load profiles and the one-year benchmarking horizon in the project brief. Whether a sub-hourly step is needed for battery fast-response behaviour is TBD.
"I did 1 hour for this cause 15 mins time steps will be quite compute heavy for RL training, so we do need to talk about that."
Sign conventions
| Quantity | Positive means | Negative means |
|---|---|---|
P_battery |
discharging (supplying the bus) | charging (absorbing from the bus) |
P_grid |
importing from grid | exporting to grid |
n_H2_net |
net production into tank | net consumption from tank |
All other power values — P_PV, P_electrolyser, P_fuelcell, P_load — are non-negative
by definition.
Power balance
The invariant the simulator must satisfy at every step:
P_PV_used + P_fuelcell + P_grid + P_battery
= P_load_served_critical + P_load_served_noncritical + P_electrolyser
Any residual after the policy's action is absorbed by unmet load — with critical load prioritised (see §4).
Units
SI throughout: power in W, energy in Wh, mass in kg, amount in mol, time in s (or h for hourly steps). TBD to lock down before code is written.
"I don't know the conventions for this, I let AI handle this, not an electrical engineer sorry."
1. Static configuration inputs
Set once per simulation run.
1.1 Electrolyser
| Symbol | Name | Unit | Notes |
|---|---|---|---|
N_c_ele |
Number of cells | — | Usually difficult to find |
mu_F |
Faraday efficiency | — | Fall back to literature average (~0.95–0.99 for PEM) |
P_ele_max |
Rated / max power | W | |
P_ele_min |
Minimum operating power | W | Below this the electrolyser shuts off (efficiency cliff) |
I_ele_min |
Minimum operating current | A | Alternative to P_ele_min |
cal_H2 |
H₂ production calibration factor | — | If we end up reading H₂ flow from measured data |
1.2 Fuel cell
| Symbol | Name | Unit | Notes |
|---|---|---|---|
N_c_fc |
Number of cells | — | |
utilisation_fc |
H₂ utilisation | % | |
P_fc_max |
Maximum output power | W | Project spec: 100 kW |
V_fc_min, V_fc_max |
Operating voltage range | V |
1.3 Hydrogen tank
| Symbol | Name | Unit | Notes |
|---|---|---|---|
V_H2_max |
Maximum stored volume | L (or kg) | Project spec: up to 200 kg total across two tanks |
V_H2_init |
Initial fill level | L (or kg) | |
T_tank |
Operating temperature | K | TBD — isothermal assumption likely fine |
p_tank |
Operating pressure | atm (or bar) | TBD — isobaric vs. ideal-gas model |
1.4 PV
| Symbol | Name | Unit | Notes |
|---|---|---|---|
A_PV |
Total panel area | m² | Project spec: 2,300 m² |
mu_PV |
Panel efficiency | — | |
P_PV_max |
Inverter / rated cap | W | Optional; if set, clipping occurs above this |
1.5 Battery
| Symbol | Name | Unit | Notes |
|---|---|---|---|
E_rated |
Rated energy capacity | Wh | |
Q_rated |
Rated charge capacity | Ah | |
P_batt_charge_max |
Max charge power | W | |
P_batt_discharge_max |
Max discharge power | W | |
SoC_init |
Initial state of charge | — (0–1) | |
SoC_min, SoC_max |
Operating window | — (0–1) | E.g. 0.1–0.9 |
eta_batt_ch, eta_batt_dis |
Round-trip efficiencies | — | Often split into charge & discharge |
1.6 Load
| Symbol | Name | Unit | Notes |
|---|---|---|---|
V_load |
Bus voltage | V | Constant, per Robert's note |
1.7 Grid
| Symbol | Name | Unit | Notes |
|---|---|---|---|
P_grid_max |
Max connection capacity (import & export) | W | Constant, per Robert's note |
V_grid |
Bus voltage | V |
2. Per-timestep inputs
2.1 Exogenous time-series
Read from data; not under policy control.
| Symbol | Name | Unit | Source / note |
|---|---|---|---|
G(t) |
PV generated power | W | Forecasted |
L_crit(t) |
Critical hospital load demand | W | ICU, life-support, etc. — must always be served |
L_noncrit(t) |
Non-critical hospital load demand | W | Lighting, HVAC, admin |
grid_on(t) |
Grid availability (1/0) | — | Models outages |
price(t) |
Grid electricity price | €/kWh | Import & export prices — TBD whether they differ |
CO2_int(t) |
Grid carbon intensity | kg CO₂/kWh | For emissions accounting |
2.2 Control inputs
From the AI/RL policy or the rule-based baseline. At each timestep the controller emits setpoints, not direct power flows — the simulator clips them to physical limits and reports actuals.
| Symbol | Name | Unit | Range |
|---|---|---|---|
u_ele(t) |
Electrolyser power setpoint | W | [0, P_ele_max]; values in (0, P_ele_min) round to 0 (off) |
u_fc(t) |
Fuel cell power setpoint | W | [0, P_fc_max] |
u_batt(t) |
Battery setpoint (signed) | W | [-P_batt_charge_max, P_batt_discharge_max] |
sw_ele(t) |
Electrolyser ON/OFF | 1/0 | Optional — can be folded into u_ele = 0 |
sw_fc(t) |
Fuel cell ON/OFF | 1/0 | Optional — can be folded into u_fc = 0 |
On the grid: the grid is treated as the slack bus — whatever the power-balance residual
is after all other components act, the grid absorbs, within P_grid_max and grid_on(t). The
RL action space therefore probably does not include the grid directly.
3. Per-timestep outputs
3.1 State variables
Carried forward to the next step.
| Symbol | Name | Unit |
|---|---|---|
SoC(t) |
Battery state of charge | — (0–1) |
H2_level(t) |
H₂ stored in tank | mol (or kg) |
T_tank(t) |
Tank temperature | K (only if non-isothermal model) |
p_tank(t) |
Tank pressure | bar (if modelled) |
3.2 Power flows
| Symbol | Name | Unit |
|---|---|---|
P_PV_available(t) |
PV power available given irradiance | W |
P_PV_used(t) |
PV power actually consumed | W |
P_PV_curtailed(t) |
PV potential that was thrown away | W |
P_ele(t) |
Actual electrolyser consumption | W |
P_fc(t) |
Actual fuel cell output | W |
P_batt(t) |
Actual battery flow (signed) | W |
P_grid(t) |
Actual grid flow (signed) | W |
P_load_served_crit(t) |
Critical load served | W |
P_load_served_noncrit(t) |
Non-critical load served | W |
3.3 Mass flows (hydrogen)
| Symbol | Name | Unit |
|---|---|---|
n_H2_prod(t) |
H₂ produced by electrolyser | mol/s (or kg/h) |
n_H2_cons(t) |
H₂ consumed by fuel cell | mol/s (or kg/h) |
n_H2_net(t) |
Net flow into tank | mol/s |
3.4 KPIs and accounting
"the heart of the task"
| Symbol | Name | Unit | Notes |
|---|---|---|---|
unmet_crit(t) |
Unserved critical load | W | Must be near-zero — primary resilience KPI |
unmet_noncrit(t) |
Unserved non-critical load | W | Restated as a KPI for clarity |
curtailment(t) |
= P_PV_curtailed(t) |
W | |
cost(t) |
Operating cost of this step | € | TBD — see §5 |
CO2(t) |
Emissions of this step | kg CO₂ | TBD — see §5 |
3.5 Diagnostic / efficiency outputs
Recommended. Ties directly to AI Efficiency Improvements, which flagged ~30–40% electrolyser losses and ~40% fuel-cell losses as the biggest optimisation targets. If the simulator returns per-step efficiencies, the RL reward and the post-hoc analysis can both attack those losses directly.
| Symbol | Name | Unit |
|---|---|---|
eta_ele(t) |
Electrolyser efficiency this step | — |
eta_fc(t) |
Fuel cell efficiency this step | — |
eta_PV(t) |
Effective PV efficiency this step | — |
eta_batt(t) |
Battery round-trip-equivalent | — |
4. Priority rules the simulator enforces
Not I/O, but contract-level — the policy needs to know what the simulator will do with a setpoint that violates physics or safety.
- Critical load is sacred. If the policy's setpoints leave critical load unserved while the battery has charge, the fuel cell can run, or the grid is available, the simulator overrides the policy in that order and reports the override (e.g. via an output flag) so it shows up in training.
- State limits are hard.
SoC ∈ [SoC_min, SoC_max],H2_level ∈ [0, V_H2_max]. Setpoints that would breach these are clipped; the difference shows up asP_batt(t)vsu_batt(t). - Electrolyser dead-zone. Setpoints in
(0, P_ele_min)are rounded to 0. - Grid outage. If
grid_on(t) = 0thenP_grid(t) = 0regardless of slack residual; the residual becomesunmet_*orcurtailment.
5. Open questions
Need answers before v1.0.
- Cost & CO₂ scope. Flagged TBD in §3.4. If Economics handles these downstream, the
simulator only needs to return
P_grid(t)plus exogenousprice(t)andCO2_int(t), and Economics computes cost/CO₂ themselves. If the simulator computes them, it also needs to know whether there is an O&M cost per kWh through the electrolyser/fuel cell, a degradation cost, and so on. - Tank model. Isothermal + ideal gas, or do we need temperature and pressure dynamics?
- Battery degradation. Modelled or ignored?
- Sub-hourly dynamics. Does the battery's fast-response role require
dt < 1 h? If so, mixed time-scale handling between battery (minutes) and electrolyser (hours) becomes a design question. - Action space format. Continuous setpoints (
u_ele ∈ [0, P_ele_max]) vs. discrete buckets — affects what the RL team expects as input. - Forecast vs. realised exogenous inputs. The policy may see a forecast of
G(t+1)andL(t+1); the simulator advances with the realised values. Decide whether the simulator delivers both or only realised. - Critical vs non-critical split — data availability. Confirm with the hospital data source whether the load profile can actually be split, or whether we need a proxy fraction (e.g. assume X% of total load is critical).
- Mutual exclusion of electrolyser and fuel cell. Should the action space structurally prevent simultaneous operation (mode-switch / hybrid action space), or allow them independently and let the reward penalise simultaneous operation? Has efficiency, sample-efficiency, and policy-expressiveness trade-offs.
Cross-document notes
Three consistency issues between this document and its neighbours:
| Issue | Detail |
|---|---|
| Naming convention | This document uses physics-style symbols (P_PV, SoC(t), u_ele). RL State Variables and RL Action Variables use descriptive identifiers (PV_Generation, Battery_SOC, Electrolyzer_PowerSetpoint). Neither references the other; one must win. |
| State coverage | This sheet omits component temperatures, stack health, and water level, which the RL state doc lists. Consistent with the isothermal/no-degradation assumptions flagged TBD above. |
| Action coverage | This sheet accepts 5 control signals; the RL action doc lists 16. Grid import/export and load shedding are deliberately excluded here (slack bus, and outcome-not-action respectively); PV curtailment control, thermal management, and mode supervision are genuine gaps. |
Load-tier terminology also differs from Energy Management's
BIDMC/UCSD Energy Flow and Balances,
which uses a three-tier model (Tier 1 critical / Tier 2 essential / Tier 3 non-critical)
against this document's two-way split (L_crit / L_noncrit).
Related
- Shift Input Data — the predecessor variable list this sheet formalises
- RL State Variables · RL Action Variables · RL Reward Function
- Rule-Based Controller — the baseline policy that consumes this contract
- Forecasting Requirements — produces
G(t),L(t),price(t)