Coverage for src/distopf/pyomo_models/results.py: 94%

33 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-11-13 17:34 -0800

1import pandas as pd 

2import pyomo.environ as pyo 

3from math import sqrt 

4from distopf.pyomo_models.protocol import LindistModelProtocol 

5 

6 

7class OpfResult: 

8 def __init__(self, model: pyo.ConcreteModel | LindistModelProtocol): 

9 self.voltages = get_voltages(model.v2) 

10 vars = [ 

11 att 

12 for att in model.__dict__.keys() 

13 if isinstance(getattr(model, att), pyo.Var) 

14 ] 

15 for var in vars: 

16 setattr(self, var, get_values(getattr(model, var))) 

17 

18 

19def get_values(var: pyo.Var): 

20 df = get_values_tidy(var) 

21 df = df.pivot( 

22 index=["id", "name", "t"], columns="phase", values="value" 

23 ).reset_index() 

24 df.columns.name = None 

25 return df 

26 

27 

28def get_values_tidy_3ph(var: pyo.Var): 

29 return pd.DataFrame( 

30 data=[ 

31 [_id, var.model().name_map[_id], t, _ph, _val] 

32 for (_id, _ph, t), _val in var.extract_values().items() 

33 ], 

34 columns=["id", "name", "t", "phase", "value"], 

35 ) 

36 

37 

38def get_values_1ph(var: pyo.Var): 

39 return pd.DataFrame( 

40 data=[ 

41 [_id, var.model().name_map[_id], t, _val] 

42 for (_id, t), _val in var.extract_values().items() 

43 ], 

44 columns=["id", "name", "t", "value"], 

45 ) 

46 

47 

48def get_values_tidy(var: pyo.Var): 

49 if var.name == "v2": 

50 return pd.DataFrame( 

51 data=[ 

52 [_id, var.model().name_map[_id], t, _ph, sqrt(_val)] 

53 for (_id, _ph, t), _val in var.extract_values().items() 

54 ], 

55 columns=["id", "name", "t", "phase", "value"], 

56 ) 

57 if var.dim() == 2: 

58 return pd.DataFrame( 

59 data=[ 

60 [_id, var.model().name_map[_id], t, "value", _val] 

61 for (_id, t), _val in var.extract_values().items() 

62 ], 

63 columns=["id", "name", "t", "phase", "value"], 

64 ) 

65 if var.dim() == 3: 

66 return pd.DataFrame( 

67 data=[ 

68 [_id, var.model().name_map[_id], t, _ph, _val] 

69 for (_id, _ph, t), _val in var.extract_values().items() 

70 ], 

71 columns=["id", "name", "t", "phase", "value"], 

72 ) 

73 return pd.DataFrame(columns=["id", "name", "t", "phase", "value"]) 

74 

75 

76def get_voltages(var: pyo.Var) -> pd.DataFrame: 

77 """ 

78 Extract voltage magnitudes from solved Pyomo model. 

79 

80 Parameters 

81 ---------- 

82 model : pyo.ConcreteModel 

83 Solved Pyomo model with voltage variables 

84 bus_data : pd.DataFrame 

85 Bus data for getting bus names 

86 

87 Returns 

88 ------- 

89 pd.DataFrame 

90 DataFrame with columns ["id", "name", "a", "b", "c"] containing 

91 voltage magnitudes (not squared) 

92 """ 

93 v = get_values_tidy_3ph(var) 

94 v["value"] = v.value.map(sqrt) 

95 v = v.pivot( 

96 index=["id", "name", "t"], columns="phase", values="value" 

97 ).reset_index() 

98 v.columns.name = None 

99 return v