| Conditions | 9 |
| Total Lines | 163 |
| Code Lines | 58 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | # -*- coding: utf-8 -*- |
||
| 239 | def additional_total_limit(model, keyword, limit=None, consider_offset=True): |
||
| 240 | r""" |
||
| 241 | Global limit for investment flows and operation flows |
||
| 242 | weighted by an attribute keyword. |
||
| 243 | |||
| 244 | This constraint is valid for Flows and for an |
||
| 245 | investment storage. |
||
| 246 | |||
| 247 | The attribute named by keyword has to be added to every Investment |
||
| 248 | attribute of the flow you want to take into account. |
||
| 249 | Total value of keyword attributes after optimization can be retrieved |
||
| 250 | calling the `oemof.solph._models.Model.total_limit_${keyword}()`. |
||
| 251 | |||
| 252 | .. math:: |
||
| 253 | \sum_{p \in \textrm{PERIODS}} |
||
| 254 | \sum_{i \in IF} P_{i}(p) \cdot w_i |
||
| 255 | \sum_{i \in F_E} \sum_{t \in T} P_i(p, t) \cdot w_i(t) |
||
| 256 | \cdot \tau(t) \leq limit |
||
| 257 | |||
| 258 | With `IF` being the set of InvestmentFlows considered for the integral |
||
| 259 | limit, `F_I` being the set of flows considered for the integral limit and |
||
| 260 | `T` being the set of time steps. |
||
| 261 | |||
| 262 | The symbols used are defined as follows |
||
| 263 | (with Variables (V) and Parameters (P)): |
||
| 264 | |||
| 265 | +------------------+---------------------------------------+------+--------------------------------------------------------------+ |
||
| 266 | | symbol | attribute | type | explanation | |
||
| 267 | +==================+=======================================+======+==============================================================+ |
||
| 268 | | :math:`P_{i}(p)` | `InvestmentFlowBlock.invest[i, o, p]` | V | invested capacity of investment flow in period p | |
||
| 269 | +------------------+---------------------------------------+------+--------------------------------------------------------------+ |
||
| 270 | | :math:`w_i` | `keyword` | P | weight given to investment flow named according to `keyword` | |
||
| 271 | +------------------+---------------------------------------+------+--------------------------------------------------------------+ |
||
| 272 | | :math:`limit` | `limit` | P | global limit given by keyword `limit` | |
||
| 273 | +------------------+---------------------------------------+------+--------------------------------------------------------------+ |
||
| 274 | | :math:`P_n(p, t)`| `limit` | P | power flow :math:`n` at time index :math:`p, t` | |
||
| 275 | +------------------+---------------------------------------+------+--------------------------------------------------------------+ |
||
| 276 | | :math:`w_N(t)` | `limit` | P | weight given to Flow named according to `keyword` | |
||
| 277 | +------------------+---------------------------------------+------+--------------------------------------------------------------+ |
||
| 278 | | :math:`\tau(t)` | `limit` | P | width of time step :math:`t` | |
||
| 279 | +------------------+---------------------------------------+------+--------------------------------------------------------------+ |
||
| 280 | |||
| 281 | Parameters |
||
| 282 | ---------- |
||
| 283 | model : oemof.solph.Model |
||
| 284 | Model to which constraints are added. |
||
| 285 | keyword : attribute to consider |
||
| 286 | All flows with Investment attribute containing the keyword will be |
||
| 287 | used. |
||
| 288 | limit : numeric |
||
| 289 | Global limit of keyword attribute for the energy system. |
||
| 290 | |||
| 291 | Note |
||
| 292 | ---- |
||
| 293 | The Investment attribute of the considered (Investment-)flows requires an |
||
| 294 | attribute named like keyword! |
||
| 295 | |||
| 296 | Examples |
||
| 297 | -------- |
||
| 298 | >>> import pandas as pd |
||
| 299 | >>> from oemof import solph |
||
| 300 | >>> date_time_index = pd.date_range('1/1/2020', periods=6, freq='h') |
||
| 301 | >>> es = solph.EnergySystem( |
||
| 302 | ... timeindex=date_time_index, |
||
| 303 | ... infer_last_interval=False, |
||
| 304 | ... ) |
||
| 305 | >>> bus = solph.buses.Bus(label='bus_1') |
||
| 306 | >>> sink = solph.components.Sink(label="sink", inputs={bus: |
||
| 307 | ... solph.flows.Flow(nominal_capacity=10, fix=[10, 20, 30, 40, 50])}) |
||
| 308 | >>> src1 = solph.components.Source( |
||
| 309 | ... label='source_0', outputs={bus: solph.flows.Flow( |
||
| 310 | ... nominal_capacity=solph.Investment( |
||
| 311 | ... ep_costs=50, custom_attributes={"space": 4}, |
||
| 312 | ... )) |
||
| 313 | ... }) |
||
| 314 | >>> src2 = solph.components.Source( |
||
| 315 | ... label='source_1', outputs={bus: solph.flows.Flow( |
||
| 316 | ... nominal_capacity=solph.Investment( |
||
| 317 | ... ep_costs=100, custom_attributes={"space": 1}, |
||
| 318 | ... )) |
||
| 319 | ... }) |
||
| 320 | >>> es.add(bus, sink, src1, src2) |
||
| 321 | >>> model = solph.Model(es) |
||
| 322 | >>> model = solph.constraints.additional_investment_flow_limit( |
||
| 323 | ... model, "space", limit=1500) |
||
| 324 | >>> a = model.solve(solver="cbc") |
||
| 325 | >>> int(round(model.invest_limit_space())) |
||
| 326 | 1500 |
||
| 327 | """ # noqa: E501 |
||
| 328 | invest_flows = {} |
||
| 329 | operational_flows = {} |
||
| 330 | storages = {} |
||
| 331 | for i, o in model.flows: |
||
| 332 | if hasattr(model.flows[i, o].investment, keyword): |
||
| 333 | invest_flows[(i, o)] = model.flows[i, o].investment |
||
| 334 | if hasattr(model.flows[i, o], keyword): |
||
| 335 | operational_flows[(i, o)] = model.flows[i, o] |
||
| 336 | limit_name = "total_limit_" + keyword |
||
| 337 | |||
| 338 | if hasattr(model, "GenericInvestmentStorageBlock"): |
||
| 339 | for st, _ in model.GenericInvestmentStorageBlock.invest: |
||
| 340 | storages[st] = [st] |
||
| 341 | |||
| 342 | setattr( |
||
| 343 | model, |
||
| 344 | limit_name, |
||
| 345 | po.Expression( |
||
| 346 | rule=lambda m: sum( |
||
| 347 | model.InvestmentFlowBlock.invest[inflow, outflow, p] |
||
| 348 | * getattr(invest_flows[inflow, outflow], keyword).get( |
||
| 349 | "linear", 0 |
||
| 350 | ) |
||
| 351 | + ( |
||
| 352 | model.InvestmentFlowBlock.invest_status[inflow, outflow, p] |
||
| 353 | * getattr(invest_flows[inflow, outflow], keyword).get( |
||
| 354 | "offset", 0 |
||
| 355 | ) |
||
| 356 | if (inflow, outflow, p) |
||
| 357 | in model.InvestmentFlowBlock.invest_status |
||
| 358 | else 0 |
||
| 359 | ) |
||
| 360 | for (inflow, outflow) in invest_flows |
||
| 361 | for p in model.PERIODS |
||
| 362 | ) |
||
| 363 | + sum( |
||
| 364 | model.flow[inflow, outflow, t] |
||
| 365 | * model.tsam_weighting[t] |
||
| 366 | * model.timeincrement[t] |
||
| 367 | * sequence( |
||
| 368 | getattr(operational_flows[inflow, outflow], keyword) |
||
| 369 | )[t] |
||
| 370 | for (inflow, outflow) in operational_flows |
||
| 371 | for p in model.PERIODS |
||
| 372 | for t in model.TIMESTEPS_IN_PERIOD[p] |
||
| 373 | ) |
||
| 374 | + sum( |
||
| 375 | ( |
||
| 376 | model.GenericInvestmentStorageBlock.invest[st, p] |
||
| 377 | * getattr(storages[st][0].investment, keyword).get( |
||
| 378 | "linear", 0 |
||
| 379 | ) |
||
| 380 | + model.GenericInvestmentStorageBlock.invest_status[st, p] |
||
| 381 | * getattr(storages[st][0].investment, keyword).get( |
||
| 382 | "offset", 0 |
||
| 383 | ) |
||
| 384 | if (st, p) |
||
| 385 | in model.GenericInvestmentStorageBlock.invest_status |
||
| 386 | else 0 |
||
| 387 | ) |
||
| 388 | for st in storages |
||
| 389 | for p in model.PERIODS |
||
| 390 | if hasattr(model, "GenericInvestmentStorageBlock") |
||
| 391 | ) |
||
| 392 | ), |
||
| 393 | ) |
||
| 394 | |||
| 395 | setattr( |
||
| 396 | model, |
||
| 397 | limit_name + "_constraint", |
||
| 398 | po.Constraint(expr=(getattr(model, limit_name) <= limit)), |
||
| 399 | ) |
||
| 400 | |||
| 401 | return model |
||
| 402 |