Edges

Contents

Overview | Fields | Types | Constructors | Methods | Examples

Overview

Edges are connections between components, allowing for one or two-way flows of Commodities. They are one of the four primary components in Macro, alongside Nodes, Storage, and Transformations.

Each Edge can only carry one Commodity so they are usually described with reference to that Commodity, e.g. as Edge{Electricity}, Edge{Hydrogen}, or Edge{CO2}. The general description is an Edge{T}, where T can be any Commodity or sub-Commodity.

Edges in Assets

Most Edges{T} are incorporated into Assets, representing the ability of those Assets to transfer Commodities. This is intuitive in some instances but it must be remembered that Edges and other primary components within an Asset do not represent physical components. Instead, they represent the capabilities of the Asset as a whole.

Electricity Edges in a transmission line

A simple transmission line Asset has a strong correspondance between the physical component and its representation in Macro. A transmission line Asset can be defined as an Edge{Electricity} between two Electricity Nodes (aka. two Node{Electricty}). The transmission of electricity is represented by the operational variables of the Edge{Electricity}, and those variables are limited by its investment variables. The costs which come with those operations and investments are associated with the Edge{Electricity}.

Electricity Edges in a natural gas power plant

An Edge{Electricity} could also represent the ability of a natural gas power plant (aka. ThermalPower{NaturalGas}) to transfer Electricity to a grid. The ThermalPower{NaturalGas} will be made up of Edges carrying NaturalGas fuel, Electricity, and CO2 emissions. These Edges will all meet at a Transformation which regulates the relationship between the three.

It might be intuitive to think of the Transformation as the power plant and the three Edges as the fuel lines, power lines, and flue-gas stack respectively. However, this is not correct with Macro. The combination of the three Edges and Transform represent the entire natural gas power plant. This is discussed in more detail in the Assets documentation.

Edges outside of Assets

It is not currently possible to define Edges outside of Assets using the standard input files. We believe most users will be better served using a simple Asset to represent a connection. However, it is possible to define Edges directly in the Julia script you use to build and solve your model. Please feel free to reach out to the developemnt team via a GitHub issue if you have a use case for this.

Key Concepts

  • Flow Direction: Edges can be unidirectional or bidirectional
  • Commodity Types: Each Edge carries flows of a single Commodity type
  • Capacity: Edges can have capacity limits which limit flows along them. Capacity can be fixed or expandable via investment.
  • Investment: Edges can have investment costs associated with investments and operation
  • Time Dependence: Support time-varying parameters and constraints

Edge Fields

Edges have the following fields. When running a model, the fields are set by the input files. When creating an Asset, the defaults below can can be altered using the @edge_data macro. The internal fields are used by Macro and are not intended to be set by users in most circumstances.

Units in Macro

We have assumed that your System is using units of MWh for energy, tonnes for mass, and hour-long time steps. You can use any set of units as long as they are consistent across your operations and investment inputs.

Network Structure

FieldTypeDescriptionDefault
idSymbolUnique identifier-
start_vertexAbstractVertexOrigin vertex-
end_vertexAbstractVertexDestination vertex-
commodityTypeCommodity type-
unidirectionalBoolFlow direction constrainttrue

Investment Parameters

FieldTypeDescriptionUnitsDefault
has_capacityBoolWhether edge has capacity limits-false
can_expandBoolWhether capacity can be expanded-false
can_retireBoolWhether capacity can be retired-false
existing_capacityFloat64Initial installed capacityMWh/hr0.0
max_capacityFloat64Maximum total capacityMWh/hrInf
min_capacityFloat64Minimum total capacityMWh/hr0.0
max_new_capacityFloat64Maximum new capacity additionsMWh/hrInf
capacity_sizeFloat64Unit size for capacity decisionsMWh/hr1.0
integer_decisionsBoolWhether to use integer capacity vars-false

Economic Parameters

FieldTypeDescriptionUnitsDefault
investment_costFloat64CAPEX per unit capacity$/MW0.0
annualized_investment_costFloat64Annualized CAPEX$/MW/yrcalculated
fixed_om_costFloat64Fixed O&M costs$/MW/yr0.0
variable_om_costFloat64Variable O&M costs$/MWh0.0
waccFloat64Weighted average cost of capitalfraction0.0
lifetimeIntAsset lifetime in yearsyears1
capital_recovery_periodIntInvestment recovery periodyears1
retirement_periodIntRetirement periodyears0

