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

Battery electric vehicle #94

Draft
wants to merge 98 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
256dd27
Add Bev
jnnr Feb 14, 2023
2be9d22
Merge branch 'dev' into feature/battery-electric-vehicle
nailend Jul 24, 2023
da470c7
Merge branch 'dev' into feature/battery-electric-vehicle
nailend Jul 28, 2023
e3e6640
Update to working state
nailend Aug 4, 2023
4cbd80b
Update constraint test
nailend Aug 4, 2023
e16cd89
Add storage conversion rate and balance parameter
nailend Aug 4, 2023
0275ba7
Plumb inflow/outflow conversion rate with sequence
nailend Aug 4, 2023
8a2694c
Fix label
nailend Aug 15, 2023
75f8be0
Draft for joint extension constraint
nailend Aug 15, 2023
829895d
Merge branch 'dev' into feature/battery-electric-vehicle
nailend Aug 30, 2023
6f8a4d3
Merge branch 'dev' into feature/battery-electric-vehicle
nailend Sep 18, 2023
82707e6
Update converter
nailend Sep 25, 2023
616ae77
Update buses
nailend Sep 25, 2023
89061db
Comment sequencing
nailend Sep 25, 2023
be8c743
Rename labels
nailend Sep 28, 2023
6383a86
Add mobility sector facade
nailend Sep 28, 2023
31a8a69
Merge branch 'dev' into feature/battery-electric-vehicle
nailend Oct 17, 2023
944679c
Merge branch 'dev' into feature/battery-electric-vehicle
nailend Oct 19, 2023
a7ff4ad
Add `bev` flag to _investment()
nailend Oct 24, 2023
fef8d93
Make bev expandable
nailend Oct 24, 2023
69754d0
Add test script for mobility with bev
nailend Oct 24, 2023
1cbafcc
Add graph plotting helpers
nailend Oct 24, 2023
863b69c
Add bev to typemap
nailend Oct 30, 2023
2d276e5
Rework bev component
nailend Oct 30, 2023
62b734e
Add helper functions
nailend Oct 30, 2023
7019712
Add equal invest and mob share constraint
nailend Oct 30, 2023
dd5c572
Add draft for bev constraint test
nailend Oct 30, 2023
a4aeea6
Add draft for bev multi-period constraint test
nailend Oct 30, 2023
bf4b260
Remove constraints from mobility example
nailend Oct 30, 2023
f0b9c0c
Change storage color in bev system plot
nailend Oct 30, 2023
ea2579a
Remove charging converter
nailend Oct 31, 2023
1615fef
Modify test-case
nailend Oct 31, 2023
9cf2322
Merge remote-tracking branch 'origin/dev' into feature/battery-electr…
nailend Oct 31, 2023
7606c6f
Add private-transport example
nailend Nov 3, 2023
3629756
Add facade test module incl first bev test draft
nailend Nov 7, 2023
0570456
Extend docstring
nailend Nov 7, 2023
5c8bd01
Rework parameters
nailend Nov 7, 2023
61db0ad
Rename parameter charging_power
nailend Nov 7, 2023
036c283
Rename parameter mobility_bus
nailend Nov 7, 2023
8c8a153
Rename parameter bev_invest_costs
nailend Nov 7, 2023
656940c
Rename parameter variable_costs
nailend Nov 7, 2023
ead80fb
Rename parameter charging_power
nailend Nov 7, 2023
b7a99b5
Consumption Sink for expandable not implemented yet
nailend Nov 7, 2023
f591510
Add fixed and variable costs
nailend Nov 7, 2023
b48b3f0
Conversion rate 2pkm and electrical eta
nailend Nov 7, 2023
d4e33ae
Fix conversion factor bug
nailend Nov 7, 2023
c0989a2
Add excess & shortage commented
nailend Nov 7, 2023
a96fc03
Describe parameter in bev test
nailend Nov 7, 2023
8a6762d
Set variable costs at storage inflow
nailend Nov 7, 2023
9e5e541
Fix efficiency g2v
nailend Nov 8, 2023
a803d63
Add docstring and comments to constraints
nailend Nov 9, 2023
cad9013
Rename bus and conversion rate
nailend Nov 9, 2023
041c749
Use _converter_investment instead of modifying _investment
nailend Nov 9, 2023
976e218
Remove bev-flag from _investment
nailend Nov 9, 2023
72e4778
Move conversion_factors to output flows
SabineHaas Nov 13, 2023
873da6c
Adapt basic dispatch test for bev_v2g. make flake8 pass
SabineHaas Nov 13, 2023
e6dfe63
Adapt bev facade v2g tests
SabineHaas Nov 14, 2023
afbd8fd
Remove unnecessary code and solved todos
SabineHaas Nov 14, 2023
2e559c8
Add docstring describing test_bev_v2g_dispatch
SabineHaas Nov 14, 2023
6af1fa2
Rename initial storage level as named in BEV class: initial_storage_c…
SabineHaas Nov 14, 2023
03cbb5a
Uncomment availability in commodity converter and storage
SabineHaas Nov 14, 2023
0a0c0cf
Add todo and correction
SabineHaas Nov 14, 2023
0ded9cc
Add test case for v2g, inflex, g2v trio - note: adaptions needed
SabineHaas Nov 14, 2023
1e6b39b
Add test case for bev inflex facade - note: adaptions needed
SabineHaas Nov 14, 2023
3ac45c2
Adapt bev inflex test and add description
SabineHaas Nov 16, 2023
32ea252
Add bev g2v dispatch test
SabineHaas Nov 20, 2023
9cc74c2
Adapt bev trio (v2g, g2v, inflex) test
SabineHaas Nov 20, 2023
0f737d2
Add description to `test_bev_trio_dispatch()`
SabineHaas Nov 20, 2023
1bd1569
Move variable_costs to input flow of storage also for expandable=False
SabineHaas Nov 21, 2023
68eaf44
Add test class and first test case for BEV investment tests
SabineHaas Nov 21, 2023
5bdc4d3
Rename test class for bev dispatch tests to TestBevFacadesDispatch
SabineHaas Nov 21, 2023
f20244d
Add solving of test case and first assertion
SabineHaas Nov 21, 2023
c22fc19
Add lines for constraints
SabineHaas Nov 21, 2023
246ee4b
Corrections
SabineHaas Nov 21, 2023
5380dc0
Manually add bev constraints
nailend Nov 21, 2023
fe2c39c
Working V2G BEV test with one time step, todos added
SabineHaas Nov 23, 2023
fbca239
Join classes of dispatch and investment tests
SabineHaas Nov 28, 2023
0276011
Add BEV investment tests with constraints
SabineHaas Nov 28, 2023
2d356ad
Remove unused lines
SabineHaas Nov 28, 2023
c04c3f3
Add to changelog and authors
SabineHaas Nov 28, 2023
4d767e6
Minor adaptions to docstrings
SabineHaas Nov 30, 2023
ba9e455
Remove initial_storage_capacity from tests, and use initial_storage_l…
SabineHaas Nov 30, 2023
4c8899e
Add BEV multi-period investment tests (skip tests)
SabineHaas Nov 30, 2023
f1367f8
Add BEV multi-period dispatch test for V2G
SabineHaas Nov 30, 2023
d83b685
Name issue in reason of skipped tests
SabineHaas Nov 30, 2023
7472a15
Remove equal-invest constraint from bev constraint lp test
nailend Dec 4, 2023
7a9d9da
Revert "Remove equal-invest constraint from bev constraint lp test"
nailend Dec 4, 2023
9eb57a9
Add timesteps to docstring
nailend Dec 4, 2023
0c37c8a
Add lines to table in docstrings
nailend Dec 4, 2023
7410421
Add explanation on invest constraint
nailend Dec 4, 2023
83f3ab7
Adapt bev constraint test
nailend Dec 4, 2023
a64ef1e
Remove bev multi-period constraint test
nailend Dec 4, 2023
42223c2
Add bev trio constraint lp file
nailend Dec 4, 2023
c7aadd1
Merge branch 'dev' into feature/bev_tests
nailend Dec 4, 2023
9774aea
Rename lp file
nailend Dec 4, 2023
3ea89f9
Update lp file
nailend Dec 4, 2023
3d30c87
Merge pull request #142 from oemof/feature/bev_tests
nailend Dec 4, 2023
77d4a06
Merge branch 'dev' into feature/battery-electric-vehicle
nailend Feb 26, 2024
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
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ Authors
* Sarah Berendes
* Marie-Claire Gering
* Julian Endres
* Sabine Haas
* Felix Maurer
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Unreleased

