ALLSHIFT/docs/02-specifications/simulator-io-interface.md
pepe 72dd781dbc Organize documentation into docs/ and superseded/
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>
2026-07-25 21:20:33 -07:00

320 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SHIFT Simulator — Input/Output Interface
> **Markdown report of a non-markdown source document.**
>
> | | |
> |---|---|
> | **Source** | [`docs/_originals/Simulator Interface Input-Output sheet.pdf`](../_originals/Simulator%20Interface%20Input-Output%20sheet.pdf) |
> | **Format** | PDF, 10 pages, 556 kB |
> | **MD5** | `0712f05593c39897abc8f651834bebde` |
> | **Owner** | 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](../04-simulations/shift-input-data.md) — §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](#4-priority-rules-the-simulator-enforces)).
### 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.950.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 | — (01) | |
| `SoC_min`, `SoC_max` | Operating window | — (01) | E.g. 0.10.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 | — (01) |
| `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](#5-open-questions) |
| `CO2(t)` | Emissions of this step | kg CO₂ | TBD — see [§5](#5-open-questions) |
### 3.5 Diagnostic / efficiency outputs
Recommended. Ties directly to
[AI Efficiency Improvements](../01-project/ai-efficiency-improvements.md), which flagged
~3040% 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.
1. **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.
2. **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 as `P_batt(t)` vs
`u_batt(t)`.
3. **Electrolyser dead-zone.** Setpoints in `(0, P_ele_min)` are rounded to 0.
4. **Grid outage.** If `grid_on(t) = 0` then `P_grid(t) = 0` regardless of slack residual; the
residual becomes `unmet_*` or `curtailment`.
---
## 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 exogenous `price(t)` and `CO2_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)` and
`L(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](rl-state-variables.md) and [RL Action Variables](rl-action-variables.md) 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](../03-energy-management/bidmc-ucsd-energy-flow-and-balances.md),
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](../04-simulations/shift-input-data.md) — the predecessor variable list this sheet formalises
- [RL State Variables](rl-state-variables.md) · [RL Action Variables](rl-action-variables.md) · [RL Reward Function](rl-reward-function.md)
- [Rule-Based Controller](rule-based-controller.md) — the baseline policy that consumes this contract
- [Forecasting Requirements](forecasting-requirements.md) — produces `G(t)`, `L(t)`, `price(t)`