Unit Commitment Economic Parameters (EdgeWithUC only)

FieldTypeDescriptionUnitsDefault
startup_costFloat64Cost per startup$0.0
startup_fuel_consumptionFloat64Fuel consumed during startupMWh0.0
min_up_timeFloat64Minimum up timehours0.0
min_down_timeFloat64Minimum down timehours0.0

Operational Parameters

FieldTypeDescriptionUnitsDefault
availabilityVector{Float64}Time-varying availability factorsfraction1.0
loss_fractionVector{Float64}Flow lossesfractionFloat64[]
min_flow_fractionFloat64Minimum operating levelfraction0.0
ramp_up_fractionFloat64Maximum ramp-up ratefraction/step1.0
ramp_down_fractionFloat64Maximum ramp-down ratefraction/step1.0
distanceFloat64Connection distancekm0.0

Investment and Operations Tracking (Internal)

FieldTypeDescriptionUnitsDefault
flowUnion{JuMPVariable,Vector{Float64}}Commodity flow through edgeMWh/hr-
capacityUnion{AffExpr,Float64}Total available capacityMWh/hr-
new_capacityJuMPVariableNew capacity investmentsMWh/hr-
new_capacity_trackDict{Int,Float64}Capacity additions by periodMWh/hr-
retired_capacityJuMPVariableCapacity retirementsMWh/hr-
retired_capacity_trackDict{Int,Float64}Retirements by periodMWh/hr-
new_unitsJuMPVariableNew unit installationsunits-
retired_unitsJuMPVariableUnit retirementsunits-
constraintsVector{AbstractTypeConstraint}Additional constraints-[]

Unit Commitment Tracking (EdgeWithUC only, Internal)

FieldTypeDescriptionUnitsDefault
ucommitJuMPVariableCommitment status variables--
ustartJuMPVariableStartup decision variables--
ushutJuMPVariableShutdown decision variables--
startup_fuel_balance_idSymbolID of the balance used to track start-up fuel consumption--

Types

Type Hierarchy

AbstractEdge{T}
├── Edge{T}
└── EdgeWithUC{T}

AbstractEdge{T}

Abstract base type for all edges,parameterized by commodity type T.

Edge{T}

Standard edge implementation, without unit commitment constraints. It is parameterized by commodity type T

EdgeWithUC{T}

Edge with unit commitment constraints for modeling assets with startup/shutdown dynamics. It is parameterized by commodity type T

Constructors

Keyword Constructors

Edge{T}(; id::Symbol, start_vertex::AbstractVertex, end_vertex::AbstractVertex, 
        time_data::TimeData, commodity::Type{T}, [additional_fields...])

EdgeWithUC{T}(; id::Symbol, start_vertex::AbstractVertex, end_vertex::AbstractVertex, 
              time_data::TimeData, commodity::Type{T}, [additional_fields...])

Direct constructors using keyword arguments for all fields, where T is the type of commodity flowing through the edge, e.g. Electricity, NaturalGas, etc.

ParameterTypeDescriptionRequired
idSymbolUnique identifierYes
start_vertexAbstractVertexOrigin vertexYes
end_vertexAbstractVertexDestination vertexYes
time_dataTimeDataTime-related data structureYes
commodityType{T}Commodity type flowing through edgeYes
unidirectionalBoolFlow direction constraintNo
has_capacityBoolWhether edge has capacity limitsNo
existing_capacityFloat64Initial installed capacityNo
max_capacityFloat64Maximum total capacityNo
investment_costFloat64CAPEX per unit capacityNo
variable_om_costFloat64Variable O&M costsNo
...VariousAdditional edge-specific fieldsNo

Primary Constructors

Edge(id::Symbol, data::AbstractDict{Symbol,Any}, time_data::TimeData, 
     commodity::Type, start_vertex::AbstractVertex, end_vertex::AbstractVertex)

EdgeWithUC(id::Symbol, data::AbstractDict{Symbol,Any}, time_data::TimeData, 
           commodity::Type, start_vertex::AbstractVertex, end_vertex::AbstractVertex)

Creates Edge components from input data dictionary, time data, commodity type, and vertices.

ParameterTypeDescription
idSymbolUnique identifier of the Edge
dataAbstractDict{Symbol,Any}Configuration data
time_dataTimeDataTemporal data on the representative periods being modelled
commodityTypeCommodity type flowing through Edge
start_vertexAbstractVertexOrigin vertex of the Edge
end_vertexAbstractVertexDestination vertex of the Edge