Features

* Add tests for BEV facades developed in #94 `#142 <https://github.com/oemof/oemof-tabular/pull/142>`_


Fixes


Expand Down
13 changes: 9 additions & 4 deletions src/oemof/tabular/_facade.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def __init__(self, *args, **kwargs):
add_subnodes, sender=self
)

def _nominal_value(self):
def _nominal_value(self, value=None):
nailend marked this conversation as resolved.
Show resolved Hide resolved
"""Returns None if self.expandable ist True otherwise it returns
the capacity
"""
Expand All @@ -168,18 +168,23 @@ def _nominal_value(self):
"to_from": self.to_from_capacity,
}
else:
return self.capacity
if value:
return value
else:
return self.capacity

def _investment(self):
def _investment(self, bev=False):
if not self.expandable:
self.investment = None
return self.investment

if self.capacity_cost is None:
msg = (
"If you set `expandable`to True you need to set "
"attribute `capacity_cost` of component {}!"
)
raise ValueError(msg.format(self.label))

# If storage component
if isinstance(self, GenericStorage):
# If invest costs/MWH are given
Expand Down Expand Up @@ -207,7 +212,7 @@ def _investment(self):
age=getattr(self, "age", 0),
fixed_costs=getattr(self, "fixed_costs", None),
)
# If other component than storage
# If other component than storage or Bev
else:
self.investment = Investment(
ep_costs=self.capacity_cost,
Expand Down
180 changes: 179 additions & 1 deletion src/oemof/tabular/constraint_facades.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,38 @@
from dataclasses import dataclass

from oemof.solph.constraints.integral_limit import generic_integral_limit
from pyomo.environ import Constraint

from oemof.tabular.facades import Bev


def var2str(var):
return "_".join(
[i.label if not isinstance(i, int) else str(i) for i in var]
)


def get_bev_label(var):
return var[1].label.split("-storage")[0]


def get_period(model, year, constraint_type=None):
if model.es.periods:
years = [period.year.min() for period in model.es.periods]
for period_index, period_year in enumerate(years):
if period_year == year:
return period_index
raise ValueError(
f"'{constraint_type}' constraint facade:\n"
f"Year {year} is not in model.PERIODS."
)
elif year == model.es.timeindex.year.min():
return 0
else:
raise ValueError(
f"'{constraint_type}' constraint facade:\n"
f"Year {year} is not in model.timeindex."
)


class ConstraintFacade(abc.ABC):
Expand Down Expand Up @@ -39,4 +71,150 @@ def build_constraint(self, model):
)


