Getting Started

Nosy is a Julia package for building optimisation models of energy systems. You provide a JuMP-compatible optimiser, create carriers and nodes, connect components into a Snapshot, optimize an objective, and extract a solution snapshot for post-processing.

Requirements

Nosy requires Julia 1.11 or newer and a LP or MILP solver compatible with JuMP. The examples in this documentation use HiGHS because it is open source and works well for many linear examples. Other JuMP-compatible solvers can be used the same way. Please note: some solvers require a separate installation and license.

Minimal Workflow

using Nosy
using HiGHS

# Create a simulation with a JuMP model and the default hourly time mesh.
s = Sim(Model(HiGHS.Optimizer); mesh=TimeMesh())
elec = EnergyCarrier("power", s)

# Create one snapshot and one electricity node.
snapshot = Snapshot(s)
grid = Node("grid", elec, rule=:curtailed)

# Add an exogenous electricity demand.
load = 100 * (2 .+ [sin(2pi * h/24) for h in 1:8760])  # consumption as a base load + sinus term
demand = Component("demand", Demand(elec, load))
connect!(snapshot, demand, grid)

# Add a dispatchable source with optimizable capacity and operating cost.
plant = Component(
    "plant",
    DispatchableSource(elec),
    [
        VariableCapacity("output", energy), # output capacity of the plant is an optimization variable
        FixedCost(:capex, "output", energy, 60_000.0), # annualized CAPEX of 60000 USD/MW/year
        VariableCost(:fuel, "output", energy, 50.0), # fuel cost of 50 USD/MWh
    ],
)
connect!(snapshot, plant, grid)

# Minimize total system cost and extract the solved values.
optimize!(snapshot, cost(snapshot)) # optimize the Snapshot (with HiGHS) by minimizing total cost
result = extract(snapshot) # generate a Snapshot populated with the optimal solution

# Inspect results.
cost(result) # total cost of the snapshot, in USD/year
capacity(result, "plant") # capacity of the plant, in MW
balance(result, "plant", :output, energy; collapse=true, aggregate=true) # energy generated by the plant, in MWh/year

The original snapshot contains JuMP variables and expressions. The extracted result has the same structure, but is populated with optimal values when the optimisation succeeds.

Inspecting Results

# Total cost of the solved system.
cost(result)

# Cost breakdown by cost tag.
costs(result)

# Optimised component capacities.
table(result, capacity)

# Aggregated plant output over the model horizon.
balance(result, "plant", :output, energy; collapse=true, aggregate=true)