Factory Constructors

make_edge(id::Symbol, data::AbstractDict{Symbol,Any}, time_data::TimeData, 
          commodity::Type, start_vertex::AbstractVertex, end_vertex::AbstractVertex)

make_edge_with_uc(id::Symbol, data::AbstractDict{Symbol,Any}, time_data::TimeData, 
                  commodity::Type, start_vertex::AbstractVertex, end_vertex::AbstractVertex)

Internal factory methods for creating Edge components with data processing and validation.

ParameterTypeDescription
idSymbolUnique identifier for the edge
dataAbstractDict{Symbol,Any}Configuration data for the edge
time_dataTimeDataTime-related data structure
commodityTypeCommodity type for the edge
start_vertexAbstractVertexOrigin vertex of the edge
end_vertexAbstractVertexDestination vertex of the edge

Methods

Accessor Functions

FunctionDescriptionReturns
id(edge)Get edge IDSymbol
flow(edge)Get flow variable/valuesUnion{JuMPVariable,Vector{Float64}}
flow(edge, t)Get flow at timestep tFloat64
capacity(edge)Get total capacityUnion{AffExpr,Float64}
existing_capacity(edge)Get existing capacityFloat64
new_capacity(edge)Get new capacity variableJuMPVariable
availability(edge)Get availability profileVector{Float64}
availability(edge, t)Get availability at timestep tFloat64
loss_fraction(edge)Get loss profileVector{Float64}
loss_fraction(edge, t)Get loss at timestep tFloat64
commodity_type(edge)Get commodity typeType
start_vertex(edge)Get origin vertexAbstractVertex
end_vertex(edge)Get destination vertexAbstractVertex

Capacity and Investment

FunctionDescriptionReturns
can_expand(edge)Check if expandableBool
can_retire(edge)Check if retirableBool
has_capacity(edge)Check if capacity-constrainedBool
max_capacity(edge)Get maximum capacityFloat64
min_capacity(edge)Get minimum capacityFloat64
investment_cost(edge)Get investment costFloat64
annualized_investment_cost(edge)Get annualized costFloat64

Unit Commitment Methods (EdgeWithUC only)

FunctionDescriptionReturns
min_up_time(edge)Get minimum up timeFloat64
min_down_time(edge)Get minimum down timeFloat64
startup_cost(edge)Get startup costFloat64
startup_fuel_consumption(edge)Get startup fuel consumptionFloat64

Asset Creation

FunctionDescriptionReturns
@edge_data(new_defaults)Macro to set new default fields for an AssetDict{Symbol,Any}

Model Creation

FunctionDescriptionReturns
operation_model!(edge, model)Create operational variables and constraints for the Edge and add to modelNothing
planning_model!(edge, model)Create investment variables and constraints for the Edge and add to modelNothing
compute_investment_costs!(edge, model)Calculate annualized, discounted investment costsNothing
compute_om_fixed_costs!(edge, model)Calculate discounted fixed OM costsNothing
compute_fixed_costs!(edge, model)Calculate annualized, discounted fixed costsNothing
add_linking_variables!(edge, model)Add linking variables between the planning and operational modelsNothing
define_available_capacity!(edge, model)Calculate and fix available capacityNothing

Constraint Management

FunctionDescriptionReturns
all_constraints(edge)Get all constraintsVector{AbstractTypeConstraint}
all_constraints_types(edge)Get constraint typesVector{Type}
get_constraint_by_type(edge, type)Get specific constraint typeUnion{AbstractTypeConstraint,Nothing}

Utility Functions

FunctionDescriptionReturns
edges_with_capacity_variables(edges)Filter edges with capacity variablesVector{AbstractEdge}
target_is_valid(edge, target)Validate edge-vertex compatibilityBool
edge_default_data()Get default edge data valuesDict{Symbol,Any}

Examples

Transmission Line

Transmission lines can be represented as TransmissionLink{Electricity} Assets. These are made up of an Edge{Electricity} between two Node{Electricity} vertices.

Transmission Line Inputs

Assets can be defined using the standard or advanced JSON input formats, or a blend of the two. The standard format is simpler and more concise, while the advanced format allows for more flexibility and additional fields.

Macro also supports CSV inputs. These will usually use the standard input format. Please refer to the CSV Input documentation for more details on how to use CSV files.

Standard JSON Input Format

