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

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 

6 

7from core.managers import AccessControlManager 

8 

9class ScenarioTabTypeEnum(models.TextChoices): 

10 

11 SteadyState = "steady state" 

12 MultiSteadyState = "mss" 

13 Dynamic = "dynamic" 

14 

15class SolverOptionEnum(models.TextChoices): 

16 Ipopt= "ipopt" 

17 Ipopt_v2 = "ipopt_v2" 

18 Ipopt_WaterTAP = "ipopt-watertap" 

19 Bomin = "bonmin" 

20 Petsc = "petsc" 

21 

22 

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 

29 

30 

31 

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"] 

61 

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) 

66 

67 created_at = models.DateTimeField(auto_now_add=True) 

68 

69 objects = AccessControlManager() 

70 

71 

72 

73 

74 

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() 

83 

84