Skip to content

odys.parameters.entity_arrays

Internal implementation detail. Most users do not need this page directly.

The typed parameter arrays of each entity type, built by vectorize.

Typed parameter arrays of each entity type, vectorized along the entity's dimension.

Each class lists the entity fields the optimization model reads, named exactly like the domain fields, and is built by vectorize. Derived arrays that are not entity fields (such as EV trip arrays over time, durations in steps, or the run's initial and final conditions) are built by hand.

BatteryArrays

Bases: EntityArrays

Battery parameters of battery storages or electric vehicles, along their dimension.

Source code in src/odys/parameters/entity_arrays.py
79
80
81
82
83
84
85
86
87
88
89
90
class BatteryArrays(EntityArrays):
    """Battery parameters of battery storages or electric vehicles, along their dimension."""

    capacity: xr.DataArray
    max_charge_power: xr.DataArray
    max_discharge_power: xr.DataArray
    efficiency_charging: xr.DataArray
    efficiency_discharging: xr.DataArray
    self_discharge_rate: xr.DataArray
    soc_min: xr.DataArray
    soc_max: xr.DataArray
    degradation_cost: xr.DataArray

BatteryStateArrays

Bases: EntityArrays

State of charge of each battery at the start of the run and, where set, at its end.

Source code in src/odys/parameters/entity_arrays.py
93
94
95
96
97
class BatteryStateArrays(EntityArrays):
    """State of charge of each battery at the start of the run and, where set, at its end."""

    soc_start: xr.DataArray
    soc_end: xr.DataArray

ChargerArrays

Bases: EntityArrays

Charger parameters along the charger dimension.

Source code in src/odys/parameters/entity_arrays.py
129
130
131
132
class ChargerArrays(EntityArrays):
    """Charger parameters along the charger dimension."""

    max_power: xr.DataArray

CommitmentArrays

Bases: EntityArrays

Commitment parameters along an entity dimension: the cost of each start and stop.

Source code in src/odys/parameters/entity_arrays.py
46
47
48
49
50
class CommitmentArrays(EntityArrays):
    """Commitment parameters along an entity dimension: the cost of each start and stop."""

    startup_cost: xr.DataArray
    shutdown_cost: xr.DataArray

CommitmentStateArrays

Bases: EntityArrays

On/off quantities that depend on the run: minimum times in steps and the initial status.

Without a minimum time, the minimum is one step. Without a time in state, the entity has been in its initial status for longer than any minimum time (inf steps), so nothing carries over.

Source code in src/odys/parameters/entity_arrays.py
53
54
55
56
57
58
59
60
61
62
63
64
class CommitmentStateArrays(EntityArrays):
    """On/off quantities that depend on the run: minimum times in steps and the initial status.

    Without a minimum time, the minimum is one step. Without a time in state, the
    entity has been in its initial status for longer than any minimum time (`inf`
    steps), so nothing carries over.
    """

    min_up_steps: xr.DataArray
    min_down_steps: xr.DataArray
    initially_on: xr.DataArray
    initial_steps_in_state: xr.DataArray

ElectricVehicleArrays

Bases: EntityArrays

Electric vehicle parameters: battery arrays along the EV dimension, trip arrays over EV and time.

Source code in src/odys/parameters/entity_arrays.py
143
144
145
146
147
148
class ElectricVehicleArrays(EntityArrays):
    """Electric vehicle parameters: battery arrays along the EV dimension, trip arrays over EV and time."""

    battery: BatteryArrays
    states: BatteryStateArrays
    trips: ElectricVehicleTripArrays

ElectricVehicleTripArrays

Bases: EntityArrays

Trip schedule of each electric vehicle at each timestep, derived from its trips.

Source code in src/odys/parameters/entity_arrays.py
135
136
137
138
139
140
class ElectricVehicleTripArrays(EntityArrays):
    """Trip schedule of each electric vehicle at each timestep, derived from its trips."""

    is_driving: xr.DataArray
    trip_energy: xr.DataArray
    min_soc_at_departure: xr.DataArray

FlexibleLoadArrays

Bases: EntityArrays

Flexible load parameters along the flexible load dimension.

Source code in src/odys/parameters/entity_arrays.py
100
101
102
103
104
105
class FlexibleLoadArrays(EntityArrays):
    """Flexible load parameters along the flexible load dimension."""

    value_of_consumption: xr.DataArray
    ramp_up: xr.DataArray
    ramp_down: xr.DataArray

FlexibleLoadStateArrays

Bases: EntityArrays

Flexible load quantities that depend on the run: the initial consumption and the on/off states.

Without an initial state, the load starts at 0 MW, running if it has no commitment and off if it has one. is_switchable marks the loads with a commitment; the others are always running.

Source code in src/odys/parameters/entity_arrays.py
108
109
110
111
112
113
114
115
116
117
118
class FlexibleLoadStateArrays(EntityArrays):
    """Flexible load quantities that depend on the run: the initial consumption and the on/off states.

    Without an initial state, the load starts at 0 MW, running if it has no
    commitment and off if it has one. `is_switchable` marks the loads with a
    commitment; the others are always running.
    """

    initial_power: xr.DataArray
    is_switchable: xr.DataArray
    commitment: CommitmentStateArrays

GeneratorArrays

Bases: EntityArrays

Generator parameters along the generator dimension.

Source code in src/odys/parameters/entity_arrays.py
36
37
38
39
40
41
42
43
class GeneratorArrays(EntityArrays):
    """Generator parameters along the generator dimension."""

    nominal_power: xr.DataArray
    variable_cost: xr.DataArray
    min_power: xr.DataArray
    ramp_up: xr.DataArray
    ramp_down: xr.DataArray

GeneratorStateArrays

Bases: EntityArrays

Generator quantities that depend on the run: the initial and final power, and the on/off states.

Without an initial state, the generator starts off (power 0). final_power is NaN where there is no final state.

Source code in src/odys/parameters/entity_arrays.py
67
68
69
70
71
72
73
74
75
76
class GeneratorStateArrays(EntityArrays):
    """Generator quantities that depend on the run: the initial and final power, and the on/off states.

    Without an initial state, the generator starts off (power 0). `final_power` is
    NaN where there is no final state.
    """

    initial_power: xr.DataArray
    final_power: xr.DataArray
    commitment: CommitmentStateArrays

MarketArrays

Bases: EntityArrays

Energy market parameters along the market dimension.

Source code in src/odys/parameters/entity_arrays.py
121
122
123
124
125
126
class MarketArrays(EntityArrays):
    """Energy market parameters along the market dimension."""

    max_trading_volume_per_step: xr.DataArray
    stage_fixed: xr.DataArray
    allowed_trade_direction: xr.DataArray

battery_storage_state_arrays(storages, coordinates, context)

Build the initial and final state of charge of the battery storages.

Parameters:

Name Type Description Default
storages Sequence[BatteryStorage]

The battery storages, in coordinate order.

required
coordinates Coordinates

The labels of the storages along their dimension.

required
context ModelContext

The shared indexing of the problem, with its conditions.

required

Returns:

Type Description
BatteryStateArrays

The storages' state of charge arrays; soc_end is NaN where there is no final state.

Source code in src/odys/parameters/entity_arrays.py
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
def battery_storage_state_arrays(
    storages: Sequence[BatteryStorage],
    coordinates: Coordinates,
    context: ModelContext,
) -> BatteryStateArrays:
    """Build the initial and final state of charge of the battery storages.

    Args:
        storages: The battery storages, in coordinate order.
        coordinates: The labels of the storages along their dimension.
        context: The shared indexing of the problem, with its conditions.

    Returns:
        The storages' state of charge arrays; `soc_end` is NaN where there is no final state.

    """
    return _battery_state_arrays(StorageInitialState, StorageFinalState, storages, coordinates, context)

commitment_state_arrays(commitments, coordinates, horizon, initially_on, initial_steps_in_state)

Build the minimum up and down times in steps of the given commitments, with their entities' initial status.

Parameters:

Name Type Description Default
commitments Sequence[Commitment]

The commitments, in coordinate order.

required
coordinates Coordinates

The labels of their entities along the entity dimension.

required
horizon Horizon

The time grid of the optimization.

required
initially_on DataArray

Whether each entity is on just before the first timestep.

required
initial_steps_in_state DataArray

How many steps each entity has been in its initial status (inf when unknown).

required

Returns:

Type Description
CommitmentStateArrays

The on/off state arrays.

Source code in src/odys/parameters/entity_arrays.py
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
def commitment_state_arrays(
    commitments: Sequence[Commitment],
    coordinates: Coordinates,
    horizon: Horizon,
    initially_on: xr.DataArray,
    initial_steps_in_state: xr.DataArray,
) -> CommitmentStateArrays:
    """Build the minimum up and down times in steps of the given commitments, with their entities' initial status.

    Args:
        commitments: The commitments, in coordinate order.
        coordinates: The labels of their entities along the entity dimension.
        horizon: The time grid of the optimization.
        initially_on: Whether each entity is on just before the first timestep.
        initial_steps_in_state: How many steps each entity has been in its initial status (`inf` when unknown).

    Returns:
        The on/off state arrays.

    """

    def steps(duration: timedelta | None) -> int:
        return 1 if duration is None else horizon.steps_in(duration)

    def along_entities(values: Sequence[float]) -> xr.DataArray:
        return xr.DataArray(values, dims=coordinates.dimension, coords=coordinates.dimension_coordinates_map)

    return CommitmentStateArrays(
        min_up_steps=along_entities([steps(commitment.min_up_time) for commitment in commitments]),
        min_down_steps=along_entities([steps(commitment.min_down_time) for commitment in commitments]),
        initially_on=initially_on,
        initial_steps_in_state=initial_steps_in_state,
    )

electric_vehicle_arrays(electric_vehicles, coordinates, context)

Build the battery, state of charge and trip arrays of the electric vehicles.

Parameters:

Name Type Description Default
electric_vehicles Sequence[ElectricVehicle]

The electric vehicles, in coordinate order.

required
coordinates Coordinates

The labels of the electric vehicles along the EV dimension.

required
context ModelContext

The shared indexing of the problem, with its time coordinates and conditions.

required

Returns:

Type Description
ElectricVehicleArrays

The electric vehicles' arrays.

Source code in src/odys/parameters/entity_arrays.py
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
def electric_vehicle_arrays(
    electric_vehicles: Sequence[ElectricVehicle],
    coordinates: Coordinates,
    context: ModelContext,
) -> ElectricVehicleArrays:
    """Build the battery, state of charge and trip arrays of the electric vehicles.

    Args:
        electric_vehicles: The electric vehicles, in coordinate order.
        coordinates: The labels of the electric vehicles along the EV dimension.
        context: The shared indexing of the problem, with its time coordinates and conditions.

    Returns:
        The electric vehicles' arrays.

    """
    return ElectricVehicleArrays(
        battery=vectorize(BatteryArrays, [ev.battery for ev in electric_vehicles], coordinates),
        states=_battery_state_arrays(
            ElectricVehicleInitialState,
            ElectricVehicleFinalState,
            electric_vehicles,
            coordinates,
            context,
        ),
        trips=_trip_arrays(electric_vehicles, coordinates, context),
    )

flexible_load_state_arrays(loads, coordinates, context)

Build the flexible loads' initial consumption and their on/off states.

A load without a commitment gets Commitment() here, so every load has an on/off state; it is always on.

Parameters:

Name Type Description Default
loads Sequence[FlexibleLoad]

The flexible loads, in coordinate order.

required
coordinates Coordinates

The labels of the loads along the flexible load dimension.

required
context ModelContext

The shared indexing of the problem, with its horizon and conditions.

required

Returns:

Type Description
FlexibleLoadStateArrays

The flexible loads' state arrays.

Source code in src/odys/parameters/entity_arrays.py
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
def flexible_load_state_arrays(
    loads: Sequence[FlexibleLoad],
    coordinates: Coordinates,
    context: ModelContext,
) -> FlexibleLoadStateArrays:
    """Build the flexible loads' initial consumption and their on/off states.

    A load without a commitment gets `Commitment()` here, so every load has an on/off state; it is always on.

    Args:
        loads: The flexible loads, in coordinate order.
        coordinates: The labels of the loads along the flexible load dimension.
        context: The shared indexing of the problem, with its horizon and conditions.

    Returns:
        The flexible loads' state arrays.

    """
    initial_power = context.conditions(
        FlexibleLoadInitialState,
        loads,
        coordinates,
        lambda state: state.power,
        default=0.0,
    )
    is_switchable = xr.DataArray(
        [load.commitment is not None for load in loads],
        dims=coordinates.dimension,
        coords=coordinates.dimension_coordinates_map,
    )
    initial_steps_in_state = context.conditions(
        FlexibleLoadInitialState,
        loads,
        coordinates,
        lambda state: _steps_in_state(state.time_in_state, context.horizon),
        default=np.inf,
    )
    return FlexibleLoadStateArrays(
        initial_power=initial_power,
        is_switchable=is_switchable,
        commitment=commitment_state_arrays(
            [load.commitment or Commitment() for load in loads],
            coordinates,
            context.horizon,
            initially_on=~is_switchable | (initial_power > 0),
            initial_steps_in_state=initial_steps_in_state,
        ),
    )

generator_state_arrays(generators, coordinates, context)

Build the generators' initial and final power and their on/off states.

Parameters:

Name Type Description Default
generators Sequence[Generator]

The generators, in coordinate order.

required
coordinates Coordinates

The labels of the generators along the generator dimension.

required
context ModelContext

The shared indexing of the problem, with its horizon and conditions.

required

Returns:

Type Description
GeneratorStateArrays

The generators' state arrays.

Source code in src/odys/parameters/entity_arrays.py
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
def generator_state_arrays(
    generators: Sequence[Generator],
    coordinates: Coordinates,
    context: ModelContext,
) -> GeneratorStateArrays:
    """Build the generators' initial and final power and their on/off states.

    Args:
        generators: The generators, in coordinate order.
        coordinates: The labels of the generators along the generator dimension.
        context: The shared indexing of the problem, with its horizon and conditions.

    Returns:
        The generators' state arrays.

    """
    initial_power = context.conditions(
        GeneratorInitialState,
        generators,
        coordinates,
        lambda state: state.power,
        default=0.0,
    )
    initial_steps_in_state = context.conditions(
        GeneratorInitialState,
        generators,
        coordinates,
        lambda state: _steps_in_state(state.time_in_state, context.horizon),
        default=np.inf,
    )
    return GeneratorStateArrays(
        initial_power=initial_power,
        final_power=context.conditions(
            GeneratorFinalState,
            generators,
            coordinates,
            lambda state: state.power,
            default=np.nan,
        ),
        commitment=commitment_state_arrays(
            [generator.commitment for generator in generators],
            coordinates,
            context.horizon,
            initially_on=initial_power > 0,
            initial_steps_in_state=initial_steps_in_state,
        ),
    )