Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
8 changes: 8 additions & 0 deletions src/power_grid_model_ds/_core/model/arrays/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
"""

from power_grid_model_ds._core.model.arrays.pgm_arrays import (
AsymCurrentSensorArray,
AsymLineArray,
AsymVoltageSensorArray,
Branch3Array,
BranchArray,
GenericBranchArray,
IdArray,
LineArray,
LinkArray,
NodeArray,
SourceArray,
SymCurrentSensorArray,
SymGenArray,
SymLoadArray,
SymPowerSensorArray,
Expand All @@ -26,17 +30,21 @@

__all__ = [
"AsymVoltageSensorArray",
"AsymCurrentSensorArray",
"Branch3Array",
"BranchArray",
"GenericBranchArray",
"IdArray",
"LineArray",
"LinkArray",
"NodeArray",
"SourceArray",
"SymLoadArray",
"SymGenArray",
"SymCurrentSensorArray",
"SymPowerSensorArray",
"SymVoltageSensorArray",
"AsymLineArray",
"ThreeWindingTransformerArray",
"TransformerArray",
"TransformerTapRegulatorArray",
Expand Down
26 changes: 25 additions & 1 deletion src/power_grid_model_ds/_core/model/arrays/pgm_arrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
from power_grid_model_ds._core.model.arrays.base.array import FancyArray
from power_grid_model_ds._core.model.dtypes.appliances import Source, SymGen, SymLoad
from power_grid_model_ds._core.model.dtypes.branches import (
AsymLine,
Branch,
Branch3,
GenericBranch,
Line,
Link,
ThreeWindingTransformer,
Expand All @@ -23,7 +25,13 @@
from power_grid_model_ds._core.model.dtypes.id import Id
from power_grid_model_ds._core.model.dtypes.nodes import Node
from power_grid_model_ds._core.model.dtypes.regulators import TransformerTapRegulator
from power_grid_model_ds._core.model.dtypes.sensors import AsymVoltageSensor, SymPowerSensor, SymVoltageSensor
from power_grid_model_ds._core.model.dtypes.sensors import (
AsymCurrentSensor,
AsymVoltageSensor,
SymCurrentSensor,
SymPowerSensor,
SymVoltageSensor,
)

# pylint: disable=missing-class-docstring

Expand Down Expand Up @@ -99,6 +107,14 @@ class TransformerArray(Transformer, BranchArray):
pass


class GenericBranchArray(GenericBranch, BranchArray):
pass


class AsymLineArray(AsymLine, BranchArray):
pass


class Branch3Array(IdArray, Branch3):
def as_branches(self) -> BranchArray:
"""Convert Branch3Array to BranchArray."""
Expand Down Expand Up @@ -140,3 +156,11 @@ class SymVoltageSensorArray(IdArray, SymVoltageSensor):

class AsymVoltageSensorArray(IdArray, AsymVoltageSensor):
pass


class SymCurrentSensorArray(IdArray, SymCurrentSensor):
pass


class AsymCurrentSensorArray(IdArray, AsymCurrentSensor):
pass
89 changes: 89 additions & 0 deletions src/power_grid_model_ds/_core/model/dtypes/branches.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,28 @@ class Line(Branch):
i_n: NDArray[np.float64] # rated current


class GenericBranch(Branch):
"""GenericBranch data type (generic_branch in power-grid-model)

Off-nominal ratio k and phase shift theta are modelled explicitly. Rated power sn optional.
The impedance (r1, x1) and admittance (g1, b1) are given wrt the to-side.
"""

r1: NDArray[np.float64] # positive-sequence resistance
x1: NDArray[np.float64] # positive-sequence reactance
g1: NDArray[np.float64] # positive-sequence conductance
b1: NDArray[np.float64] # positive-sequence susceptance
k: NDArray[np.float64] # off-nominal ratio
theta: NDArray[np.float64] # angle shift (radian)
sn: NDArray[np.float64] # rated power

_defaults = {
"k": 1.0,
"theta": 0.0,
"sn": 0.0,
}


class Transformer(Branch):
"""Transformer data type"""

Expand Down Expand Up @@ -115,3 +137,70 @@ class ThreeWindingTransformer(Branch3):
pk_12_max: NDArray[np.float64]
pk_13_max: NDArray[np.float64]
pk_23_max: NDArray[np.float64]


class AsymLine(Branch):
"""Asymmetric Line data type (asym_line in power-grid-model)

