ALLSHIFT/docs/04-simulations/pv-battery-simulink.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

148 lines
7.6 KiB
Markdown
Raw 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.

# PV + Battery Simulink Model
> **Markdown report consolidating two non-markdown sources plus one duplicate markdown file.**
>
> | | |
> |---|---|
> | **Sources** | `Shift Matlab Drive/.../Simulations/PV+Battery Simulink/PV+Battery.docx`<br>`Shift Matlab Drive/.../Simulations/PV+Battery Simulink/PVBatteryRead.mlx`<br>`Shift Matlab Drive/.../Simulations/PV+Battery Simulink/Constants.mlx` |
> | **Also duplicated as** | `PV+Battery.md` at the repository root — **retired to [`superseded/`](../../superseded/)** |
> | **Owner** | Simulations cluster |
> | **Status** | Current — **model has a known unresolved bug** (see [Known issue](#known-issue--model-is-not-time-dependent)) |
> | **Report generated** | 2026-07-25 |
## What this is
The Simulations cluster's first end-to-end vertical slice: read real profile data out of a
spreadsheet, hand it to Simulink, and run coupled PV and battery models against it. It is a
methodology trial as much as a model — the closing question in the source is *"Discuss if this
is a good standard for all parts."*
## Components
### 1. Profiles SHIFT (spreadsheet)
- A new tab has been added to the existing Excel data sheet.
- Quick-search data has been filled in for fast experimentation with the Simulink models.
See [Generation Profiles Workbook](generation-profiles-workbook.md) for the sheet contents.
### 2. `PVBatteryRead.mlx`
- Code developed with large assistance from ChatGPT.
- Originally intended to read *everything* off the spreadsheet; it currently reads **dynamic
data** and prepares it for Simulink use.
- The constants reading would not function, for reasons not established — so constants are set
in `Constants.mlx` instead.
**What the script actually does**, step by step:
| Step | Behaviour |
|---|---|
| File settings | Reads `Profiles SHIFT(Generators Factors + Battery).xlsx`, sheet **`Fake Simulink Data`**, with `HeaderLines = 1` and `VariableNamingRule = 'preserve'` |
| 1 — Type conversion | Converts cell-text numbers to double, **replacing `,` with `.`** for decimal commas; converts `duration` columns to hours |
| 2 — Trim | Detects the last valid signal row (any non-NaN numeric, and a date after 2000-01-01) and truncates the table there |
| 3 — Extract | Parses variable names out of headers of the form `Name - var (unit)` via the regex `-\s*(.*?)\s*\(`, then `matlab.lang.makeValidName`. Time (`t`) is converted to **seconds** — a max ≤ 1 is treated as fraction-of-day, otherwise as hours. A column whose values are all identical becomes a **constant**; otherwise a time series |
| 4 — Simulink signals | For every numeric variable of the same length as `t`, creates `<name>_simulink = [t, values]` in the base workspace — the two-column `[time, data]` format Simulink's *From Workspace* block expects |
> The sheet name is literally **`Fake Simulink Data`** — placeholder data for wiring up the
> pipeline, not a real profile.
### 3. `Constants.mlx`
Remember to run this **and** `PVBatteryRead.mlx` before attempting to run the Simulink models.
```matlab
A_PV = 3060; % PV Area (m2)
mu_PV = 0.2; % Panel Efficiency (%)
V_PV = 24; % PV Voltage (V)
P_ele = 1500000; % Electrolyzer Power Consumption (W)
E_t0 = 0; % Initial Battery Energy (Wh)
E_rated = 170000; % Battery Rated Energy (W)
Q_rated = 100000; % Battery Rated Charge Capacity (W)
Charge_max = 1; % Maximum Charge (%)
Disharge_max = 2; % Maximum Discharge (%)
SoC_max = 1; % SoC limit (%)
SoC_t0 = 0; % Initial SoC (%)
P_B_int = 0; % Initial Battery power (W)
I_B_int = 0; % Initial Battery current (A)
```
**Parameter cross-check against the project spec:**
| Constant | Value here | Project spec | Comment |
|---|---|---|---|
| `A_PV` | 3060 m² | **2,300 m²** ([Simulator I/O §1.4](../02-specifications/simulator-io-interface.md#14-pv)) | 33% larger than spec |
| `mu_PV` | 0.2 | — | Reasonable for commercial silicon |
| `P_ele` | 1.5 MW | — | Large relative to a 2,300 m² × 20% array (~460 kW peak) |
| `E_rated` | 170000, commented **W** | Rated energy capacity in **Wh** | Unit comment is wrong; should be Wh |
| `Q_rated` | 100000, commented **W** | Rated charge capacity in **Ah** | Unit comment is wrong; should be Ah |
| `Disharge_max` | 2 | — | Commented "%" but a discharge *limit* of 2 with `SoC_max = 1` is dimensionally inconsistent. Also a typo for `Discharge_max` |
| `SoC_t0` | 0 | — | Starting from an empty battery |
None of these break the model — they are annotation errors and a not-yet-calibrated parameter
set — but they should be reconciled with the simulator contract before results are quoted.
### 4. `SolarPanel.slx` + `Battery.slx` (and `SolarPanel_n_Battery.slx`)
- Two individual models using the equations from *paper 1* to derive the desired outputs over
time.
- **Both do this in two different ways**, using different variables, to compare consistency.
- Most SoC-related quantities are handled in **%**. The dynamic data found is likely in
another unit — that is what `Q_rated` and `E_rated` are for, to be used according to paper 1.
## Known issue — model is not time-dependent
> *"An issue was encountered where this code does not appear to be time dependant despite
> drawing the appropriate `_simulink` matrices from the workspace. This is most likely some
> kind of conversion issue between time in seconds in code and time measured in the simulinks
> themselves."*
This is unresolved and is the first item on the to-do list. The author's diagnosis is
consistent with what `PVBatteryRead.mlx` does: it converts `t` to **seconds** in step 3, so any
Simulink block configured in hours — or a solver whose stop time is set in hours — will see a
signal that appears constant across the run because the simulated interval covers only the
first few samples.
**Where to look first:** the `[t, values]` matrices are built with `t` in seconds; check the
Simulink model's configured stop time and the *From Workspace* block's sample-time
interpretation match that unit.
## To be continued
Carried forward verbatim from the source:
- Fix the aforementioned time-dependency issue.
- Test and see if these values make sense. Compare the two versions for both.
- Discuss if this is a good standard for all parts.
## File locations
All of these files were submitted on MATLAB Drive and ClickUp under
*Simulations → PV+Battery Simulink*. In this repository:
| File | Size | Note |
|---|---|---|
| `PV+Battery.docx` | 1.6 kB | Source of this report |
| `PVBatteryRead.mlx` | — | Data import script |
| `Constants.mlx` | — | Parameter definitions |
| `SolarPanel.slx` | — | PV model |
| `Battery.slx` | — | Battery model |
| `SolarPanel_n_Battery.slx` | — | Combined model |
| `SolarPanel.slxc` | — | Simulink cache — build artefact |
| `Profiles SHIFT(Generators Factors + Battery).xlsx` | — | Byte-identical to the copy in `Current Framework/` |
| `slprj/` | — | Simulink build cache — machine-generated |
## Duplicate source note
The repository root contained `PV+Battery.md`, a markdown transcription of `PV+Battery.docx`
with the same content. Since this report supersedes both, the root markdown copy is retired to
[`superseded/`](../../superseded/) and the `.docx` remains in place as the original.
## Related
- [Generation Profiles Workbook](generation-profiles-workbook.md) — the spreadsheet this reads
- [MATLAB Live Scripts](matlab-live-scripts.md) — inventory of all `.mlx` files
- [Simulink Model Inventory](simulink-model-inventory.md) — all `.slx` files and their lineage
- [Simulator I/O Interface §1.41.5](../02-specifications/simulator-io-interface.md#14-pv) — the parameter spec these constants should match