CONSTRAINT_TYPE_MAP = {"generic_integral_limit": GenericIntegralLimit}
@dataclass
class BevShareMob(ConstraintFacade):
# TODO: rework docstring
"""This constraint is only feasible if the definition of one vehicle is the
same (charging_capacity/storage_capacity) for all three bev technologies"""
name: str
type: str
year: int
label: str
share_mob_flex_G2V: (int, float)
share_mob_flex_V2G: (int, float)
share_mob_inflex: (int, float)

@staticmethod
def map_share2vars(model, share_mob, period):
invest_vars = []
for node in model.es.nodes:
if isinstance(node, Bev):
invest_vars.extend(
[
inv
for inv in model.InvestmentFlowBlock.invest
if node.electricity_bus.label == inv[0].label
and f"{node.facade_label}-storage" in inv[1].label
and period == inv[2]
]
)

share_mob = {
inv_var: value
for key, value in share_mob.items()
for inv_var in invest_vars
if key in inv_var[1].label
}
return invest_vars, share_mob

@staticmethod
def convert_share(share):
if 0 <= share <= 1:
return share
elif 0 <= share <= 100:
return share / 100
else:
raise ValueError(f"Mob share: {share} not in [0,1] or [0,100]")

def build_constraint(self, model):
period = get_period(model, self.year, self.__class__.__name__)

if period > len(model.PERIODS):
raise ValueError(
f"Period {period} not in model.PERIODS {model.PERIODS}"
)

share_mob = {
f"{self.label}-G2V-storage": self.convert_share(
self.share_mob_flex_G2V
),
f"{self.label}-V2G-storage": self.convert_share(
self.share_mob_flex_V2G
),
f"{self.label}-inflex-storage": self.convert_share(
self.share_mob_inflex
),
}

