Beispiel #1
0
    def __init__(self):
        self.solver = KLUSolver()
        self.converter = PandaPowerConverter()
        self.ppci = None
        self.V = None
        self.Ybus = None
        self.pv = None
        self.pq = None

        # TODO
        self.ppci = None
        self.Ybus = None
        self.Yf = None
        self.Yt = None
        self.bus = None
        self.gen = None
        self.branch = None
        self.ref = None
        self.pv = None
        self.pq = None
        self.ref_gens = None
        self.baseMVA = None
        raise RuntimeError("This module is deprecated.")
 def setUp(self):
     self.converter = PandaPowerConverter()
     self.tol = 1e-8
class MakeTests(unittest.TestCase):
    def setUp(self):
        self.converter = PandaPowerConverter()
        self.tol = 1e-8

    def assert_equal(self, tmp, ref):
        assert np.max(np.abs(tmp - ref)) <= self.tol
        assert np.sum(np.abs(tmp - ref)) <= tmp.shape[0] * self.tol

    def test_case6_data(self):
        net = pn.case6ww()
        self.converter.set_sn_mva(
            net.sn_mva)  # TODO raise an error if not set !
        self.converter.set_f_hz(net.f_hz)
        line_r, line_x, line_h = self.converter.get_line_param(
            net.line["r_ohm_per_km"].values * net.line["length_km"].values,
            net.line["x_ohm_per_km"].values * net.line["length_km"].values,
            net.line["c_nf_per_km"].values * net.line["length_km"].values,
            net.line["g_us_per_km"].values * net.line["length_km"].values,
            net.bus.loc[net.line["from_bus"]]["vn_kv"],
            net.bus.loc[net.line["to_bus"]]["vn_kv"])
        res_r = np.array([
            0.001, 0.0005, 0.001, 0.0008, 0.0005, 0.0005, 0.001, 0.0007,
            0.0012, 0.0002, 0.002
        ])
        res_x = np.array([
            0.002, 0.002, 0.003, 0.003, 0.0025, 0.001, 0.003, 0.002, 0.0026,
            0.001, 0.004
        ])
        res_h = np.array([
            4. + 0.j, 4. + 0.j, 6. + 0.j, 6. + 0.j, 6. + 0.j, 2. + 0.j,
            4. + 0.j, 5. + 0.j, 5. + 0.j, 2. + 0.j, 8. + 0.j
        ])
        self.assert_equal(line_r, res_r)
        self.assert_equal(line_x, res_x)
        self.assert_equal(line_h, res_h)

    def test_case30_data(self):
        net = pn.case30()
        self.converter.set_sn_mva(
            net.sn_mva)  # TODO raise an error if not set !
        self.converter.set_f_hz(net.f_hz)
        line_r, line_x, line_h = self.converter.get_line_param(
            net.line["r_ohm_per_km"].values * net.line["length_km"].values,
            net.line["x_ohm_per_km"].values * net.line["length_km"].values,
            net.line["c_nf_per_km"].values * net.line["length_km"].values,
            net.line["g_us_per_km"].values * net.line["length_km"].values,
            net.bus.loc[net.line["from_bus"]]["vn_kv"],
            net.bus.loc[net.line["to_bus"]]["vn_kv"])
        res_r = np.array([
            0.0002, 0.0005, 0., 0., 0., 0., 0., 0., 0.0012, 0.0007, 0.0009,
            0.0022, 0.0006, 0.0008, 0.0011, 0.0006, 0.0003, 0.0009, 0.0003,
            0.0003, 0.0007, 0.0001, 0.001, 0.0001, 0.0012, 0.0013, 0.0019,
            0.0025, 0.0011, 0., 0.0022, 0.0032, 0.0024, 0.0006, 0.0005, 0.0002,
            0.0006, 0.0001, 0.0005, 0.0003, 0.0001
        ])
        res_x = np.array([
            0.0006, 0.0019, 0.0021, 0.0056, 0.0021, 0.0011, 0.0026, 0.0014,
            0.0026, 0.0013, 0.002, 0.002, 0.0017, 0.0019, 0.0022, 0.0013,
            0.0007, 0.0021, 0.0008, 0.0007, 0.0015, 0.0002, 0.002, 0.0004,
            0.0018, 0.0027, 0.0033, 0.0038, 0.0021, 0.004, 0.0042, 0.006,
            0.0045, 0.002, 0.002, 0.0006, 0.0018, 0.0004, 0.0012, 0.0008,
            0.0004
        ])
        res_h = np.array([
            3. + 0.j, 2. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
            0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
            2. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
            0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
            0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
            0. + 0.j, 0. + 0.j, 0. + 0.j, 2. + 0.j, 2. + 0.j, 1. + 0.j,
            2. + 0.j, 0. + 0.j, 1. + 0.j, 1. + 0.j, 0. + 0.j
        ])
        self.assert_equal(line_r, res_r)
        self.assert_equal(line_x, res_x)
        self.assert_equal(line_h, res_h)

    def test_case118_data(self):
        net = pn.case118()
        self.converter.set_sn_mva(
            net.sn_mva)  # TODO raise an error if not set !
        self.converter.set_f_hz(net.f_hz)
        line_r, line_x, line_h = self.converter.get_line_param(
            net.line["r_ohm_per_km"].values * net.line["length_km"].values,
            net.line["x_ohm_per_km"].values * net.line["length_km"].values,
            net.line["c_nf_per_km"].values * net.line["length_km"].values,
            net.line["g_us_per_km"].values * net.line["length_km"].values,
            net.bus.loc[net.line["from_bus"]]["vn_kv"],
            net.bus.loc[net.line["to_bus"]]["vn_kv"])
        res_r = np.array([
            3.030e-04, 1.290e-04, 5.950e-05, 8.820e-05, 4.880e-04, 4.460e-04,
            8.660e-05, 4.010e-04, 4.280e-04, 4.050e-04, 1.230e-04, 4.440e-04,
            3.090e-04, 1.870e-04, 6.010e-04, 3.760e-05, 5.460e-05, 1.700e-04,
            2.940e-04, 1.560e-04, 2.980e-04, 1.120e-04, 6.250e-04, 4.300e-04,
            4.840e-04, 3.020e-04, 3.500e-04, 2.000e-04, 2.390e-04, 1.390e-04,
            5.180e-04, 2.380e-04, 2.540e-04, 9.900e-05, 3.930e-04, 8.620e-05,
            3.870e-04, 2.580e-04, 4.810e-04, 2.230e-04, 1.320e-04, 3.560e-04,
            1.620e-04, 2.690e-04, 1.830e-04, 2.380e-04, 2.225e-04, 4.540e-04,
            6.480e-04, 1.780e-04, 1.710e-04, 1.730e-04, 3.970e-04, 1.800e-04,
            2.770e-04, 1.230e-04, 2.460e-04, 2.150e-04, 1.600e-04, 4.510e-04,
            4.660e-04, 5.350e-04, 6.050e-04, 9.940e-05, 1.400e-04, 5.300e-04,
            2.610e-04, 5.300e-04, 7.440e-04, 1.050e-04, 3.906e-04, 2.780e-04,
            2.200e-04, 2.470e-04, 9.130e-05, 6.150e-04, 1.350e-04, 1.640e-04,
            2.300e-05, 5.950e-04, 3.290e-04, 1.450e-04, 1.640e-04, 2.120e-04,
            1.320e-04, 1.760e-05, 4.540e-04, 1.230e-04, 1.119e-04, 2.520e-04,
            1.200e-04, 1.830e-04, 2.090e-04, 3.420e-04, 1.350e-04, 1.560e-04,
            2.410e-04, 3.180e-04, 1.913e-04, 2.370e-04, 4.310e-05, 7.990e-05,
            4.740e-04, 1.080e-04, 3.170e-04, 2.980e-04, 2.290e-04, 1.190e-04,
            3.800e-04, 7.520e-04, 2.240e-05, 1.100e-04, 4.150e-04, 8.710e-05,
            2.560e-05, 3.210e-04, 5.930e-04, 4.640e-05, 4.590e-05, 1.840e-04,
            1.450e-04, 5.550e-04, 4.100e-04, 6.080e-04, 4.130e-04, 2.240e-04,
            4.000e-04, 3.800e-04, 6.010e-04, 2.440e-05, 1.910e-04, 7.150e-04,
            7.150e-04, 6.840e-04, 1.790e-04, 2.670e-04, 4.860e-04, 2.030e-04,
            4.050e-04, 2.630e-04, 2.580e-05, 7.300e-04, 8.690e-04, 1.690e-04,
            2.750e-05, 4.880e-05, 3.430e-04, 4.740e-04, 3.430e-04, 2.550e-04,
            5.030e-04, 2.090e-04, 8.250e-04, 8.030e-04, 4.739e-04, 3.170e-04,
            3.280e-04, 2.640e-05, 1.230e-04, 8.240e-05, 1.720e-05, 9.010e-05,
            2.030e-04, 2.690e-05, 1.800e-04, 1.800e-04, 4.820e-04, 2.580e-04,
            2.240e-04, 8.440e-04, 9.850e-04, 3.000e-04, 2.210e-05
        ])
        res_x = np.array([
            9.990e-04, 4.240e-04, 1.960e-04, 3.550e-04, 1.960e-03, 1.800e-03,
            4.540e-04, 1.323e-03, 1.410e-03, 1.220e-03, 4.060e-04, 1.480e-03,
            1.010e-03, 6.160e-04, 1.999e-03, 1.240e-04, 2.440e-04, 4.850e-04,
            1.050e-03, 7.040e-04, 8.530e-04, 3.665e-04, 1.320e-03, 1.480e-03,
            1.600e-03, 6.410e-04, 1.230e-03, 1.020e-03, 1.730e-03, 7.120e-04,
            1.880e-03, 9.970e-04, 8.360e-04, 5.050e-04, 1.581e-03, 3.400e-04,
            1.272e-03, 8.480e-04, 1.580e-03, 7.320e-04, 4.340e-04, 1.820e-03,
            5.300e-04, 8.690e-04, 9.340e-04, 1.080e-03, 7.310e-04, 2.060e-03,
            2.950e-03, 5.800e-04, 5.470e-04, 8.850e-04, 1.790e-03, 8.130e-04,
            1.262e-03, 5.590e-04, 1.120e-03, 7.070e-04, 5.250e-04, 2.040e-03,
            1.584e-03, 1.625e-03, 2.290e-03, 3.780e-04, 5.470e-04, 1.830e-03,
            7.030e-04, 1.830e-03, 2.444e-03, 2.880e-04, 1.813e-03, 7.620e-04,
            7.550e-04, 6.400e-04, 3.010e-04, 2.030e-03, 6.120e-04, 7.410e-04,
            1.040e-04, 1.950e-03, 1.400e-03, 4.810e-04, 5.440e-04, 8.340e-04,
            4.370e-04, 7.980e-05, 1.801e-03, 5.050e-04, 4.930e-04, 1.170e-03,
            3.940e-04, 8.490e-04, 9.700e-04, 1.590e-03, 4.920e-04, 8.000e-04,
            1.080e-03, 1.630e-03, 8.550e-04, 9.430e-04, 5.040e-04, 8.600e-04,
            1.563e-03, 3.310e-04, 1.153e-03, 9.850e-04, 7.550e-04, 5.400e-04,
            1.244e-03, 2.470e-03, 1.020e-04, 4.970e-04, 1.420e-03, 2.680e-04,
            9.400e-05, 1.060e-03, 1.680e-03, 5.400e-04, 2.080e-04, 6.050e-04,
            4.870e-04, 1.830e-03, 1.350e-03, 2.454e-03, 1.681e-03, 9.010e-04,
            1.356e-03, 1.270e-03, 1.890e-03, 3.050e-04, 6.250e-04, 3.230e-03,
            3.230e-03, 1.860e-03, 5.050e-04, 7.520e-04, 1.370e-03, 5.880e-04,
            1.635e-03, 1.220e-03, 3.220e-04, 2.890e-03, 2.910e-03, 7.070e-04,
            9.550e-05, 1.510e-04, 9.660e-04, 1.340e-03, 9.660e-04, 7.190e-04,
            2.293e-03, 6.880e-04, 2.510e-03, 2.390e-03, 2.158e-03, 1.450e-03,
            1.500e-03, 1.350e-04, 5.610e-04, 3.760e-04, 2.000e-04, 9.860e-04,
            6.820e-04, 3.020e-04, 9.190e-04, 9.190e-04, 2.180e-03, 1.170e-03,
            1.015e-03, 2.778e-03, 3.240e-03, 1.270e-03, 4.115e-03
        ])
        res_h = np.array([
            2.54 + 0.j, 1.082 + 0.j, 0.502 + 0.j, 0.878 + 0.j, 4.88 + 0.j,
            4.444 + 0.j, 1.178 + 0.j, 3.368 + 0.j, 3.6 + 0.j, 12.4 + 0.j,
            1.034 + 0.j, 3.68 + 0.j, 10.38 + 0.j, 1.572 + 0.j, 4.978 + 0.j,
            1.264 + 0.j, 0.648 + 0.j, 4.72 + 0.j, 2.28 + 0.j, 1.87 + 0.j,
            8.174 + 0.j, 3.796 + 0.j, 2.58 + 0.j, 3.48 + 0.j, 4.06 + 0.j,
            1.234 + 0.j, 2.76 + 0.j, 2.76 + 0.j, 4.7 + 0.j, 1.934 + 0.j,
            5.28 + 0.j, 10.6 + 0.j, 2.14 + 0.j, 5.48 + 0.j, 4.14 + 0.j,
            0.874 + 0.j, 3.268 + 0.j, 2.18 + 0.j, 4.06 + 0.j, 1.876 + 0.j,
            1.11 + 0.j, 4.94 + 0.j, 5.44 + 0.j, 2.3 + 0.j, 2.54 + 0.j, 2.86 +
            0.j, 1.876 + 0.j, 5.46 + 0.j, 4.72 + 0.j, 6.04 + 0.j, 1.474 + 0.j,
            2.4 + 0.j, 4.76 + 0.j, 2.16 + 0.j, 3.28 + 0.j, 1.464 + 0.j,
            2.94 + 0.j, 1.816 + 0.j, 5.36 + 0.j, 5.41 + 0.j, 4.07 + 0.j,
            4.08 + 0.j, 6.2 + 0.j, 0.986 + 0.j, 1.434 + 0.j, 4.72 + 0.j,
            1.844 + 0.j, 4.72 + 0.j, 6.268 + 0.j, 0.76 + 0.j, 4.61 + 0.j,
            2.02 + 0.j, 2. + 0.j, 6.2 + 0.j, 0.768 + 0.j, 5.18 + 0.j,
            1.628 + 0.j, 1.972 + 0.j, 0.276 + 0.j, 5.02 + 0.j, 3.58 + 0.j,
            1.198 + 0.j, 1.356 + 0.j, 2.14 + 0.j, 4.44 + 0.j, 0.21 + 0.j,
            4.66 + 0.j, 1.298 + 0.j, 1.142 + 0.j, 2.98 + 0.j, 1.01 + 0.j,
            2.16 + 0.j, 2.46 + 0.j, 4.04 + 0.j, 4.98 + 0.j, 8.64 + 0.j, 2.84 +
            0.j, 17.64 + 0.j, 2.16 + 0.j, 2.38 + 0.j, 51.4 + 0.j, 90.8 + 0.j,
            3.99 + 0.j, 0.83 + 0.j, 11.73 + 0.j, 2.51 + 0.j, 1.926 + 0.j,
            1.426 + 0.j, 3.194 + 0.j, 6.32 + 0.j, 0.268 + 0.j, 1.318 + 0.j,
            3.66 + 0.j, 0.568 + 0.j, 0.984 + 0.j, 2.7 + 0.j, 4.2 + 0.j,
            42.2 + 0.j, 0.55 + 0.j, 1.552 + 0.j, 1.222 + 0.j, 4.66 + 0.j,
            3.44 + 0.j, 6.068 + 0.j, 4.226 + 0.j, 2.24 + 0.j, 3.32 + 0.j,
            3.16 + 0.j, 4.72 + 0.j, 116.2 + 0.j, 1.604 + 0.j, 8.6 + 0.j,
            8.6 + 0.j, 4.44 + 0.j, 1.258 + 0.j, 1.874 + 0.j, 3.42 + 0.j,
            1.396 + 0.j, 4.058 + 0.j, 3.1 + 0.j, 123. + 0.j, 7.38 + 0.j, 7.3 +
            0.j, 2.02 + 0.j, 0.732 + 0.j, 0.374 + 0.j, 2.42 + 0.j, 3.32 + 0.j,
            2.42 + 0.j, 1.788 + 0.j, 5.98 + 0.j, 1.748 + 0.j, 5.69 + 0.j,
            5.36 + 0.j, 5.646 + 0.j, 3.76 + 0.j, 3.88 + 0.j, 1.456 + 0.j,
            1.468 + 0.j, 0.98 + 0.j, 21.6 + 0.j, 104.6 + 0.j, 1.738 + 0.j,
            38. + 0.j, 2.48 + 0.j, 2.48 + 0.j, 5.78 + 0.j, 3.1 + 0.j,
            2.682 + 0.j, 7.092 + 0.j, 8.28 + 0.j, 12.2 + 0.j, 10.198 + 0.j
        ])
        self.assert_equal(line_r, res_r)
        self.assert_equal(line_x, res_x)
        self.assert_equal(line_h, res_h)

        pp_net = net
        # fix the missing values
        tap_step_pct = 1.0 * pp_net.trafo["tap_step_percent"].values
        tap_step_pct[~np.isfinite(tap_step_pct)] = 0.

        tap_pos = 1.0 * pp_net.trafo["tap_pos"].values
        tap_pos[~np.isfinite(tap_pos)] = 0.

        is_tap_hv_side = pp_net.trafo["tap_side"].values == "hv"
        is_tap_hv_side[~np.isfinite(is_tap_hv_side)] = True

        tap_angles_ = 1.0 * pp_net.trafo["tap_step_degree"].values
        tap_angles_[~np.isfinite(tap_angles_)] = 0.
        tap_angles_ = np.deg2rad(tap_angles_)

        trafo_r, trafo_x, trafo_b = self.converter.get_trafo_param(
            tap_step_pct,
            tap_pos,
            tap_angles_,  # in radian !
            is_tap_hv_side,
            pp_net.bus.loc[pp_net.trafo["hv_bus"]]["vn_kv"],
            pp_net.bus.loc[pp_net.trafo["lv_bus"]]["vn_kv"],
            pp_net.trafo["vk_percent"].values,
            pp_net.trafo["vkr_percent"].values,
            pp_net.trafo["sn_mva"].values,
            pp_net.trafo["pfe_kw"].values,
            pp_net.trafo["i0_percent"].values,
        )
        trafo_r_res = np.array([
            0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 2.81494977e-04,
            3.39887086e-06, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
            0.00000000e+00, 0.00000000e+00, 1.37295648e-05, 0.00000000e+00,
            1.73571860e-05
        ])
        trafo_x_res = np.array([
            2.67000000e-04, 3.82000000e-04, 3.70000000e-04, 2.06930358e-03,
            4.04933224e-05, 3.88000000e-04, 3.75000000e-04, 3.86000000e-04,
            2.68000000e-04, 3.70000000e-04, 1.59594718e-04, 3.70000000e-04,
            2.01181945e-04
        ])
        trafo_h_res = np.array([
            0. - 0.j, 0. - 0.j, 0. - 0.j, 4.4602909 - 0.00140652j,
            16.40272367 - 0.00022869j, 0. - 0.j, 0. - 0.j, 0. - 0.j, 0. - 0.j,
            0. - 0.j, 63.96323106 - 0.01411497j, 0. - 0.j,
            81.1310369 - 0.02879733j
        ])
        self.assert_equal(trafo_r, trafo_r_res)
        self.assert_equal(trafo_x, trafo_x_res)
        self.assert_equal(trafo_b, trafo_h_res)