Supports 3 or 4 phase (with neutral) resistance / reactance matrices and optional capacitance matrix
or sequence capacitances c0/c1. If c_* matrix is omitted, c0 & c1 may be specified instead.
Only include fields; validation logic handled elsewhere (not implemented here yet).
"""

# Resistance matrix entries (series)
r_aa: NDArray[np.float64]
r_ba: NDArray[np.float64]
r_bb: NDArray[np.float64]
r_ca: NDArray[np.float64]
r_cb: NDArray[np.float64]
r_cc: NDArray[np.float64]
r_na: NDArray[np.float64] # optional neutral
r_nb: NDArray[np.float64]
r_nc: NDArray[np.float64]
r_nn: NDArray[np.float64]

# Reactance matrix entries (series)
x_aa: NDArray[np.float64]
x_ba: NDArray[np.float64]
x_bb: NDArray[np.float64]
x_ca: NDArray[np.float64]
x_cb: NDArray[np.float64]
x_cc: NDArray[np.float64]
x_na: NDArray[np.float64]
x_nb: NDArray[np.float64]
x_nc: NDArray[np.float64]
x_nn: NDArray[np.float64]

# Capacitance matrix entries (shunt) optional
c_aa: NDArray[np.float64]
c_ba: NDArray[np.float64]
c_bb: NDArray[np.float64]
c_ca: NDArray[np.float64]
c_cb: NDArray[np.float64]
c_cc: NDArray[np.float64]

# Alternative sequence capacitances
c0: NDArray[np.float64]
c1: NDArray[np.float64]

i_n: NDArray[np.float64] # rated current

_defaults = {
"r_na": empty,
"r_nb": empty,
"r_nc": empty,
"r_nn": empty,
"x_na": empty,
"x_nb": empty,
"x_nc": empty,
"x_nn": empty,
"c_aa": empty,
"c_ba": empty,
"c_bb": empty,
"c_ca": empty,
"c_cb": empty,
"c_cc": empty,
"c0": empty,
"c1": empty,
"i_n": empty,
}
23 changes: 23 additions & 0 deletions src/power_grid_model_ds/_core/model/dtypes/sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,26 @@ class AsymVoltageSensor(GenericVoltageSensor):
u_sigma: NDArray3[np.float64] # std of 3 voltages
u_measured: NDArray3[np.float64] # measured 3 voltages
u_angle_measured: NDArray3[np.float64] # measured 3 phases


class GenericCurrentSensor(Sensor):
"""Base class for current sensor data type"""

measured_terminal_type: NDArray[np.int32]
angle_measurement_type: NDArray[np.int32]
i_sigma: NDArray[np.float64]
i_angle_sigma: NDArray[np.float64]


class SymCurrentSensor(GenericCurrentSensor):
"""SymCurrentSensor data type"""

i_measured: NDArray[np.float64]
i_angle_measured: NDArray[np.float64]


class AsymCurrentSensor(GenericCurrentSensor):
"""AsymCurrentSensor data type"""

i_measured: NDArray3[np.float64]
i_angle_measured: NDArray3[np.float64]
14 changes: 13 additions & 1 deletion src/power_grid_model_ds/_core/model/grids/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@

from power_grid_model_ds._core import fancypy as fp
from power_grid_model_ds._core.model.arrays import (
AsymCurrentSensorArray,
AsymLineArray,
AsymVoltageSensorArray,
Branch3Array,
BranchArray,
GenericBranchArray,
LineArray,
LinkArray,
NodeArray,
SourceArray,
SymCurrentSensorArray,
SymGenArray,
SymLoadArray,
SymPowerSensorArray,
Expand Down Expand Up @@ -72,6 +76,8 @@ class Grid(FancyArrayContainer):
three_winding_transformer: ThreeWindingTransformerArray
line: LineArray
link: LinkArray
generic_branch: GenericBranchArray
asym_line: AsymLineArray

source: SourceArray
sym_load: SymLoadArray
Expand All @@ -84,6 +90,8 @@ class Grid(FancyArrayContainer):
sym_power_sensor: SymPowerSensorArray
sym_voltage_sensor: SymVoltageSensorArray
asym_voltage_sensor: AsymVoltageSensorArray
sym_current_sensor: SymCurrentSensorArray
asym_current_sensor: AsymCurrentSensorArray

def __str__(self) -> str:
"""String representation of the grid.
Expand Down Expand Up @@ -114,8 +122,12 @@ def __str__(self) -> str:
suffix_str = f"{suffix_str},link"
elif branch.id in self.line.id:
pass # no suffix needed
elif branch.id in self.generic_branch.id:
suffix_str = f"{suffix_str},generic_branch"
elif branch.id in self.asym_line.id:
suffix_str = f"{suffix_str},asym_line"
else:
raise ValueError(f"Branch {branch.id} is not a transformer, link or line")
raise ValueError(f"Branch {branch.id} is not a transformer, link, line, generic_branch or asym_line")

grid_str += f"{from_node_str} {to_node_str} {suffix_str}\n"
return grid_str
Expand Down
8 changes: 8 additions & 0 deletions src/power_grid_model_ds/arrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
# SPDX-License-Identifier: MPL-2.0

from power_grid_model_ds._core.model.arrays import (
AsymCurrentSensorArray,
AsymLineArray,
AsymVoltageSensorArray,
Branch3Array,
BranchArray,
GenericBranchArray,
IdArray,
LineArray,
LinkArray,
NodeArray,
SourceArray,
SymCurrentSensorArray,
SymGenArray,
SymLoadArray,
SymPowerSensorArray,
Expand All @@ -26,6 +30,8 @@
"BranchArray",
"LinkArray",
"LineArray",
"GenericBranchArray",
"AsymLineArray",
"TransformerArray",
"Branch3Array",
"ThreeWindingTransformerArray",
Expand All @@ -34,6 +40,8 @@
"SymLoadArray",
"TransformerTapRegulatorArray",
"AsymVoltageSensorArray",
"AsymCurrentSensorArray",
"SymPowerSensorArray",
"SymVoltageSensorArray",
"SymCurrentSensorArray",
]
4 changes: 4 additions & 0 deletions tests/unit/model/grids/test_grid_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,14 @@ def test_initialize_empty_grid(grid: Grid):
"_id_counter",
"transformer_tap_regulator",
"asym_voltage_sensor",
"sym_current_sensor",
"asym_current_sensor",
"three_winding_transformer",
"transformer",
"node",
"line",
"generic_branch",
"asym_line",
"sym_gen",
"graphs",
"sym_voltage_sensor",
Expand Down
Loading