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