Repository: NREL-Sienna/PowerSystems.jl
Pull request #1306: Changes for Transformer3W
Author: login: rbolgaryn
Created: 2025-03-19T20:26:23Z | Merged: 2025-03-26T04:00:37Z

We need some changes for Transformer3W functions to allow for its integration in PowerNetworkMatrices


Diff:
diff --git a/.github/workflows/cross-package-test.yml b/.github/workflows/cross-package-test.yml
index 19f55eb9ce..75f4872b25 100644
--- a/.github/workflows/cross-package-test.yml
+++ b/.github/workflows/cross-package-test.yml
@@ -14,7 +14,7 @@ jobs:
       matrix:
         julia-version: [1]
         os: [ubuntu-latest]
-        package_name: [PowerSimulations, PowerSystemCaseBuilder, PowerNetworkMatrices]
+        package_name: [PowerSimulations, PowerSystemCaseBuilder, PowerNetworkMatrices, PowerFlows]
     continue-on-error: true
     steps:
       - uses: actions/checkout@v2
diff --git a/src/data_format_conversions.jl b/src/data_format_conversions.jl
index 03f67c3410..096f75a659 100644
--- a/src/data_format_conversions.jl
+++ b/src/data_format_conversions.jl
@@ -176,6 +176,30 @@ function _convert_data!(
     return
 end
 
+function _convert_data!(
+    raw::Dict{String, Any},
+    ::Val{Symbol("4.0.0")},
+    ::Val{Symbol("5.0.0")},
+)
+    for component in raw["data"]["components"]
+        if component["__metadata__"]["type"] == "TwoTerminalHVDCLine"
+            component["__metadata__"]["type"] = "TwoTerminalGenericHVDCLine"
+            continue
+        end
+    end
+    return
+end
+
+function _convert_data!(
+    raw::Dict{String, Any},
+    from::Val,
+    ::Val{Symbol("5.0.0")},
+)
+    _convert_data!(raw, from, Val{Symbol("4.0.0")}())
+    _convert_data!(raw, Val{Symbol("4.0.0")}(), Val{Symbol("5.0.0")}())
+    return
+end
+
 # Conversions to occur immediately after the data is loaded from disk
 function pre_read_conversion!(raw)
     if VersionNumber(raw["data_format_version"]) < v"4.0.0"
diff --git a/src/models/supplemental_accessors.jl b/src/models/supplemental_accessors.jl
index 114df98a8c..ae64c86ea3 100644
--- a/src/models/supplemental_accessors.jl
+++ b/src/models/supplemental_accessors.jl
@@ -27,6 +27,23 @@ function get_series_susceptance(b::Union{PhaseShiftingTransformer, TapTransforme
     return y_a
 end
 
+"""
+Returns the series susceptance of a 3 winding transformer as three values 
+(for each of the 3 branches) following the convention
+in power systems to define susceptance as the inverse of the imaginary part of the impedance.
+"""
+function get_series_susceptance(b::Transformer3W)
+    Z1s = get_r_primary(b) + get_x_primary(b) * 1im
+    Z2s = get_r_secondary(b) + get_x_secondary(b) * 1im
+    Z3s = get_r_tertiary(b) + get_x_tertiary(b) * 1im
+
+    b1s = imag(1 / Z1s)
+    b2s = imag(1 / Z2s)
+    b3s = imag(1 / Z3s)
+
+    return (b1s, b2s, b3s)
+end
+
 get_series_admittance(b::ACBranch) = 1 / (get_r(b) + get_x(b) * 1im)
 
 """
diff --git a/src/parsers/power_models_data.jl b/src/parsers/power_models_data.jl
index 4e611d6c44..b94fb5a0b0 100644
--- a/src/parsers/power_models_data.jl
+++ b/src/parsers/power_models_data.jl
@@ -92,7 +92,11 @@ end
 Internal component name retreval from pm2ps_dict
 """
 function _get_pm_dict_name(device_dict::Dict)::String
-    if haskey(device_dict, "name")
+    if haskey(device_dict, "shunt_bus")
+        # With shunts, we have FixedAdmittance and SwitchedAdmittance types.
+        # To avoid potential name collision, we add the connected bus number to the name.
+        name = join(strip.(string.((device_dict["shunt_bus"], device_dict["name"]))), "-")
+    elseif haskey(device_dict, "name")
         name = string(device_dict["name"])
     elseif haskey(device_dict, "source_id")
         name = strip(join(string.(device_dict["source_id"]), "-"))
@@ -1094,8 +1098,7 @@ function read_switched_shunt!(
         d["name"] = get(d, "name", d_key)
         name = _get_name(d)
         bus = bus_number_to_bus[d["shunt_bus"]]
-        full_name = "$(d["shunt_bus"])_$(name)"
-        shunt = make_switched_shunt(full_name, d, bus)
+        shunt = make_switched_shunt(name, d, bus)
 
         add_component!(sys, shunt; skip_validation = SKIP_PM_VALIDATION)
     end
@@ -1128,8 +1131,7 @@ function read_shunt!(
         d["name"] = get(d, "name", d_key)
         name = _get_name(d)
         bus = bus_number_to_bus[d["shunt_bus"]]
-        full_name = "$(d["shunt_bus"])_$(name)"
-        shunt = make_shunt(full_name, d, bus)
+        shunt = make_shunt(name, d, bus)
 
         add_component!(sys, shunt; skip_validation = SKIP_PM_VALIDATION)
     end
diff --git a/test/test_parse_psse.jl b/test/test_parse_psse.jl
index 98b4c2cd7f..cba9860ec0 100644
--- a/test/test_parse_psse.jl
+++ b/test/test_parse_psse.jl
@@ -68,25 +68,26 @@ end
     @test length(get_components(Transformer3W, sys5)) == 5
 
     @info "Testing Switched Shunt Parsing"
-    @test get_available(get_component(SwitchedAdmittance, sys3, "1030_9")) == false
-    @test only(get_Y_increase(get_component(SwitchedAdmittance, sys3, "3147_42"))).im == 35
-    @test get_admittance_limits(get_component(SwitchedAdmittance, sys3, "3147_42")).min ==
+    @test get_available(get_component(SwitchedAdmittance, sys3, "1030-9")) == false
+    @test only(get_Y_increase(get_component(SwitchedAdmittance, sys3, "3147-42"))).im ==
+          0.35
+    @test get_admittance_limits(get_component(SwitchedAdmittance, sys3, "3147-42")).min ==
           1.03
-    @test only(get_number_of_steps(get_component(SwitchedAdmittance, sys3, "7075_119"))) ==
+    @test only(get_number_of_steps(get_component(SwitchedAdmittance, sys3, "7075-119"))) ==
           1
-    @test only(get_Y_increase(get_component(SwitchedAdmittance, sys3, "7075_119"))).im ==
-          342.5
+    @test only(get_Y_increase(get_component(SwitchedAdmittance, sys3, "7075-119"))).im ==
+          3.425
 
-    @test get_available(get_component(SwitchedAdmittance, sys4, "1005_2")) == true
-    @test get_Y(get_component(SwitchedAdmittance, sys4, "1005_2")) == 6im
-    @test get_admittance_limits(get_component(SwitchedAdmittance, sys4, "1005_2")).max ==
+    @test get_available(get_component(SwitchedAdmittance, sys4, "1005-2")) == true
+    @test get_Y(get_component(SwitchedAdmittance, sys4, "1005-2")) == 0.06im
+    @test get_admittance_limits(get_component(SwitchedAdmittance, sys4, "1005-2")).max ==
           1.045
-    @test only(get_Y_increase(get_component(SwitchedAdmittance, sys4, "1005_2"))).im == 6
+    @test only(get_Y_increase(get_component(SwitchedAdmittance, sys4, "1005-2"))).im == 0.06
 
     @test length(get_components(SwitchedAdmittance, sys4)) == 2
-    @test get_available(get_component(SwitchedAdmittance, sys4, "1003_1")) == true
-    @test get_Y(get_component(SwitchedAdmittance, sys4, "1003_1")) == 3.8im
-    @test get_admittance_limits(get_component(SwitchedAdmittance, sys4, "1003_1")).min ==
+    @test get_available(get_component(SwitchedAdmittance, sys4, "1003-1")) == true
+    @test get_Y(get_component(SwitchedAdmittance, sys4, "1003-1")) == 0.038im
+    @test get_admittance_limits(get_component(SwitchedAdmittance, sys4, "1003-1")).min ==
           0.95
 
     @info "Testing VSC Parser"


Reviews:
user: login: jd-lara
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T13:22:12Z
user: login: jd-lara
body: The changes to the parsing could generate problems with name collisions. Why did you remove the bus number from the name? 
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-25T13:23:43Z
user: login: rbolgaryn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T16:06:16Z
user: login: rbolgaryn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T20:49:06Z
user: login: jd-lara
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-26T04:00:29Z

Review comments:
diff_hunk: @@ -20,7 +20,7 @@ function _convert_data!(
             component["__metadata__"]["type"] = "ACBus"
             continue
         end
-        if component["__metadata__"]["type"] == "HVDCLine"
+        if component["__metadata__"]["type"] ⋹ ("HVDCLine", "TwoTerminalHVDCLine")
path: src/data_format_conversions.jl
user: login: jd-lara
body: Why this change? 
created_at: 2025-03-25T13:22:12Z
author_association: MEMBER
diff_hunk: @@ -20,7 +20,7 @@ function _convert_data!(
             component["__metadata__"]["type"] = "ACBus"
             continue
         end
-        if component["__metadata__"]["type"] == "HVDCLine"
+        if component["__metadata__"]["type"] ⋹ ("HVDCLine", "TwoTerminalHVDCLine")
path: src/data_format_conversions.jl
user: login: rbolgaryn
body: The TwoTerminalHVDCLine was renamed to TwoTerminalGenericHVDCLine
created_at: 2025-03-25T16:06:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -20,7 +20,7 @@ function _convert_data!(
             component["__metadata__"]["type"] = "ACBus"
             continue
         end
-        if component["__metadata__"]["type"] == "HVDCLine"
+        if component["__metadata__"]["type"] ⋹ ("HVDCLine", "TwoTerminalHVDCLine")
path: src/data_format_conversions.jl
user: login: rbolgaryn
body: This change was moved to a separate function for 5.0.0
created_at: 2025-03-25T20:49:06Z
author_association: CONTRIBUTOR

PR comments:
user: login: codecov[bot]
created_at: 2025-03-19T20:39:19Z
body: ## [Codecov](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna) Report
Attention: Patch coverage is `20.83333%` with `19 lines` in your changes missing coverage. Please review.
> Project coverage is 84.21%. Comparing base [(`663f8f7`)](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/commit/663f8f7a1d68e111e682ce9e5a5e90402d5bec2e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna) to head [(`d27dfe3`)](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/commit/d27dfe3a6ae6b51cb564509b0bbe2234cd2e98c8?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna).
> Report is 125 commits behind head on psy5.

| [Files with missing lines](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna) | Patch % | Lines |
|---|---|---|
| [src/data\_format\_conversions.jl](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?src=pr&el=tree&filepath=src%2Fdata_format_conversions.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna#diff-c3JjL2RhdGFfZm9ybWF0X2NvbnZlcnNpb25zLmps) | 0.00% | [11 Missing :warning: ](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna) |
| [src/models/supplemental\_accessors.jl](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?src=pr&el=tree&filepath=src%2Fmodels%2Fsupplemental_accessors.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna#diff-c3JjL21vZGVscy9zdXBwbGVtZW50YWxfYWNjZXNzb3JzLmps) | 0.00% | [8 Missing :warning: ](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna) |

:x: Your patch status has failed because the patch coverage (20.83%) is below the target coverage (70.00%). You can increase the patch coverage or adjust the [target](https://docs.codecov.com/docs/commit-status#target) coverage.

<details><summary>Additional details and impacted files</summary>


[![Impacted file tree graph](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306/graphs/tree.svg?width=650&height=150&src=pr&token=AEzJsDhpxL&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna)](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna)

```diff
@@            Coverage Diff             @@
##             psy5    #1306      +/-   ##
==========================================
- Coverage   84.31%   84.21%   -0.11%     
==========================================
  Files         188      188              
  Lines        8868     8880      +12     
==========================================
+ Hits         7477     7478       +1     
- Misses       1391     1402      +11     
```

| [Flag](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna) | Coverage Δ | |
|---|---|---|
| [unittests](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna) | `84.21% <20.83%> (-0.11%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Files with missing lines](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna) | Coverage Δ | |
|---|---|---|
| [src/parsers/power\_models\_data.jl](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?src=pr&el=tree&filepath=src%2Fparsers%2Fpower_models_data.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna#diff-c3JjL3BhcnNlcnMvcG93ZXJfbW9kZWxzX2RhdGEuamw=) | `91.44% <100.00%> (+0.02%)` | :arrow_up: |
| [src/models/supplemental\_accessors.jl](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?src=pr&el=tree&filepath=src%2Fmodels%2Fsupplemental_accessors.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna#diff-c3JjL21vZGVscy9zdXBwbGVtZW50YWxfYWNjZXNzb3JzLmps) | `36.73% <0.00%> (ø)` | |
| [src/data\_format\_conversions.jl](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306?src=pr&el=tree&filepath=src%2Fdata_format_conversions.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna#diff-c3JjL2RhdGFfZm9ybWF0X2NvbnZlcnNpb25zLmps) | `0.00% <0.00%> (ø)` | |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/NREL-Sienna/PowerSystems.jl/pull/1306/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NREL-Sienna)

</details>
<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
author_association: NONE
user: login: rbolgaryn
created_at: 2025-03-25T16:05:16Z
body: > The changes to the parsing could generate problems with name collisions. Why did you remove the bus number from the name?

The parsing for FixedAdmittance and SwitchedAdmittance for name was different. This way, it is consistent between FixedAdmittance and SwitchedAdmittance. 
author_association: CONTRIBUTOR
user: login: jd-lara
created_at: 2025-03-25T16:06:25Z
body: > > The changes to the parsing could generate problems with name collisions. Why did you remove the bus number from the name?
> 
> The parsing for FixedAdmittance and SwitchedAdmittance for name was different. This way, it is consistent between FixedAdmittance and SwitchedAdmittance.

Then add the bus number to the FixedAdmittance please 
author_association: MEMBER
user: login: rbolgaryn
created_at: 2025-03-25T16:51:21Z
body: > > > The changes to the parsing could generate problems with name collisions. Why did you remove the bus number from the name?
> > 
> > 
> > The parsing for FixedAdmittance and SwitchedAdmittance for name was different. This way, it is consistent between FixedAdmittance and SwitchedAdmittance.
> 
> Then add the bus number to the FixedAdmittance please

This broke the tests in PowerFlows. I will try modifying the function shunt_name_formatter and see if it works with PowerFlows
author_association: CONTRIBUTOR
user: login: rbolgaryn
created_at: 2025-03-25T20:48:17Z
body: I think the conversion functions are now defined properly for PSY5

The shunt naming convention is changed to have the connected bus, without breaking the tests in PowerFlows.
author_association: CONTRIBUTOR