Skip to content

Commit d620b47

Browse files
committed
doc string updates
1 parent 4f72029 commit d620b47

10 files changed

Lines changed: 246 additions & 607 deletions

File tree

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ examples/wec_models/LUPA/temp/*
141141
*.mat
142142

143143
# Configuration files with user-specific paths
144-
src/wecgrid/wec/wecsim_config.json
145-
src/wecgrid/database/database_config.json
144+
src/wecgrid/modelers/wec_sim/wecsim_config.json
145+
src/wecgrid/util/database_config.json
146146

147147
.*
148148
!/.gitignore
@@ -155,4 +155,4 @@ src/wecgrid/database/database_config.json
155155

156156

157157
docs/examples/jupyter_notebooks/
158-
docs/examples/WECGrid.db
158+
docs/examples/WECGrid.db

docs/reference/api.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# API Reference
2+
3+
## Engine
4+
5+
::: wecgrid.Engine
6+
7+
## WEC
8+
9+
::: wecgrid.wec.WECFarm
10+
11+
::: wecgrid.wec.WECDevice
12+
13+
::: wecgrid.wec.WECSimRunner
14+
15+
## Modelers
16+
17+
### Base
18+
19+
::: wecgrid.modelers.power_system.base.GridState
20+
21+
::: wecgrid.modelers.power_system.base.SolveReport
22+
23+
::: wecgrid.modelers.power_system.base.PowerSystemModeler
24+
25+
### PSS®E
26+
27+
::: wecgrid.modelers.power_system.psse.PSSEModeler
28+
29+
### PyPSA
30+
31+
::: wecgrid.modelers.power_system.pypsa.PyPSAModeler
32+
33+
## Utilities
34+
35+
::: wecgrid.util.WECGridTime
36+
37+
::: wecgrid.util.WECGridDB
38+
39+
::: wecgrid.util.WECGridPlot

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,6 @@ nav:
115115
- Preloaded Database: data/preloaded_database.md
116116
- Reference:
117117
- Performance Metrics: reference/performance_metrics.md
118+
- API Reference: reference/api.md
118119
- Troubleshooting: reference/troubleshooting.md
119120
- Citation: reference/citation.md

src/wecgrid/engine.py

Lines changed: 55 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
"""Top-level orchestration for WEC-Grid simulations.
1+
"""Simulation orchestration for WEC-Grid.
22
3-
Defines the :class:`Engine` that coordinates WEC farms, power system modelers,
4-
database access, and visualization utilities. The module links PSS®E and
5-
PyPSA backends, manages time through :class:`WECGridTime`, and integrates
6-
WEC-Sim for device-level modeling.
3+
Provides the :class:`Engine` entry point that wires together WEC farms,
4+
power-system modelers (PSS®E, PyPSA), time management, a results database,
5+
and plotting utilities.
76
"""
87

98
# Standard library
@@ -22,28 +21,22 @@
2221

2322

2423
class Engine:
25-
"""Main orchestrator for WEC-Grid simulations.
24+
"""Top-level controller for WEC-Grid simulations.
2625
27-
Coordinates Wave Energy Converter (WEC) farm integration with PSS®E
28-
and PyPSA power system modeling backends. Manages simulation
29-
workflows, time synchronization, and visualization for grid studies.
26+
Coordinates WEC farm integration with PSS®E and/or PyPSA, manages
27+
simulation time, and provides access to the database and plotting.
3028
3129
Attributes:
32-
case_file (Optional[str]): Path to the power system case file
33-
(RAW format).
34-
case_name (Optional[str]): Human-readable identifier for the
35-
loaded case.
36-
time (WECGridTime): Manages simulation time and snapshots.
37-
psse (Optional[PSSEModeler]): PSS®E simulation backend.
38-
pypsa (Optional[PyPSAModeler]): PyPSA simulation backend.
39-
wec_farms (List[WECFarm]): Collection of WEC farms in the
40-
simulation.
41-
database (WECGridDB): Interface for reading/writing simulation
42-
data.
43-
plot (WECGridPlot): Visualization and plotting utilities.
44-
wecsim (WECSimRunner): WEC-Sim integration for device-level
45-
hydrodynamic modeling.
46-
sbase (Optional[float]): System base power in MVA.
30+
case_file: Path to the input case file (RAW/SAV).
31+
case_name: Human-readable case identifier.
32+
time: Time manager (:class:`WECGridTime`).
33+
psse: PSS®E modeler instance or ``None``.
34+
pypsa: PyPSA modeler instance or ``None``.
35+
wec_farms: WEC farms added to the simulation.
36+
database: Database interface (:class:`WECGridDB`).
37+
plot: Plotting utilities (:class:`WECGridPlot`).
38+
wecsim: WEC-Sim runner (:class:`WECSimRunner`).
39+
sbase: System base power [MVA] once a modeler is initialized.
4740
"""
4841

4942
def __init__(self):
@@ -66,12 +59,7 @@ def __init__(self):
6659

6760

6861
def __repr__(self) -> str:
69-
"""Return a string representation of the engine state.
70-
71-
Returns:
72-
str: Tree-style summary of loaded case, modelers, farms,
73-
and system base power (MVA).
74-
"""
62+
"""Return a compact tree-style summary of the engine state."""
7563
return (
7664
f"Engine:\n"
7765
f"├─ Case: {self.case_name}\n"
@@ -84,34 +72,27 @@ def __repr__(self) -> str:
8472
)
8573

8674
def case(self, case_file: str):
87-
"""Specify the power system case file for subsequent loading.
75+
"""Set the power-system case file to load later.
8876
8977
Args:
90-
case_file (str): Path or identifier for a PSS®E RAW case file.
91-
Full paths, bundled cases like ``IEEE_30_bus``, or filenames
92-
such as ``IEEE_39_bus.RAW`` are supported.
93-
94-
Notes:
95-
This method only stores the file path and a human-friendly name.
96-
It does not check whether the file exists or is valid.
97-
Only PSS®E RAW (``.RAW``) format is supported.
78+
case_file: Path or identifier for a case file (RAW/SAV).
79+
80+
Note:
81+
This only records the path and a friendly name; it does not
82+
validate file existence or format.
9883
"""
9984

10085
self.case_file = str(case_file)
10186
self.case_name = Path(case_file).stem.replace("_", " ").replace("-", " ")
10287

10388
def load(self, software: List[str]) -> None:
104-
"""Initialize power system simulation backends.
89+
"""Initialize one or more modelers.
10590
10691
Args:
107-
software (List[str]): List of backends to initialize.
108-
Supported values are ``"psse"`` and ``"pypsa"``.
92+
software: Iterable of backends to initialize ("psse", "pypsa").
10993
11094
Raises:
111-
ValueError: If no case file has been set or if an invalid
112-
backend name is provided.
113-
RuntimeError: If backend initialization fails (e.g. missing
114-
license or API issue).
95+
ValueError: If no case is set or an unsupported backend is given.
11596
"""
11697
if self.case_file is None:
11798
raise ValueError(
@@ -144,27 +125,21 @@ def apply_wec(
144125
wec_sim_id: int = 1,
145126
bus_location: int = 1,
146127
connecting_bus: int = 1, # todo this should default to swing bus
147-
scaling_factor: int = 1, # used for scaling wec power output
128+
scaling_factor: float = 1.0, # used for scaling WEC power output
148129
) -> None:
149-
"""Add a Wave Energy Converter (WEC) farm to the power system.
130+
"""Add a WEC farm connected at a bus.
150131
151132
Args:
152-
farm_name (str): Human-readable WEC farm identifier.
153-
size (int, optional): Number of WEC devices in the farm.
154-
Defaults to ``1``.
155-
wec_sim_id (int, optional): Database simulation ID for WEC data.
156-
Defaults to ``1``.
157-
bus_location (int, optional): Grid bus for WEC connection.
158-
Defaults to ``1``.
159-
connecting_bus (int, optional): Network topology connection bus.
160-
Defaults to ``1``.
161-
scaling_factor (int, optional): Multiplier applied to WEC power
162-
output (unitless). Defaults to ``1``.
163-
164-
Notes:
165-
- Farm power scales linearly with device count.
166-
- WEC data is sourced from the database using ``wec_sim_id``.
167-
- Generator IDs are auto-assigned sequentially based on farm order.
133+
farm_name: Farm identifier.
134+
size: Number of identical devices in the farm.
135+
wec_sim_id: WEC-Sim run ID in the database.
136+
bus_location: Bus number to connect the WEC farm.
137+
connecting_bus: Existing bus to which the new bus/branch ties.
138+
scaling_factor: Linear multiplier applied to device power.
139+
140+
Note:
141+
Power scales with ``size`` and ``scaling_factor``. Modelers are
142+
updated if already loaded.
168143
"""
169144
wec_farm: WECFarm = WECFarm(
170145
farm_name=farm_name,
@@ -200,45 +175,27 @@ def generate_load_curves(
200175
evening_peak_hour: float = 18.0,
201176
morning_sigma_h: float = 2.0,
202177
evening_sigma_h: float = 3.0,
203-
amplitude: float = 0.05, # ±30% swing around mean
178+
amplitude: float = 0.05, # ±5% swing around mean
204179
min_multiplier: float = 0.50, # floor/ceiling clamp
205180
amp_overrides: Optional[Dict[int, float]] = None,
206181
) -> pd.DataFrame:
207-
"""Generate realistic, time-varying load profiles.
208-
209-
Produces bus-specific demand time series with a double-peak
210-
(morning/evening) daily pattern. Profiles scale base case loads
211-
with configurable timing and variability.
182+
"""Create simple double-peak daily load multipliers (per-unit).
212183
213184
Args:
214-
morning_peak_hour (float, optional): Morning demand peak time
215-
(hours). Defaults to ``8.0``.
216-
evening_peak_hour (float, optional): Evening demand peak time
217-
(hours). Defaults to ``18.0``.
218-
morning_sigma_h (float, optional): Width of the morning peak
219-
(hours). Defaults to ``2.0``.
220-
evening_sigma_h (float, optional): Width of the evening peak
221-
(hours). Defaults to ``3.0``.
222-
amplitude (float, optional): Maximum variation around base load.
223-
Defaults to ``0.05`` (±5%).
224-
min_multiplier (float, optional): Minimum scaling factor for load.
225-
Defaults to ``0.50``.
226-
amp_overrides (Dict[int, float], optional): Per-bus amplitude
227-
overrides. Keys are bus numbers.
185+
morning_peak_hour: Morning peak time [h].
186+
evening_peak_hour: Evening peak time [h].
187+
morning_sigma_h: Morning peak width [h].
188+
evening_sigma_h: Evening peak width [h].
189+
amplitude: Max variation (e.g., 0.05 for ±5%).
190+
min_multiplier: Floor for the multiplier.
191+
amp_overrides: Optional per-bus amplitude overrides.
228192
229193
Returns:
230-
pd.DataFrame: Time-indexed load profiles in MW.
231-
- Index: simulation snapshots
232-
- Columns: bus numbers
233-
- Values: active power demand
194+
DataFrame indexed by simulation snapshots with bus-number columns
195+
and per-unit load values as entries.
234196
235197
Raises:
236-
ValueError: If no power system modeler is loaded.
237-
238-
Notes:
239-
- Short simulations (<6h) produce flat load profiles.
240-
- PSS®E base loads use system MVA base.
241-
- PyPSA base loads are aggregated per bus.
198+
ValueError: If no modeler is loaded to provide base loads.
242199
"""
243200
if self.psse is None and self.pypsa is None:
244201
raise ValueError(
@@ -320,28 +277,12 @@ def g(h, mu, sig):
320277
def simulate(
321278
self, num_steps: Optional[int] = None, load_curve: bool = False, strict_convergence: bool = False
322279
) -> None:
323-
"""Run time-series power system simulations.
280+
"""Run a time-series simulation across loaded modelers.
324281
325282
Args:
326-
num_steps (int | None, optional): Number of simulation steps.
327-
If ``None``, the maximum length available is used, constrained
328-
by WEC data if present.
329-
load_curve (bool, optional): Whether to enable time-varying load
330-
profiles. Defaults to ``False``.
331-
strict_convergence (bool, optional): Whether to stop on the first
332-
convergence failure. Defaults to ``False``.
333-
334-
Raises:
335-
ValueError: If no power system modelers are loaded.
336-
337-
Notes:
338-
- All backends use identical time snapshots for comparison.
339-
- WEC data length limits simulation duration.
340-
- Load curves use reduced amplitude (10%) for realism.
341-
- Results are available through ``engine.psse.grid`` and
342-
``engine.pypsa.grid``.
343-
- ``strict_convergence=True`` enforces classical power system
344-
analysis behavior.
283+
num_steps: Optional number of steps to run; defaults to available data.
284+
load_curve: If True, apply synthetic per-unit load multipliers.
285+
strict_convergence: Reserved for future use.
345286
"""
346287

347288
# show that if different farms have different wec durations this logic fails
@@ -373,4 +314,3 @@ def simulate(
373314
for modeler in [self.psse, self.pypsa]:
374315
if modeler is not None:
375316
modeler.simulate(load_curve=load_curve_df)
376-
# todo if plot then plot

0 commit comments

Comments
 (0)