Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
837fa3e
Improve EMGUI-testing tool for plotting all results
Aug 14, 2025
6a3bd1f
Enable reading model results from files by enabling model::String bei…
Aug 14, 2025
b04717f
Enhance visualization of plots over OperationalPeriods having a const…
Aug 15, 2025
d0d92a1
Format using JuliaFormatter
Aug 15, 2025
a90997d
Move functions from generating cases from the example files to a sing…
Aug 15, 2025
5da4ebb
Fix bugs and format code
Aug 15, 2025
70c8dbf
Resolve issues around closing screens for testing
Aug 15, 2025
ad02ea6
Ressolve issue with z_leveling that was introduced when displaying fi…
Aug 17, 2025
3b0b08e
Create dictionary for repr look-up for speed improvements
Aug 17, 2025
b3286e9
Optimize runtime
Aug 18, 2025
d1e526b
Move using JuMP, HiGHS and PrettyTables to examples/generate_examples.jl
Sep 10, 2025
b2cd9d8
Fix example in docs to the new structure for examples
Sep 10, 2025
9ee51f6
Move case7.jl to the test folder
Sep 10, 2025
a4f3cd4
Remove redundant design files
Sep 10, 2025
38b6db3
Dispatch more consistently on the functions from EMB and EMG to avoid…
Sep 10, 2025
6b97574
Move the input files of case 7
Sep 15, 2025
4c30aca
Add miscellaneous suggestions from review
Sep 15, 2025
9db156a
Remove redundant dependency on GLMakie in the test environment
Sep 16, 2025
5955f9c
Revert test of Base.show as testing for string equality using repr pr…
Sep 16, 2025
b70a97d
Modify tests of Base.show to test against its definition
Sep 16, 2025
660fb1d
Remove redundant git-ignores
Sep 23, 2025
840dcaf
Add warning on docstrings regarding variables with more than three in…
Sep 23, 2025
88d9ff7
Minor update to docstrings
JulStraus Sep 24, 2025
5a51b9a
Fixed CI and docs errors
JulStraus Sep 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,8 @@
# environment.
*Manifest.toml

# Internal files for testing the system locally
*.geojson
*startup.jl
/test/test_coverage.jl

# Build artifacts for creating documentation generated by the Documenter package
/examples/exported_files
/docs/build/
/docs/src/manual/NEWS.md
/docs/src/figures/example.png
/docs/src/figures/colors_visualization.png

# Exported files when running the tests
/examples/exported_files
/docs/src/figures/colors_visualization.png
19 changes: 19 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Release notes

## Unversioned

### Enhancement

* Enable reading model results from files by enabling `model::String` being the directory to the saved files instead of `model::JuMP.Model`. Note that the files can be generated by `EnergyModelsGUI.save_results(model::JuMP.model)`.
* Enhance the descriptive names for nodes having dictionaries with keys of type Resource as in the `MultipleBuildingTypes`-node in `EnergyModelsLanguageInterfaces.jl`.
* Enhance visualization of plots over OperationalPeriods having a constant non-zero value.

### Adjustment

* Move functions from generating cases from the example files to a single file to enable testing without requiring rerunning the cases.

## Version 0.5.15 (2025-08-07)

### Bugfix

* Fix bug from breaking changes in GLMakie v0.10 on Windows.

## Version 0.5.14 (2025-06-25)

### Bugfix
Expand All @@ -20,6 +38,7 @@
* Added more descriptive names for `EnergyModelsHeat` and `EnergyModelsHydrogen` and add a colors for the `HeatLT` and `HeatHT` resources.

### Adjustment

