Curtailment Output

Contents

Overview | Columns | Calculation | Configuration | Assumptions | Examples | See Also

Overview

File: curtailment.csv

curtailment.csv records the curtailed generation for every VRE (Variable Renewable Energy) asset at every representative time step. Curtailment is the difference between the maximum available generation (capacity × availability factor) and the actual generation (flow). It represents renewable energy that could have been produced but was not dispatched.

Only assets of type VRE produce rows in this file. If the system has no VRE assets, the file will not be written.

Curtailment is a derived quantity

Curtailment is not an optimization variable — it is computed from the optimal capacity and flow values after the solve. A value of 0.0 means the VRE asset was fully utilized at that time step.

Columns

ColumnTypeDescription
commodityStringCommodity type generated by the VRE asset (typically Electricity)
zoneStringZone (location) where the VRE asset is installed
resource_idStringUnique identifier of the parent VRE asset
component_idStringUnique identifier of the VRE edge component
resource_typeStringAsset type (always VRE for this output)
component_typeStringType of the edge (e.g., UnidirectionalEdge{Electricity})
variableStringAlways "curtailment"
timeIntRepresentative time step index (1-based integer, matches time in other output files)
valueFloat64Curtailed power at this time step, in the same units as capacity (default: MW)

Calculation

Curtailment at time step $t$ is calculated as:

\[\text{curtailment}(t) = \max\!\Big(0,\; \text{capacity} \times \text{availability}(t) - \text{flow}(t)\Big)\]

where:

  • capacity is the optimal total installed capacity of the VRE edge (MW), from capacity.csv
  • availability(t) is the capacity factor at time step $t$ (a value between 0 and 1), from the VRE asset's availability time series input
  • flow(t) is the actual generation dispatched at time step $t$, from flows.csv

The max(0, ...) ensures curtailment is always non-negative. In practice, the optimizer will only curtail when it is optimal to do so (e.g., when electricity supply exceeds demand and storage is full).

Annual curtailment energy

To compute total annual curtailed energy for an asset, multiply value(t) × weight(t) and sum over all time steps, where weight(t) comes from time_weights.csv:

Annual curtailment (MWh) = Σ_t  curtailment(t) × weight(t) × hours_per_timestep

Configuration

SettingFileDefaultEffect
OutputLayout (or OutputLayout.Curtailment)macro_settings.json"long"Set to "wide" to pivot time steps into columns.
WriteFullTimeseriescase_settings.jsonfalseWhen true and TDR is active, also write full-year curtailment to full_time_series/curtailment.csv.

Assumptions

  • VRE assets only. Only assets of type VRE are included. Other asset types (e.g., ThermalPower, Battery) do not produce curtailment rows.
  • Requires has_capacity = true (true by default). Curtailment is only meaningful when the VRE edge has capacity variables enabled. If the user sets has_capacity = false, the availability × capacity term is zero and curtailment will be 0.0.
  • Availability time series. The availability (capacity factor) profile is typically specified in the VRE asset's input data as a time series of values in [0, 1] for each representative time step. Note that if no availability time series is provided, Macro defaults to full availability (1.0) at all time steps.
  • File not written if empty. If the system has no VRE assets, or all VRE edges have has_capacity = false, the curtailment.csv file will not be written. Note: if VRE assets exist but the optimizer assigns them zero capacity, the file is still written (with all-zero values).

Examples

Default Long Format (example rows)

commodityzoneresource_idcomponent_idresource_typecomponent_typevariabletimevalue
ElectricityNENE_offshorewind_1NE_offshorewind_1_edgeVREUnidirectionalEdge{Electricity}curtailment10.0
ElectricityNENE_offshorewind_1NE_offshorewind_1_edgeVREUnidirectionalEdge{Electricity}curtailment245.2
ElectricityNENE_offshorewind_1NE_offshorewind_1_edgeVREUnidirectionalEdge{Electricity}curtailment30.0

Computing Annual Curtailment

using CSV, DataFrames

curtailment = CSV.read("results/curtailment.csv", DataFrame)
weights = CSV.read("results/time_weights.csv", DataFrame)

# Join and compute annual curtailment per asset
df = leftjoin(curtailment, weights, on=:time)
df.annual_MWh = df.value .* df.weight

# Group by asset to get total annual curtailment per VRE asset
annual_by_asset = combine(groupby(df, :resource_id), :annual_MWh => sum => :annual_curtailment_MWh)

See Also