Beispiel #4
0
class KLU4Pandapower():
    def __init__(self):
        self.solver = KLUSolver()
        self.converter = PandaPowerConverter()
        self.ppci = None
        self.V = None
        self.Ybus = None
        self.pv = None
        self.pq = None

        # TODO
        self.ppci = None
        self.Ybus = None
        self.Yf = None
        self.Yt = None
        self.bus = None
        self.gen = None
        self.branch = None
        self.ref = None
        self.pv = None
        self.pq = None
        self.ref_gens = None
        self.baseMVA = None
        raise RuntimeError("This module is deprecated.")

    def runpp(self, net, max_iteration=10, need_reset=True, **kwargs):
        net_orig = copy.deepcopy(net)
        pp.runpp(net_orig)
        V_orig = net_orig._ppc["internal"]["V"]

        # ---------- pp.run.runpp() -----------------
        t0_start = time()

        t0_options = time()
        passed_parameters = _passed_runpp_parameters(locals())
        _init_runpp_options(net,
                            algorithm="nr",
                            calculate_voltage_angles="auto",
                            init="auto",
                            max_iteration=max_iteration,
                            tolerance_mva=1e-8,
                            trafo_model="t",
                            trafo_loading="current",
                            enforce_q_lims=False,
                            check_connectivity=False,
                            voltage_depend_loads=True,
                            consider_line_temperature=False,
                            passed_parameters=passed_parameters,
                            numba=True,
                            **kwargs)
        _check_bus_index_and_print_warning_if_high(net)
        _check_gen_index_and_print_warning_if_high(net)
        et_options = time() - t0_options

        # ---------- pp.powerflow._powerflow() -----------------
        """
        Gets called by runpp or rundcpp with different arguments.
        """
        # get infos from options
        t0_early_init = time()
        init_results = net["_options"]["init_results"]
        ac = net["_options"]["ac"]
        algorithm = net["_options"]["algorithm"]

        net["converged"] = False
        net["OPF_converged"] = False
        _add_auxiliary_elements(net)

        if not ac or init_results:
            verify_results(net)
        else:
            reset_results(net, all_empty=False)

        # TODO remove this when zip loads are integrated for all PF algorithms
        if algorithm not in ['nr', 'bfsw']:
            net["_options"]["voltage_depend_loads"] = False

        _add_auxiliary_elements(net)
        # convert pandapower net to ppc
        ppc, self.ppci = _pd2ppc(net)

        # pdb.set_trace()
        # store variables
        net["_ppc"] = ppc

        if not "VERBOSE" in kwargs:
            kwargs["VERBOSE"] = 0

        # ----- run the powerflow -----
        options = net["_options"]
        et_early_init = time() - t0_early_init

        # ---------- pp.powerflow._run_pf_algorithm() ----------------
        # ---------- pp.pf.run_newton_raphson_pf.run_newton_raphson_pf() ----------------
        t0 = time()
        t0_init = t0
        et_init_dc = 0.
        if need_reset:
            if isinstance(options["init_va_degree"],
                          str) and options["init_va_degree"] == "dc":
                self.ppci = _run_dc_pf(self.ppci)
                et_init_dc = time() - t0
            if options["enforce_q_lims"]:
                raise NotImplementedError("enforce_q_lims not yet implemented")

            t0_init = time()
            # ---------- pp.pf.run_newton_raphson_pf._run_ac_pf_without_qlims_enforced ----------
            # ppci, success, iterations = _run_ac_pf_without_qlims_enforced(ppci, options)
            makeYbus, pfsoln = _get_numba_functions(self.ppci, options)
            self.baseMVA, self.bus, self.gen, self.branch, self.ref, self.pv, self.pq, _, _, V0, self.ref_gens = _get_pf_variables_from_ppci(
                self.ppci)
            self.ppci, self.Ybus, self.Yf, self.Yt = _get_Y_bus(
                self.ppci, options, makeYbus, self.baseMVA, self.bus,
                self.branch)

            # TODO i have a problem here for the order of the bus / id of bus
            tmp_bus_ind = np.argsort(net.bus.index)
            model = DataModel()
            # model.set_sn_mva(net.sn_mva)
            # model.set_f_hz(net.f_hz)

            # TODO set that elsewhere
            self.converter.set_sn_mva(net.sn_mva)
            self.converter.set_f_hz(net.f_hz)

            # init_but should be called first among all the rest
            model.init_bus(net.bus.iloc[tmp_bus_ind]["vn_kv"].values,
                           net.line.shape[0], net.trafo.shape[0])

            # init the shunts
            line_r, line_x, line_h = self.converter.get_line_param(
                net.line["r_ohm_per_km"].values * net.line["length_km"].values,
                net.line["x_ohm_per_km"].values * net.line["length_km"].values,
                net.line["c_nf_per_km"].values * net.line["length_km"].values,
                net.line["g_us_per_km"].values * net.line["length_km"].values,
                net.bus.loc[net.line["from_bus"]]["vn_kv"],
                net.bus.loc[net.line["to_bus"]]["vn_kv"])
            model.init_powerlines(line_r, line_x, line_h,
                                  net.line["from_bus"].values,
                                  net.line["to_bus"].values)

            # init the shunts
            model.init_shunt(net.shunt["p_mw"].values,
                             net.shunt["q_mvar"].values,
                             net.shunt["bus"].values)
            # init trafo
            if net.trafo.shape[0]:
                trafo_r, trafo_x, trafo_b = self.converter.get_trafo_param(
                    net.trafo["vn_hv_kv"].values, net.trafo["vn_lv_kv"].values,
                    net.trafo["vk_percent"].values,
                    net.trafo["vkr_percent"].values,
                    net.trafo["sn_mva"].values, net.trafo["pfe_kw"].values,
                    net.trafo["i0_percent"].values,
                    net.bus.loc[net.trafo["lv_bus"]]["vn_kv"])

                # trafo_branch = ppc["branch"][net.line.shape[0]:, :]

                tap_step_pct = net.trafo["tap_step_percent"].values
                tap_step_pct[~np.isfinite(tap_step_pct)] = 0.

                tap_pos = net.trafo["tap_pos"].values
                tap_pos[~np.isfinite(tap_pos)] = 0.

                is_tap_hv_side = net.trafo["tap_side"].values == "hv"
                is_tap_hv_side[~np.isfinite(tap_pos)] = True
                model.init_trafo(trafo_r, trafo_x, trafo_b, tap_step_pct,
                                 tap_pos, is_tap_hv_side,
                                 net.trafo["hv_bus"].values,
                                 net.trafo["lv_bus"].values)

            model.init_loads(net.load["p_mw"].values,
                             net.load["q_mvar"].values, net.load["bus"].values)
            model.init_generators(net.gen["p_mw"].values,
                                  net.gen["vm_pu"].values,
                                  net.gen["bus"].values)
            # TODO better way here!
            model.add_slackbus(net.ext_grid["bus"].values)

            # model.init_Ybus()
            # Ybus = model.get_Ybus()

            # be careful, the order is not the same between this and pandapower, you need to change it
            # Ybus_proper_oder = Ybus[np.array([net.bus.index]).T, np.array([net.bus.index])]
            # self.Ybus_proper_oder = self.Ybus
        else:
            pass
            # TODO update self.ppci with new values of generation - load such that  Sbus is properly udpated

        # compute complex bus power injections [generation - load]
        Sbus = _get_Sbus(self.ppci, False)

        # Sbus_me = model.get_Sbus()
        # pdb.set_trace()
        # Sbus_me_r = np.real(Sbus_me)
        # Va0 = np.full(net.bus.shape[0], fill_value=net["_options"]["init_vm_pu"], dtype=np.complex_)
        # Va0[net.ext_grid["bus"].values] = net.ext_grid["vm_pu"].values * np.exp(1j * net.ext_grid["va_degree"].values / 360. * 2 * np.pi)
        #dctheta = model.dc_pf(Sbus_me_r, Va0)
        # self.dctheta = V0[tmp_bus_ind]

        # self.dcYbus = self.ppci["internal"]['Bbus'][np.array([tmp_bus_ind]).T, np.array([tmp_bus_ind])]
        # tmpdc = np.abs(dcYbus - self.dcYbus)
        # pv_me = model.get_pv()
        # pq_me = model.get_pq()
        # pdb.set_trace()

        # run the newton power  flow
        # ------------------- pp.pypower.newtonpf ---------------------
        max_it = options["max_iteration"]
        tol = options['tolerance_mva']
        self.Ybus = sparse.csc_matrix(self.Ybus)
        et_init = time() - t0_init

        t0__ = time()
        if need_reset:
            # reset the solver
            self.solver.reset()
            self.V = 1.0 * copy.deepcopy(V0)
        else:
            # reuse previous voltages
            pass
        self.solver.solve(self.Ybus, self.V, Sbus, self.pv, self.pq, max_it,
                          tol)
        et__ = time() - t0__

        t0_ = time()
        Va = self.solver.get_Va()
        Vm = self.solver.get_Vm()
        self.V = Vm * np.exp(1j * Va)
        J = self.solver.get_J()
        success = self.solver.converged()
        iterations = self.solver.get_nb_iter()
        # timer_Fx_, timer_solve_, timer_initialize_, timer_check_, timer_dSbus_, timer_fillJ_, timer_total_nr_
        timers = self.solver.get_timers()
        et_ = time() - t0_
        # ---------------------- pp.pypower.newtonpf ---------------------

        self.ppci = _store_internal(
            self.ppci, {
                "J": J,
                "Vm_it": None,
                "Va_it": None,
                "bus": self.bus,
                "gen": self.gen,
                "branch": self.branch,
                "baseMVA": self.baseMVA,
                "V": self.V,
                "pv": self.pv,
                "pq": self.pq,
                "ref": self.ref,
                "Sbus": Sbus,
                "ref_gens": self.ref_gens,
                "Ybus": self.Ybus,
                "Yf": self.Yf,
                "Yt": self.Yt,
                "timers": timers,
                "time_get_res": et_,
                "time_solve": et__,
                "time_init": et_init,
                "time_init_dc": et_init_dc,
                "time_early_init": et_early_init,
                "time_options": et_options
            })
        t0_ppci_to_pfsoln = time()
        # update data matrices with solution store in ppci
        # ---------- pp.pf.run_newton_raphson_pf._run_ac_pf_without_qlims_enforced ----------
        self.bus, self.gen, self.branch = ppci_to_pfsoln(self.ppci, options)
        te_ppci_to_pfsoln = time() - t0_ppci_to_pfsoln
        # these are the values from pypower / matlab
        t0_store_res = time()
        et = t0_store_res - t0
        result = _store_results_from_pf_in_ppci(self.ppci, self.bus, self.gen,
                                                self.branch, success,
                                                iterations, et)
        t0_to_net = time()
        et_store_res = t0_to_net - t0_store_res
        # ---------- pp.pf.run_newton_raphson_pf.run_newton_raphson_pf() ----------------
        # ---------- pp.powerflow._run_pf_algorithm() ----------------

        # read the results (=ppci with results) to net
        _ppci_to_net(result, net)
        et_to_net = time() - t0_to_net
        # ---------- pp.powerflow._powerflow() ----------------
        # ---------- pp.run.runpp() -----------------

        # added
        et_start = time() - t0_start
        self.ppci = _store_internal(
            self.ppci, {
                "time_store_res": et_store_res,
                "time_to_net": et_to_net,
                "time_all": et_start,
                "time_ppci_to_pfsoln": te_ppci_to_pfsoln
            })

        has_conv = model.compute_newton(V0[tmp_bus_ind], max_it, tol)
        # check the results
        results_solver = np.max(np.abs(V_orig - self.V))

        Ybus = model.get_Ybus()
        Ybus_proper_oder = Ybus
        self.Ybus_proper_oder = self.Ybus[np.array([tmp_bus_ind]).T,
                                          np.array([tmp_bus_ind])]

        tmp = np.abs(Ybus_proper_oder - self.Ybus_proper_oder)  # > 1e-7
        por, qor, vor, aor = model.get_lineor_res()
        pex, qex, vex, aex = model.get_lineex_res()
        load_p, load_q, load_v = model.get_loads_res()

        np.max(np.abs(por - net_orig.res_line["p_from_mw"]))
        np.max(np.abs(qor - net_orig.res_line["q_from_mvar"]))
        a_or_pp = np.sqrt(net.res_line["p_from_mw"].values**2 +
                          net.res_line["q_from_mvar"].values**2)
        a_or_pp /= np.sqrt(3) * net.bus.loc[net.line["from_bus"].values][
            "vn_kv"].values * net.res_line["vm_from_pu"].values
        np.max(np.abs(a_or_pp - aor))
        np.max(np.abs(a_or_pp - net.res_line["i_from_ka"]))
        np.max(np.abs(a_or_pp - net.res_line["i_from_ka"]))

        Va_me2 = model.get_Va()
        Vm_me2 = model.get_Vm()
        res_vm = np.abs(Vm_me2 - Vm[tmp_bus_ind])
        res_va = np.abs(Va_me2 - Va[tmp_bus_ind])

        # check that if i start the solver on the data
        Sbus_me = model.get_Sbus()
        pv_me = model.get_pv()
        pq_me = model.get_pq()

        np.all(sorted(pv_me) == sorted(net.gen["bus"]))
        np.all(sorted(pq_me) == sorted(tmp_bus_ind[self.pq]))

        plv, qlv, vlv, alv = model.get_trafolv_res()
        phv, qhv, vhv, ahv = model.get_trafohv_res()
        res_trafo = np.abs(plv - net_orig.res_trafo["p_lv_mw"].values)

        res_trafo_q = np.abs(qlv - net_orig.res_trafo["q_lv_mvar"].values)
        # self.solver.reset()
        # self.solver.solve(Ybus, V0, Sbus, pv_me, pq_me, max_it, tol)
        # Va2 = self.solver.get_Va()
        # Vm2 = self.solver.get_Vm()

        pdb.set_trace()
