-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add non-clean version of some examples
- Loading branch information
Stefan Strömer
committed
Jun 1, 2024
1 parent
ac69f21
commit d3ca200
Showing
68 changed files
with
178,680 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# Comments indicate points of this model file that changed compared to the previous examples. All other elements are not | ||
# explained/described anymore. See also: 01_basic_single_node.yaml | ||
|
||
config: | ||
optimization: | ||
problem_type: LP | ||
snapshots: | ||
count: 4 | ||
solver: | ||
name: highs | ||
|
||
carriers: | ||
electricity: {} | ||
gas: {} | ||
co2: {} | ||
|
||
components: | ||
# This is the single node power grid that connects everything. It now does **not** include any storage itself. | ||
node: | ||
type: Node | ||
carrier: electricity | ||
|
||
# This models the storage of a simple battery energy storage system, extending the previous example without losses. | ||
# It features bounds that indicate, that the battery can only be used inside a 10%-90% SoC, and will be charged and | ||
# discharged by separate units. | ||
bess: | ||
type: Node | ||
carrier: electricity | ||
has_state: true | ||
state_lb: 1 | ||
state_ub: 9 | ||
|
||
# This is the direction of the inverter that is used to charge the BESS with an efficiency of 90% and a limit of 3. | ||
inverter_charge: | ||
type: Unit | ||
inputs: {electricity: node} | ||
outputs: {electricity: bess} | ||
capacity: 3 in:electricity | ||
conversion: 1 electricity -> 0.9 electricity | ||
|
||
# This is the direction of the inverter that is used to discharge the BESS with an efficiency of 90% and a limit of 3. | ||
inverter_discharge: | ||
type: Unit | ||
inputs: {electricity: bess} | ||
outputs: {electricity: node} | ||
capacity: 3 out:electricity | ||
conversion: 1 electricity -> 0.9 electricity | ||
|
||
# The wind power plant now features a (low) marginal cost of generation. | ||
plant_wind: | ||
type: Unit | ||
outputs: {electricity: node} | ||
conversion: ~ -> 1 electricity | ||
capacity: 10 out:electricity | ||
availability_factor: [0.9, 0.1, 0.1, 0.1] | ||
marginal_cost: 1.0 per out:electricity | ||
|
||
plant_gas: | ||
type: Unit | ||
inputs: {gas: gas_grid} | ||
outputs: {electricity: node, co2: total_co2} | ||
conversion: 1 gas -> 0.4 electricity + 0.2 co2 | ||
capacity: 10 out:electricity | ||
|
||
demand: | ||
type: Profile | ||
carrier: electricity | ||
node_from: node | ||
value: [1, 4, 5, 5] | ||
|
||
gas_grid: | ||
type: Node | ||
carrier: gas | ||
|
||
total_co2: | ||
type: Node | ||
carrier: co2 | ||
|
||
create_gas: | ||
type: Profile | ||
carrier: gas | ||
node_to: gas_grid | ||
mode: create | ||
cost: 50.0 | ||
|
||
co2_emissions: | ||
type: Profile | ||
carrier: co2 | ||
node_from: total_co2 | ||
mode: destroy | ||
cost: 100.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# Comments indicate points of this model file that changed compared to the previous examples. All other elements are not | ||
# explained/described anymore. See also: 02_advanced_single_node.yaml | ||
|
||
config: | ||
optimization: | ||
problem_type: LP | ||
snapshots: | ||
count: 4 | ||
solver: | ||
name: highs | ||
|
||
carriers: | ||
electricity: {} | ||
gas: {} | ||
co2: {} | ||
|
||
components: | ||
# There are now two nodes in the power grid, that will be connected by a line; node2 includes a lossless storage. | ||
node1: | ||
type: Node | ||
carrier: electricity | ||
|
||
node2: | ||
type: Node | ||
carrier: electricity | ||
has_state: true | ||
state_lb: 0 | ||
state_ub: 10 | ||
|
||
# This new type of core component is used to connect two nodes (that use the same energy carrier). It can model | ||
# directional flows, losses, delays, flow limits, and so on. Specifying "capacity" as we do it here, constructs a | ||
# connection that allows flows with -5 <= flow <= 5. The Nodes that are set as "from" and "to" indicate the direction | ||
# of the flow; here positive values relate to a flow "from node1 to node2". | ||
conn: | ||
type: Connection | ||
capacity: 5 | ||
node_from: node1 | ||
node_to: node2 | ||
|
||
# The wind power plant now feeds into node2 with a modified availability factor. | ||
plant_wind: | ||
type: Unit | ||
outputs: {electricity: node2} | ||
conversion: ~ -> 1 electricity | ||
capacity: 10 out:electricity | ||
availability_factor: [0.9, 0.0, 0.9, 0.0] | ||
|
||
# The gas power plant now feeds into node1. | ||
plant_gas: | ||
type: Unit | ||
inputs: {gas: gas_grid} | ||
outputs: {electricity: node1, co2: total_co2} | ||
conversion: 1 gas -> 0.4 electricity + 0.2 co2 | ||
capacity: 10 out:electricity | ||
|
||
# Both nodes feature a unique demand time series, represented by two different Profiles. | ||
demand1: | ||
type: Profile | ||
carrier: electricity | ||
node_from: node1 | ||
value: [3, 3, 3, 3] | ||
|
||
demand2: | ||
type: Profile | ||
carrier: electricity | ||
node_from: node2 | ||
value: [4, 3, 1, 5] | ||
|
||
gas_grid: | ||
type: Node | ||
carrier: gas | ||
|
||
total_co2: | ||
type: Node | ||
carrier: co2 | ||
|
||
create_gas: | ||
type: Profile | ||
carrier: gas | ||
node_to: gas_grid | ||
mode: create | ||
cost: 50.0 | ||
|
||
co2_emissions: | ||
type: Profile | ||
carrier: co2 | ||
node_from: total_co2 | ||
mode: destroy | ||
cost: 100.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# This example demonstrates the effect and use of the inbuilt "constraint safety" feature. This artifically alters | ||
# constraints inside the core components, in order to (hopefully) catch infeasibilities during the optimization run, | ||
# returning a (partially) valid solution as well as an indication where the infeasibility occurs. | ||
# Comments indicate points of this model file that changed compared to the previous examples. All other elements are not | ||
# explained/described anymore. See also: 03_basic_two_nodes.yaml | ||
# | ||
# What does the safety feature do? | ||
# Looking at the result of this optimization (e.g. using `JuMP.solution_summary(model, verbose=true)`), we can see that | ||
# one of the "aux" (auxiliary) variables is not at 0 anymore (here: `connection_flow_aux[conn]`). This indicates that | ||
# an additional 0.25 capacity are needed on the Connection "conn" to make the model feasible. This is also indicated by | ||
# the large increase in the objective value (now being > 2.5e14), which comes from the constraint safety cost. | ||
# | ||
# Important: After optimizing the model, we can extract the "real" objective value from the solution using: | ||
# `JuMP.value(model.ext[:objective])`. Keep in mind though, that this is the optimum that is achieved using the "fix" | ||
# that the safety feature applies. | ||
|
||
config: | ||
optimization: | ||
problem_type: LP | ||
snapshots: | ||
count: 4 | ||
solver: | ||
name: highs | ||
# This tells IESopt to enable the constraint safety feature (which is currently on by default). | ||
constraint_safety: true | ||
# This parameterizes the cost of utilizing the safety feature. This should be much higher than other costs in the | ||
# objective function and defaults to 1e15. This, while being a rather safe number - meaning it most likely will not | ||
# interfer in any wrong way with your model - comes at the cost of numerical instability. This can be handled | ||
# "properly" by some solvers (like Gurobi) but will negatively impact others (like GLPK). To counter this we can | ||
# specify a lower cost coefficient here. Consider setting a lower tolerance for these solvers, for example call | ||
# `JuMP.set_optimizer_attribute(model, "tol_dj", 1e-12)` for GLPK. | ||
constraint_safety_cost: 1.0e9 | ||
|
||
carriers: | ||
electricity: {} | ||
gas: {} | ||
co2: {} | ||
|
||
components: | ||
node1: | ||
type: Node | ||
carrier: electricity | ||
|
||
node2: | ||
type: Node | ||
carrier: electricity | ||
has_state: true | ||
state_lb: 0 | ||
state_ub: 10 | ||
|
||
# The capacity of the connection is reduced (from 5 to 1). | ||
conn: | ||
type: Connection | ||
capacity: 1 | ||
node_from: node1 | ||
node_to: node2 | ||
|
||
# Furthermore, the wind availability factor is reduced to introduce an infeasibility. | ||
plant_wind: | ||
type: Unit | ||
outputs: {electricity: node2} | ||
conversion: ~ -> 1 electricity | ||
capacity: 10 out:electricity | ||
availability_factor: [0.4, 0.0, 0.4, 0.0] | ||
|
||
plant_gas: | ||
type: Unit | ||
inputs: {gas: gas_grid} | ||
outputs: {electricity: node1, co2: total_co2} | ||
conversion: 1 gas -> 0.4 electricity + 0.2 co2 | ||
capacity: 10 out:electricity | ||
|
||
demand1: | ||
type: Profile | ||
carrier: electricity | ||
node_from: node1 | ||
value: [3, 3, 3, 3] | ||
|
||
demand2: | ||
type: Profile | ||
carrier: electricity | ||
node_from: node2 | ||
value: [4, 3, 1, 5] | ||
|
||
gas_grid: | ||
type: Node | ||
carrier: gas | ||
|
||
total_co2: | ||
type: Node | ||
carrier: co2 | ||
|
||
create_gas: | ||
type: Profile | ||
carrier: gas | ||
node_to: gas_grid | ||
mode: create | ||
cost: 50.0 | ||
|
||
co2_emissions: | ||
type: Profile | ||
carrier: co2 | ||
node_from: total_co2 | ||
mode: destroy | ||
cost: 100.0 |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# Comments indicate points of this model file that changed compared to the previous examples. All other elements are not | ||
# explained/described anymore. | ||
# This example constructs a simple model that produces hydrogen from excess solar energy and tries to only import | ||
# as little energy as possible (this is here done by only assigning a cost to H2 import). | ||
|
||
config: | ||
optimization: | ||
problem_type: LP | ||
snapshots: | ||
count: 168 | ||
solver: | ||
name: highs | ||
results: | ||
enabled: true | ||
memory_only: true | ||
|
||
# We not only define units but also colors, that can be later picked up by the standardized visualization tools. Observe | ||
# the fact, that the hexcode is in "", since a `#` counts as starting an in-line comment. Also we use the "block" format | ||
# that YAML supports instead of the in-line format that we used up until now. These are exactly the same. | ||
carriers: | ||
electricity: | ||
unit: MWh | ||
color: "rgba(50, 94, 23, 0.7)" | ||
h2: | ||
unit: MWh | ||
color: "rgba(3, 36, 252, 0.7)" | ||
solar: | ||
unit: MWh | ||
color: "rgba(255, 196, 0, 0.7)" | ||
|
||
components: | ||
elec_grid: | ||
type: Node | ||
carrier: electricity | ||
|
||
h2_storage: | ||
type: Node | ||
carrier: h2 | ||
has_state: true | ||
state_cyclic: geq | ||
state_lb: 0 | ||
state_ub: 50 | ||
|
||
# While core components need a unique name, it is allowed to use a name for a core component that is used by a | ||
# carrier. While this is obviously NOT recommended, it is possible and can sometimes | ||
solar: | ||
type: Node | ||
carrier: solar | ||
|
||
plant_gas: | ||
type: Unit | ||
inputs: {h2: h2_storage} | ||
outputs: {electricity: elec_grid} | ||
conversion: 1 h2 -> 0.8 electricity | ||
capacity: 10 out:electricity | ||
|
||
plant_pv: | ||
type: Unit | ||
inputs: {solar: solar} | ||
outputs: {electricity: elec_grid} | ||
conversion: 1 solar -> 1 electricity | ||
capacity: 5 out:electricity | ||
availability_factor: [0.0, 0.0, 0.02, 0.07, 0.16, 0.26, 0.45, 0.66, 0.76, 0.88, 1.0, 1.0, 1.0, 0.95, 0.81, 0.66, 0.44, 0.26, 0.16, 0.06, 0.02, 0.01, 0.0, 0.0, 0.0, 0.01, 0.02, 0.06, 0.14, 0.26, 0.47, 0.63, 0.75, 0.88, 1.0, 1.0, 1.0, 1.0, 0.75, 0.61, 0.45, 0.25, 0.14, 0.07, 0.02, 0.0, 0.0, 0.0, 0.0, 0.01, 0.02, 0.07, 0.15, 0.26, 0.44, 0.61, 0.75, 1.0, 1.0, 1.0, 1.0, 0.88, 0.77, 0.65, 0.45, 0.27, 0.16, 0.07, 0.03, 0.01, 0.0, 0.0, 0.0, 0.01, 0.02, 0.07, 0.16, 0.3, 0.42, 0.59, 0.83, 0.88, 1.0, 1.0, 1.0, 0.9, 0.78, 0.57, 0.43, 0.28, 0.16, 0.06, 0.02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.02, 0.06, 0.14, 0.26, 0.44, 0.57, 0.85, 0.96, 0.97, 1.0, 1.0, 1.0, 0.79, 0.64, 0.41, 0.26, 0.14, 0.07, 0.02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.02, 0.07, 0.16, 0.3, 0.43, 0.63, 0.78, 0.9, 1.0, 1.0, 1.0, 0.91, 0.74, 0.58, 0.44, 0.28, 0.14, 0.07, 0.03, 0.0, 0.0, 0.0, 0.0, 0.0, 0.02, 0.07, 0.16, 0.28, 0.46, 0.66, 0.84, 0.9, 1.0, 1.0, 1.0, 0.97, 0.86, 0.63, 0.45, 0.27, 0.15, 0.06, 0.02, 0.0, 0.0, 0.0] | ||
|
||
# Up until now we only ever restricted the output capacity. This time we cap the input capacity. | ||
electrolyser: | ||
type: Unit | ||
inputs: {electricity: elec_grid} | ||
outputs: {h2: h2_storage} | ||
conversion: 1 electricity -> 0.7 h2 | ||
capacity: 10 in:electricity | ||
|
||
# These profiles define a full "model boundary", allowing us to analyze the model easily afterwards. | ||
create_solar: | ||
type: Profile | ||
mode: create | ||
carrier: solar | ||
node_to: solar | ||
|
||
buy_h2: | ||
type: Profile | ||
mode: create | ||
carrier: h2 | ||
node_to: h2_storage | ||
cost: 100 | ||
|
||
demand: | ||
type: Profile | ||
carrier: electricity | ||
node_from: elec_grid | ||
value: [3.96, 4.24, 0.06, 3.36, 2.34, 0.22, 0.57, 4.41, 4.91, 3.01, 3.78, 4.36, 4.26, 2.2, 3.71, 4.35, 4.88, 2.25, 2.63, 2.15, 0.92, 4.18, 4.88, 2.85, 0.17, 2.48, 4.23, 4.72, 4.86, 1.46, 4.81, 1.94, 4.52, 4.77, 1.84, 1.27, 2.13, 4.15, 4.09, 1.16, 1.87, 2.18, 3.42, 3.7, 0.89, 0.93, 1.15, 2.62, 1.08, 1.72, 1.2, 0.06, 2.46, 4.73, 1.08, 0.41, 1.2, 0.53, 1.51, 2.59, 2.7, 4.83, 2.69, 0.51, 2.43, 3.2, 4.01, 0.21, 2.72, 1.5, 2.92, 2.51, 1.54, 2.63, 3.59, 4.86, 4.64, 4.88, 3.69, 3.64, 0.16, 3.4, 2.1, 3.87, 1.85, 3.6, 3.24, 3.61, 2.12, 0.43, 3.6, 3.94, 2.8, 0.78, 3.18, 3.05, 3.02, 4.14, 1.25, 3.05, 0.12, 3.54, 1.45, 1.53, 2.06, 0.23, 0.01, 3.47, 0.23, 3.21, 0.73, 3.33, 4.84, 0.89, 3.6, 4.87, 1.47, 3.48, 0.64, 2.77, 1.66, 2.79, 2.64, 4.73, 2.75, 0.44, 4.5, 2.7, 2.87, 1.76, 2.21, 2.48, 3.83, 3.81, 1.13, 2.53, 1.54, 1.32, 0.6, 4.25, 4.04, 2.23, 1.58, 4.9, 4.78, 2.85, 2.1, 0.2, 2.97, 2.26, 3.91, 0.68, 1.02, 1.61, 0.98, 4.5, 1.82, 2.41, 3.06, 3.05, 1.64, 0.03, 4.39, 3.03, 1.8, 0.37, 1.56, 2.17] |
Oops, something went wrong.