Repository: e2nIEE/pandapower

Issue:
Minimal 1ph short circuit current
Hello,
is this feature gonna be implemented? It would be very useful in my opinion, in many practical application of protection selectivity  and sizing studies the most important short circuit currents to consider are:
- maximal 3ph (implemented)
- minimal 1ph (not implemented yet)

Thanks

Discussion:

Patch:
diff --git a/pandapower/pd2ppc.py b/pandapower/pd2ppc.py
index cba942b4..275dfa4a 100644
--- a/pandapower/pd2ppc.py
+++ b/pandapower/pd2ppc.py
@@ -3,24 +3,17 @@
 # Copyright (c) 2016-2020 by University of Kassel and Fraunhofer Institute for Energy Economics
 # and Energy System Technology (IEE), Kassel. All rights reserved.
 
-import copy
 import numpy as np
-import math
 import pandapower.auxiliary as aux
-import warnings
-from pandapower.build_branch import _initialize_branch_lookup,\
-_build_branch_ppc, _switch_branches, _branches_with_oos_buses,\
-_calc_tap_from_dataframe,_calc_nominal_ratio_from_dataframe,\
-_transformer_correction_factor
+from pandapower.build_branch import _switch_branches, _branches_with_oos_buses, _build_branch_ppc
 from pandapower.build_bus import _build_bus_ppc, _calc_pq_elements_and_add_on_ppc, \
 _calc_shunts_and_add_on_ppc, _add_gen_impedances_ppc, _add_motor_impedances_ppc
 from pandapower.build_gen import _build_gen_ppc, _check_voltage_setpoints_at_same_bus, \
     _check_voltage_angles_at_same_bus, _check_for_reference_bus
 from pandapower.opf.make_objective import _make_objective
 from pandapower.pypower.idx_area import PRICE_REF_BUS
-from pandapower.pypower.idx_brch import F_BUS, T_BUS, BR_STATUS, branch_cols, \
-    TAP, SHIFT, BR_R, BR_X, BR_B
-from pandapower.pypower.idx_bus import NONE, BUS_I, BUS_TYPE, BASE_KV, GS, BS
+from pandapower.pypower.idx_brch import F_BUS, T_BUS, BR_STATUS
+from pandapower.pypower.idx_bus import NONE, BUS_I, BUS_TYPE
 from pandapower.pypower.idx_gen import GEN_BUS, GEN_STATUS
 from pandapower.pypower.run_userfcn import run_userfcn
 
@@ -78,6 +71,7 @@ def _pd2ppc(net, sequence=None):
     # generate ppc['bus'] and the bus lookup
     _build_bus_ppc(net, ppc)
     if sequence == 0:
+        from pandapower.pd2ppc_zero import _add_ext_grid_sc_impedance_zero, _build_branch_ppc_zero
         # Adds external grid impedance for 3ph and sc calculations in ppc0
         _add_ext_grid_sc_impedance_zero(net, ppc)
         # Calculates ppc0 branch impedances from branch elements
@@ -311,346 +305,4 @@ def _init_lookup(net, lookup_name, pandapower_index, ppc_index):
     # update lookup
     lookup[pandapower_index] = ppc_index
 
