Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Network Charges #73

Merged
merged 16 commits into from
Sep 14, 2024
Merged

Allow Network Charges #73

merged 16 commits into from
Sep 14, 2024

Conversation

ADGEfficiency
Copy link
Owner

@ADGEfficiency ADGEfficiency commented Aug 24, 2024

@rdmolony

This PR adds the ability to optimize for a network charge.

It required adding in the ability to supply custom interval data, to use with a custom objective function that sets up the network charge.

Features:

  • adds custom interval data to the __init__ of assets and the site.

Other changes:

  • makes the default for including a spill asset in asset.__init__ to False.

TODO:

  • rename all use of extra interval data to custom interval data,
  • document the custom interval data into customization.interval data,
  • document the network charges into use_cases.network_charges,
  • add include_spill: bool = False to all assets.

@ADGEfficiency
Copy link
Owner Author

The rough idea is:

import energypylinear as epl

site = epl.Site(
    assets=[
        epl.Battery(
            power_mw=2, capacity_mwh=4, efficiency_pct=0.9
        ),
    ],
    electricity_prices=[100, 1000, -20, 40, 45],
    network_charge=[0, 300, 300, 0, 0],
)
objective = {
    "terms": [
        {
            "asset_type": "site",
            "variable": "import_power_mwh",
            "interval_data": "electricity_prices",
        },
        {
            "asset_type": "site",
            "variable": "export_power_mwh",
            "interval_data": "electricity_prices",
            "coefficient": -1,
        },
        {
            "asset_type": "site",
            "variable": "import_power_mwh",
            "interval_data": "network_charge",
        },
    ]
}
site.optimize(objective)

@rdmolony
Copy link

rdmolony commented Sep 11, 2024

Thanks Adam, the Site API has remained really minimal.

I understand that Site has now become generalised such that I can pass any interval data as a keyword argument & use it in my custom objective function.


I found it a bit tricky to nail down how network_charge is used by the optimizer ->

network_charge is passed via **kwargs to Site. In Site.__init__ it is appended to site.cfg.interval_data at runtime in validate_interval_data rather than during the creation of the site.cfg object in SiteConfig via SiteIntervalData.

Is pydantic a blocker for adding these custom fields to SiteIntervalData?

Dynamic model creation looks a little awkward - https://docs.pydantic.dev/latest/concepts/models/#dynamic-model-creation

interval_data is unpacked for use in the objective function in Site.optimize > self.optimizer.objective via add_simple_terms, add_two_variable_terms & add_many_variables_terms which use terms from the objective dict created by the user to access site.cfg.interval_data via getattr.

So this interval data only impacts the objective function?


Unfeasible simulations are enabled via include_spill, why?

@ADGEfficiency ADGEfficiency merged commit 558be05 into main Sep 14, 2024
2 checks passed
@ADGEfficiency ADGEfficiency deleted the network-charges branch September 14, 2024 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants