You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A custom objective function allows users to create their own objective functions in the linear program.
8
+
9
+
This allows users to optimize for a custom set of revenues and costs. The objective function can target assets by type or name, and can include multiplication by interval data and/or a coefficient.
10
+
11
+
The example below shows how to include a cost for battery use (a cycle cost) applied to the battery discharge:
12
+
13
+
```python
14
+
import numpy as np
15
+
import energypylinear as epl
16
+
17
+
assets = [
18
+
epl.Battery(power_mw=20, capacity_mwh=20)
19
+
]
20
+
site = epl.Site(
21
+
assets=assets,
22
+
electricity_prices=np.random.normal(0, 1000, 48)
23
+
)
24
+
terms=[
25
+
{
26
+
"asset_type":"site",
27
+
"variable":"import_power_mwh",
28
+
"interval_data":"electricity_prices"
29
+
},
30
+
{
31
+
"asset_type":"site",
32
+
"variable":"export_power_mwh",
33
+
"interval_data":"electricity_prices",
34
+
"coefficient":-1
35
+
},
36
+
{
37
+
"asset_type": "battery",
38
+
"variable": "electric_discharge_mwh",
39
+
"interval_data": "electricity_prices",
40
+
"coefficient": 0.25
41
+
}
42
+
]
43
+
site.optimize(objective={"terms": terms})
44
+
```
45
+
46
+
See [Custom Objectives](https://energypylinear.adgefficiency.com/latest/how-to/custom-objectives/) in the documentation for more examples.
47
+
48
+
### Logging Improvements
49
+
50
+
The dependency on `structlog` has been removed - we now only use `rich.logging.Console` to log to STDOUT. The ability to log to a file has been removed.
51
+
52
+
The `verbose` flag now accepts either a `bool` or an `int`. The mapping of `verbose` to log levels is as follows:
Copy file name to clipboardexpand all lines: docs/docs/how-to/custom-objectives.md
+16-20
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,8 @@
1
-
## Custom Objective Functions
1
+
`energypylinear` has two different objective functions (price or carbon) built into the library.
2
2
3
-
`energypylinear` can optimize for two different objective functions (price or carbon) built into the library.
3
+
However you may want to optimize for a different objective function in the linear program. You may have a business problem with a different set of revenues and costs than are included by default.
4
4
5
-
However you may want to optimize for a different objective function in the linear program.
6
-
7
-
**A custom objective function allows you to construct an objective function as you see fit** - allowing you to optimize a site and assets for the incentives and costs that are important to you.
5
+
**A custom objective function allows you to construct an objective function as you see fit** - allowing you to optimize a site and assets for the revenues and costs that are important to you.
8
6
9
7
Core to the custom objective function is the `epl.Term` - representing a single term in the objective function:
10
8
@@ -21,9 +19,9 @@ class Term:
21
19
coefficient: float=1.0
22
20
```
23
21
24
-
Each term can target either many assets by type or one asset by name. It can also include multiplication by interval data or by a coefficient.
22
+
A term can target either many assets by type or one asset by name. It can also include multiplication by interval data or by a coefficient.
25
23
26
-
A custom objective function is a list of `epl.Term` - the sum of these terms becomes the objective function.
24
+
A custom objective function is a list of terms:
27
25
28
26
<!--phmdoctest-share-names-->
29
27
```python
@@ -32,11 +30,13 @@ class CustomObjectiveFunction:
32
30
terms: list[Term]
33
31
```
34
32
33
+
The objective function used in the linear program is the sum of these terms.
34
+
35
35
### Price and Carbon
36
36
37
-
In this example we will show how to optimize a battery for an objective optimizes for both profit and carbon at the same time.
37
+
This example shows how to optimize a battery for an objective that includes terms for both price and carbon.
38
38
39
-
The example below creates an objective function where we incentive a site to:
39
+
Below we create an objective function where we incentive a site to:
40
40
41
41
- reduce import when the electricity price or carbon intensity is high,
42
42
- increase export when the electricity price or carbon intensity is low.
@@ -52,9 +52,9 @@ def simulate(
52
52
carbon_price: int,
53
53
seed: int,
54
54
n: int,
55
-
verbose: int=2
55
+
verbose: int=3
56
56
) -> epl.SimulationResult:
57
-
"""Runs one battery simulation at a given carbon price with a custom objective function."""
57
+
"""Run a battery simulation with a custom objective function."""
We can validate that our custom objective function is working as expected by running simulations across many carbon prices, and see the effect on the profit and emissions of our site:
106
+
We can validate that our custom objective function is working as expected by running simulations across many carbon prices:
111
107
112
108
<!--phmdoctest-share-names-->
113
109
```python
@@ -148,7 +144,7 @@ In the previous example we used a custom objective function to apply incentives
148
144
149
145
An example of this is a renewable energy certificate scheme, where the generation from one asset receives additional income for each MWh generated.
150
146
151
-
In the example below, our `solar` asset receives additional income for each MWh generated.
147
+
In the example below, our `solar` asset receives additional income for each MWh generated.
152
148
153
149
The site has a constrained export limit, which limits how much both generators can output. The site electric load increases in each interval, which allows us to see which generator is called first:
154
150
@@ -213,15 +209,15 @@ print(
213
209
4 50.0 50.0
214
210
```
215
211
216
-
As expected, the first generator that is called is the `solar` generator, as it receives additional income for it's output.
212
+
As expected, the first generator that is called is the `solar` generator, as it receives additional income for it's output.
217
213
218
214
As the site demand increases, the `wind` generator is called to make up the remaining demand.
219
215
220
216
### Synthetic PPA
221
217
222
218
A synthetic PPA is a financial instrument that allows swapping of the output of a wholesale exposed generator to a fixed price.
223
219
224
-
This can be modelled as a custom objective function.
220
+
This can be modelled as a custom objective function.
225
221
226
222
In the example below, we model a site with wholesale exposed import and export, and swap the output of our `wind` generator from the wholesale to a fixed price:
227
223
@@ -356,7 +352,7 @@ terms=[
356
352
]
357
353
```
358
354
359
-
We can validate that this works by applying a stronger cycle cost and seeing the battery use descrease:
355
+
We can validate that this works by applying a stronger cycle cost and seeing the battery use decrease:
0 commit comments