* Order the colors (by id) in the Resources legend.
* Move boundaries for countries just above the ocean layer.
* Fix default placements of the nodes in a uniform circle (when coordinates are not provided).
Expand Down
4 changes: 4 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ authors = ["Jon Vegard Venås <JonVegard.Venas@sintef.no>", "Magnus Askeland <Ma
version = "0.5.15"

[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
EnergyModelsBase = "5d7e687e-f956-46f3-9045-6f5a5fd49f50"
EnergyModelsInvestments = "fca3f8eb-b383-437d-8e7b-aac76bb2004f"
Expand All @@ -31,8 +33,10 @@ EnergyModelsGeography = "3f775d88-a4da-46c4-a2cc-aa9f16db6708"
EMGExt = "EnergyModelsGeography"

[compat]
CSV = "0.10"
CairoMakie = "=0.12.18"
Colors = "0.12"
DataFrames = "1.7"
Dates = "1.9"
EnergyModelsBase = "0.9"
EnergyModelsGeography = "0.11"
Expand Down
2 changes: 2 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
[deps]
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656"
EnergyModelsBase = "5d7e687e-f956-46f3-9045-6f5a5fd49f50"
EnergyModelsGUI = "737a7361-d3b7-40e9-b1ac-59bee4c5ea2d"
EnergyModelsGeography = "3f775d88-a4da-46c4-a2cc-aa9f16db6708"
EnergyModelsInvestments = "fca3f8eb-b383-437d-8e7b-aac76bb2004f"
EnergyModelsRenewableProducers = "b007c34f-ba52-4995-ba37-fffe79fbde35"
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
TimeStruct = "f9ed5ce0-9f41-4eaa-96da-f38ab8df101c"
Expand Down
1 change: 1 addition & 0 deletions docs/generate_images.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ end
Create figures of the GUI based on the EMI_geography.jl example to be used for docs and README.md.
"""
function create_EMI_geography_images()
include(joinpath(@__DIR__, "..", "examples", "generate_examples.jl"))
include(joinpath(@__DIR__, "..", "examples", "EMI_geography.jl"))

# Create examples.png image
Expand Down
9 changes: 8 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Documenter
using DocumenterInterLinks
using EnergyModelsBase
using EnergyModelsGeography
using EnergyModelsGUI
Expand All @@ -18,13 +19,18 @@ DocMeta.setdocmeta!(
EnergyModelsGUI, :DocTestSetup, :(using EnergyModelsGUI); recursive = true,
)

links = InterLinks(
"EnergyModelsBase" => "https://energymodelsx.github.io/EnergyModelsBase.jl/stable/",
)

makedocs(;
sitename = "EnergyModelsGUI.jl",
format = Documenter.HTML(;
prettyurls = get(ENV, "CI", "false") == "true",
edit_link = "main",
assets = String[],
ansicolor = true,
size_threshold = 307200, # Default is 204800 (KiB)
),
modules = [EnergyModelsGUI],
pages = [
Expand All @@ -35,7 +41,7 @@ makedocs(;
"Example"=>"manual/simple-example.md",
"Release notes"=>"manual/NEWS.md",
],
"How-to" => Any[
"How to" => Any[
"Save design to file"=>"how-to/save-design.md",
"Export results"=>"how-to/export-results.md",
"Customize colors"=>"how-to/customize-colors.md",
Expand All @@ -47,6 +53,7 @@ makedocs(;
"Internals"=>Any["Reference"=>"library/internals/reference.md",],
],
],
plugins = [links],
)

deploydocs(; repo = "github.com/EnergyModelsX/EnergyModelsGUI.jl.git")
Binary file modified docs/src/figures/EMI_geography.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/src/figures/EMI_geography_Oslo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 1 addition & 4 deletions docs/src/manual/simple-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,8 @@ using EnergyModelsGUI
# Get the path of the examples directory
exdir = joinpath(pkgdir(EnergyModelsGUI), "examples")

# Activate project for the examples in the EnergyModelsGUI repository
Pkg.activate(exdir)
Pkg.instantiate()

# Include the code into the Julia REPL to run the following example
include(joinpath(exdir, "generate_examples.jl"))
include(joinpath(exdir, "EMI_geography.jl"))
```

Expand Down
133 changes: 0 additions & 133 deletions examples/EMB_network.jl
Original file line number Diff line number Diff line change
@@ -1,135 +1,3 @@
# Import the required packages
using EnergyModelsBase
using JuMP
using HiGHS
using PrettyTables
using TimeStruct

"""
generate_example_network()

Generate the data for an example consisting of a simple electricity network.
The more stringent CO₂ emission in latter investment periods force the utilization of the
more expensive natural gas power plant with CCS to reduce emissions.
"""
function generate_example_network()
@info "Generate case data - Simple network example"

# Define the different resources and their emission intensity in tCO2/MWh
NG = ResourceEmit("NG", 0.2)
Coal = ResourceCarrier("Coal", 0.35)
Power = ResourceCarrier("Power", 0.0)
CO2 = ResourceEmit("CO2", 1.0)
products = [NG, Coal, Power, CO2]

# Variables for the individual entries of the time structure
op_duration = 2 # Each operational period has a duration of 2
op_number = 4 # There are in total 4 operational periods
operational_periods = SimpleTimes(op_number, op_duration)

# The number of operational periods times the duration of the operational periods, which
# can also be extracted using the function `duration` of a `SimpleTimes` structure.
# This implies, that a strategic period is 8 times longer than an operational period,
# resulting in the values below as "/8h".
op_per_strat = op_duration * op_number

# Creation of the time structure and global data
T = TwoLevel(4, 1, operational_periods; op_per_strat)
model = OperationalModel(
Dict( # Emission cap for CO₂ in t/8h and for NG in MWh/8h
CO2 => StrategicProfile([160, 140, 120, 100]),
NG => FixedProfile(1e6),
),
Dict( # Emission price for CO₂ in EUR/t and for NG in EUR/MWh
CO2 => FixedProfile(0),
NG => FixedProfile(0),
),
CO2, # CO2 instance
)

# Creation of the emission data for the individual nodes.
capture_data = CaptureEnergyEmissions(0.9)
emission_data = EmissionsEnergy()

# Create the individual test nodes, corresponding to a system with an electricity demand/sink,
# coal and nautral gas sources, coal and natural gas (with CCS) power plants and CO₂ storage.
nodes = [
GenAvailability("Availability", products),
RefSource(
"NG source", # Node id
FixedProfile(100), # Capacity in MW
FixedProfile(30), # Variable OPEX in EUR/MW
FixedProfile(0), # Fixed OPEX in EUR/MW/8h
Dict(NG => 1), # Output from the Node, in this case, NG
),
RefSource(
"coal source", # Node id
FixedProfile(100), # Capacity in MW
FixedProfile(9), # Variable OPEX in EUR/MWh
FixedProfile(0), # Fixed OPEX in EUR/MW/8h
Dict(Coal => 1), # Output from the Node, in this case, coal
),
RefNetworkNode(
"NG+CCS power plant", # Node id
FixedProfile(25), # Capacity in MW
FixedProfile(5.5), # Variable OPEX in EUR/MWh
FixedProfile(0), # Fixed OPEX in EUR/MW/8h
Dict(NG => 2), # Input to the node with input ratio
Dict(Power => 1, CO2 => 1), # Output from the node with output ratio
# Line above: CO2 is required as output for variable definition, but the
# value does not matter
[capture_data], # Additonal data for emissions and CO₂ capture
),
RefNetworkNode(
"coal power plant", # Node id
FixedProfile(25), # Capacity in MW
FixedProfile(6), # Variable OPEX in EUR/MWh
FixedProfile(0), # Fixed OPEX in EUR/MW/8h
Dict(Coal => 2.5), # Input to the node with input ratio
Dict(Power => 1), # Output from the node with output ratio
[emission_data], # Additonal data for emissions
),
RefStorage{AccumulatingEmissions}(
"CO2 storage", # Node id
StorCapOpex(
FixedProfile(60), # Charge capacity in t/h
FixedProfile(9.1), # Storage variable OPEX for the charging in EUR/t
FixedProfile(0) # Storage fixed OPEX for the charging in EUR/(t/h 8h)
),
StorCap(FixedProfile(600)), # Storage capacity in t
CO2, # Stored resource
Dict(CO2 => 1, Power => 0.02), # Input resource with input ratio
# Line above: This implies that storing CO₂ requires Power
Dict(CO2 => 1), # Output from the node with output ratio
# In practice, for CO₂ storage, this is never used.
),
RefSink(
"electricity demand", # Node id
OperationalProfile([20, 30, 40, 30]), # Demand in MW
Dict(:surplus => FixedProfile(0), :deficit => FixedProfile(1e6)),
# Line above: Surplus and deficit penalty for the node in EUR/MWh
Dict(Power => 1), # Energy demand and corresponding ratio
),
]

# Connect all nodes with the availability node for the overall energy/mass balance
links = [
Direct("Av-NG_pp", nodes[1], nodes[4], Linear())
Direct("Av-coal_pp", nodes[1], nodes[5], Linear())
Direct("Av-CO2_stor", nodes[1], nodes[6], Linear())
Direct("Av-demand", nodes[1], nodes[7], Linear())
Direct("NG_src-av", nodes[2], nodes[1], Linear())
Direct("Coal_src-av", nodes[3], nodes[1], Linear())
Direct("NG_pp-av", nodes[4], nodes[1], Linear())
Direct("Coal_pp-av", nodes[5], nodes[1], Linear())
Direct("CO2_stor-av", nodes[6], nodes[1], Linear())
]

# Input data structure
case = Case(T, products, [nodes, links], [[get_nodes, get_links]])
return case, model
end

# Generate the case and model data and run the model
case, model = generate_example_network()
optimizer = optimizer_with_attributes(HiGHS.Optimizer, MOI.Silent() => true)
Expand Down Expand Up @@ -159,7 +27,6 @@ pretty_table(
## Code below for displaying the GUI

using EnergyModelsGUI
const EMB = EnergyModelsBase

# Set a special icon only for last node and the other icons based on type
id_to_icon_map = Dict(
Expand Down
69 changes: 0 additions & 69 deletions examples/EMB_sink_source.jl
Original file line number Diff line number Diff line change
@@ -1,72 +1,3 @@
# Import the required packages
using EnergyModelsBase
using JuMP
using HiGHS
using PrettyTables
using TimeStruct

"""
generate_example_ss()

Generate the data for an example consisting of an electricity source and sink. It shows how
the source adjusts to the demand.
"""
function generate_example_ss()
@info "Generate case data - Simple sink-source example"

# Define the different resources and their emission intensity in tCO2/MWh
Power = ResourceCarrier("Power", 0.0)
CO2 = ResourceEmit("CO2", 1.0)
products = [Power, CO2]

# Variables for the individual entries of the time structure
op_duration = 2 # Each operational period has a duration of 2
op_number = 4 # There are in total 4 operational periods
operational_periods = SimpleTimes(op_number, op_duration)

# The number of operational periods times the duration of the operational periods, which
# can also be extracted using the function `duration` of a `SimpleTimes` structure.
# This implies, that a strategic period is 8 times longer than an operational period,
# resulting in the values below as "/8h".
op_per_strat = op_duration * op_number

# Creation of the time structure and global data
T = TwoLevel(2, 1, operational_periods; op_per_strat)
model = OperationalModel(
Dict(CO2 => FixedProfile(10)), # Emission cap for CO₂ in t/8h
Dict(CO2 => FixedProfile(0)), # Emission price for CO₂ in EUR/t
CO2, # CO₂ instance
)

# Create the individual test nodes, corresponding to a system with an electricity
# demand/sink and source
nodes = [
RefSource(
"electricity source", # Node id
FixedProfile(50), # Capacity in MW
FixedProfile(30), # Variable OPEX in EUR/MW
FixedProfile(0), # Fixed OPEX in EUR/MW/8h
Dict(Power => 1), # Output from the Node, in this case, Power
),
RefSink(
"electricity demand", # Node id
OperationalProfile([20, 30, 40, 30]), # Demand in MW
Dict(:surplus => FixedProfile(0), :deficit => FixedProfile(1e6)),
# Line above: Surplus and deficit penalty for the node in EUR/MWh
Dict(Power => 1), # Energy demand and corresponding ratio
),
]

# Connect all nodes with the availability node for the overall energy/mass balance
links = [
Direct("source-demand", nodes[1], nodes[2], Linear()),
]

# Input data structure
case = Case(T, products, [nodes, links], [[get_nodes, get_links]])
return case, model
end

# Generate the case and model data and run the model
case, model = generate_example_ss()
optimizer = optimizer_with_attributes(HiGHS.Optimizer, MOI.Silent() => true)
Expand Down
Loading
Loading