invest_vars, share_mob = self.map_share2vars(
model=model, share_mob=share_mob, period=period
)

def investment_constraints_rule(InvestmentFlowBlock):
return InvestmentFlowBlock.invest[inv_var] == share_mob[
inv_var
] * sum(InvestmentFlowBlock.invest[iv] for iv in invest_vars)

for inv_var in invest_vars:
name = f"mob_share_{get_bev_label(inv_var)}_{period}"
setattr(
model.InvestmentFlowBlock,
name,
Constraint(rule=investment_constraints_rule),
)


# TODO maybe move inside facade
@dataclass
class BevEqualInvest(ConstraintFacade):
name: str
type: str
year: int

@staticmethod
def double_with_offset(lst):
result = []
for i in range(len(lst) - 1):
result.append((lst[i], lst[i + 1]))
return result

@staticmethod
def get_bev_invest_vars(model, period):
all_invest_vars = {}
for node in model.es.nodes:
if isinstance(node, Bev):
invest_vars_bev = list(
set(
inv
for inv in model.InvestmentFlowBlock.invest
if inv[2] == period
for edge in inv[:2]
if node.facade_label in edge.label
)
)
all_invest_vars[node.facade_label] = invest_vars_bev
return all_invest_vars

def build_constraint(self, model):
# TODO add checks
period = get_period(model, self.year, self.__class__.__name__)
if period > len(model.PERIODS):
raise ValueError(
f"Period {period} not in model.PERIODS {model.PERIODS}"
)

invest_vars = self.get_bev_invest_vars(model, period)

def equate_variables_rule(InvestmentFlowBlock):
return (
InvestmentFlowBlock.invest[var1]
== InvestmentFlowBlock.invest[var2]
)

for bev_label, invest_vars in invest_vars.items():
for i, (var1, var2) in enumerate(
self.double_with_offset(invest_vars)
):
name = f"{bev_label}_equal_invest_{i}_({period})"
setattr(
model.InvestmentFlowBlock,
name,
Constraint(rule=equate_variables_rule),
)


CONSTRAINT_TYPE_MAP = {
"generic_integral_limit": GenericIntegralLimit,
"bev_equal_invest": BevEqualInvest,
"bev_share_mob": BevShareMob,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Emission constraint example for oemof-tabular

Run `scripts/infer.py` from the datapackage root directory to add the
meta data file `datapackage.json` after updating the resources of the
datapackage.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name;type;year;label;share_mob_flex_G2V;share_mob_flex_V2G;share_mob_inflex
bev_share_mob_2020;bev_share_mob;2020;BEV;10;20;70
bev_share_mob_2030;bev_share_mob;2030;BEV;20;30;50
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name;type;year
bev_equal_invest;bev_equal_invest;2020
bev_equal_invest;bev_equal_invest;2030
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name;type;balanced
bus-electricity;bus;true
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name;type;carrier;tech;capacity;bus;marginal_cost;profile;output_parameters
gas;dispatchable;gas;gt;1000;bus-electricity;40;1;{"custom_attributes": {"emission_factor": 10}}
coal;dispatchable;coal;st;1000;bus-electricity;40;1;{"custom_attributes": {"emission_factor": 20}}
lignite;dispatchable;lignite;st;500;bus-electricity;20;1;{"custom_attributes": {"emission_factor": 30}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name;type;bus
electricity-excess;excess;bus-electricity
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name;amount;profile;type;bus
electricity-demand;5000;electricity-load-profile;load;bus-electricity
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name,carrier,tech,storage_capacity,capacity,capacity_cost,storage_capacity_initial,type,bus
el-storage,lithium,battery,100,10,10,0.5,storage,bus-electricity
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name;type;carrier;tech;capacity;capacity_cost;bus;marginal_cost;profile;output_parameters
wind;volatile;wind;onshore;50;;bus-electricity;0;wind-profile;{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
timeindex,electricity-load-profile
2011-01-01T00:00:00Z,0.000745659236
2011-01-01T01:00:00Z,0.000709651546
2011-01-01T02:00:00Z,0.00068564642
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
timeindex,wind-profile
2011-01-01T00:00:00Z,0.147532
2011-01-01T01:00:00Z,0.184181
2011-01-01T02:00:00Z,0.223937
Loading
Loading