Beispiel #5
0
def init(pp_net):
    """
    Convert a pandapower network as input into a GridModel.

    This does not throw any error at the moment when the conversion is not possible.

    Cases for which conversion is not possible include, but are not limited to:

    - the pandapower grid has 3 winding transformers
    - the pandapower grid has xwards
    - the pandapower grid any parrallel "elements" (at least one of the column "parrallel" is not 1)
    - some `g_us_per_km` for some lines are not zero
    - some `p_mw` for some shunts are not zero
    - some `tap_step_degre` are non zero for some trafo
    - no "ext_grid" is reported on the initial grid

    if you really need any of the above, please submit a github issue and we will work on their support.

    This conversion has been extensively studied for the case118() of pandapower.networks and should work
    really well for this grid. Actually, this grid is used for testing the GridModel class.

    Parameters
    ----------
    pp_net: :class:`pandapower.grid`
        The initial pandapower network you want to convert

    Returns
    -------
    model: :class:`GridModel`
        The initialize gridmodel

    """
    # initialize and use converters
    converter = PandaPowerConverter()
    converter.set_sn_mva(pp_net.sn_mva)  # TODO raise an error if not set !
    converter.set_f_hz(pp_net.f_hz)
    line_r, line_x, line_h = \
        converter.get_line_param(
            pp_net.line["r_ohm_per_km"].values * pp_net.line["length_km"].values,
            pp_net.line["x_ohm_per_km"].values * pp_net.line["length_km"].values,
            pp_net.line["c_nf_per_km"].values * pp_net.line["length_km"].values,
            pp_net.line["g_us_per_km"].values * pp_net.line["length_km"].values,
            pp_net.bus.loc[pp_net.line["from_bus"]]["vn_kv"],
            pp_net.bus.loc[pp_net.line["to_bus"]]["vn_kv"]
        )
    trafo_r, trafo_x, trafo_b = \
        converter.get_trafo_param(pp_net.trafo["vn_hv_kv"].values,
                                  pp_net.trafo["vn_lv_kv"].values,
                                  pp_net.trafo["vk_percent"].values,
                                  pp_net.trafo["vkr_percent"].values,
                                  pp_net.trafo["sn_mva"].values,
                                  pp_net.trafo["pfe_kw"].values,
                                  pp_net.trafo["i0_percent"].values,
                                  pp_net.bus.loc[pp_net.trafo["lv_bus"]]["vn_kv"]
                                       )

    # set up the data model accordingly
    model = GridModel()
    tmp_bus_ind = np.argsort(pp_net.bus.index)
    model.init_bus(pp_net.bus.iloc[tmp_bus_ind]["vn_kv"].values,
                   pp_net.line.shape[0],
                   pp_net.trafo.shape[0])

    model.init_powerlines(line_r, line_x, line_h,
                          pp_net.line["from_bus"].values,
                          pp_net.line["to_bus"].values
                               )

    # init the shunts
    model.init_shunt(pp_net.shunt["p_mw"].values,
                     pp_net.shunt["q_mvar"].values,
                     pp_net.shunt["bus"].values
                          )

    tap_step_pct = pp_net.trafo["tap_step_percent"].values
    tap_step_pct[~np.isfinite(tap_step_pct)] = 0.

    tap_pos = pp_net.trafo["tap_pos"].values
    tap_pos[~np.isfinite(tap_pos)] = 0.

    is_tap_hv_side = pp_net.trafo["tap_side"].values == "hv"
    is_tap_hv_side[~np.isfinite(tap_pos)] = True
    model.init_trafo(trafo_r,
                     trafo_x,
                     trafo_b,
                     tap_step_pct,
                     tap_pos,
                     is_tap_hv_side,
                     pp_net.trafo["hv_bus"].values,
                     pp_net.trafo["lv_bus"].values)

    model.init_loads(pp_net.load["p_mw"].values,
                     pp_net.load["q_mvar"].values,
                     pp_net.load["bus"].values
                          )
    model.init_generators(pp_net.gen["p_mw"].values,
                          pp_net.gen["vm_pu"].values,
                          pp_net.gen["min_q_mvar"].values,
                          pp_net.gen["max_q_mvar"].values,
                          pp_net.gen["bus"].values
                          )

    # TODO handle that better maybe, and warn only one slack bus is implemented
    if np.any(pp_net.gen["slack"].values):
        slack_gen_id = np.where(pp_net.gen["slack"].values)[0]
    else:
        # there is no slack bus in the generator of the pp grid

        # first i try to see if a generator is connected to a slack bus
        slack_bus_id = pp_net.ext_grid["bus"].values[0]
        if np.any(pp_net.gen["bus"].values == slack_bus_id):
            slack_gen_id = np.where(pp_net.gen["bus"].values == slack_bus_id)[0]
        else:
            # no gen is connected to a slack bus, so i create one.
            gen_p = np.concatenate((pp_net.gen["p_mw"].values, [np.sum(pp_net.load["p_mw"]) - np.sum(pp_net.gen["p_mw"])]))
            gen_v = np.concatenate((pp_net.gen["vm_pu"].values, [pp_net.ext_grid["vm_pu"].values[0]]))
            gen_bus = np.concatenate((pp_net.gen["bus"].values, [slack_bus_id]))
            gen_min_q = np.concatenate((pp_net.gen["min_q_mvar"].values, [-999999.]))
            gen_max_q = np.concatenate((pp_net.gen["max_q_mvar"].values, [+99999.]))
            model.init_generators(gen_p, gen_v, gen_min_q, gen_max_q, gen_bus)
            slack_gen_id = pp_net.gen["bus"].shape[0]

    model.add_gen_slackbus(slack_gen_id)
    return model
