| Conditions | 16 |
| Total Lines | 302 |
| Code Lines | 191 |
| Lines | 75 |
| Ratio | 24.83 % |
| 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:
Complex classes like solph.flows._non_convex_flow.NonConvexFlowBlock._create() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | # -*- coding: utf-8 -*- |
||
| 319 | def _create(self, group=None): |
||
| 320 | """Creates set, variables, constraints for all flow object with |
||
| 321 | an attribute flow of type class:`.NonConvexFlowBlock`. |
||
| 322 | |||
| 323 | Parameters |
||
| 324 | ---------- |
||
| 325 | group : list |
||
| 326 | List of oemof.solph.NonConvexFlowBlock objects for which |
||
| 327 | the constraints are build. |
||
| 328 | """ |
||
| 329 | if group is None: |
||
| 330 | return None |
||
| 331 | |||
| 332 | m = self.parent_block() |
||
| 333 | # ########################## SETS ##################################### |
||
| 334 | self.NONCONVEX_FLOWS = Set(initialize=[(g[0], g[1]) for g in group]) |
||
| 335 | |||
| 336 | self.MIN_FLOWS = Set( |
||
| 337 | initialize=[(g[0], g[1]) for g in group if g[2].min[0] is not None] |
||
| 338 | ) |
||
| 339 | self.STARTUPFLOWS = Set( |
||
| 340 | initialize=[ |
||
| 341 | (g[0], g[1]) |
||
| 342 | for g in group |
||
| 343 | if g[2].nonconvex.startup_costs[0] is not None |
||
| 344 | or g[2].nonconvex.maximum_startups is not None |
||
| 345 | ] |
||
| 346 | ) |
||
| 347 | self.MAXSTARTUPFLOWS = Set( |
||
| 348 | initialize=[ |
||
| 349 | (g[0], g[1]) |
||
| 350 | for g in group |
||
| 351 | if g[2].nonconvex.maximum_startups is not None |
||
| 352 | ] |
||
| 353 | ) |
||
| 354 | self.SHUTDOWNFLOWS = Set( |
||
| 355 | initialize=[ |
||
| 356 | (g[0], g[1]) |
||
| 357 | for g in group |
||
| 358 | if g[2].nonconvex.shutdown_costs[0] is not None |
||
| 359 | or g[2].nonconvex.maximum_shutdowns is not None |
||
| 360 | ] |
||
| 361 | ) |
||
| 362 | self.MAXSHUTDOWNFLOWS = Set( |
||
| 363 | initialize=[ |
||
| 364 | (g[0], g[1]) |
||
| 365 | for g in group |
||
| 366 | if g[2].nonconvex.maximum_shutdowns is not None |
||
| 367 | ] |
||
| 368 | ) |
||
| 369 | self.MINUPTIMEFLOWS = Set( |
||
| 370 | initialize=[ |
||
| 371 | (g[0], g[1]) |
||
| 372 | for g in group |
||
| 373 | if g[2].nonconvex.minimum_uptime is not None |
||
| 374 | ] |
||
| 375 | ) |
||
| 376 | |||
| 377 | self.MINDOWNTIMEFLOWS = Set( |
||
| 378 | initialize=[ |
||
| 379 | (g[0], g[1]) |
||
| 380 | for g in group |
||
| 381 | if g[2].nonconvex.minimum_downtime is not None |
||
| 382 | ] |
||
| 383 | ) |
||
| 384 | |||
| 385 | self.ACTIVITYCOSTFLOWS = Set( |
||
| 386 | initialize=[ |
||
| 387 | (g[0], g[1]) |
||
| 388 | for g in group |
||
| 389 | if g[2].nonconvex.activity_costs[0] is not None |
||
| 390 | ] |
||
| 391 | ) |
||
| 392 | |||
| 393 | self.INACTIVITYCOSTFLOWS = Set( |
||
| 394 | initialize=[ |
||
| 395 | (g[0], g[1]) |
||
| 396 | for g in group |
||
| 397 | if g[2].nonconvex.inactivity_costs[0] is not None |
||
| 398 | ] |
||
| 399 | ) |
||
| 400 | |||
| 401 | self.NEGATIVE_GRADIENT_FLOWS = Set( |
||
| 402 | initialize=[ |
||
| 403 | (g[0], g[1]) |
||
| 404 | for g in group |
||
| 405 | if g[2].nonconvex.negative_gradient["ub"][0] is not None |
||
| 406 | ] |
||
| 407 | ) |
||
| 408 | |||
| 409 | self.POSITIVE_GRADIENT_FLOWS = Set( |
||
| 410 | initialize=[ |
||
| 411 | (g[0], g[1]) |
||
| 412 | for g in group |
||
| 413 | if g[2].nonconvex.positive_gradient["ub"][0] is not None |
||
| 414 | ] |
||
| 415 | ) |
||
| 416 | |||
| 417 | # ################### VARIABLES AND CONSTRAINTS ####################### |
||
| 418 | self.status = Var(self.NONCONVEX_FLOWS, m.TIMESTEPS, within=Binary) |
||
| 419 | |||
| 420 | if self.STARTUPFLOWS: |
||
| 421 | self.startup = Var(self.STARTUPFLOWS, m.TIMESTEPS, within=Binary) |
||
| 422 | |||
| 423 | if self.SHUTDOWNFLOWS: |
||
| 424 | self.shutdown = Var(self.SHUTDOWNFLOWS, m.TIMESTEPS, within=Binary) |
||
| 425 | |||
| 426 | if self.POSITIVE_GRADIENT_FLOWS: |
||
| 427 | self.positive_gradient = Var( |
||
| 428 | self.POSITIVE_GRADIENT_FLOWS, m.TIMESTEPS |
||
| 429 | ) |
||
| 430 | |||
| 431 | if self.NEGATIVE_GRADIENT_FLOWS: |
||
| 432 | self.negative_gradient = Var( |
||
| 433 | self.NEGATIVE_GRADIENT_FLOWS, m.TIMESTEPS |
||
| 434 | ) |
||
| 435 | |||
| 436 | def _minimum_flow_rule(block, i, o, t): |
||
| 437 | """Rule definition for MILP minimum flow constraints.""" |
||
| 438 | expr = ( |
||
| 439 | self.status[i, o, t] |
||
| 440 | * m.flows[i, o].min[t] |
||
|
|
|||
| 441 | * m.flows[i, o].nominal_value |
||
| 442 | <= m.flow[i, o, t] |
||
| 443 | ) |
||
| 444 | return expr |
||
| 445 | |||
| 446 | self.min = Constraint( |
||
| 447 | self.MIN_FLOWS, m.TIMESTEPS, rule=_minimum_flow_rule |
||
| 448 | ) |
||
| 449 | |||
| 450 | def _maximum_flow_rule(block, i, o, t): |
||
| 451 | """Rule definition for MILP maximum flow constraints.""" |
||
| 452 | expr = ( |
||
| 453 | self.status[i, o, t] |
||
| 454 | * m.flows[i, o].max[t] |
||
| 455 | * m.flows[i, o].nominal_value |
||
| 456 | >= m.flow[i, o, t] |
||
| 457 | ) |
||
| 458 | return expr |
||
| 459 | |||
| 460 | self.max = Constraint( |
||
| 461 | self.MIN_FLOWS, m.TIMESTEPS, rule=_maximum_flow_rule |
||
| 462 | ) |
||
| 463 | |||
| 464 | View Code Duplication | def _startup_rule(block, i, o, t): |
|
| 465 | """Rule definition for startup constraint of nonconvex flows.""" |
||
| 466 | if t > m.TIMESTEPS[1]: |
||
| 467 | expr = ( |
||
| 468 | self.startup[i, o, t] |
||
| 469 | >= self.status[i, o, t] - self.status[i, o, t - 1] |
||
| 470 | ) |
||
| 471 | else: |
||
| 472 | expr = ( |
||
| 473 | self.startup[i, o, t] |
||
| 474 | >= self.status[i, o, t] |
||
| 475 | - m.flows[i, o].nonconvex.initial_status |
||
| 476 | ) |
||
| 477 | return expr |
||
| 478 | |||
| 479 | self.startup_constr = Constraint( |
||
| 480 | self.STARTUPFLOWS, m.TIMESTEPS, rule=_startup_rule |
||
| 481 | ) |
||
| 482 | |||
| 483 | def _max_startup_rule(block, i, o): |
||
| 484 | """Rule definition for maximum number of start-ups.""" |
||
| 485 | lhs = sum(self.startup[i, o, t] for t in m.TIMESTEPS) |
||
| 486 | return lhs <= m.flows[i, o].nonconvex.maximum_startups |
||
| 487 | |||
| 488 | self.max_startup_constr = Constraint( |
||
| 489 | self.MAXSTARTUPFLOWS, rule=_max_startup_rule |
||
| 490 | ) |
||
| 491 | |||
| 492 | View Code Duplication | def _shutdown_rule(block, i, o, t): |
|
| 493 | """Rule definition for shutdown constraints of nonconvex flows.""" |
||
| 494 | if t > m.TIMESTEPS[1]: |
||
| 495 | expr = ( |
||
| 496 | self.shutdown[i, o, t] |
||
| 497 | >= self.status[i, o, t - 1] - self.status[i, o, t] |
||
| 498 | ) |
||
| 499 | else: |
||
| 500 | expr = ( |
||
| 501 | self.shutdown[i, o, t] |
||
| 502 | >= m.flows[i, o].nonconvex.initial_status |
||
| 503 | - self.status[i, o, t] |
||
| 504 | ) |
||
| 505 | return expr |
||
| 506 | |||
| 507 | self.shutdown_constr = Constraint( |
||
| 508 | self.SHUTDOWNFLOWS, m.TIMESTEPS, rule=_shutdown_rule |
||
| 509 | ) |
||
| 510 | |||
| 511 | def _max_shutdown_rule(block, i, o): |
||
| 512 | """Rule definition for maximum number of start-ups.""" |
||
| 513 | lhs = sum(self.shutdown[i, o, t] for t in m.TIMESTEPS) |
||
| 514 | return lhs <= m.flows[i, o].nonconvex.maximum_shutdowns |
||
| 515 | |||
| 516 | self.max_shutdown_constr = Constraint( |
||
| 517 | self.MAXSHUTDOWNFLOWS, rule=_max_shutdown_rule |
||
| 518 | ) |
||
| 519 | |||
| 520 | View Code Duplication | def _min_uptime_rule(block, i, o, t): |
|
| 521 | """ |
||
| 522 | Rule definition for min-uptime constraints of nonconvex flows. |
||
| 523 | """ |
||
| 524 | if ( |
||
| 525 | m.flows[i, o].nonconvex.max_up_down |
||
| 526 | <= t |
||
| 527 | <= m.TIMESTEPS[-1] - m.flows[i, o].nonconvex.max_up_down |
||
| 528 | ): |
||
| 529 | expr = 0 |
||
| 530 | expr += ( |
||
| 531 | self.status[i, o, t] - self.status[i, o, t - 1] |
||
| 532 | ) * m.flows[i, o].nonconvex.minimum_uptime |
||
| 533 | expr += -sum( |
||
| 534 | self.status[i, o, t + u] |
||
| 535 | for u in range(0, m.flows[i, o].nonconvex.minimum_uptime) |
||
| 536 | ) |
||
| 537 | return expr <= 0 |
||
| 538 | else: |
||
| 539 | expr = 0 |
||
| 540 | expr += self.status[i, o, t] |
||
| 541 | expr += -m.flows[i, o].nonconvex.initial_status |
||
| 542 | return expr == 0 |
||
| 543 | |||
| 544 | self.min_uptime_constr = Constraint( |
||
| 545 | self.MINUPTIMEFLOWS, m.TIMESTEPS, rule=_min_uptime_rule |
||
| 546 | ) |
||
| 547 | |||
| 548 | View Code Duplication | def _min_downtime_rule(block, i, o, t): |
|
| 549 | """ |
||
| 550 | Rule definition for min-downtime constraints of nonconvex flows. |
||
| 551 | """ |
||
| 552 | if ( |
||
| 553 | m.flows[i, o].nonconvex.max_up_down |
||
| 554 | <= t |
||
| 555 | <= m.TIMESTEPS[-1] - m.flows[i, o].nonconvex.max_up_down |
||
| 556 | ): |
||
| 557 | expr = 0 |
||
| 558 | expr += ( |
||
| 559 | self.status[i, o, t - 1] - self.status[i, o, t] |
||
| 560 | ) * m.flows[i, o].nonconvex.minimum_downtime |
||
| 561 | expr += -m.flows[i, o].nonconvex.minimum_downtime |
||
| 562 | expr += sum( |
||
| 563 | self.status[i, o, t + d] |
||
| 564 | for d in range(0, m.flows[i, o].nonconvex.minimum_downtime) |
||
| 565 | ) |
||
| 566 | return expr <= 0 |
||
| 567 | else: |
||
| 568 | expr = 0 |
||
| 569 | expr += self.status[i, o, t] |
||
| 570 | expr += -m.flows[i, o].nonconvex.initial_status |
||
| 571 | return expr == 0 |
||
| 572 | |||
| 573 | self.min_downtime_constr = Constraint( |
||
| 574 | self.MINDOWNTIMEFLOWS, m.TIMESTEPS, rule=_min_downtime_rule |
||
| 575 | ) |
||
| 576 | |||
| 577 | def _positive_gradient_flow_rule(block): |
||
| 578 | """Rule definition for positive gradient constraint.""" |
||
| 579 | for i, o in self.POSITIVE_GRADIENT_FLOWS: |
||
| 580 | for t in m.TIMESTEPS: |
||
| 581 | if t > 0: |
||
| 582 | lhs = ( |
||
| 583 | m.flow[i, o, t] * self.status[i, o, t] |
||
| 584 | - m.flow[i, o, t - 1] * self.status[i, o, t - 1] |
||
| 585 | ) |
||
| 586 | rhs = self.positive_gradient[i, o, t] |
||
| 587 | self.positive_gradient_constr.add( |
||
| 588 | (i, o, t), lhs <= rhs |
||
| 589 | ) |
||
| 590 | else: |
||
| 591 | pass # return(Constraint.Skip) |
||
| 592 | |||
| 593 | self.positive_gradient_constr = Constraint( |
||
| 594 | self.POSITIVE_GRADIENT_FLOWS, m.TIMESTEPS, noruleinit=True |
||
| 595 | ) |
||
| 596 | self.positive_gradient_build = BuildAction( |
||
| 597 | rule=_positive_gradient_flow_rule |
||
| 598 | ) |
||
| 599 | |||
| 600 | def _negative_gradient_flow_rule(block): |
||
| 601 | """Rule definition for negative gradient constraint.""" |
||
| 602 | for i, o in self.NEGATIVE_GRADIENT_FLOWS: |
||
| 603 | for t in m.TIMESTEPS: |
||
| 604 | if t > 0: |
||
| 605 | lhs = ( |
||
| 606 | m.flow[i, o, t - 1] * self.status[i, o, t - 1] |
||
| 607 | - m.flow[i, o, t] * self.status[i, o, t] |
||
| 608 | ) |
||
| 609 | rhs = self.negative_gradient[i, o, t] |
||
| 610 | self.negative_gradient_constr.add( |
||
| 611 | (i, o, t), lhs <= rhs |
||
| 612 | ) |
||
| 613 | else: |
||
| 614 | pass # return(Constraint.Skip) |
||
| 615 | |||
| 616 | self.negative_gradient_constr = Constraint( |
||
| 617 | self.NEGATIVE_GRADIENT_FLOWS, m.TIMESTEPS, noruleinit=True |
||
| 618 | ) |
||
| 619 | self.negative_gradient_build = BuildAction( |
||
| 620 | rule=_negative_gradient_flow_rule |
||
| 621 | ) |
||
| 685 |