Coverage for backend/core/auxiliary/models/RecycleData.py: 96%
38 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 django.db import models
2from flowsheetInternals.unitops.models.SimulationObject import SimulationObject
3from .PropertyInfo import PropertyInfo
5from core.managers import AccessControlManager
6class RecycleData(models.Model):
7 """
8 Recycle data for a recycle block simulation object
9 Stores which tear object is connected to the recycle block
10 """
11 flowsheet = models.ForeignKey("Flowsheet", on_delete=models.CASCADE, related_name="RecycleDatas")
12 # parent recycle block
13 simulationObject = models.OneToOneField(SimulationObject, on_delete=models.CASCADE, related_name="recycleData", null=True)
14 # tear object, makes properties of this object enabled
15 tearObject = models.OneToOneField(SimulationObject, on_delete=models.SET_NULL, related_name="recycleConnection", null=True)
17 created_at = models.DateTimeField(auto_now_add=True)
18 objects = AccessControlManager()
23 def update(self, tear_object: SimulationObject | None) -> None:
24 """
25 Update the tear object's properties to be enabled
26 """
27 prev_tear = self.tearObject
28 self.tearObject = tear_object
29 self.save()
31 # reevaluate enabled properties
32 if prev_tear is not None:
33 # cleanup internal controls
34 for prop in prev_tear.properties.containedProperties.all():
35 for prop_value in prop.values.all():
36 if prop_value.is_control_set_point() and not prop_value.is_externally_controlled(): 36 ↛ 38line 36 didn't jump to line 38 because the condition on line 36 was never true
37 # delete this control
38 prop_value.controlSetPoint.delete()
40 prev_tear.reevaluate_properties_enabled()
41 if tear_object is not None and prev_tear != tear_object:
42 tear_object.reevaluate_properties_enabled()
44 # delete old property connections
45 self.propertyConnections.all().delete()
46 # create new property connections for the new tear object
47 recycle_properties = []
48 if tear_object is not None:
49 # hardcoded for now
50 # default to mole_frac_comp/molarFlow fixed
51 state_vars = {
52 "mole_frac_comp": True,
53 "flow_mol": True,
54 "temperature": False,
55 "pressure": False
56 }
57 for prop in tear_object.properties.containedProperties.filter(key__in=state_vars):
58 recycle_properties.append(
59 RecycleProperty(recycleData=self, propertyInfo=prop, fixed=state_vars[prop.key], flowsheet=self.flowsheet)
60 )
62 RecycleProperty.objects.bulk_create(recycle_properties)
65 def clear(self) -> None:
66 """
67 Clear the tear object
68 """
69 self.update(None)
72class RecycleProperty(models.Model):
73 """
74 Used to store "fix var and remove the equality constraint"
75 at the the tear object. Also contributes towards access
76 levels for frontend and idaes_factory (meaning, is this property editable?)
77 """
78 flowsheet = models.ForeignKey("Flowsheet", on_delete=models.CASCADE, related_name="RecycleProperties")
79 recycleData = models.ForeignKey(RecycleData, on_delete=models.CASCADE, related_name="propertyConnections", null=True)
80 # this relation may need to become PropertyValue eventually
81 propertyInfo = models.OneToOneField(PropertyInfo, on_delete=models.CASCADE, related_name="recycleConnection", null=True)
82 fixed = models.BooleanField(default=False) # if true, fix var and remove the equality constraint across the tear
84 created_at = models.DateTimeField(auto_now_add=True)
85 objects = AccessControlManager()