Using the simplified, standard JSON input format, a transmission line can be defined as shown below.

{
    "type": "TransmissionLink",
    "instance_data": {
        "id": "TransmissionLine_SE_MIDAT",
        "commodity": "Electricity",
        "location": "elec_SE",
        "transmission_destination": "elec_MIDAT",
        "unidirectional": false,
        "distance": 491.4512001,
        "existing_capacity": 5552,
        "max_capacity": 27760,
        "investment_cost": 40219,
        "loss_fraction": 0.04914512,
        "constraints": {
            "MaxCapacityConstraint": true
        }
    }
}
Advanced JSON Input Format

A transmission line can also be defined using the full, advanced JSON input format. This more closely mirrors the fields of the Assets components. Note that some fields are set to their default values, such as can_expand, can_retire, and integer_decisions. These could be omitted but are often included to make the inputs more explicit or facilitate future changes.

The commodity input is not a field of the Edge{Electricity}. Here, it is one of the additional inputs required by the TransmissionLink Asset. It is used to decide the commodity type of the Edge and Asset, in this instance Electricity.

Additional inputs like this are set when defining an Asset and its make() function. They will not be made fields of the Asset's components, but will be used when creating the Asset. Other common examples are the location input, which is used to connect an Asset to multiple Nodes with the same location field, and the uc input which is used to specify whether an Asset should use a regular Edge or an EdgeWithUC.

{
    "type": "TransmissionLink",
    "instance_data": {
        "id": "TransmissionLine_SE_MIDAT",
        "edges": {
            "transmission_edge": {
                "commodity": "Electricity",
                "start_vertex": "elec_SE",
                "end_vertex": "elec_MIDAT",
                "unidirectional": false,
                "has_capacity": true,
                "can_expand": true,
                "can_retire": false,
                "integer_decisions": false,
                "distance": 491.4512001,
                "existing_capacity": 5552,
                "max_capacity": 27760,
                "investment_cost": 40219,
                "loss_fraction": 0.04914512,
                "constraints": {
                    "CapacityConstraint": true,
                    "MaxCapacityConstraint": true
                }
            }
        }
    }
}

Creating the Transmission Line Asset

A full guide on how to create Assets can be found in the Creating a New Asset section. Further discussion of Assets and the @edge_data macro can be found in the Assets documentation.

First, we add an Edge to the TransmissionLink Asset struct. TransmissionLinks are generalized connections meant to represent transmission lines, pipelines without linepack, data connections, etc. Therefore, we parameterized the Asset by the commodity its Edge carries, e.g. TransmissionLink{Electricity} or TransmissionLink{NaturalGas}.

struct TransmissionLink{T} <: AbstractAsset
    id::AssetId
    transmission_edge::Edge{<:T}
end

The next step is to define how the TransmissionLink Asset inputs should be parsed into the data required to create the Edge{Electricity}. This is done as part of the TransmissionLink Assets make() function.

We will break down the steps of the make() function but the entire function is shown below to put the code snippet in context:

function make(asset_type::Type{<:TransmissionLink}, data::AbstractDict{Symbol,Any}, system::System)
    id = AssetId(data[:id]) 

    @setup_data(asset_type, data, id)

    transmission_edge_key = :transmission_edge
    @process_data(
        transmission_edge_data,
        data[:edges][transmission_edge_key],
        [
            (data[:edges][transmission_edge_key], key),
            (data[:edges][transmission_edge_key], Symbol("transmission_", key)),
            (data, Symbol("transmission_", key)),
            (data, key), 
        ]
    )

    commodity_symbol = Symbol(transmission_edge_data[:commodity])
    commodity = commodity_types()[commodity_symbol]
    
    @start_vertex(
        t_start_node,
        transmission_edge_data,
        commodity,
        [(transmission_edge_data, :start_vertex), (data, :transmission_origin), (data, :location)],
    )
    @end_vertex(
        t_end_node,
        transmission_edge_data,
        commodity,
        [(transmission_edge_data, :end_vertex), (data, :transmission_dest), (data, :location)],
    )

    transmission_edge = Edge(
        Symbol(id, "_", transmission_edge_key),
        transmission_edge_data,
        system.time_data[commodity_symbol],
        commodity,
        t_start_node,
        t_end_node,
    )
    return TransmissionLink(id, transmission_edge)
end
Assign the Asset ID and setup the defaults
id = AssetId(data[:id])
@setup_data(asset_type, data, id)