Beispiel #6
0
def init(pp_net):
    """
    Convert a pandapower network as input into a GridModel.

    This does not throw any error at the moment when the conversion is not possible.

    Cases for which conversion is not possible include, but are not limited to:

    - the pandapower grid has 3 winding transformers
    - the pandapower grid has xwards
    - the pandapower grid any parrallel "elements" (at least one of the column "parrallel" is not 1)
    - some `g_us_per_km` for some lines are not zero
    - some `p_mw` for some shunts are not zero
    - some `tap_step_degre` are non zero for some trafo
    - no "ext_grid" is reported on the initial grid

    if you really need any of the above, please submit a github issue and we will work on their support.

    This conversion has been extensively studied for the case118() of pandapower.networks and should work
    really well for this grid. Actually, this grid is used for testing the GridModel class.

    Parameters
    ----------
    pp_net: :class:`pandapower.grid`
        The initial pandapower network you want to convert

    Returns
    -------
    model: :class:`GridModel`
        The initialize gridmodel

    """
    # check for things not supported and raise if needed
    _aux_check_legit(pp_net)

    # initialize and use converters
    converter = PandaPowerConverter()
    converter.set_sn_mva(pp_net.sn_mva)  # TODO raise an error if not set !
    converter.set_f_hz(pp_net.f_hz)

    # set up the data model accordingly
    model = GridModel()
    if "_options" in pp_net:
        if "init_vm_pu" in pp_net["_options"]:
            model.set_init_vm_pu(pp_net["_options"]["init_vm_pu"])

    model.set_sn_mva(pp_net.sn_mva)

    tmp_bus_ind = np.argsort(pp_net.bus.index)
    model.init_bus(pp_net.bus.iloc[tmp_bus_ind]["vn_kv"].values,
                   pp_net.line.shape[0], pp_net.trafo.shape[0])

    # init the powerlines
    _aux_add_line(converter, model, pp_net)

    # init the shunts
    _aux_add_shunt(model, pp_net)

    # handle the trafos
    _aux_add_trafo(converter, model, pp_net)

    # handle loads
    _aux_add_load(model, pp_net)

    # handle static generators (PQ generator)
    _aux_add_sgen(model, pp_net)

    # handle generators
    _aux_add_gen(model, pp_net)

    # handle storage units
    _aux_add_storage(model, pp_net)

    # deal with slack bus
    _aux_add_slack(model, pp_net)

    return model
            me_lv = tpex[id_trafo_bug]
            me_hv = tpor[id_trafo_bug]
            pdb.set_trace()

