Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/src/explanation/buses_type_explanation.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ misleading results in large or radially structured networks.
+ Unknown: Real Power ($P$) and Reactive Power ($Q$). These values are calculated as residuals after the power flow solution converges to account for system losses and imbalances and are allocated using participation factors in the model formulation.
+ This kind of bus absorbs or supplies the difference between the total generation and total load plus losses in the system. There can be several slack buses in a system.

- Ref:
- `REF`:

+ Known: Voltage Magnitude ($|V|$) and Voltage Angle ($\delta$). Typically, the angle is set to 0 degrees for simplicity, and the voltage is set to a fixed value per unit.0 degrees for simplicity and the voltage is set to a fixed value per unit.
+ Known: Voltage Magnitude ($|V|$) and Voltage Angle ($\delta$). Typically, the angle is set to 0 degrees for simplicity, and the voltage is set to a fixed value per unit.
+ Unknown: Real Power ($P$) and Reactive Power ($Q$). These values are calculated as residuals after the power flow solution converges to account for system losses and imbalances when there is a single slack bus that matches the reference bus.
+ Serves as the "reference" for all other bus voltage angles in the AC interconnected system.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ generation rather than passive demand. This is also known as "Dispatchable Deman

In `PowerSystems.jl`, these distinctions surface in two places:

