Skip to content

odys.domain.entities.generator

Power generator asset with operational constraints: nominal power, variable cost, ramp rates, startup/shutdown costs, and minimum up/down time.

See Generator in the User Guide for a conceptual walkthrough.

Generator asset implementation.

This module provides the Generator class for modeling electrical generators in energy system optimization problems.

Generator

Bases: Asset

Represents a power generator in the energy system.

This class models generators with various operational constraints including nominal power, variable costs and ramp rates. How it is switched on and off (minimum up and down times, startup and shutdown costs) is its Commitment.

Source code in src/odys/domain/entities/generator.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
class Generator(Asset):
    """Represents a power generator in the energy system.

    This class models generators with various operational constraints
    including nominal power, variable costs and ramp rates. How it is switched
    on and off (minimum up and down times, startup and shutdown costs) is its
    `Commitment`.
    """

    nominal_power: float = Field(
        strict=True,
        gt=0,
        description="Nominal power of the generator in MW.",
    )

    variable_cost: float = Field(
        strict=True,
        ge=0,
        description="Variable cost of the generator in currency per MWh.",
    )

    ramp_up: float | None = Field(
        default=None,
        strict=True,
        ge=0,
        description="Largest increase in output, in MW per hour; each step allows ramp_up times its length in hours.",
    )

    ramp_down: float | None = Field(
        default=None,
        strict=True,
        ge=0,
        description="Largest decrease in output, in MW per hour; each step allows ramp_down times its length in hours.",
    )

    min_power: float = Field(
        default=0.0,
        strict=True,
        ge=0,
        description="Minimum power output",
    )

    commitment: Commitment = Field(
        default_factory=Commitment,
        description="How the generator is switched on and off: minimum up and down times, startup and shutdown costs.",
    )

    def max_supply(self, conditions: OperatingConditions) -> tuple[float, ...]:
        """Return the available capacity profile if the scenario has one, else the nominal power, in MW."""
        if conditions.profile_values is not None:
            return conditions.profile_values
        return (self.nominal_power,) * conditions.horizon.number_of_steps

    def validate_horizon(self, horizon: Horizon) -> None:
        """Check that the minimum up and down times span a whole number of timesteps.

        Args:
            horizon: The time grid of the optimization.

        Raises:
            OdysValidationError: If a minimum time is not a whole number of timesteps.
        """
        self.commitment.validate_horizon(horizon, f"Generator '{self.name}'")

max_supply(conditions)

Return the available capacity profile if the scenario has one, else the nominal power, in MW.

Source code in src/odys/domain/entities/generator.py
61
62
63
64
65
def max_supply(self, conditions: OperatingConditions) -> tuple[float, ...]:
    """Return the available capacity profile if the scenario has one, else the nominal power, in MW."""
    if conditions.profile_values is not None:
        return conditions.profile_values
    return (self.nominal_power,) * conditions.horizon.number_of_steps

validate_horizon(horizon)

Check that the minimum up and down times span a whole number of timesteps.

Parameters:

Name Type Description Default
horizon Horizon

The time grid of the optimization.

required

Raises:

Type Description
OdysValidationError

If a minimum time is not a whole number of timesteps.

Source code in src/odys/domain/entities/generator.py
67
68
69
70
71
72
73
74
75
76
def validate_horizon(self, horizon: Horizon) -> None:
    """Check that the minimum up and down times span a whole number of timesteps.

    Args:
        horizon: The time grid of the optimization.

    Raises:
        OdysValidationError: If a minimum time is not a whole number of timesteps.
    """
    self.commitment.validate_horizon(horizon, f"Generator '{self.name}'")