Coverage for backend/django/core/auxiliary/models/Scenario.py: 100%
50 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-05-13 02:47 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-05-13 02:47 +0000
1from django.core.validators import MaxValueValidator, MinValueValidator
2from django.db import models
3from .PropertyInfo import PropertyInfo
4from .PropertyValue import PropertyValue
5from flowsheetInternals.unitops.models.SimulationObject import SimulationObject
7from core.managers import AccessControlManager
9class ScenarioTabTypeEnum(models.TextChoices):
11 SteadyState = "steady state"
12 MultiSteadyState = "mss"
13 Dynamic = "dynamic"
15class SolverOptionEnum(models.TextChoices):
16 Ipopt= "ipopt"
17 Ipopt_v2 = "ipopt_v2"
18 Ipopt_WaterTAP = "ipopt-watertap"
19 Bomin = "bonmin"
20 Petsc = "petsc"
23# Bound user-configurable solve timeouts to a range that is useful in practice:
24# short enough to stop obviously stuck solves quickly, but long enough to allow
25# legitimate large solves to finish without leaving them unbounded.
26SOLVE_TIMEOUT_MIN_SECONDS = 5
27SOLVE_TIMEOUT_MAX_SECONDS = 60 * 60
28SOLVE_TIMEOUT_DEFAULT_SECONDS = 300
32class Scenario(models.Model):
33 """
34 Stores all relevant information about an optimization
35 """
36 flowsheet = models.ForeignKey("Flowsheet", on_delete=models.CASCADE, related_name="Optimizations")
37 # owner of the optimization
38 simulationObject = models.ForeignKey(SimulationObject, on_delete=models.CASCADE, related_name="optimizations", null=True)
39 displayName = models.CharField(max_length=64, blank=True, default="Scenario")
40 enable_optimization = models.BooleanField(default=False)
41 enable_dynamics = models.BooleanField(default=False)
42 state_name = models.CharField(max_length=64, blank=True, choices=ScenarioTabTypeEnum.choices, default=ScenarioTabTypeEnum.SteadyState)
43 num_time_steps = models.IntegerField(default=1)
44 simulation_length = models.FloatField(default=1.0)
45 simulation_length_units = models.CharField(max_length=32, blank=True)
46 Uploaded_fileName = models.CharField(max_length=64, blank=True, default="No file Chosen")
47 enable_rating = models.BooleanField(default=False)
48 solver_option = models.CharField(max_length=64, blank=True, choices=SolverOptionEnum.choices, default=SolverOptionEnum.Ipopt)
49 solve_timeout_seconds = models.PositiveIntegerField(
50 default=SOLVE_TIMEOUT_DEFAULT_SECONDS,
51 validators=[
52 MinValueValidator(SOLVE_TIMEOUT_MIN_SECONDS),
53 MaxValueValidator(SOLVE_TIMEOUT_MAX_SECONDS),
54 ],
55 )
56 is_LiveData = models.BooleanField(default=False)
57 disable_initialization = models.BooleanField(default=False)
58 skip_initialization_for_units_with_initial_values = models.BooleanField(default=False)
59 send_solve_complete_email = models.BooleanField(default=False)
60 degreesOfFreedom : models.QuerySet["OptimizationDegreesOfFreedom"]
62 # expression to minimize or maximize
63 objective = models.ForeignKey(PropertyInfo, on_delete=models.SET_NULL, null=True)
64 # boolean to find minimum or maximum or the objective
65 minimize = models.BooleanField(default=True)
67 created_at = models.DateTimeField(auto_now_add=True)
69 objects = AccessControlManager()
75class OptimizationDegreesOfFreedom(models.Model):
76 flowsheet = models.ForeignKey("Flowsheet", on_delete=models.CASCADE, related_name="OptimizationDegreesOfFreedoms")
77 scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE, related_name="degreesOfFreedom", null=True)
78 propertyValue: PropertyValue = models.ForeignKey(PropertyValue, on_delete=models.CASCADE, null=True)
79 upper_bound = models.FloatField(null=True, blank=True)
80 lower_bound = models.FloatField(null=True, blank=True)
81 created_at = models.DateTimeField(auto_now_add=True)
82 objects = AccessControlManager()