Coverage for backend/idaes_service/solver/tear_manager.py: 100%
45 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-11-06 23:27 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2025-11-06 23:27 +0000
1from pyomo.environ import value
2from pyomo.network import Arc
3from idaes.core.util.tables import _get_state_from_port
4from pyomo.core.base.expression import ScalarExpression
5from common.models.idaes.arc_schema import TearGuessSchema
6from .flowsheet_manager_type import FlowsheetManager
7from common.models.idaes import PortId
8from .methods.adapter import fix_var
11class TearManager:
12 """
13 Manages the tears in the flowsheet
14 """
16 def __init__(self, flowsheet_manager: FlowsheetManager):
17 """
18 Create a new tear manager
19 """
20 self._flowsheet_manager = flowsheet_manager
21 self._tears: list[Arc] = []
23 def load(self):
24 """
25 Load all the tears (from the recycle unitops)
26 """
27 schema = self._flowsheet_manager.schema
29 for arc_schema in schema.arcs:
30 if arc_schema.tear_guess:
31 self.add_tear(arc_schema)
33 def add_tear(self, arc_schema):
34 """
35 Add a tear to the flowsheet
36 """
37 portId = arc_schema.destination
38 guess = arc_schema.tear_guess
40 port = self._flowsheet_manager.ports.get_port(portId)
41 arc = port.arcs()[0]
42 self._tears.append(arc)
44 """
45 During model loading, we add in all the constraints and fix the variables
46 for this port. Since it is a tear, things need to be deactivated/unfixed
47 to ensure 0 degrees of freedom
49 If the state block is defined by constraints, we need to solve it to get the
50 correct values for the state variables. Then we deactivate the constraints
51 since we will be fixing the state variables instead (where applicable).
52 """
54 # hardcoding time indexes to [0] for now
55 time_indexes = [0]
57 # need to get the correct value for state variables before running
58 # sequential decomposition (since all state variables are fixed
59 # during sequential decomposition).
60 sb = _get_state_from_port(port, time_indexes[0])
61 # deactivate any guesses
62 for key, value in guess.items():
63 var = getattr(sb, key)
64 if value != True:
65 if isinstance(var,ScalarExpression):
66 pass # we want to solve with constraints
67 else:
68 # this might give too few dof if we have other constraints. We need to unfix
69 # this value
70 var.unfix()
72 if len(list(sb.constraints.component_objects())) > 0:
73 # state block is defined by some constraints, so we need to solve it.
74 # initialize the state block, which should put the correct value in
75 # the state variables
76 sb.parent_component().initialize()
77 # deactivate the state block constraints, since we should use the
78 # state variables as guesses (or fix them instead)
79 sb.constraints.deactivate()
81 blk = sb.parent_component()
82 for key in sb.define_state_vars():
83 if guess.get(key, False):
84 # deactivate the equality constraint (expanded arcs)
85 expanded_arc = getattr(
86 self._flowsheet_manager.model.fs, arc._name + "_expanded"
87 )
88 equality_constraint = getattr(expanded_arc, key + "_equality")
89 equality_constraint.deactivate()
91 # fix the variable
92 for b in blk.values():
93 getattr(b, key).fix()
95 else:
96 # unfix this variable
97 for b in blk.values():
98 getattr(b, key).unfix()