diff --git a/docs/src/format.md b/docs/src/format.md index 7707b48..267da58 100644 --- a/docs/src/format.md +++ b/docs/src/format.md @@ -70,7 +70,10 @@ This section describes the characteristics of each bus in the system. ### Generators -This section describes all generators in the system, including thermal units, renewable units and virtual units. Two types of generators can be specified - thermal units and profiled units. A thermal unit consists of different fields, while a profiled unit is a simple generator with only a production capacity and a per-unit cost. +This section describes all generators in the system. Two types of units can be specified: + +- **Thermal units:** Units that produce power by converting heat into electrical energy, such as coal and oil power plants. These units use a more complex model, with binary decision variables, and various constraints to enforce ramp rates and minimum up/down time. +- **Profiled units:** Simplified model for units that do not require the constraints mentioned above, only a maximum and minimum power output for each time period. Typically used for renewables and hydro. #### Thermal Units @@ -90,7 +93,7 @@ This section describes all generators in the system, including thermal units, re | `Initial power (MW)` | Amount of power the generator at time step `-1`, immediately before the planning horizon starts. | Required | N | `Must run?` | If `true`, the generator should be committed, even if that is not economical (Boolean). | `false` | Y | `Reserve eligibility` | List of reserve products this generator is eligibe to provide. By default, the generator is not eligible to provide any reserves. | `[]` | N -| `Commitment status` | List of commitment status over the time horizon. At time `t`, if `true`, the generator must be commited at that time period; if `false`, the generator must not be commited at that time period. If `null` at time `t`, the generator's commitment status is then decided by the model. By default, the status is a list of `null` values. | `[null]` | Y +| `Commitment status` | List of commitment status over the time horizon. At time `t`, if `true`, the generator must be commited at that time period; if `false`, the generator must not be commited at that time period. If `null` at time `t`, the generator's commitment status is then decided by the model. By default, the status is a list of `null` values. | `null` | Y #### Profiled Units @@ -99,8 +102,8 @@ This section describes all generators in the system, including thermal units, re | `Bus` | Identifier of the bus where this generator is located (string). | Required | N | `Type` | Type of the generator (string). For profiled generators, this must be `Profiled`. | Required | N | `Cost ($/MW)` | Cost incurred for serving each MW of power by this generator. | Required | Y -| `Minimum power (MW)` | Minimum amount of power to be supplied by this generator. Any amount greater than this may be supplied. | `0.0` | Y -| `Maximum power (MW)` | Maximum amount of power to be supplied by this generator. Any amount lower than this may be supplied. | Required | Y +| `Minimum power (MW)` | Minimum amount of power this generator may supply. | `0.0` | Y +| `Maximum power (MW)` | Maximum amount of power this generator may supply. | Required | Y #### Production costs and limits diff --git a/src/model/formulations/base/unit.jl b/src/model/formulations/base/unit.jl index 83cf543..664d1f4 100644 --- a/src/model/formulations/base/unit.jl +++ b/src/model/formulations/base/unit.jl @@ -24,6 +24,7 @@ function _add_unit_commitment!( _add_min_uptime_downtime_eqs!(model, g) _add_startup_cost_eqs!(model, g, formulation.startup_costs) _add_status_eqs!(model, g, formulation.status_vars) + _add_commitment_status_eqs!(model, g) return end @@ -61,7 +62,6 @@ function _add_unit_dispatch!( sc, ) _add_startup_shutdown_limit_eqs!(model, g, sc) - _add_commitment_status_eqs!(model, g, sc) return end @@ -274,15 +274,13 @@ end function _add_commitment_status_eqs!( model::JuMP.Model, g::ThermalUnit, - sc::UnitCommitmentScenario, )::Nothing is_on = model[:is_on] T = model[:instance].time eq_commitment_status = _init(model, :eq_commitment_status) for t in 1:T - # Fix commitment status if g.commitment_status[t] !== nothing - eq_commitment_status[sc.name, g.name, t] = @constraint( + eq_commitment_status[g.name, t] = @constraint( model, is_on[g.name, t] == (g.commitment_status[t] ? 1.0 : 0.0) )