-    aux._write_lookup_to_net(net, lookup_name, lookup)
-
-
-def _build_branch_ppc_zero(net, ppc):
-    """
-    Takes an empty ppc0 and puts zero sequence branch impedances. The branch
-    datatype will be np.complex 128 afterwards.
-
-    .. note:: The order of branches in the ppc is:
-            1. Lines
-            2. Transformers
-
-    **INPUT**:
-        **net** -The pandapower format network
-
-        **ppc** - The PYPOWER format network to fill in values
-
-    """
-    length = _initialize_branch_lookup(net)
-    lookup = net._pd2ppc_lookups["branch"]
-    mode = net._options["mode"]
-    ppc["branch"] = np.zeros(shape=(length, branch_cols), dtype=np.complex128)
-    if mode == "sc":
-        from pandapower.shortcircuit.idx_brch import branch_cols_sc
-        branch_sc = np.empty(shape=(length, branch_cols_sc), dtype=float)
-        branch_sc.fill(np.nan)
-        ppc["branch"] = np.hstack((ppc["branch"], branch_sc))
-    ppc["branch"][:, :13] = np.array([0, 0, 0, 0, 0, 250, 250, 250, 1, 0, \
-                                      1, -360, 360])
-    # Adds zero sequence impedances of lines in ppc0
-    _add_line_sc_impedance_zero(net, ppc)
-    # Adds zero sequence impedances of transformers in ppc0
-    _add_trafo_sc_impedance_zero(net, ppc)
-    if "trafo3w" in lookup:
-        raise NotImplementedError("Three winding transformers are not \
-                                  implemented for unbalanced calculations")
-
-
-def _add_trafo_sc_impedance_zero(net, ppc, trafo_df=None):
-    if trafo_df is None:
-        trafo_df = net["trafo"]
-    branch_lookup = net["_pd2ppc_lookups"]["branch"]
-    if not "trafo" in branch_lookup:
-        return
-    bus_lookup = net["_pd2ppc_lookups"]["bus"]
-    mode = net["_options"]["mode"]
-    f, t = branch_lookup["trafo"]
-    trafo_df["_ppc_idx"] = range(f, t)
-    bus_lookup = net["_pd2ppc_lookups"]["bus"]
-    buses_all, gs_all, bs_all = np.array([], dtype=int), np.array([]), \
-                                np.array([])
-    if not "vector_group" in trafo_df:
-        raise ValueError("Vector Group of transformer needs to be specified for zero \
-                         sequence modelling \n Try : net.trafo[\"vector_group\"] = 'Dyn'" )
-
-    for vector_group, trafos in trafo_df.groupby("vector_group"):
-        ppc_idx = trafos["_ppc_idx"].values.astype(int)
-        ppc["branch"][ppc_idx, BR_STATUS] = 0
-
-        if vector_group in ["Yy", "Yd", "Dy", "Dd"]:
-            continue
-
-        vk_percent = trafos["vk_percent"].values.astype(float)
-        vkr_percent = trafos["vkr_percent"].values.astype(float)
-        sn_mva = trafos["sn_mva"].values.astype(float)
-        # Just put pos seq parameter if zero seq parameter is zero
-        if not "vk0_percent" in trafos:
-            raise ValueError("Short circuit voltage of transformer Vk0 needs to be specified for zero \
-                             sequence modelling \n Try : net.trafo[\"vk0_percent\"] = net.trafo[\"vk_percent\"]" )
-        vk0_percent = trafos["vk0_percent"].values.astype(float) if \
-            trafos["vk0_percent"].values.astype(float).all() != 0. else \
-            trafos["vk_percent"].values.astype(float)
-        # Just put pos seq parameter if zero seq parameter is zero
-        if not "vkr0_percent" in trafos:
-            raise ValueError("Real part of short circuit voltage Vk0(Real) needs to be specified for transformer \
-                             modelling \n Try : net.trafo[\"vkr0_percent\"] = net.trafo[\"vkr_percent\"]" )        
-        vkr0_percent = trafos["vkr0_percent"].values.astype(float) if \
-            trafos["vkr0_percent"].values.astype(float).all() != 0. else \
-            trafos["vkr_percent"].values.astype(float)
-        lv_buses = trafos["lv_bus"].values.astype(int)
-        hv_buses = trafos["hv_bus"].values.astype(int)
-        lv_buses_ppc = bus_lookup[lv_buses]
-        hv_buses_ppc = bus_lookup[hv_buses]
-        if not "mag0_percent" in trafos:
-            # For Shell Type transformers vk0 = vk * 1
-            #        and mag0_percent = 10 ... 100  Zm0/ Zsc0
-            # --pg 50 DigSilent Power Factory Transformer manual
-            raise ValueError("Magnetizing impedance to vk0 ratio needs to be specified for transformer \
-                             modelling  \n Try : net.trafo[\"mag0_percent\"] = 100" )           
-        mag0_ratio = trafos.mag0_percent.values.astype(float)
-        if not "mag0_rx" in trafos:
-            raise ValueError("Magnetizing impedance R/X ratio needs to be specified for transformer \
-                             modelling \n Try : net.trafo[\"mag0_rx\"] = 0 " )        
-        mag0_rx = trafos["mag0_rx"].values.astype(float)
-        if not "si0_hv_partial" in trafos:
-            raise ValueError("Zero sequence short circuit impedance partition towards HV side needs to be specified for transformer \
-                             modelling \n Try : net.trafo[\"si0_hv_partial\"] = 0.9 " )          
-        si0_hv_partial = trafos.si0_hv_partial.values.astype(float)
-        parallel = trafos.parallel.values.astype(float)
-        in_service = trafos["in_service"].astype(int)
-
-        ppc["branch"][ppc_idx, F_BUS] = hv_buses_ppc
-        ppc["branch"][ppc_idx, T_BUS] = lv_buses_ppc
-
-        vn_trafo_hv, vn_trafo_lv, shift = _calc_tap_from_dataframe(net, trafos)
-        vn_lv = ppc["bus"][lv_buses_ppc, BASE_KV]
-        ratio = _calc_nominal_ratio_from_dataframe(ppc, trafos, vn_trafo_hv, \
-                                                   vn_trafo_lv, bus_lookup)
-        ppc["branch"][ppc_idx, TAP] = ratio
-        ppc["branch"][ppc_idx, SHIFT] = shift
-
-        # zero seq. transformer impedance
-        tap_lv = np.square(vn_trafo_lv / vn_lv) * net.sn_mva
-        if mode == 'pf_3ph':
-            # =============================================================================
-            #     Changing base from transformer base to Network base to get Zpu(Net)
-            #     Zbase = (kV).squared/S_mva
-            #     Zpu(Net)={Zpu(trafo) * Zb(trafo)} / {Zb(Net)}
-            #        Note:
-            #             Network base voltage is Line-Neutral voltage in each phase
-            #             Line-Neutral voltage= Line-Line Voltage(vn_lv) divided by sq.root(3)
-            # =============================================================================
-            tap_lv = np.square(vn_trafo_lv / vn_lv) * (3 * net.sn_mva)
-
-        z_sc = vk0_percent / 100. / sn_mva * tap_lv
-        r_sc = vkr0_percent / 100. / sn_mva * tap_lv
-        z_sc = z_sc.astype(float)
-        r_sc = r_sc.astype(float)
-        x_sc = np.sign(z_sc) * np.sqrt(z_sc ** 2 - r_sc ** 2)
-        z0_k = (r_sc + x_sc * 1j) / parallel
-        if mode == "sc":
-            from pandapower.shortcircuit.idx_bus import C_MAX
-            cmax = net._ppc["bus"][lv_buses_ppc, C_MAX]
-            kt = _transformer_correction_factor(vk_percent, vkr_percent, \
-                                                sn_mva, cmax)
-            z0_k *= kt
-        #        y0_k = 1 / z0_k   --- No longer needed since we are using Pi model
-        # =============================================================================
-        #       Transformer magnetising impedance for zero sequence
-        # =============================================================================
-        z_m = z_sc * mag0_ratio
-        x_m = z_m / np.sqrt(mag0_rx ** 2 + 1)
-        r_m = x_m * mag0_rx
-        r0_trafo_mag = r_m / parallel
-        x0_trafo_mag = x_m / parallel
-        z0_mag = r0_trafo_mag + x0_trafo_mag * 1j
-        # =============================================================================
-        #         Star - Delta conversion ( T model to Pi Model)
-        #      ----------- |__zc=ZAB__|-----------------
-        #            _|                   _|
-        #     za=ZAN|_|                  |_| zb=ZBN
-        #            |                    |
-        # =============================================================================
-        z1 = si0_hv_partial * z0_k
-        z2 = (1 - si0_hv_partial) * z0_k
-        z3 = z0_mag
-        z_temp = z1 * z2 + z2 * z3 + z1 * z3
-        za = z_temp / z2
-        zb = z_temp / z1
-        zc = z_temp / z3  # ZAB  Transfer impedance
-        YAB = 1 / zc.astype(complex)
-        YAN = 1 / za.astype(complex)
-        YBN = 1 / zb.astype(complex)
-        YAB_AN = 1 / (zc + za).astype(complex)  # Series conn YAB and YAN
-        YAB_BN = 1 / (zc + zb).astype(complex)  # Series conn YAB and YBN
-
-        if vector_group == "Dyn":
-            buses_all = np.hstack([buses_all, lv_buses_ppc])
-
-            y = (YAB + YBN).astype(complex) * int(ppc["baseMVA"])  # pi model
-            gs_all = np.hstack([gs_all, y.real * in_service])
-            bs_all = np.hstack([bs_all, y.imag * in_service])
-
-        elif vector_group == "YNd":
-            buses_all = np.hstack([buses_all, hv_buses_ppc])
-
-            #            gs_all = np.hstack([gs_all, y0_k.real*in_service])#T model
-            #            bs_all = np.hstack([bs_all, y0_k.imag*in_service])
-
-            y = (YAB_BN + YAN).astype(complex) * int(ppc["baseMVA"])  # pi model
-            gs_all = np.hstack([gs_all, y.real * in_service])
-            bs_all = np.hstack([bs_all, y.imag * in_service])
-
-        elif vector_group == "Yyn":
-            buses_all = np.hstack([buses_all, lv_buses_ppc])
-            #            y = 1/(z0_mag+z0_k).astype(complex)* int(ppc["baseMVA"])#T model
-
-            y = (YAB_AN + YBN).astype(complex) * int(ppc["baseMVA"])  # pi model
-            gs_all = np.hstack([gs_all, y.real * in_service])
-            bs_all = np.hstack([bs_all, y.imag * in_service])
-
-        elif vector_group == "YNyn":
-            ppc["branch"][ppc_idx, BR_STATUS] = in_service
-            # zc = ZAB
-            ppc["branch"][ppc_idx, BR_R] = zc.real
-            ppc["branch"][ppc_idx, BR_X] = zc.imag
-
-            buses_all = np.hstack([buses_all, hv_buses_ppc])
-            gs_all = np.hstack([gs_all, YAN.real * in_service \
-                                * int(ppc["baseMVA"])])
-            bs_all = np.hstack([bs_all, YAN.imag * in_service \
-                                * int(ppc["baseMVA"])])
-
-            buses_all = np.hstack([buses_all, lv_buses_ppc])
-            gs_all = np.hstack([gs_all, YBN.real * in_service \
-                                * int(ppc["baseMVA"])])
-            bs_all = np.hstack([bs_all, YBN.imag * in_service \
-                                * int(ppc["baseMVA"])])
-
-        elif vector_group == "YNy":
-            buses_all = np.hstack([buses_all, hv_buses_ppc])
-            #            y = 1/(z0_mag+z0_k).astype(complex)* int(ppc["baseMVA"])#T model
-            y = (YAB_BN + YAN).astype(complex) * int(ppc["baseMVA"])  # pi model
-            gs_all = np.hstack([gs_all, y.real * in_service])
-            bs_all = np.hstack([bs_all, y.imag * in_service])
-
-        elif vector_group == "Yzn":
-            buses_all = np.hstack([buses_all, lv_buses_ppc])
-            #            y = 1/(z0_mag+z0_k).astype(complex)* int(ppc["baseMVA"])#T model
-            #            y= (za+zb+zc)/((za+zc)*zb).astype(complex)* int(ppc["baseMVA"])#pi model
-            y = (YAB_AN + YBN).astype(complex) * int(ppc["baseMVA"])  # pi model
-            gs_all = np.hstack([gs_all, (1.1547) * y.real * in_service \
-                                * int(ppc["baseMVA"])])
-            bs_all = np.hstack([bs_all, (1.1547) * y.imag * in_service \
-                                * int(ppc["baseMVA"])])
-
-        elif vector_group[-1].isdigit():
-            raise ValueError("Unknown transformer vector group %s -\
-                             please specify vector group without \
-                             phase shift number. Phase shift can be \
-                             specified in net.trafo.shift_degree" % vector_group)
-        else:
-            raise ValueError("Transformer vector group %s is unknown\
-                    / not implemented for three phase load flow" % vector_group)
-
-    buses, gs, bs = aux._sum_by_group(buses_all, gs_all, bs_all)
-    ppc["bus"][buses, GS] += gs
-    ppc["bus"][buses, BS] += bs
-    del net.trafo["_ppc_idx"]
-
-
-def _add_ext_grid_sc_impedance_zero(net, ppc):
-    mode = net["_options"]["mode"]
-
-    if mode == "sc":
-        from pandapower.shortcircuit.idx_bus import C_MAX, C_MIN
-        case = net._options["case"]
-    else:
-        case = "max"
-    bus_lookup = net["_pd2ppc_lookups"]["bus"]
-    eg = net["ext_grid"][net._is_elements["ext_grid"]]
-    if len(eg) == 0:
-        return
-    eg_buses = eg.bus.values
-    eg_buses_ppc = bus_lookup[eg_buses]
-
-    if mode == "sc":
-        c = ppc["bus"][eg_buses_ppc, C_MAX] if case == "max" else \
-            ppc["bus"][eg_buses_ppc, C_MIN]
-    else:
-        c = 1.1
-    if not "s_sc_%s_mva" % case in eg:
-        raise ValueError("Short Circuit apparent power s_sc_%s_mva for zero sequence needs to be specified for "% case +
-                         "external grid \n Try: net.ext_grid['s_sc_max_mva'] = 1000" )
-    else:
-        s_sc = eg["s_sc_%s_mva" % case].values/ppc['baseMVA']
-    if not "rx_%s" % case in eg:
-        raise ValueError("Positive sequence short circuit R/X rate rx_%s needs to be specified\
-                         for external grid \n Try: net.ext_grid['rx_max'] = 0.1" % case)
-    rx = eg["rx_%s" % case].values
-    z_grid = c / s_sc
-    if mode == 'pf_3ph':
-        z_grid = c / (s_sc / 3)
-    x_grid = z_grid / np.sqrt(rx ** 2 + 1)
-    r_grid = rx * x_grid
-    eg["r"] = r_grid
-    eg["x"] = x_grid
-
-    if not "x0x_%s" % case in eg:
-        raise ValueError("Zero sequence to positive sequence reactance ratio x0x_%s needs to be specified for "% case +
-                         "external grid \n Try : net.ext_grid[\"x0x_max\"] = 1.0" )
-    if not "r0x0_%s" % case in eg:
-        raise ValueError("Zero sequence short circuit R0/X0 rate r0x0_%s needs to be specified\
-                         for external grid \n Try : net.ext_grid[\"r0x0_max\"] = 0.1" % case )
-
-    # ext_grid zero sequence impedance
-    if case == "max":
-        x0_grid = net.ext_grid["x0x_%s" % case] * x_grid
-        r0_grid = net.ext_grid["r0x0_%s" % case] * x0_grid
-    elif case == "min":
-        x0_grid = net.ext_grid["x0x_%s" % case] * x_grid
-        r0_grid = net.ext_grid["r0x0_%s" % case] * x0_grid
-    y0_grid = 1 / (r0_grid + x0_grid * 1j)
-    buses, gs, bs = aux._sum_by_group(eg_buses_ppc, np.real(np.array(y0_grid)), np.imag(np.array(y0_grid)))
-    ppc["bus"][buses, GS] = gs * ppc['baseMVA']
-    ppc["bus"][buses, BS] = bs * ppc['baseMVA']   
-
-def _add_line_sc_impedance_zero(net, ppc):
-    branch_lookup = net["_pd2ppc_lookups"]["branch"]
-    mode = net["_options"]["mode"]
-    if not "line" in branch_lookup:
-        return
-#    line = net["line"].loc[net._is_elements["line_is_idx"].values.tolist()]
-    line = net["line"]
-    bus_lookup = net["_pd2ppc_lookups"]["bus"]
-    length = line["length_km"].values
-    parallel = line["parallel"].values
-
-    fb = bus_lookup[line["from_bus"].values]
-    tb = bus_lookup[line["to_bus"].values]
-    baseR = np.square(ppc["bus"][fb, BASE_KV]) / net.sn_mva
-    if mode == 'pf_3ph':
-        baseR = np.square(ppc["bus"][fb, BASE_KV]) / (3 * net.sn_mva)
-    f, t = branch_lookup["line"]
-    # line zero sequence impedance
-    ppc["branch"][f:t, F_BUS] = fb
-    ppc["branch"][f:t, T_BUS] = tb
-    # Just putting pos seq resistance if zero seq resistance is zero 
-    if not "r0_ohm_per_km" in line:
-        raise ValueError("Zero sequence resistance R0 needs to be specified\
-                         for line \n Try : net.line[\"r0_ohm_per_km\"] = net.line[\"r_ohm_per_km\"].values * 4" )
-    ppc["branch"][f:t, BR_R] = line["r0_ohm_per_km"].values * length / baseR / parallel if \
-            line["r0_ohm_per_km"].values.all() != 0 else \
-            line["r_ohm_per_km"].values * 4 * length / baseR / parallel 
-    # Just putting pos seq inducatance if zero seq inductance is zero
-    if not "x0_ohm_per_km" in line:
-        raise ValueError("Zero sequence reactance X0 needs to be specified\
-                         for line \n Try : net.line[\"x0_ohm_per_km\"] = net.line[\"x_ohm_per_km\"].values * 4" )
-    ppc["branch"][f:t, BR_X] = \
-        line["x0_ohm_per_km"].values * length / baseR / parallel if \
-            line["x0_ohm_per_km"].values.all() != 0 else \
-            line["x_ohm_per_km"].values * 4 *  length / baseR / parallel
-    # Just putting pos seq capacitance if zero seq capacitance is zero
-    if not "c0_nf_per_km" in line:
-        raise ValueError("Zero sequence capacitance C0 needs to be specified\
-                         for line \n Try : net.line[\"c0_nf_per_km\"] = net.line[\"c_nf_per_km\"].values * 0.25" )
-    ppc["branch"][f:t, BR_B] = \
-        (2 * net["f_hz"] * math.pi * line["c0_nf_per_km"].values * 1e-9 * baseR \
-         * length * parallel) if \
-            line["c0_nf_per_km"].values.all() != 0 else \
-            (2 * net["f_hz"] * math.pi * (line["c_nf_per_km"].values * 0.25) * 1e-9 \
-             * baseR * length * parallel)
-    ppc["branch"][f:t, BR_STATUS] = line["in_service"].astype(int)
\ No newline at end of file
+    aux._write_lookup_to_net(net, lookup_name, lookup)
\ No newline at end of file
diff --git a/pandapower/pd2ppc_zero.py b/pandapower/pd2ppc_zero.py
index a850efbf..0609629b 100644
--- a/pandapower/pd2ppc_zero.py
+++ b/pandapower/pd2ppc_zero.py
@@ -5,20 +5,18 @@
 
 import math
 import numpy as np