The first step is to assign the Asset an ID, using on the id field in the input data. The AssetId type is currently just an alias for a Symbol but may be extended in the future to include additional metadata about the Asset.

The @setup_data macro is used to configure the default values for the Asset, based on the generic defaults of each component and the specific defaults for the Asset. The latter are set using the default_data() functions, which is described in the Assets documentation.

Process the Edge data
transmission_edge_key = :transmission_edge
@process_data(
    transmission_edge_data,
    data[:edges][transmission_edge_key],
    [
        (data[:edges][transmission_edge_key], key),
        (data[:edges][transmission_edge_key], Symbol("transmission_", key)),
        (data, Symbol("transmission_", key)),
        (data, key), 
    ]
)

The next step is to parse the input data for the Edge into the format required by the Edge constructor. This could be done with a simple dictionary lookup between the input data and the Edge fields. However, that would limit the input data to being formatted in a very specific way.

To allow for more flexibility, and simpler input files, we can use the @process_data macro to extract the relevant data from multiple possible locations in the input dictionary. This gives the user many options for how to structure their input files, at the cost of making the Asset modellers job a bit more complex.

The core idea of the @process_data macro is that it gives Macro a list of locations to look for each piece of data. This is explained in more detail in the Assets documentation. However, the intuition is that the macro will loop through the Edges fields, searching for each field in the options listed in the third argument to the macro.

For example, when searching for the has_capacity field, it will look in:

  • data[:edges][transmission_edge_key][:has_capacity] first. If it is not found, it will look in:
  • data[:edges][transmission_edge_key][:transmission_has_capacity], then:
  • data[:transmission_has_capacity], and finally:
  • data[:has_capacity].

You will note that the search progresses from the most nested / specific location to the least. This makes it easier to mix global and instance input data for Assets.

Ultimately, the @process_data macro will extract the relevant data from the input dictionary and store it in the transmission_edge_data variable. This variable will then be used to create the Edge{Electricity}.

Set the commodity type
commodity_symbol = Symbol(transmission_edge_data[:commodity])
commodity = commodity_types()[commodity_symbol]

TransmissionLink Assets require a commodity field in their inputs. This will be a String, which we first convert into a Symbol and then look up in the list of available commodity types. This list is accessed using the commodity_types() function, which returns a dictionary mapping commodity symbols to their types.

Define the start and end vertices
@start_vertex(
    t_start_node,
    transmission_edge_data,
    commodity,
    [(transmission_edge_data, :start_vertex), (data, :transmission_origin), (data, :location)],
)
@end_vertex(
    t_end_node,
    transmission_edge_data,
    commodity,
    [(transmission_edge_data, :end_vertex), (data, :transmission_dest), (data, :location)],
)

The next step is to find the start and end vertices of the Edge{Electricity}. In our example these are the Node{Electricity}. However, they can be other Vertices.

The @start_vertex and @end_vertex macros are similar to the @process_data macro in that they allow for flexibility in how the input data is structured. They will search for the ids given in the start_vertex and end_vertex fields of the input data. They will first look in the most specific location before moving to the more general locations.

If the two Vertices are found, they will be assigned to the t_start_node and t_end_node variables.

transmission_edge = Edge(
    Symbol(id, "_", transmission_edge_key),
    transmission_edge_data,
    system.time_data[commodity_symbol],
    commodity,
    t_start_node,
    t_end_node,
)
return TransmissionLink(id, transmission_edge)

The final step is to create the Edge{Electricity} using the Edge constructor. This requires:

  • A new ID, derived from the Assets unique ID.
  • The transmission_edge_data dictionary, which contains the data for the Edge.
  • The temporal data for the Edge based on its Commodity. This data is found in the System-wide time_data dictionary.
  • The Commodity type, which was looked up earlier.
  • The start and end vertices, which were found using the @start_vertex and @end_vertex macros.

The make() function then returns a new TransmissionLink Asset, which contains the Edge{Electricity} as one of its components.

Modellers can define Asset-specific default values for the TransmissionLink Asset using the full_default_data() and simple_default_data() functions. These allow Users to provide much shorter and simpler input files than are otherwise required. The two functions are described in the Assets documentation.

Solar PV Power Plant

Solar PV, Standard JSON Input Format

