Coverage for tests/cim_converter/unit/test_regulator_impedances.py: 100%

101 statements  

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

1import pytest 

2from cimgraph.data_profile import cimhub_2023 as cim 

3from distopf.cim_importer.processors.regulator_processor import RegulatorProcessor 

4 

5 

6def make_terminal(name: str): 

7 node = cim.ConnectivityNode(mRID=f"mrid_{name}", name=name) 

8 term = cim.Terminal(ConnectivityNode=node) 

9 node.Terminals = [term] 

10 return term 

11 

12 

13def make_tank_with_basevoltage(nominal_voltage: float = 480.0): 

14 # Construct without passing r/x into ctor, set attributes afterwards if needed 

15 base_voltage = cim.BaseVoltage(nominalVoltage=float(nominal_voltage)) 

16 tank_end = cim.TransformerTankEnd() 

17 tank_end.BaseVoltage = base_voltage 

18 tank_end.FromMeshImpedance = [] 

19 tank = cim.TransformerTank(name="tank_for_reg", TransformerTankEnds=[tank_end]) 

20 return tank 

21 

22 

23def test_regulator_impedance_from_mesh_on_powertransformerend(): 

24 reg_proc = RegulatorProcessor(1e6) 

25 t0 = make_terminal("frombus") 

26 t1 = make_terminal("tobus") 

27 tank = make_tank_with_basevoltage(480.0) 

28 # Create mesh impedance and assign to a PowerTransformerEnd after construction 

29 mesh_imp = cim.TransformerMeshImpedance() 

30 mesh_imp.r = 0.1 

31 mesh_imp.x = 0.2 

32 pte = cim.PowerTransformerEnd() 

33 pte.endNumber = 1 

34 pte.ratedU = 480.0 

35 pte.FromMeshImpedance = [mesh_imp] 

36 xfmr = cim.PowerTransformer( 

37 name="RegMesh", 

38 Terminals=[t0, t1], 

39 TransformerTanks=[tank], 

40 PowerTransformerEnd=[pte], 

41 ) 

42 

43 data = reg_proc._create_regulator_branch_entry(xfmr) 

44 v_base = float(tank.TransformerTankEnds[0].BaseVoltage.nominalVoltage) 

45 v_ln_base = v_base / (3**0.5) 

46 z_base = v_ln_base**2 / reg_proc.s_base 

47 expected_r = float(mesh_imp.r) / z_base 

48 expected_x = float(mesh_imp.x) / z_base 

49 assert pytest.approx(data["raa"], rel=1e-9) == expected_r 

50 assert pytest.approx(data["xaa"], rel=1e-9) == expected_x 

51 

52 

53def test_regulator_impedance_from_starimpedance_on_powertransformerend(): 

54 reg_proc = RegulatorProcessor(1e6) 

55 t0 = make_terminal("A") 

56 t1 = make_terminal("B") 

57 tank = make_tank_with_basevoltage(480.0) 

58 # Create star impedance and set on PowerTransformerEnd after instantiation 

59 star_imp = cim.TransformerStarImpedance() 

60 star_imp.r = 0.05 

61 star_imp.x = 0.07 

62 pte = cim.PowerTransformerEnd() 

63 pte.endNumber = 1 

64 pte.ratedU = 480.0 

65 pte.FromMeshImpedance = [] 

66 pte.StarImpedance = star_imp 

67 xfmr = cim.PowerTransformer( 

68 name="RegStar", 

69 Terminals=[t0, t1], 

70 TransformerTanks=[tank], 

71 PowerTransformerEnd=[pte], 

72 ) 

73 

74 data = reg_proc._create_regulator_branch_entry(xfmr) 

75 v_base = float(tank.TransformerTankEnds[0].BaseVoltage.nominalVoltage) 

76 v_ln_base = v_base / (3**0.5) 

77 z_base = v_ln_base**2 / reg_proc.s_base 

78 expected_r = float(star_imp.r) / z_base 

79 expected_x = float(star_imp.x) / z_base 

80 assert pytest.approx(data["raa"], rel=1e-9) == expected_r 

81 assert pytest.approx(data["xaa"], rel=1e-9) == expected_x 

82 

83 

84def test_regulator_impedance_from_direct_r_x_on_powertransformerend(): 

85 reg_proc = RegulatorProcessor(1e6) 

86 t0 = make_terminal("from") 

87 t1 = make_terminal("to") 

88 tank = make_tank_with_basevoltage(480.0) 

89 pte = cim.PowerTransformerEnd() 

90 pte.endNumber = 1 

91 pte.ratedU = 480.0 

92 # assign direct r/x attributes after creation 

93 pte.r = 0.02 

94 pte.x = 0.03 

95 pte.FromMeshImpedance = [] 

96 pte.StarImpedance = None 

97 xfmr = cim.PowerTransformer( 

98 name="RegDirect", 

99 Terminals=[t0, t1], 

100 TransformerTanks=[tank], 

101 PowerTransformerEnd=[pte], 

102 ) 

103 

104 data = reg_proc._create_regulator_branch_entry(xfmr) 

105 v_base = float(tank.TransformerTankEnds[0].BaseVoltage.nominalVoltage) 

106 v_ln_base = v_base / (3**0.5) 

107 z_base = v_ln_base**2 / reg_proc.s_base 

108 expected_r = float(pte.r) / z_base 

109 expected_x = float(pte.x) / z_base 

110 assert pytest.approx(data["raa"], rel=1e-9) == expected_r 

111 assert pytest.approx(data["xaa"], rel=1e-9) == expected_x 

112 

113 

114def test_regulator_tank_impedance_fallback_and_phases_and_names(): 

115 reg_proc = RegulatorProcessor(1e6) 

116 base_voltage = cim.BaseVoltage() 

117 base_voltage.nominalVoltage = 480.0 

118 # mesh impedance instance 

119 mesh_imp = cim.TransformerMeshImpedance() 

120 mesh_imp.r = 0.11 

121 mesh_imp.x = 0.22 

122 tank_end = cim.TransformerTankEnd() 

123 tank_end.BaseVoltage = base_voltage 

124 tank_end.FromMeshImpedance = [mesh_imp] 

125 tank_end.orderedPhases = None 

126 tank = cim.TransformerTank(name="tank_only", TransformerTankEnds=[tank_end]) 

127 data = reg_proc._create_regulator_branch_entry_from_tank(tank) 

128 v_base = float(tank_end.BaseVoltage.nominalVoltage) 

129 v_ln = v_base / (3**0.5) 

130 z_base = v_ln**2 / reg_proc.s_base 

131 expected_r = float(mesh_imp.r) / z_base 

132 expected_x = float(mesh_imp.x) / z_base 

133 assert pytest.approx(data["raa"], rel=1e-9) == expected_r 

134 assert pytest.approx(data["xaa"], rel=1e-9) == expected_x 

135 assert isinstance(data["phases"], str) 

136 assert "from_name" in data and "to_name" in data