|
4 | 4 | from typing import Literal |
5 | 5 |
|
6 | 6 | import pyomo.environ as pyo |
7 | | -from numpy import zeros |
8 | | -from pyomo.core.base.matrix_constraint import MatrixConstraint |
9 | 7 |
|
10 | 8 |
|
11 | 9 | def initialisations( |
@@ -244,18 +242,46 @@ def static_equilibrium_constraints(model, aeq, afr, p) -> Callable: |
244 | 242 |
|
245 | 243 | """ |
246 | 244 |
|
247 | | - equilibrium_constraints = MatrixConstraint( |
248 | | - aeq.data, aeq.indices, aeq.indptr, -p.flatten(), -p.flatten(), model.array_f |
249 | | - ) |
250 | | - |
251 | | - friction_constraint = MatrixConstraint( |
252 | | - afr.data, |
253 | | - afr.indices, |
254 | | - afr.indptr, |
255 | | - [None for i in range(afr.shape[0])], |
256 | | - zeros(afr.shape[0]), |
257 | | - model.array_f, |
258 | | - ) |
| 245 | + # The previous MatrixConstraint function was causing problems, |
| 246 | + # it's now replaced by |
| 247 | + |
| 248 | + # aeq = aeq.tocsr() # tocsr gives data, indicies and indptr instead of decomposing them one by one |
| 249 | + # afr = afr.tocsr() |
| 250 | + rhs = (-p).flatten() |
| 251 | + f_var = model.array_f |
| 252 | + |
| 253 | + # Deprecated code for reference: |
| 254 | + # equilibrium_constraints = matrix_constraint( |
| 255 | + # aeq.data, aeq.indices, aeq.indptr, -p.flatten(), |
| 256 | + # -p.flatten(), model.array_f ) |
| 257 | + # A_eq is the tangent matrix, equal to -p, |
| 258 | + # A container for constraints of the form lb <= Ax <= ub. |
| 259 | + # here, lp and ub are both equal to -p, |
| 260 | + # so the constraint is Ax = -p, which is the equilibrium equation. |
| 261 | + # https://pyomo.readthedocs.io/en/6.9.1/api/pyomo.core.kernel.matrix_constraint.matrix_constraint.html |
| 262 | + |
| 263 | + def eq_rule(m, i): |
| 264 | + s, e = aeq.indptr[i], aeq.indptr[i + 1] |
| 265 | + if s == e: |
| 266 | + return pyo.Constraint.Skip |
| 267 | + expr = pyo.quicksum(float(aeq.data[k]) * f_var[int(aeq.indices[k])] for k in range(s, e)) |
| 268 | + return expr == float(rhs[i]) |
| 269 | + |
| 270 | + # Expression equivalent to: |
| 271 | + # -p <= A_eq * f <= -p (Friction) |
| 272 | + |
| 273 | + def fr_rule(m, j): |
| 274 | + s, e = afr.indptr[j], afr.indptr[j + 1] |
| 275 | + if s == e: |
| 276 | + return pyo.Constraint.Skip |
| 277 | + expr = pyo.quicksum(float(afr.data[k]) * f_var[int(afr.indices[k])] for k in range(s, e)) |
| 278 | + return expr <= 0.0 |
| 279 | + |
| 280 | + # Expression equivalent to: |
| 281 | + # A_fr * f <= 0 (Unilateral constraint) |
| 282 | + |
| 283 | + equilibrium_constraints = pyo.Constraint(range(aeq.shape[0]), rule=eq_rule) |
| 284 | + friction_constraint = pyo.Constraint(range(afr.shape[0]), rule=fr_rule) |
259 | 285 | return equilibrium_constraints, friction_constraint |
260 | 286 |
|
261 | 287 |
|
|
0 commit comments