Coverage for backend/django/PinchAnalysis/models/OptionModels.py: 100%
89 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
1from django.db import models
2from core.auxiliary.enums import uiEnums
3from core.auxiliary.models.PropertyValue import PropertyValue
4from flowsheetInternals.unitops.services.edit_operations.recorder import (
5 tracked_bulk_create,
6)
7from core.auxiliary.models.PropertySet import PropertySet
8from core.auxiliary.enums import pinchEnums
9from django.db.models.signals import post_save
10from django.dispatch import receiver
11from core.auxiliary.models.PropertyInfo import PropertyInfo
13from typing import Literal
14from common.config_types import *
15from flowsheetInternals.unitops.config.config_methods import *
17from core.managers import AccessControlManager, AllFlowsheetStatesManager
22# Main Options PropKey Enum
23class MainOptionsPropKeys(models.TextChoices):
24 TIT_BUTTON_SELECTED = "PROP_MOP_0"
25 TS_BUTTON_SELECTED = "PROP_MOP_1"
26 TURBINE_WORK_BUTTON = "PROP_MOP_2"
27 AREA_BUTTON = "PROP_MOP_3"
28 ENERGY_RETROFIT_BUTTON = "PROP_MOP_4"
29 EXERGY_BUTTON = "PROP_MOP_5"
30 PRINT_PTS = "PROP_MOP_6"
31 PLOT_GRAPHS = "PROP_MOP_7"
33# Graph Options PropKey Enum
34class GraphOptionsPropKeys(models.TextChoices):
35 CC = "PROP_GOP_0"
36 SCC = "PROP_GOP_1"
37 BCC = "PROP_GOP_2"
38 GCC = "PROP_GOP_3"
39 GCC_NP = "PROP_GOP_4"
40 GCCU = "PROP_GOP_5"
41 LGCC = "PROP_GOP_6"
42 TOTAL_SITE = "PROP_GOP_7"
43 ERC = "PROP_GOP_8"
44 NLC = "PROP_GOP_9"
45 EC = "PROP_GOP_10"
47class TurbineOptionsPropKeys(models.TextChoices):
48 TURBINEFORM_T_TURBINE_BOX = "PROP_TOP_0"
49 TURBINEFORM_P_TURBINE_BOX = "PROP_TOP_1"
50 TURBINEFORM_MIN_EFF = "PROP_TOP_2"
51 TURBINEFORM_ELECTRICITY_PRICE = "PROP_TOP_3"
52 TURBINEFORM_LOAD = "PROP_TOP_4"
53 TURBINEFORM_MECH_EFF = "PROP_TOP_5"
54 TURBINEFORM_COMBOBOX = "PROP_TOP_6"
55 TURBINEFORM_ABOVE_PINCH_CHECKBOX = "PROP_TOP_7"
56 TURBINEFORM_BELOW_PINCH_CHECKBOX = "PROP_TOP_8"
57 TURBINEFORM_CONDESATE_FLASH_CORRECTION = "PROP_TOP_9"
61OptionSets = Literal["MainOptions", "TurbineOptions"]
63OptionsType = Dict[OptionSets, PropertiesType]
65pinch_options: OptionsType = {
66 "MainOptions": PropertiesType.model_validate({
67 MainOptionsPropKeys.TIT_BUTTON_SELECTED: { "displayName": "Totally Integrated Site", "value": True, "unitType": "dimensionless", "type": "checkbox" },
68 MainOptionsPropKeys.TS_BUTTON_SELECTED: { "displayName": "Total Site Heat Integration", "value": True, "unitType": "dimensionless", "type": "checkbox" },
69 MainOptionsPropKeys.TURBINE_WORK_BUTTON: { "displayName": "Turbine Shaft Work", "value": False, "unitType": "dimensionless", "type": "checkbox" },
70 MainOptionsPropKeys.AREA_BUTTON: { "displayName": "Target Area and Cost", "value": False, "unitType": "dimensionless", "type": "checkbox" },
71 MainOptionsPropKeys.ENERGY_RETROFIT_BUTTON: { "displayName": "Energy Retrofit", "value": False, "unitType": "dimensionless", "type": "checkbox" },
72 MainOptionsPropKeys.EXERGY_BUTTON: { "displayName": "Thermal Exergy", "value": False, "unitType": "dimensionless", "type": "checkbox" },
73 MainOptionsPropKeys.PRINT_PTS: { "displayName": "Print Problem Tables", "value": False, "unitType": "dimensionless", "type": "checkbox" },
74 }),
75 "TurbineOptions": PropertiesType.model_validate({
76 TurbineOptionsPropKeys.TURBINEFORM_T_TURBINE_BOX: { "displayName": "Inlet Temperature", "value": 450, "unitType": "temperature", "type": "numeric" },
77 TurbineOptionsPropKeys.TURBINEFORM_P_TURBINE_BOX: { "displayName": "Inlet Pressure", "value": 90, "unitType": "pressure", "type": "numeric" },
78 TurbineOptionsPropKeys.TURBINEFORM_MIN_EFF: { "displayName": "Minimum (Fixed)", "value": 0.1, "unitType": "dimensionless", "type": "numeric" },
79 TurbineOptionsPropKeys.TURBINEFORM_ELECTRICITY_PRICE: { "displayName": "Electricity Price", "value": 100, "unitType": "dimensionless", "type": "numeric" },
80 TurbineOptionsPropKeys.TURBINEFORM_LOAD: { "displayName": "Part Load Fraction", "value": 1.0, "unitType": "dimensionless", "type": "numeric" },
81 TurbineOptionsPropKeys.TURBINEFORM_MECH_EFF: { "displayName": "Mechanical Efficiency", "value": 1.0, "unitType": "dimensionless", "type": "numeric" },
82 TurbineOptionsPropKeys.TURBINEFORM_COMBOBOX: { "displayName": "Turbine Model", "value": pinchEnums.TurbineModel.MEDINA_FLORES, "unitType": "dimensionless", "type": "dropdown" },
83 TurbineOptionsPropKeys.TURBINEFORM_ABOVE_PINCH_CHECKBOX: { "displayName": "Above Pinch", "value": True, "unitType": "dimensionless", "type": "checkbox" },
84 TurbineOptionsPropKeys.TURBINEFORM_BELOW_PINCH_CHECKBOX: { "displayName": "Below Pinch", "value": False, "unitType": "dimensionless", "type": "checkbox" },
85 TurbineOptionsPropKeys.TURBINEFORM_CONDESATE_FLASH_CORRECTION: { "displayName": "High Pressure Condensate", "value": False, "unitType": "dimensionless", "type": "checkbox" },
86 }),
87}
89propKeyMapping = {
90 MainOptionsPropKeys.EXERGY_BUTTON: GraphOptionsPropKeys.EC,
91 MainOptionsPropKeys.TIT_BUTTON_SELECTED: GraphOptionsPropKeys.TOTAL_SITE,
92 MainOptionsPropKeys.ENERGY_RETROFIT_BUTTON: GraphOptionsPropKeys.ERC
93}
96# Additional options for turbine shaft work
97class TurbineOptions(models.Model):
98 flowsheet_state = models.ForeignKey("core_auxiliary.FlowsheetState", on_delete=models.CASCADE, related_name="TurbineOptions")
99 properties = models.ForeignKey(PropertySet, on_delete=models.CASCADE, default=None, null=True)
100 is_active = models.BooleanField(default=True)
102 created_at = models.DateTimeField(auto_now_add=True)
103 objects = AccessControlManager()
104 all_states = AllFlowsheetStatesManager()
107 @classmethod
108 def create(cls, flowsheet_state, **kwargs):
109 # Create property set and options object
110 property_set = create_property_set_options("TurbineOptions", flowsheet_state)
111 instance = cls.objects.create(
112 properties=property_set,
113 flowsheet_state=flowsheet_state,
114 )
115 instance.save()
116 return instance
118# Main options for the system
119class MainOptions(models.Model):
120 flowsheet_state = models.ForeignKey("core_auxiliary.FlowsheetState", on_delete=models.CASCADE, related_name="MainOptions")
121 selections = models.ForeignKey(PropertySet, on_delete=models.CASCADE, default=None, null=True)
122 turbine_options = models.ForeignKey(TurbineOptions, on_delete=models.CASCADE, default=None, null=True)
123 project_owner = models.OneToOneField("PinchAnalysis.StreamDataProject", on_delete=models.CASCADE, related_name="Options", null=True)
125 created_at = models.DateTimeField(auto_now_add=True)
126 objects = AccessControlManager()
127 all_states = AllFlowsheetStatesManager()
130 @classmethod
131 def create(cls, project_owner, flowsheet_state, **kwargs):
132 # Create property set and options object
133 property_set = create_property_set_options("MainOptions", flowsheet_state)
134 turbine_options = TurbineOptions.create(flowsheet_state)
135 # graph_options = GraphOptions.create(flowsheet)
136 instance = cls.objects.create(
137 selections=property_set,
138 turbine_options=turbine_options,
139 project_owner=project_owner,
140 flowsheet_state=flowsheet_state,
141 )
142 instance.save()
143 return instance
146def create_property_set_options(option_set: OptionSets, flowsheet_state):
147 property_set = PropertySet.objects.create(flowsheet_state=flowsheet_state)
148 properties_to_create = []
149 properties_values_to_create = []
151 for key, schema in pinch_options[option_set].items():
152 property_info_data = get_property_fields(key, schema, property_set)
153 property_info, property_values = PropertyInfo.create(
154 **property_info_data,
155 flowsheet_state=flowsheet_state,
156 )
157 properties_to_create.append(property_info)
158 properties_values_to_create.extend(property_values)
159 tracked_bulk_create(PropertyInfo.objects, properties_to_create)
160 tracked_bulk_create(PropertyValue.objects, properties_values_to_create)
162 return property_set