-import copy
-import pandas as pd
-from packaging import version
 import pandapower.auxiliary as aux
-from pandapower.pd2ppc import _init_ppc
 from pandapower.build_bus import _build_bus_ppc
 from pandapower.build_gen import _build_gen_ppc
-from pandapower.pd2ppc import _ppc2ppci
+#from pandapower.pd2ppc import _ppc2ppci, _init_ppc
 from pandapower.pypower.idx_brch import BR_B, BR_R, BR_X, F_BUS, T_BUS, branch_cols, BR_STATUS, SHIFT, TAP
 from pandapower.pypower.idx_bus import BASE_KV, BS, GS
 from pandapower.build_branch import _calc_tap_from_dataframe, _transformer_correction_factor, _calc_nominal_ratio_from_dataframe
-from pandapower.build_branch import _switch_branches, _branches_with_oos_buses, _initialize_branch_lookup
+from pandapower.build_branch import _switch_branches, _branches_with_oos_buses, _initialize_branch_lookup, _end_temperature_correction_factor
 
 def _pd2ppc_zero(net, sequence=0):
+    from pandapower.pd2ppc import _ppc2ppci, _init_ppc
+
     """
     Builds the ppc data structure for zero impedance system. Includes the impedance values of
     lines and transformers, but no load or generation data.
@@ -77,7 +75,7 @@ def _build_branch_ppc_zero(net, ppc):
     _add_line_sc_impedance_zero(net, ppc)
     _add_trafo_sc_impedance_zero(net, ppc)
     if "trafo3w" in lookup:
-        raise NotImplemented("Three winding transformers are not implemented for unbalanced calculations")
+        raise NotImplementedError("Three winding transformers are not implemented for unbalanced calculations")
 
 
 def _add_trafo_sc_impedance_zero(net, ppc, trafo_df=None):
@@ -89,9 +87,14 @@ def _add_trafo_sc_impedance_zero(net, ppc, trafo_df=None):
     bus_lookup = net["_pd2ppc_lookups"]["bus"]
     mode = net["_options"]["mode"]
     f, t = branch_lookup["trafo"]
-    trafo_df["_ppc_idx"] = range(f,t)
+    trafo_df["_ppc_idx"] = range(f, t)
     bus_lookup = net["_pd2ppc_lookups"]["bus"]
-    buses_all, gs_all, bs_all = np.array([], dtype=int), np.array([]), np.array([])
+    buses_all, gs_all, bs_all = np.array([], dtype=int), np.array([]), \
+                                np.array([])
+    if not "vector_group" in trafo_df:
+        raise ValueError("Vector Group of transformer needs to be specified for zero \
+                         sequence modelling \n Try : net.trafo[\"vector_group\"] = 'Dyn'" )
+
     for vector_group, trafos in trafo_df.groupby("vector_group"):
         ppc_idx = trafos["_ppc_idx"].values.astype(int)
         ppc["branch"][ppc_idx, BR_STATUS] = 0
@@ -102,14 +105,38 @@ def _add_trafo_sc_impedance_zero(net, ppc, trafo_df=None):
         vk_percent = trafos["vk_percent"].values.astype(float)
         vkr_percent = trafos["vkr_percent"].values.astype(float)
         sn_mva = trafos["sn_mva"].values.astype(float)
-        vk0_percent = trafos["vk0_percent"].values.astype(float)
-        vkr0_percent = trafos["vkr0_percent"].values.astype(float)
+        # Just put pos seq parameter if zero seq parameter is zero
+        if not "vk0_percent" in trafos:
+            raise ValueError("Short circuit voltage of transformer Vk0 needs to be specified for zero \
+                             sequence modelling \n Try : net.trafo[\"vk0_percent\"] = net.trafo[\"vk_percent\"]" )
+        vk0_percent = trafos["vk0_percent"].values.astype(float) if \
+            trafos["vk0_percent"].values.astype(float).all() != 0. else \
+            trafos["vk_percent"].values.astype(float)
+        # Just put pos seq parameter if zero seq parameter is zero
+        if not "vkr0_percent" in trafos:
+            raise ValueError("Real part of short circuit voltage Vk0(Real) needs to be specified for transformer \
+                             modelling \n Try : net.trafo[\"vkr0_percent\"] = net.trafo[\"vkr_percent\"]" )        
+        vkr0_percent = trafos["vkr0_percent"].values.astype(float) if \
+            trafos["vkr0_percent"].values.astype(float).all() != 0. else \
+            trafos["vkr_percent"].values.astype(float)
         lv_buses = trafos["lv_bus"].values.astype(int)
         hv_buses = trafos["hv_bus"].values.astype(int)
         lv_buses_ppc = bus_lookup[lv_buses]
         hv_buses_ppc = bus_lookup[hv_buses]
+        if not "mag0_percent" in trafos:
+            # For Shell Type transformers vk0 = vk * 1
+            #        and mag0_percent = 10 ... 100  Zm0/ Zsc0
+            # --pg 50 DigSilent Power Factory Transformer manual
+            raise ValueError("Magnetizing impedance to vk0 ratio needs to be specified for transformer \
+                             modelling  \n Try : net.trafo[\"mag0_percent\"] = 100" )           
         mag0_ratio = trafos.mag0_percent.values.astype(float)
+        if not "mag0_rx" in trafos:
+            raise ValueError("Magnetizing impedance R/X ratio needs to be specified for transformer \
+                             modelling \n Try : net.trafo[\"mag0_rx\"] = 0 " )        
         mag0_rx = trafos["mag0_rx"].values.astype(float)
+        if not "si0_hv_partial" in trafos:
+            raise ValueError("Zero sequence short circuit impedance partition towards HV side needs to be specified for transformer \
+                             modelling \n Try : net.trafo[\"si0_hv_partial\"] = 0.9 " )          
         si0_hv_partial = trafos.si0_hv_partial.values.astype(float)
         parallel = trafos.parallel.values.astype(float)
         in_service = trafos["in_service"].astype(int)
@@ -119,86 +146,138 @@ def _add_trafo_sc_impedance_zero(net, ppc, trafo_df=None):
 
         vn_trafo_hv, vn_trafo_lv, shift = _calc_tap_from_dataframe(net, trafos)
         vn_lv = ppc["bus"][lv_buses_ppc, BASE_KV]
-        ratio = _calc_nominal_ratio_from_dataframe(ppc, trafos, vn_trafo_hv, vn_trafo_lv,
-                                                   bus_lookup)
+        ratio = _calc_nominal_ratio_from_dataframe(ppc, trafos, vn_trafo_hv, \
+                                                   vn_trafo_lv, bus_lookup)
         ppc["branch"][ppc_idx, TAP] = ratio
         ppc["branch"][ppc_idx, SHIFT] = shift
 
         # zero seq. transformer impedance
-        tap_lv = np.square(vn_trafo_lv / vn_lv) * net.sn_mva  # adjust for low voltage side voltage converter
+        tap_lv = np.square(vn_trafo_lv / vn_lv) * net.sn_mva
         if mode == 'pf_3ph':
-            tap_lv = np.square(vn_trafo_lv / vn_lv) * (3*net.sn_mva)  # adjust for low voltage side voltage converter
-                    
+            # =============================================================================
+            #     Changing base from transformer base to Network base to get Zpu(Net)
+            #     Zbase = (kV).squared/S_mva
+            #     Zpu(Net)={Zpu(trafo) * Zb(trafo)} / {Zb(Net)}
+            #        Note:
+            #             Network base voltage is Line-Neutral voltage in each phase
+            #             Line-Neutral voltage= Line-Line Voltage(vn_lv) divided by sq.root(3)
+            # =============================================================================
+            tap_lv = np.square(vn_trafo_lv / vn_lv) * (3 * net.sn_mva)
+
         z_sc = vk0_percent / 100. / sn_mva * tap_lv
         r_sc = vkr0_percent / 100. / sn_mva * tap_lv
         z_sc = z_sc.astype(float)
         r_sc = r_sc.astype(float)
-        x_sc = np.sign(z_sc) * np.sqrt(z_sc**2 - r_sc**2)
+        x_sc = np.sign(z_sc) * np.sqrt(z_sc ** 2 - r_sc ** 2)
         z0_k = (r_sc + x_sc * 1j) / parallel
         if mode == "sc":
             from pandapower.shortcircuit.idx_bus import C_MAX
             cmax = net._ppc["bus"][lv_buses_ppc, C_MAX]
-            kt = _transformer_correction_factor(vk_percent, vkr_percent, sn_mva, cmax)
+            kt = _transformer_correction_factor(vk_percent, vkr_percent, \
+                                                sn_mva, cmax)
             z0_k *= kt
-        y0_k = 1 / z0_k
-        # zero sequence transformer magnetising impedance
+            y0_k = 1 / z0_k
+        # =============================================================================
+        #       Transformer magnetising impedance for zero sequence
+        # =============================================================================
         z_m = z_sc * mag0_ratio
-        x_m = z_m / np.sqrt(mag0_rx**2 + 1)
+        x_m = z_m / np.sqrt(mag0_rx ** 2 + 1)
         r_m = x_m * mag0_rx
         r0_trafo_mag = r_m / parallel
         x0_trafo_mag = x_m / parallel
         z0_mag = r0_trafo_mag + x0_trafo_mag * 1j
+        # =============================================================================
+        #         Star - Delta conversion ( T model to Pi Model)
+        #      ----------- |__zc=ZAB__|-----------------
+        #            _|                   _|
+        #     za=ZAN|_|                  |_| zb=ZBN
+        #            |                    |
+        # =============================================================================
+        z1 = si0_hv_partial * z0_k
+        z2 = (1 - si0_hv_partial) * z0_k
+        z3 = z0_mag
+        z_temp = z1 * z2 + z2 * z3 + z1 * z3
+        za = z_temp / z2
+        zb = z_temp / z1
+        zc = z_temp / z3  # ZAB  Transfer impedance
+        YAB = 1 / zc.astype(complex)
+        YAN = 1 / za.astype(complex)
+        YBN = 1 / zb.astype(complex)
+        YAB_AN = 1 / (zc + za).astype(complex)  # Series conn YAB and YAN
+        YAB_BN = 1 / (zc + zb).astype(complex)  # Series conn YAB and YBN
 
         if vector_group == "Dyn":
             buses_all = np.hstack([buses_all, lv_buses_ppc])
-            gs_all = np.hstack([gs_all, y0_k.real*in_service* int(ppc["baseMVA"])])
-            bs_all = np.hstack([bs_all, y0_k.imag*in_service* int(ppc["baseMVA"])])
+            if mode == "sc":
+                y = y0_k # pi model
+            else:
+                y = (YAB + YBN).astype(complex) * int(ppc["baseMVA"])  # T model
+            gs_all = np.hstack([gs_all, y.real * in_service])
+            bs_all = np.hstack([bs_all, y.imag * in_service])
 
         elif vector_group == "YNd":
             buses_all = np.hstack([buses_all, hv_buses_ppc])
-            gs_all = np.hstack([gs_all, y0_k.real*in_service* int(ppc["baseMVA"])])
-            bs_all = np.hstack([bs_all, y0_k.imag*in_service* int(ppc["baseMVA"])])
+            if mode == "sc":
+                y = y0_k # pi model
+            else:
+                y = (YAB_BN + YAN).astype(complex) * int(ppc["baseMVA"]) #T model
+            gs_all = np.hstack([gs_all, y.real * in_service])
+            bs_all = np.hstack([bs_all, y.imag * in_service])
 
         elif vector_group == "Yyn":
             buses_all = np.hstack([buses_all, lv_buses_ppc])
-            y = 1/(z0_mag+z0_k).astype(complex)* int(ppc["baseMVA"])
-            gs_all = np.hstack([gs_all, y.real*in_service])
-            bs_all = np.hstack([bs_all, y.imag*in_service])
+            if mode == "sc":
+                y = 1/(z0_mag+z0_k).astype(complex)* int(ppc["baseMVA"]) #pi model
+            else:
+                y = (YAB_AN + YBN).astype(complex) * int(ppc["baseMVA"]) #T model
+            gs_all = np.hstack([gs_all, y.real * in_service])
+            bs_all = np.hstack([bs_all, y.imag * in_service])
 
         elif vector_group == "YNyn":
             ppc["branch"][ppc_idx, BR_STATUS] = in_service
-            # convert the t model to pi model
-            z1 = si0_hv_partial * z0_k
-            z2 = (1 - si0_hv_partial) * z0_k
-            z3 = z0_mag
-
-            z_temp = z1*z2 + z2*z3 + z1*z3
-            za = z_temp / z2
-            zb = z_temp / z1
-            zc = z_temp / z3
-            ya = 1/za
-            yb = 1/zb                
+            # zc = ZAB
             ppc["branch"][ppc_idx, BR_R] = zc.real
             ppc["branch"][ppc_idx, BR_X] = zc.imag
 
             buses_all = np.hstack([buses_all, hv_buses_ppc])
-            gs_all = np.hstack([gs_all, ya.real * in_service * int(ppc["baseMVA"])])
-            bs_all = np.hstack([bs_all, ya.imag * in_service * int(ppc["baseMVA"])])
-            
-                                       
+            gs_all = np.hstack([gs_all, YAN.real * in_service \
+                                * int(ppc["baseMVA"])])
+            bs_all = np.hstack([bs_all, YAN.imag * in_service \
+                                * int(ppc["baseMVA"])])
+
             buses_all = np.hstack([buses_all, lv_buses_ppc])
-            gs_all = np.hstack([gs_all, yb.real * in_service * int(ppc["baseMVA"])])
-            bs_all = np.hstack([bs_all, yb.imag * in_service * int(ppc["baseMVA"])])
+            gs_all = np.hstack([gs_all, YBN.real * in_service \
+                                * int(ppc["baseMVA"])])
+            bs_all = np.hstack([bs_all, YBN.imag * in_service \
+                                * int(ppc["baseMVA"])])
 
         elif vector_group == "YNy":
             buses_all = np.hstack([buses_all, hv_buses_ppc])
-            y = 1 / (z0_mag+z0_k).astype(complex)* int(ppc["baseMVA"])
-            gs_all = np.hstack([gs_all, y.real*in_service])
-            bs_all = np.hstack([bs_all, y.imag*in_service])
+            if mode == "sc":
+                y = 1/(z0_mag+z0_k).astype(complex)* int(ppc["baseMVA"])#pi model
+            else:
+                y = (YAB_BN + YAN).astype(complex) * int(ppc["baseMVA"])  # pi model
+            gs_all = np.hstack([gs_all, y.real * in_service])
+            bs_all = np.hstack([bs_all, y.imag * in_service])
+
+        elif vector_group == "Yzn":
+            buses_all = np.hstack([buses_all, lv_buses_ppc])
+            #            y = 1/(z0_mag+z0_k).astype(complex)* int(ppc["baseMVA"])#T model
+            #            y= (za+zb+zc)/((za+zc)*zb).astype(complex)* int(ppc["baseMVA"])#pi model
+            y = (YAB_AN + YBN).astype(complex) * int(ppc["baseMVA"])  # pi model
+            gs_all = np.hstack([gs_all, (1.1547) * y.real * in_service \
+                                * int(ppc["baseMVA"])])
+            bs_all = np.hstack([bs_all, (1.1547) * y.imag * in_service \
+                                * int(ppc["baseMVA"])])
+
         elif vector_group[-1].isdigit():
-            raise ValueError("Unknown transformer vector group %s - please specify vector group without phase shift number. Phase shift can be specified in net.trafo.shift_degree"%vector_group)
+            raise ValueError("Unknown transformer vector group %s -\
+                             please specify vector group without \
+                             phase shift number. Phase shift can be \
+                             specified in net.trafo.shift_degree" % vector_group)
         else:
-            raise ValueError("Transformer vector group %s is unknown / not implemented"%vector_group)
+            raise ValueError("Transformer vector group %s is unknown\
+                    / not implemented for three phase load flow" % vector_group)
 
     buses, gs, bs = aux._sum_by_group(buses_all, gs_all, bs_all)
     ppc["bus"][buses, GS] += gs
@@ -275,6 +354,10 @@ def _add_line_sc_impedance_zero(net, ppc):
     ppc["branch"][f:t, F_BUS] = fb
     ppc["branch"][f:t, T_BUS] = tb
     ppc["branch"][f:t, BR_R] = line["r0_ohm_per_km"].values * length / baseR / parallel
+    if mode == "sc":
+        # temperature correction
+        if net["_options"]["case"] == "min":
+            ppc["branch"][f:t, BR_R] *= _end_temperature_correction_factor(net, short_circuit=True)
     ppc["branch"][f:t, BR_X] = line["x0_ohm_per_km"].values * length / baseR / parallel
     ppc["branch"][f:t, BR_B] = (2 * net["f_hz"] * math.pi * line["c0_nf_per_km"].values * 1e-9 * baseR * length * parallel)
     ppc["branch"][f:t, BR_STATUS] = line["in_service"].astype(int)
\ No newline at end of file
diff --git a/pandapower/shortcircuit/calc_sc.py b/pandapower/shortcircuit/calc_sc.py
index e0995a08..3225c85d 100644
--- a/pandapower/shortcircuit/calc_sc.py
+++ b/pandapower/shortcircuit/calc_sc.py
@@ -125,8 +125,6 @@ def calc_sc(net, fault="3ph", case='max', lv_tol_percent=10, topology="auto", ip
     if fault == "2ph":
         _calc_sc(net)
     if fault == "1ph":
-        if case == "min":
-            raise NotImplementedError("Minimum 1ph short-circuits are not yet implemented")
         _calc_sc_1ph(net)
 
 
diff --git a/pandapower/std_types.py b/pandapower/std_types.py
index d1d013e2..934eca64 100644
--- a/pandapower/std_types.py
+++ b/pandapower/std_types.py
@@ -334,6 +334,7 @@ def add_zero_impedance_parameters(net):
     parameter_from_std_type(net, "c0_nf_per_km")
     parameter_from_std_type(net, "r0_ohm_per_km")
     parameter_from_std_type(net, "x0_ohm_per_km")
+    parameter_from_std_type(net, "endtemp_degree")
 
 
 def add_temperature_coefficient(net, fill=None):


Test patch:
diff --git a/pandapower/test/shortcircuit/test_1ph.py b/pandapower/test/shortcircuit/test_1ph.py
index 5d3865dd..782b4786 100644
--- a/pandapower/test/shortcircuit/test_1ph.py
+++ b/pandapower/test/shortcircuit/test_1ph.py
@@ -6,7 +6,6 @@
 import pandapower as pp
 import pandapower.shortcircuit as sc
 import pandapower.test
-import copy
 import numpy as np
 import os
 import pytest
@@ -24,10 +23,13 @@ def add_network(net, vector_group):
     b4 = pp.create_bus(net, 20, zone=vector_group)
     pp.create_bus(net, 20)
 
-    pp.create_ext_grid(net, b1, s_sc_max_mva=100, s_sc_min_mva=80, rx_min=0.20, rx_max=0.35)
+    pp.create_ext_grid(net, b1, s_sc_max_mva=100, s_sc_min_mva=100, rx_min=0.35, rx_max=0.35)
     net.ext_grid["r0x0_max"] = 0.4
     net.ext_grid["x0x_max"] = 1.0
-
+    
+    net.ext_grid["r0x0_min"] = 0.4
+    net.ext_grid["x0x_min"] = 1.0
+    
     pp.create_std_type(net, {"r_ohm_per_km": 0.122, "x_ohm_per_km": 0.112, "c_nf_per_km": 304,
                          "max_i_ka": 0.421, "endtemp_degree": 70.0, "r0_ohm_per_km": 0.244,
                          "x0_ohm_per_km": 0.336, "c0_nf_per_km": 2000}, "unsymmetric_line_type")
@@ -62,6 +64,7 @@ def test_1ph_shortcircuit():
                 ,"Dyn": [0.52209347337, 3.5054043285,  2.1086590382,  1.2980120038 ]
                 ,"Dd":  [0.52209347337, 0.74400073149, 0.74563682772, 0.81607276962]
                }
+
     net = pp.create_empty_network()
     for vc in results.keys():
          add_network(net, vc)
@@ -73,6 +76,30 @@ def test_1ph_shortcircuit():
     for vc, result in results.items():
         check_results(net, vc, result)
 
+def test_1ph_shortcircuit_min():
+    results = {
+                 "Yy":  [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174]
+                ,"Yyn": [0.52209346201, 2.4135757259, 1.545054139, 0.99373917957]
+                ,"Yd":  [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174]
+                ,"YNy": [0.62316686505, 0.66632662571, 0.66756160176, 0.72517293174]
+                ,"YNyn":[0.620287259, 2.9155736491, 1.7561556936, 1.0807305212]
+                ,"YNd": [0.75434229157, 0.66632662571, 0.66756160176, 0.72517293174]
+                ,"Dy":  [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174]
+                ,"Dyn": [0.52209346201, 3.4393798093, 1.9535982949, 1.1558364456]
+                ,"Dd":  [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174]
+               }
+
+    net = pp.create_empty_network()
+    for vc in results.keys():
+         add_network(net, vc)
+         try:
+             sc.calc_sc(net, fault="1ph", case="min")
+         except:
+             raise UserWarning("Did not converge after adding transformer with vector group %s"%vc)
+
+    for vc, result in results.items():
+        check_results(net, vc, result)
+
 def test_iec60909_example_4():
     file = os.path.join(pp.pp_dir, "test", "test_files", "IEC60909-4_example.json")
     net = pp.from_json(file)
@@ -97,4 +124,4 @@ def test_1ph_with_switches():
     check_results(net, vc, [0.52209347338, 2.0620266652, 2.3255761263, 2.3066467489])
 
 if __name__ == "__main__":
-    pytest.main([__file__])
+    pytest.main([__file__])
\ No newline at end of file