print("V - Check trafo proper conversion to r,x, b")
test_ok = True
from lightsim2grid_cpp import GridModel, PandaPowerConverter, SolverType
from pandapower.build_branch import _calc_branch_values_from_trafo_df, get_trafo_values
from pandapower.build_branch import _calc_nominal_ratio_from_dataframe, _calc_r_x_y_from_dataframe
from pandapower.build_branch import _calc_tap_from_dataframe, BASE_KV, _calc_r_x_from_dataframe

# my values
# trafo_df = pp_net["trafo"]
# vn_trafo_hv, vn_trafo_lv, shift = _calc_tap_from_dataframe(pp_net, trafo_df)

converter = PandaPowerConverter()
converter.set_sn_mva(pp_net.sn_mva)  # TODO raise an error if not set !
converter.set_f_hz(pp_net.f_hz)

# fix the missing values
tap_neutral = 1.0 * pp_net.trafo["tap_neutral"].values
if np.any(~np.isfinite(tap_neutral)):
    warnings.warn(
        "There were some Nan in the pp_net.trafo[\"tap_neutral\"], they have been replaced by 0"
    )
tap_neutral[~np.isfinite(tap_neutral)] = 0.

if np.any(tap_neutral != 0.):
    raise RuntimeError(
        "lightsim converter supposes that tap_neutral is 0 for the transformers"
    )
    def _aux_test(self, pn_net):
        with tempfile.TemporaryDirectory() as path:
            case_name = os.path.join(path, "this_case.json")
            pp.to_json(pn_net, case_name)

            real_init_file = pp.from_json(case_name)
            backend = LightSimBackend()
            with warnings.catch_warnings():
                warnings.filterwarnings("ignore")
                backend.load_grid(case_name)

        nb_sub = backend.n_sub
        pp_net = backend.init_pp_backend._grid
        # first i deactivate all slack bus in pp that are connected but not handled in ls
        pp_net.ext_grid["in_service"].loc[:] = False
        pp_net.ext_grid["in_service"].iloc[0] = True
        conv = backend.runpf()
        conv_pp = backend.init_pp_backend.runpf()

        assert conv_pp, "Error: pandapower do not converge, impossible to perform the necessary checks"
        assert conv, "Error: lightsim do not converge"

        por_pp, qor_pp, vor_pp, aor_pp = copy.deepcopy(
            backend.init_pp_backend.lines_or_info())
        pex_pp, qex_pp, vex_pp, aex_pp = copy.deepcopy(
            backend.init_pp_backend.lines_ex_info())

        # I- Check for divergence and equality of flows"
        por_ls, qor_ls, vor_ls, aor_ls = backend.lines_or_info()
        max_mis = np.max(np.abs(por_ls - por_pp))
        assert max_mis <= self.tol, f"Error: por do not match, maximum absolute error is {max_mis:.5f} MW"
        max_mis = np.max(np.abs(qor_ls - qor_pp))
        assert max_mis <= self.tol, f"Error: qor do not match, maximum absolute error is {max_mis:.5f} MVAr"
        max_mis = np.max(np.abs(vor_ls - vor_pp))
        assert max_mis <= self.tol, f"Error: vor do not match, maximum absolute error is {max_mis:.5f} kV"
        max_mis = np.max(np.abs(aor_ls - aor_pp))
        assert max_mis <= self.tol, f"Error: aor do not match, maximum absolute error is {max_mis:.5f} A"

        # "II - Check for possible solver issues"
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            pp.runpp(backend.init_pp_backend._grid, v_debug=True)
        v_tmp = backend.init_pp_backend._grid.res_bus[
            "vm_pu"].values[:nb_sub] + 0j
        v_tmp *= np.exp(
            1j * np.pi / 180. *
            backend.init_pp_backend._grid.res_bus["va_degree"].values[:nb_sub])
        v_tmp = np.concatenate((v_tmp, v_tmp))
        backend._grid.ac_pf(v_tmp, 1000, 1e-5)

        Y_pp = backend.init_pp_backend._grid._ppc["internal"]["Ybus"]
        Sbus = backend.init_pp_backend._grid._ppc["internal"]["Sbus"]
        pv_ = backend.init_pp_backend._grid._ppc["internal"]["pv"]
        pq_ = backend.init_pp_backend._grid._ppc["internal"]["pq"]
        max_iter = 10
        tol_this = 1e-8
        All_Vms = backend.init_pp_backend._grid._ppc["internal"]["Vm_it"]
        AllVas = backend.init_pp_backend._grid._ppc["internal"]["Va_it"]

        for index_V in range(All_Vms.shape[1] - 1, -1, -1):
            nb_iter = All_Vms.shape[1] - 1
            # i check from easiest to hardest, so from the last iteartion of pandapower to the first iteration of pandapower
            # take the same V as pandapower
            V_init = All_Vms[:, index_V] * (np.cos(AllVas[:, index_V]) +
                                            1j * np.sin(AllVas[:, index_V]))
            # V_init *= np.exp(1j * AllVas[:, 0])
            V_init_ref = copy.deepcopy(V_init)
            solver = ClassSolver()
            solver.solve(scipy.sparse.csc_matrix(Y_pp), V_init, Sbus, pv_, pq_,
                         max_iter, tol_this)
            time_for_nr = solver.get_timers()[3]
            if TIMER_INFO:
                print(
                    f"\t Info: Time to perform {nb_iter - index_V} NR iterations for a grid with {nb_sub} "
                    f"buses: {1000. * time_for_nr:.2f}ms")
            error_va = np.abs(
                solver.get_Va() -
                np.angle(backend.init_pp_backend._grid._ppc["internal"]["V"]))
            assert np.max(error_va) <= self.tol, f"Error: VA do not match for iteration {index_V}, maximum absolute " \
                                                 f"error is {np.max(error_va):.5f} rad"

            error_vm = np.abs(
                np.abs(solver.get_Vm() - np.abs(
                    backend.init_pp_backend._grid._ppc["internal"]["V"])))
            assert np.max(error_vm) <= self.tol, f"\t Error: VM do not match for iteration {index_V}, maximum absolute " \
                                                 f"error  is {np.max(error_vm):.5f} pu"
            solver.reset()

        if TIMER_INFO:
            print("")

        # 'III - Check the data conversion'
        pp_vect_converter = backend.init_pp_backend._grid._pd2ppc_lookups[
            "bus"][:nb_sub]
        pp_net = backend.init_pp_backend._grid

        # 1) Checking Sbus conversion
        Sbus_pp = backend.init_pp_backend._grid._ppc["internal"]["Sbus"]
        Sbus_pp_right_order = Sbus_pp[pp_vect_converter]
        Sbus_me = backend._grid.get_Sbus()
        error_p = np.abs(np.real(Sbus_me) - np.real(Sbus_pp_right_order))
        assert np.max(error_p) <= self.tol, f"\t Error: P do not match for Sbus, maximum absolute error is " \
                                            f"{np.max(error_p):.5f} MW, \t Error: significative difference for bus " \
                                            f"index (lightsim): {np.where(error_p > self.tol)[0]}"

        error_q = np.abs(np.imag(Sbus_me) - np.imag(Sbus_pp_right_order))
        assert np.max(error_q) <= self.tol, f"\t Error: Q do not match for Sbus, maximum absolute error is " \
                                            f"{np.max(error_q):.5f} MVAr, \t Error: significative difference for bus " \
                                            f"index (lightsim): {np.where(error_q > self.tol)[0]}"

        # 2)  Checking Ybus conversion"
        Y_me = backend._grid.get_Ybus()
        Y_pp = backend.init_pp_backend._grid._ppc["internal"]["Ybus"]
        Y_pp_right_order = Y_pp[pp_vect_converter.reshape(nb_sub, 1),
                                pp_vect_converter.reshape(1, nb_sub)]
        error_p = np.abs(np.real(Y_me) - np.real(Y_pp_right_order))
        assert np.max(error_p) <= self.tol, f"Error: P do not match for Ybus, maximum absolute error " \
                                            f"is {np.max(error_p):.5f}"

        error_q = np.abs(np.imag(Y_me) - np.imag(Y_pp_right_order))
        assert np.max(error_q) <= self.tol, f"\t Error: Q do not match for Ybus, maximum absolute error is " \
                                            f"{np.max(error_q):.5f}"

        # "IV - Check for the initialization (dc powerflow)"
        # 1) check that the results are same for dc lightsim and dc pandapower
        Vinit = np.ones(backend.nb_bus_total,
                        dtype=np.complex_) * pp_net["_options"]["init_vm_pu"]
        backend._grid.deactivate_result_computation()
        Vdc = backend._grid.dc_pf(Vinit, max_iter, tol_this)
        backend._grid.reactivate_result_computation()
        Ydc_me = backend._grid.get_Ybus()
        Sdc_me = backend._grid.get_Sbus()
        assert np.max(np.abs(V_init_ref[pp_vect_converter] - Vdc[:nb_sub])) <= 100.*self.tol,\
            f"\t Error for the DC approximation: resulting voltages are different " \
            f"{np.max(np.abs(V_init_ref[pp_vect_converter] - Vdc[:nb_sub])):.5f}pu"

        if np.max(np.abs(V_init_ref[pp_vect_converter] -
                         Vdc[:nb_sub])) >= self.tol:
            warnings.warn(
                "\t Warning: maximum difference after DC approximation is "
                "{np.max(np.abs(V_init_ref[pp_vect_converter] - Vdc[:nb_sub])):.5f} which is higher than "
                "the tolerance (this is just a warning because we noticed this could happen even if the "
                "results match perfectly. Probably some conversion issue with complex number and "
                "radian / degree.")
        # "2) check that the Sbus vector is same for PP and lightisim in DC"
        from pandapower.pd2ppc import _pd2ppc
        from pandapower.pf.run_newton_raphson_pf import _get_pf_variables_from_ppci
        from pandapower.pypower.idx_brch import F_BUS, T_BUS, BR_X, TAP, SHIFT, BR_STATUS
        from pandapower.pypower.idx_bus import VA, GS
        from pandapower.pypower.makeBdc import makeBdc
        from pandapower.pypower.makeSbus import makeSbus

        pp_net._pd2ppc_lookups = {
            "bus": np.array([], dtype=int),
            "ext_grid": np.array([], dtype=int),
            "gen": np.array([], dtype=int),
            "branch": np.array([], dtype=int)
        }
        # convert pandapower net to ppc
        ppc, ppci = _pd2ppc(pp_net)
        baseMVA, bus, gen, branch, ref, pv, pq, on, gbus, _, refgen = _get_pf_variables_from_ppci(
            ppci)
        Va0 = bus[:, VA] * (np.pi / 180.)
        B, Bf, Pbusinj, Pfinj = makeBdc(bus, branch)

        Pbus = makeSbus(baseMVA, bus, gen) - Pbusinj - bus[:, GS] / baseMVA
        Pbus_pp_ro = Pbus[pp_vect_converter]
        error_p = np.abs(np.real(Sdc_me) - np.real(Pbus_pp_ro))
        test_ok = True

        #### pandapower DC algo (yet another one)
        Va = copy.deepcopy(Va0)
        pvpq = np.r_[pv, pq]
        pvpq_matrix = B[pvpq.T, :].tocsc()[:, pvpq]
        ref_matrix = np.transpose(Pbus[pvpq] -
                                  B[pvpq.T, :].tocsc()[:, ref] * Va0[ref])
        Va[pvpq] = np.real(scipy.sparse.linalg.spsolve(pvpq_matrix,
                                                       ref_matrix))
        ####

        assert np.max(error_p) <= self.tol, f"\t Error: P do not match for Sbus (dc), maximum absolute error is " \
                                            f"{np.max(error_p):.5f} MW, \nError: significative difference for bus " \
                                            f"index (lightsim): {np.where(error_p > self.tol)[0]}"

        error_q = np.abs(np.imag(Sdc_me) - np.imag(Pbus_pp_ro))
        assert np.max(error_q) <= self.tol, f"\t Error: Q do not match for Sbus (dc), maximum absolute error is " \
                                            f"{np.max(error_q):.5f} MVAr, \n\t Error: significative difference for " \
                                            f"bus index (lightsim): {np.where(error_q > self.tol)[0]}"

        # "3) check that the Ybus matrix is same for PP and lightisim in DC"
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            pp.rundcpp(pp_net)
        Ydc_pp = backend.init_pp_backend._grid._ppc["internal"]["Bbus"]
        Ydc_pp_right_order = Ydc_pp[pp_vect_converter.reshape(nb_sub, 1),
                                    pp_vect_converter.reshape(1, nb_sub)]
        error_p = np.abs(np.real(Ydc_me) - np.real(Ydc_pp_right_order))
        assert np.max(error_p) <= self.tol, f"Error: P do not match for Ybus (dc mode), maximum absolute error " \
                                            f"is {np.max(error_p):.5f}"
        error_q = np.abs(np.imag(Ydc_me) - np.imag(Ydc_pp_right_order))
        assert np.max(error_q) <= self.tol, f"\t Error: Q do not match for Ybus (dc mdoe), maximum absolute error " \
                                            f"is {np.max(error_q):.5f}"

        # "3) check that lightsim ac pf init with pp dc pf give same results (than pp)"
        Vinit = np.ones(backend.nb_bus_total,
                        dtype=np.complex_) * pp_net["_options"]["init_vm_pu"]
        Vinit[:nb_sub] = V_init_ref[pp_vect_converter]
        conv = backend._grid.ac_pf(Vinit, max_iter, tol_this)
        assert conv.shape[
            0] > 0, "\t Error: the lightsim diverge when initialized with pandapower Vinit_dc"
        lpor, lqor, lvor, laor = backend._grid.get_lineor_res()
        tpor, tqor, tvor, taor = backend._grid.get_trafohv_res()
        tpex, tqex, tvex, taex = backend._grid.get_trafolv_res()
        nb_trafo = tpor.shape[0]
        nb_powerline = lpor.shape[0]
        p_or_me2 = np.concatenate((lpor, tpor))
        q_or_me2 = np.concatenate((lqor, tqor))
        v_or_me2 = np.concatenate((lvor, tvor))
        a_or_me2 = 1000. * np.concatenate((laor, taor))
        test_ok = True
        # pdb.set_trace()
        max_mis = np.max(np.abs(p_or_me2 - por_pp))
        assert np.max(
            error_q
        ) <= self.tol, f"\t Error: por do not match, maximum absolute error is {max_mis:.5f} MW"
        max_mis = np.max(np.abs(q_or_me2 - qor_pp))
        assert np.max(
            error_q
        ) <= self.tol, f"\t Error: qor do not match, maximum absolute error is {max_mis:.5f} MVAr"
        max_mis = np.max(np.abs(v_or_me2 - vor_pp))
        assert np.max(
            error_q
        ) <= self.tol, f"\t Error: vor do not match, maximum absolute error is {max_mis:.5f} kV"
        max_mis = np.max(np.abs(a_or_me2 - aor_pp))
        assert np.max(
            error_q
        ) <= self.tol, f"\t Error: aor do not match, maximum absolute error is {max_mis:.5f} A"

        # "V - Check trafo proper conversion to r,x, b"
        from lightsim2grid_cpp import GridModel, PandaPowerConverter, SolverType
        from pandapower.build_branch import _calc_branch_values_from_trafo_df, get_trafo_values
        from pandapower.build_branch import _calc_nominal_ratio_from_dataframe, _calc_r_x_y_from_dataframe
        from pandapower.build_branch import _calc_tap_from_dataframe, BASE_KV, _calc_r_x_from_dataframe

        # my trafo parameters
        converter = PandaPowerConverter()
        converter.set_sn_mva(pp_net.sn_mva)
        converter.set_f_hz(pp_net.f_hz)
        tap_neutral = 1.0 * pp_net.trafo["tap_neutral"].values
        tap_neutral[~np.isfinite(tap_neutral)] = 0.
        if np.any(tap_neutral != 0.):
            raise RuntimeError(
                "lightsim converter supposes that tap_neutral is 0 for the transformers"
            )
        tap_step_pct = 1.0 * pp_net.trafo["tap_step_percent"].values
        tap_step_pct[~np.isfinite(tap_step_pct)] = 0.
        tap_pos = 1.0 * pp_net.trafo["tap_pos"].values
        tap_pos[~np.isfinite(tap_pos)] = 0.
        shift_ = 1.0 * pp_net.trafo["shift_degree"].values
        shift_[~np.isfinite(shift_)] = 0.
        is_tap_hv_side = pp_net.trafo["tap_side"].values == "hv"
        is_tap_hv_side[~np.isfinite(is_tap_hv_side)] = True
        if np.any(pp_net.trafo["tap_phase_shifter"].values):
            raise RuntimeError(
                "ideal phase shifter are not modeled. Please remove all trafo with "
                "pp_net.trafo[\"tap_phase_shifter\"] set to True.")
        tap_angles_ = 1.0 * pp_net.trafo["tap_step_degree"].values
        tap_angles_[~np.isfinite(tap_angles_)] = 0.
        tap_angles_ = np.deg2rad(tap_angles_)
        trafo_r, trafo_x, trafo_b = \
            converter.get_trafo_param(tap_step_pct,
                                      tap_pos,
                                      tap_angles_,  # in radian !
                                      is_tap_hv_side,
                                      pp_net.bus.loc[pp_net.trafo["hv_bus"]]["vn_kv"],
                                      pp_net.bus.loc[pp_net.trafo["lv_bus"]]["vn_kv"],
                                      pp_net.trafo["vk_percent"].values,
                                      pp_net.trafo["vkr_percent"].values,
                                      pp_net.trafo["sn_mva"].values,
                                      pp_net.trafo["pfe_kw"].values,
                                      pp_net.trafo["i0_percent"].values,
                                      )
        # pandapower trafo parameters
        ppc = copy.deepcopy(pp_net._ppc)
        bus_lookup = pp_net["_pd2ppc_lookups"]["bus"]
        trafo_df = pp_net["trafo"]
        lv_bus = get_trafo_values(trafo_df, "lv_bus")
        vn_lv = ppc["bus"][bus_lookup[lv_bus], BASE_KV]
        vn_trafo_hv, vn_trafo_lv, shift_pp = _calc_tap_from_dataframe(
            pp_net, trafo_df)
        ratio = _calc_nominal_ratio_from_dataframe(ppc, trafo_df, vn_trafo_hv,
                                                   vn_trafo_lv, bus_lookup)
        r_t, x_t, b_t = _calc_r_x_y_from_dataframe(pp_net, trafo_df,
                                                   vn_trafo_lv, vn_lv,
                                                   pp_net.sn_mva)

        # check where there are mismatch if any
        val_r_pp = r_t
        val_r_me = trafo_r
        all_equals_r = np.abs(val_r_pp - val_r_me) <= self.tol
        if not np.all(all_equals_r):
            test_ok = False
            print(
                f"\t Error: some trafo resistance are not equal, max error: {np.max(np.abs(val_r_pp - val_r_me)):.5f}"
            )

        val_x_pp = x_t
        val_x_me = trafo_x
        all_equals_x = np.abs(val_x_pp - val_x_me) <= self.tol
        assert np.all(all_equals_x), f"\t Error: some trafo x are not equal, max error: " \
                                     f"{np.max(np.abs(val_x_pp - val_x_me)):.5f}"

        val_ib_pp = np.imag(b_t)
        val_ib_me = np.imag(trafo_b)
        all_equals_imag_b = np.abs(val_ib_pp - val_ib_me) <= self.tol
        assert np.all(all_equals_imag_b), f"\t Error: some trafo (imag) b are not equal, max error: " \
                                          f"{np.max(np.abs(val_ib_pp - val_ib_me)):.5f}"

        val_reb_pp = np.real(b_t)
        val_reb_me = np.real(trafo_b)
        all_equals_real_b = np.abs(val_reb_pp - val_reb_me) <= self.tol
        assert np.all(all_equals_real_b), f"\t Error: some trafo (real) b are not equal, max error: " \
                                          f"{np.max(np.abs(val_reb_pp - val_reb_me)):.5f}"