Coverage for backend/ahuora-builder/src/ahuora_builder/properties_manager.py: 91%

33 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-06-23 21:51 +0000

1from ahuora_builder_types.id_types import PropertyValueId 

2from pyomo.core.base.indexed_component import Component, IndexedComponent 

3from pyomo.core.base.componentuid import ComponentUID 

4 

5def first_component(component: Component): 

6 if isinstance(component, IndexedComponent): 6 ↛ 9line 6 didn't jump to line 9 because the condition on line 6 was always true

7 return next(iter(component.values())) 

8 else: 

9 return component 

10class PropertyComponent: 

11 def __init__(self, name: str, component : IndexedComponent, unknown_units=False): 

12 """ 

13 Args: 

14 - name (str): The name of the property component (for debugging purposes) 

15 - component (Component): The Pyomo component; i.e., Expression, Var 

16 - unknown_units (bool): If units are unknown, idaes_factory will do some 

17 additional processing to determine the unit category. 

18 - corresponding_constraint (Constraint | Var | None): The component 

19 (Var or Constraint) that was fixed or activated to set the value of 

20 this property. Given an id in the properties dictionary, this field 

21 can be used to unfix or deactivate the corresponding constraint. 

22 Defaults to None (allowed for properties that are not fixed). 

23 """ 

24 self.name: str = name 

25 self.component: IndexedComponent = component 

26 self.unknown_units = unknown_units 

27 self.corresponding_constraint : list[ScalarVar | ScalarConstraint] = None # TODO: Type 

28 

29 

30class PropertiesManager: 

31 """ 

32 The properties manager is responsible for keeping track of all the properties in the model that we have fixed. 

33 This allows us to unfix/deactivate them as needed, for example when we want to initialise the model. 

34 You should be able to access this from model.fs.properties_map, or from the FlowsheetManager.PropertiesManager after the flowsheet is loaded. 

35 """ 

36 def __init__(self): 

37 self.properties : dict[PropertyValueId,PropertyComponent] = {} 

38 self._components_to_ids: dict[ComponentUID, PropertyValueId] = {} 

39 

40 def add(self, id: PropertyValueId, indexed_component: IndexedComponent, name : str, unknown_units=False)-> IndexedComponent: 

41 self.properties[id] = PropertyComponent(name, indexed_component, unknown_units) 

42 self._components_to_ids[ComponentUID(first_component(indexed_component))] = id 

43 return indexed_component 

44 

45 def get_id_by_component(self, component: Component) -> PropertyValueId | None: 

46 return self._components_to_ids.get(ComponentUID(first_component(component))) 

47 

48 def get(self, id: PropertyValueId): 

49 return self.properties[id] 

50 

51 def get_component(self, id: PropertyValueId): 

52 return self.get(id).component 

53 

54 def get_constraint(self, id: PropertyValueId): 

55 return self.get(id).corresponding_constraint 

56 

57 def add_constraint(self, id: PropertyValueId, constraint): 

58 # assumes the property has already been added 

59 self.get(id).corresponding_constraint = constraint 

60 

61 def items(self): 

62 return self.properties.items()