| Conditions | 15 |
| Total Lines | 156 |
| Code Lines | 93 |
| 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:
Complex classes like solph.blocks.flow.Flow._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 -*- |
||
| 98 | def _create(self, group=None): |
||
| 99 | r"""Creates sets, variables and constraints for all standard flows. |
||
| 100 | |||
| 101 | Parameters |
||
| 102 | ---------- |
||
| 103 | group : list |
||
| 104 | List containing tuples containing flow (f) objects and the |
||
| 105 | associated source (s) and target (t) |
||
| 106 | of flow e.g. groups=[(s1, t1, f1), (s2, t2, f2),..] |
||
| 107 | """ |
||
| 108 | if group is None: |
||
| 109 | return None |
||
| 110 | |||
| 111 | m = self.parent_block() |
||
| 112 | |||
| 113 | # ########################## SETS ################################# |
||
| 114 | # set for all flows with an global limit on the flow over time |
||
| 115 | self.SUMMED_MAX_FLOWS = Set( |
||
| 116 | initialize=[ |
||
| 117 | (g[0], g[1]) |
||
| 118 | for g in group |
||
| 119 | if g[2].summed_max is not None |
||
| 120 | and g[2].nominal_value is not None |
||
| 121 | ] |
||
| 122 | ) |
||
| 123 | |||
| 124 | self.SUMMED_MIN_FLOWS = Set( |
||
| 125 | initialize=[ |
||
| 126 | (g[0], g[1]) |
||
| 127 | for g in group |
||
| 128 | if g[2].summed_min is not None |
||
| 129 | and g[2].nominal_value is not None |
||
| 130 | ] |
||
| 131 | ) |
||
| 132 | |||
| 133 | self.NEGATIVE_GRADIENT_FLOWS = Set( |
||
| 134 | initialize=[ |
||
| 135 | (g[0], g[1]) |
||
| 136 | for g in group |
||
| 137 | if g[2].negative_gradient["ub"][0] is not None |
||
| 138 | ] |
||
| 139 | ) |
||
| 140 | |||
| 141 | self.POSITIVE_GRADIENT_FLOWS = Set( |
||
| 142 | initialize=[ |
||
| 143 | (g[0], g[1]) |
||
| 144 | for g in group |
||
| 145 | if g[2].positive_gradient["ub"][0] is not None |
||
| 146 | ] |
||
| 147 | ) |
||
| 148 | |||
| 149 | self.INTEGER_FLOWS = Set( |
||
| 150 | initialize=[(g[0], g[1]) for g in group if g[2].integer] |
||
| 151 | ) |
||
| 152 | # ######################### Variables ################################ |
||
| 153 | |||
| 154 | self.positive_gradient = Var(self.POSITIVE_GRADIENT_FLOWS, m.TIMESTEPS) |
||
| 155 | |||
| 156 | self.negative_gradient = Var(self.NEGATIVE_GRADIENT_FLOWS, m.TIMESTEPS) |
||
| 157 | |||
| 158 | self.integer_flow = Var( |
||
| 159 | self.INTEGER_FLOWS, m.TIMESTEPS, within=NonNegativeIntegers |
||
| 160 | ) |
||
| 161 | # set upper bound of gradient variable |
||
| 162 | for i, o, f in group: |
||
| 163 | if m.flows[i, o].positive_gradient["ub"][0] is not None: |
||
| 164 | for t in m.TIMESTEPS: |
||
| 165 | self.positive_gradient[i, o, t].setub( |
||
| 166 | f.positive_gradient["ub"][t] * f.nominal_value |
||
| 167 | ) |
||
| 168 | if m.flows[i, o].negative_gradient["ub"][0] is not None: |
||
| 169 | for t in m.TIMESTEPS: |
||
| 170 | self.negative_gradient[i, o, t].setub( |
||
| 171 | f.negative_gradient["ub"][t] * f.nominal_value |
||
| 172 | ) |
||
| 173 | |||
| 174 | # ######################### CONSTRAINTS ############################### |
||
| 175 | |||
| 176 | def _flow_summed_max_rule(model): |
||
| 177 | """Rule definition for build action of max. sum flow constraint.""" |
||
| 178 | for inp, out in self.SUMMED_MAX_FLOWS: |
||
| 179 | lhs = sum( |
||
| 180 | m.flow[inp, out, ts] * m.timeincrement[ts] |
||
|
|
|||
| 181 | for ts in m.TIMESTEPS |
||
| 182 | ) |
||
| 183 | rhs = ( |
||
| 184 | m.flows[inp, out].summed_max |
||
| 185 | * m.flows[inp, out].nominal_value |
||
| 186 | ) |
||
| 187 | self.summed_max.add((inp, out), lhs <= rhs) |
||
| 188 | |||
| 189 | self.summed_max = Constraint(self.SUMMED_MAX_FLOWS, noruleinit=True) |
||
| 190 | self.summed_max_build = BuildAction(rule=_flow_summed_max_rule) |
||
| 191 | |||
| 192 | def _flow_summed_min_rule(model): |
||
| 193 | """Rule definition for build action of min. sum flow constraint.""" |
||
| 194 | for inp, out in self.SUMMED_MIN_FLOWS: |
||
| 195 | lhs = sum( |
||
| 196 | m.flow[inp, out, ts] * m.timeincrement[ts] |
||
| 197 | for ts in m.TIMESTEPS |
||
| 198 | ) |
||
| 199 | rhs = ( |
||
| 200 | m.flows[inp, out].summed_min |
||
| 201 | * m.flows[inp, out].nominal_value |
||
| 202 | ) |
||
| 203 | self.summed_min.add((inp, out), lhs >= rhs) |
||
| 204 | |||
| 205 | self.summed_min = Constraint(self.SUMMED_MIN_FLOWS, noruleinit=True) |
||
| 206 | self.summed_min_build = BuildAction(rule=_flow_summed_min_rule) |
||
| 207 | |||
| 208 | def _positive_gradient_flow_rule(model): |
||
| 209 | """Rule definition for positive gradient constraint.""" |
||
| 210 | for inp, out in self.POSITIVE_GRADIENT_FLOWS: |
||
| 211 | for ts in m.TIMESTEPS: |
||
| 212 | if ts > 0: |
||
| 213 | lhs = m.flow[inp, out, ts] - m.flow[inp, out, ts - 1] |
||
| 214 | rhs = self.positive_gradient[inp, out, ts] |
||
| 215 | self.positive_gradient_constr.add( |
||
| 216 | (inp, out, ts), lhs <= rhs |
||
| 217 | ) |
||
| 218 | else: |
||
| 219 | pass # return(Constraint.Skip) |
||
| 220 | |||
| 221 | self.positive_gradient_constr = Constraint( |
||
| 222 | self.POSITIVE_GRADIENT_FLOWS, m.TIMESTEPS, noruleinit=True |
||
| 223 | ) |
||
| 224 | self.positive_gradient_build = BuildAction( |
||
| 225 | rule=_positive_gradient_flow_rule |
||
| 226 | ) |
||
| 227 | |||
| 228 | def _negative_gradient_flow_rule(model): |
||
| 229 | """Rule definition for negative gradient constraint.""" |
||
| 230 | for inp, out in self.NEGATIVE_GRADIENT_FLOWS: |
||
| 231 | for ts in m.TIMESTEPS: |
||
| 232 | if ts > 0: |
||
| 233 | lhs = m.flow[inp, out, ts - 1] - m.flow[inp, out, ts] |
||
| 234 | rhs = self.negative_gradient[inp, out, ts] |
||
| 235 | self.negative_gradient_constr.add( |
||
| 236 | (inp, out, ts), lhs <= rhs |
||
| 237 | ) |
||
| 238 | else: |
||
| 239 | pass # return(Constraint.Skip) |
||
| 240 | |||
| 241 | self.negative_gradient_constr = Constraint( |
||
| 242 | self.NEGATIVE_GRADIENT_FLOWS, m.TIMESTEPS, noruleinit=True |
||
| 243 | ) |
||
| 244 | self.negative_gradient_build = BuildAction( |
||
| 245 | rule=_negative_gradient_flow_rule |
||
| 246 | ) |
||
| 247 | |||
| 248 | def _integer_flow_rule(block, ii, oi, ti): |
||
| 249 | """Force flow variable to NonNegativeInteger values.""" |
||
| 250 | return self.integer_flow[ii, oi, ti] == m.flow[ii, oi, ti] |
||
| 251 | |||
| 252 | self.integer_flow_constr = Constraint( |
||
| 253 | self.INTEGER_FLOWS, m.TIMESTEPS, rule=_integer_flow_rule |
||
| 254 | ) |
||
| 274 |