1. **The `conformity` field.** Concrete subtypes of [`StaticLoad`](@ref) carry a
1. **The `conformity` field.** Most concrete subtypes of [`StaticLoad`](@ref) carry a
`conformity` field that records whether a load is conforming or non-conforming (see the
[`LoadConformity`](@ref)). This field exists for monitoring and
bookkeeping purposes — it allows downstream tools and analysts to identify which loads
Expand Down
4 changes: 1 addition & 3 deletions docs/src/explanation/dynamic_data.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
A **dynamic device** is a power system component whose behavior is described by differential equations that evolve over time, rather than by a single steady-state operating point. Dynamic devices capture the [transient response](https://en.wikipedia.org/wiki/Transient_response) of equipment — such as how a generator's rotor speed, voltage, or current changes in the milliseconds to seconds following a disturbance. In `PowerSystems.jl`, every dynamic device is attached to a corresponding [static](@ref S) component that provides the power flow
solution, while the dynamic component adds the differential equations needed for transient stability and electromagnetic simulation.

A dynamic device has two data layers, the static data layer with static components, and the dynamic data layer with dynamic components.

## Static and Dynamic Data Layers

`PowerSystems.jl` uses two categories to define data for dynamic simulations:

1. [Static](@ref S) components, which includes the data needed to run a power flow problem
2. [Dynamic](@ref D) components are those that define differential equations to run a transient simulation. **These dynamic data are attached to the static components.**

Although `PowerSystems.jl` is not constrained to only PSS/e files, commonly the data for a dynamic simulation comes in a pair of files: One for the static data power flow case (e.g.,`.raw` file) and a second one with the dynamic components information (e.g., `.dyr` file). However, `PowerSystems.jl` is able to take any power flow case and specify dynamic components to it. The two data layers in `PowerSystems.jl`, static components and dynamic components, are similar to the data division between the static and dynamic data layers.
This division mirrors how dynamic simulation data is commonly distributed: a power flow case (e.g., a PSS/e `.raw` file) paired with a file of dynamic component data (e.g., a `.dyr` file). `PowerSystems.jl` is not constrained to PSS/e files, however — it can take any power flow case and attach dynamic components to it.

### Layer 1: Static Components

Expand Down
7 changes: 4 additions & 3 deletions docs/src/explanation/per_unit.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ change manually, see

!!! note

The return value of the getter functions, e.g., [`get_x`](@ref) for the transformer
impedances will perform these transformations automatically, following the convention
described on this page.
The getter functions, e.g., [`get_x`](@ref) for the transformer impedances, apply the
MVA-ratio part of this conversion automatically, assuming the transformer's rated
voltages match the base voltages of its buses. If they differ, the voltage-ratio
correction must be applied manually before storing the impedance.
56 changes: 16 additions & 40 deletions docs/src/explanation/power_concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,33 @@ When working with generators in PowerSystems.jl, it's important to understand th

## Base Power

**Base power** is the reference power value used for per-unitization of a specific device.
**Base power** is the reference power value used for per-unitization of a specific
device — the denominator when converting device parameters to per-unit values, typically
the nameplate capacity. It answers: "What is the natural scale of this device?"

- **Purpose**: Serves as the denominator when converting device parameters to per-unit values
- **Units**: Always stored in **natural units** (MVA)
- **Typical value**: The nameplate capacity of the device
- **Access**: Retrieved using [`get_base_power(device)`](@ref)

Base power is a fundamental parameter for the per-unit system and represents the natural scale of the device. For more details on per-unitization, see the [Per-unit Conventions](@ref per_unit) page.
Base power is a fundamental parameter for the per-unit system. For more details on per-unitization, see the [Per-unit Conventions](@ref per_unit) page.

## Rating

**Rating** represents the maximum AC side output power rating of the synchronous machine or generator.

- **Purpose**: Defines the maximum apparent power (MVA) that the generator's electrical components can safely handle

- **Units**: Stored in per-unit using **device base** (i.e., divided by the device's `base_power`)
**Rating** represents the maximum AC side output power rating of the synchronous machine
or generator — the maximum apparent power (MVA) that the generator's electrical
components can safely handle, considering constraints such as:

- **Physical meaning**: The maximum MVA output considering electrical constraints such as:

+ Stator winding thermal limits
+ Rotor field winding limits
+ Cooling system capacity

- **Access**: Retrieved using [`get_rating(device)`](@ref)
- Stator winding thermal limits
- Rotor field winding limits
- Cooling system capacity

The rating is typically determined by the electrical design and thermal limits of the synchronous machine itself. It represents the maximum capability of the electrical generator, independent of the prime mover.

## Maximum Active Power

**Maximum active power** represents the maximum real power output of the prime mover.

- **Purpose**: Defines the maximum real power (MW) that the prime mover can deliver
**Maximum active power** represents the maximum real power (MW) output of the prime
mover, considering constraints such as:

- **Units**: Stored in per-unit using **device base** (i.e., divided by the device's `base_power`)

- **Physical meaning**: The maximum MW output considering prime mover constraints such as:

+ Turbine capacity (for steam, gas, or hydro turbines)
+ Combustion chamber limits (for gas turbines)
+ Boiler capacity (for steam generators)
+ Fuel flow limitations

- **Access**: Retrieved using [`get_max_active_power(device)`](@ref)
- Turbine capacity (for steam, gas, or hydro turbines)
- Combustion chamber limits (for gas turbines)
- Boiler capacity (for steam generators)
- Fuel flow limitations

The maximum active power is determined by the mechanical system that drives the generator. This is often less than the rating when considering only real power production.

Expand All @@ -60,14 +44,6 @@ The maximum active power is determined by the mechanical system that drives the
| Rating | Device base (p.u.) | [`get_rating()`](@ref) |
| Max Active Power | Device base (p.u.) | [`get_max_active_power()`](@ref) |

### Physical Interpretation

The relationship between these three quantities can be understood as follows:

- **Base Power**: "What is the natural scale of this device?"
- **Rating**: "What is the maximum apparent power the electrical generator can produce?"
- **Max Active Power**: "What is the maximum real power the prime mover can deliver?"

### Example

Consider a thermal generator with:
Expand Down
28 changes: 5 additions & 23 deletions docs/src/explanation/supplemental_attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ maintenance, and no validation of what was stored.

Supplemental attributes address this by using structured types instead of loose dictionaries.
Electrical behavior stays in component definitions; contextual information lives in
attributes that can be attached, queried, and shared explicitly.
attributes that can be attached, queried, and shared explicitly. This lets you build models
in layers (electrical first, context later), reuse contextual data across systems, and
update outage schedules or emissions profiles without touching electrical models — while
keeping the speed of in-memory data rather than relying on heavyweight component objects or
an external relationship database.

## How relationships work

Expand All @@ -41,28 +45,6 @@ flowchart LR
This flexibility matches how power systems actually work, where components share resources
and are affected by common factors.

## Benefits for modelers

This design changes how you build power system models:

- **Build in layers**: Start with electrical models, then add contextual information separately.
- **Reuse data**: Geographic info and weather patterns can be applied to multiple systems.
- **Work in teams**: Different people can work on electrical models and contextual data independently.
- **Easy updates**: Change outage schedules or emissions profiles without touching electrical models.

## Compared to other approaches

Other power system tools handle contextual data differently:

**Heavy objects approach**: Some tools put all contextual data directly into component
definitions. This makes objects large and unwieldy for big systems.

**External database approach**: Others store relationships in separate databases. This can
slow things down and complicate deployment.

**PowerSystems.jl's approach**: Combines the speed of in-memory data with the relationship
modeling power typically found only in databases. This works well for interactive analysis.

## What kinds of contextual data are available?

PowerSystems.jl provides supplemental attribute types for common modeling needs. Each topic
Expand Down
29 changes: 15 additions & 14 deletions docs/src/explanation/three_winding_transformers.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## The "Starbus" Representation

The resulting $Z_{12}, Z_{23},$ and $Z_{13}$ represent the series impedances in a star network. The common point of this star network is the conceptual "starbus" or internal neutral node. Each winding's terminal in the power system network is then connected to its corresponding impedance in this equivalent star.
The measured pairwise leakage impedances $Z_{12}, Z_{23},$ and $Z_{13}$ between each pair of windings are converted into the equivalent star impedances $Z_1, Z_2,$ and $Z_3$. The common point of this star network is the conceptual "starbus" or internal neutral node. Each winding's terminal in the power system network is then connected to its corresponding impedance in this equivalent star.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jd-lara I leave this to you to verify correctness on this point


```mermaid
graph TD
Expand All @@ -30,32 +30,33 @@ PSS®E represents a [`Transformer3W`](@ref) as a single element with a dedicated

It does not explicitly store the equivalent star (wye) impedances. Instead, it stores the following:

- Positive Sequence Impedance (R1-2, X1-2): Resistance and reactance between winding 1 (primary) and winding 2 (secondary) in per-unit on the transformer's base MVA.
- Positive Sequence Impedance (R1-2, X1-2): Resistance and reactance between winding 1 (primary) and winding 2 (secondary).

- Positive Sequence Impedance (R1-3, X1-3): Resistance and reactance between winding 1 (primary) and winding 3 (tertiary) in per-unit on the transformer's base MVA.
- Positive Sequence Impedance (R1-3, X1-3): Resistance and reactance between winding 1 (primary) and winding 3 (tertiary).

- Positive Sequence Impedance (R2-3, X2-3): Resistance and reactance between winding 2 (secondary) and winding 3 (tertiary) in per-unit on the transformer's base MVA.
- Positive Sequence Impedance (R2-3, X2-3): Resistance and reactance between winding 2 (secondary) and winding 3 (tertiary).

- Star Bus Number: The star bus number is optional and it might be represented or not.

The per-unit base of the impedance fields depends on the record's CZ flag: system base MVA
when CZ = 1, or the corresponding winding-pair base (SBASE1-2, etc.) when CZ = 2. The
parser handles both conventions.

### Magnetizing Admittance

- Magnetizing Conductance (GMAG1): Core loss conductance in per-unit on the transformer's base MVA, usually referred to the primary winding.
- Magnetizing Susceptance (BMAG1): Magnetizing susceptance in per-unit on the transformer's base MVA, usually referred to the primary winding.
- Magnetizing Admittance (MAG1, MAG2): Core loss conductance and magnetizing susceptance, referred to the winding 1 bus. The base depends on the record's CM flag: per-unit on the system base when CM = 1, or no-load loss in watts and exciting current when CM = 2.

### Tap Settings and Phase Shift

- Winding 1 Tap Ratio (RATIO1): Tap ratio for the primary winding.
- Winding 2 Tap Ratio (RATIO2): Tap ratio for the secondary winding.
- Winding 3 Tap Ratio (RATIO3): Tap ratio for the tertiary winding.
- Phase Shift (ANGLE1, ANGLE2, ANGLE3): Phase shift in degrees applied by each winding.
- Winding Tap Ratios (WINDV1, WINDV2, WINDV3): Off-nominal turns ratio of each winding, either in per-unit of the connected bus base voltage (CW = 1) or as a winding voltage in kV (CW = 2).
- Nominal Voltages (NOMV1, NOMV2, NOMV3): Nominal (rated) voltage of each winding in kV.
- Phase Shift (ANG1, ANG2, ANG3): Phase shift in degrees applied by each winding.

### Winding Ratings

- Winding 1 MVA Base (SBASE1): Base apparent power for winding 1.
- Winding 2 MVA Base (SBASE2): Base apparent power for winding 2.
- Winding 3 MVA Base (SBASE3): Base apparent power for winding 3.
- Nominal Voltages (WINDV1, WINDV2, WINDV3): Nominal voltage levels of each winding in kV.
- Winding 1 MVA Base (SBASE1-2): Base apparent power for the winding 1-2 pair.
- Winding 2 MVA Base (SBASE2-3): Base apparent power for the winding 2-3 pair.
- Winding 3 MVA Base (SBASE3-1): Base apparent power for the winding 3-1 pair.

### Control Information (Optional)

Expand Down
33 changes: 6 additions & 27 deletions docs/src/explanation/time_series.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,34 +83,13 @@ hourly-updated forecast and a daily-updated forecast for the same quantity.

Use [`transform_single_time_series!`](@ref) with `delete_existing = false` to create
multiple [`DeterministicSingleTimeSeries`](@ref) transforms from the same
[`SingleTimeSeries`](@ref), each with a different interval:
[`SingleTimeSeries`](@ref), each with a different interval. When multiple forecasts share
the same name and resolution, the `interval` keyword argument must be specified to
disambiguate retrieval and removal; omitting it raises an `ArgumentError`.

```julia
# Create a 30-minute interval forecast
transform_single_time_series!(sys, Hour(1), Minute(30); delete_existing = false)
# Create a 1-hour interval forecast from the same underlying data
transform_single_time_series!(sys, Hour(1), Hour(1); delete_existing = false)
```

When multiple forecasts share the same name and resolution, you must specify the `interval`
keyword argument to disambiguate retrieval and removal:

```julia
# Retrieve a specific interval's forecast
ts = get_time_series(DeterministicSingleTimeSeries, component, "max_active_power";
interval = Minute(30))

# Query forecast parameters for a specific interval
get_forecast_horizon(sys; interval = Minute(30))
get_forecast_initial_times(sys; interval = Hour(1))

# Remove only one interval's forecasts
remove_time_series!(sys, DeterministicSingleTimeSeries, component, "max_active_power";
interval = Minute(30))
```

Omitting `interval` when multiple intervals exist for the same name will raise an
`ArgumentError`.
For a worked example, see the
[Transform with Multiple Intervals](@ref "Working with Time Series Data") section of the
time series tutorial.

## Data Storage

Expand Down
11 changes: 0 additions & 11 deletions docs/src/explanation/transformer_per_unit_models.md

This file was deleted.

28 changes: 6 additions & 22 deletions docs/src/how_to/add_supplemental_attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,22 @@ outage = FixedForcedOutage(; outage_status = 0.0) # 0.0 = available, 1.0 = outa
add_supplemental_attribute!(sys, gen, outage)
```

## Attach attributes in bulk
## Attach attributes in bulk and share them across components

For adding many attributes at once, use [`begin_supplemental_attributes_update`](@ref)
to batch the operations. This reduces index update overhead and automatically reverts
all changes if an error occurs:
all changes if an error occurs. The same attribute instance can be attached to more than
one component to model shared properties:

```@example attach_contextual_data
gens = collect(get_components(ThermalStandard, sys))
gen1 = gens[1]
gen2 = gens[2]
outage1 = FixedForcedOutage(; outage_status = 0.0)
outage2 = FixedForcedOutage(; outage_status = 1.0)
shared_outage = FixedForcedOutage(; outage_status = 1.0)

begin_supplemental_attributes_update(sys) do
add_supplemental_attribute!(sys, gen1, outage1)
add_supplemental_attribute!(sys, gen2, outage2)
end
```

## Share one attribute across multiple components

Attach the same attribute instance to more than one component to model shared properties:

```@example attach_contextual_data
outage = FixedForcedOutage(; outage_status = 1.0)
gens = collect(get_components(ThermalStandard, sys))
gen1 = gens[1]
gen2 = gens[2]

begin_supplemental_attributes_update(sys) do
add_supplemental_attribute!(sys, gen1, outage)
add_supplemental_attribute!(sys, gen2, outage)
add_supplemental_attribute!(sys, gen1, shared_outage)
add_supplemental_attribute!(sys, gen2, shared_outage)
end
```

Expand Down
Loading
Loading