{
    "type": "VRE",
    "global_data": {},
    "instance_data": {
        "id": "example_solar_pv",
        "location": "boston",
        "fixed_om_cost": 13510.19684,
        "investment_cost": 41245.37889,
        "max_capacity": 989513,
        "availability": {
            "timeseries": {
                "path": "system/availability.csv",
                "header": "boston_solar_pv",
            }
        },
        "elec_can_expand": true,
        "elec_can_retire": false,
        "elec_constraints": {
            "MaxCapacityConstraint": true
        }
    }
}

Solar PV, Advanced JSON Input Format

{
    "type": "VRE",
    "global_data": {},
    "instance_data": {
        "id": "example_solar_pv",
        "transforms": {
            "timedata": "Electricity"
        },
        "edges": {
            "edge": {
                "commodity": "Electricity",
                "unidirectional": true,
                "can_expand": true,
                "can_retire": false,
                "has_capacity": true,
                "constraints": {
                    "CapacityConstraint": true,
                    "MaxCapacityConstraint": true
                },
                "fixed_om_cost": 13510.19684,
                "investment_cost": 41245.37889,
                "max_capacity": 989513,
                "end_vertex": "boston_elec",
                "availability": {
                    "timeseries": {
                        "path": "system/availability.csv",
                        "header": "boston_solar_pv",
                    }
                },
            }
        }
    }
}

Natural Gas Power Plant

Nat Gas, Standard JSON Input Format

{
    "type": "ThermalPower",
    "global_data": {},
    "instance_data": {
        "id": "example_natural_gas_power_plant",
        "location": "boston",
        "timedata": "NaturalGas",
        "fuel_commodity": "NaturalGas",
        "co2_sink": "co2_sink",
        "uc": true,
        "elec_constraints": {
            "CapacityConstraint": true,
            "RampingLimitConstraint": true,
            "MinFlowConstraint": true,
            "MinUpTimeConstraint": true,
            "MinDownTimeConstraint": true,
        },
        "emission_rate": 0.181048235160161,
        "fuel_consumption": 2.249613533,
        "can_expand": false,
        "existing_capacity": 4026.4,
        "investment_cost": 0.0,
        "fixed_om_cost": 16001,
        "variable_om_cost": 4.415,
        "capacity_size": 125.825,
        "startup_cost": 89.34,
        "startup_fuel_consumption": 0.58614214,
        "min_up_time": 6,
        "min_down_time": 6,
        "ramp_up_fraction": 0.64,
        "ramp_down_fraction": 0.64,
        "min_flow_fraction": 0.444
    }
}

Nat Gas, Advanced JSON Input Format

{
    "type": "ThermalPower",
    "global_data": {},
    "instance_data": {
        "id": "example_natural_gas_power_plant",
        "transforms": {
            "emission_rate": 0.181048235160161,
            "fuel_consumption": 2.249613533
        },
        "edges": {
            "elec_edge": {
                "commodity": "Electricity",
                "unidirectional": true,
                "has_capacity": true,
                "uc": true,
                "integer_decisions": false,
                "constraints": {
                    "CapacityConstraint": true,
                    "RampingLimitConstraint": true,
                    "MinFlowConstraint": true,
                    "MinUpTimeConstraint": true,
                    "MinDownTimeConstraint": true
                },
               "end_vertex": "boston_elec",
                "can_retire": true,
                "can_expand": false,
                "existing_capacity": 4026.4,
                "investment_cost": 0.0,
                "fixed_om_cost": 16001,
                "variable_om_cost": 4.415,
                "capacity_size": 125.825,
                "startup_cost": 89.34,
                "startup_fuel_consumption": 0.58614214,
                "min_up_time": 6,
                "min_down_time": 6,
                "ramp_up_fraction": 0.64,
                "ramp_down_fraction": 0.64,
                "min_flow_fraction": 0.444
            },
            "fuel_edge": {
                "commodity": "NaturalGas",
                "unidirectional": true,
                "has_capacity": false,
                "start_vertex": "boston_natgas"
            },
            "co2_edge": {
                "commodity": "CO2",
                "unidirectional": true,
                "has_capacity": false,
                "end_vertex": "co2_sink"
            }
        }
    }
}

See Also

  • Nodes - Network nodes that edges connect to
  • Transformations - Processes that transform flows between edges
  • Storage - Energy storage components that can be connected to edges
  • Vertices - Network nodes that edges connect
  • Assets - Higher-level components made from edges, nodes,
  • Commodities - Types of resources flowing through edges
  • Time Data - Temporal modeling framework
  • Constraints - Additional constraints for edges