Repository: e2nIEE/pandapower

Issue:
calculate_voltage_angles set to True by default
### Feature Checklist

- [X] Searched the [issues page](https://github.com/e2nIEE/pandapower/issues) for similar reports

- [X] Read the relevant sections of the [documentation](https://pandapower.readthedocs.io/en/latest/about.html)

- [X] Browse the [tutorials](https://github.com/e2nIEE/pandapower/tree/develop/tutorials) and [tests](https://github.com/e2nIEE/pandapower/tree/develop/pandapower/test) for usefull code snippets and examples of use


### Issue

So many times we encounter discrepancies in the results of power flow calculation from the expected results. And a lot of times this parameter is the clue. So the benefit in slightly better performance does not outweigh the serious drawback of having wrong results if this (not well documented) parameter is not set to True.

If someone wants to save time with ignoring voltage angles, this parameter should be set to False manually.

Will change this to always default to "False".

### Label

- [X] Relevant labels are selected



Discussion:

Resolving patch:
diff --git a/pandapower/auxiliary.py b/pandapower/auxiliary.py
--- a/pandapower/auxiliary.py
+++ b/pandapower/auxiliary.py
@@ -1352,9 +1352,7 @@ def _init_runpp_options(net, algorithm, calculate_voltage_angles, init,
 
     default_max_iteration = {"nr": 10, "iwamoto_nr": 10, "bfsw": 100, "gs": 10000, "fdxb": 30,
                              "fdbx": 30}
-    with_ssc = len(net.ssc.query("in_service & controllable")) > 0
-    with_facts = len(net.svc.query("in_service & controllable")) > 0 or \
-                 len(net.tcsc.query("in_service & controllable")) > 0 or with_ssc
+    with_facts = net.svc.in_service.any() or net.tcsc.in_service.any() or net.ssc.in_service.any()
     if max_iteration == "auto":
         # tdpf is an option rather than algorithm; svc need more iterations to converge
         max_iteration = 30 if tdpf or with_facts else default_max_iteration[algorithm]
@@ -1371,10 +1369,10 @@ def _init_runpp_options(net, algorithm, calculate_voltage_angles, init,
         init_vm_pu = None
         init_va_degree = None
 
-    # SSC devices can lead to the grid having isolated buses from the point of view of DC power flow, so choose 'flat'
+    # FACTS devices can lead to the grid having isolated buses from the point of view of DC power flow, so choose 'flat'
     if init == "auto":
         if init_va_degree is None or (isinstance(init_va_degree, str) and init_va_degree == "auto"):
-            init_va_degree = "dc" if calculate_voltage_angles and not with_ssc else "flat"
+            init_va_degree = "dc" if calculate_voltage_angles and not with_facts else "flat"
         if init_vm_pu is None or (isinstance(init_vm_pu, str) and init_vm_pu == "auto"):
             init_vm_pu = (net.ext_grid.vm_pu.values.sum() + net.gen.vm_pu.values.sum()) / \
                          (len(net.ext_grid.vm_pu.values) + len(net.gen.vm_pu.values))
diff --git a/pandapower/run.py b/pandapower/run.py
--- a/pandapower/run.py
+++ b/pandapower/run.py
@@ -68,7 +68,7 @@ def set_user_pf_options(net, overwrite=False, **kwargs):
         net.user_pf_options.update(additional_kwargs)
 
 
-def runpp(net, algorithm='nr', calculate_voltage_angles="auto", init="auto",
+def runpp(net, algorithm='nr', calculate_voltage_angles=True, init="auto",
           max_iteration="auto", tolerance_mva=1e-8, trafo_model="t",
           trafo_loading="current", enforce_q_lims=False, check_connectivity=True,
           voltage_depend_loads=True, consider_line_temperature=False,
diff --git a/pandapower/timeseries/output_writer.py b/pandapower/timeseries/output_writer.py
--- a/pandapower/timeseries/output_writer.py
+++ b/pandapower/timeseries/output_writer.py
@@ -387,7 +387,7 @@ def _init_ppc_logging(self, table, variable, net, eval_function, eval_name):
         ppc = net["_ppc"]
         if ppc is None:
             # if no ppc is in net-> create one
-            options = dict(algorithm='nr', calculate_voltage_angles="auto", init="auto",
+            options = dict(algorithm='nr', calculate_voltage_angles=True, init="auto",
                            max_iteration="auto", tolerance_mva=1e-8, trafo_model="t",
                            trafo_loading="current", enforce_q_lims=False, check_connectivity=True,
                            voltage_depend_loads=True, consider_line_temperature=False)


Test patch:
diff --git a/pandapower/test/converter/test_from_cim.py b/pandapower/test/converter/test_from_cim.py
--- a/pandapower/test/converter/test_from_cim.py
+++ b/pandapower/test/converter/test_from_cim.py
@@ -2,6 +2,8 @@
 import pytest
 import math
 import pandas as pd
+
+import pandapower as pp
 from pandapower.test import test_path
 
 from pandapower.converter import from_cim as cim2pp
@@ -70,7 +72,9 @@ def example_multivoltage():
 
     cgmes_files = [os.path.join(folder_path, 'example_multivoltage.zip')]
 
-    return cim2pp.from_cim(file_list=cgmes_files)
+    net = cim2pp.from_cim(file_list=cgmes_files)
+    pp.runpp(net, calculate_voltage_angles="auto")
+    return net
 
 
 def test_example_multivoltage_res_xward(example_multivoltage):
diff --git a/pandapower/test/estimation/test_wls_estimation.py b/pandapower/test/estimation/test_wls_estimation.py
--- a/pandapower/test/estimation/test_wls_estimation.py
+++ b/pandapower/test/estimation/test_wls_estimation.py
@@ -425,7 +425,7 @@ def test_cigre_network(init='flat'):
                               bus)
 
     # 2. Do state estimation
-    if not estimate(net, init="flat", calculate_voltage_angles=False):
+    if not estimate(net, init="flat", calculate_voltage_angles=True):
         raise AssertionError("Estimation failed!")
 
     v_result = net.res_bus_est.vm_pu.values
diff --git a/pandapower/test/loadflow/test_facts.py b/pandapower/test/loadflow/test_facts.py
--- a/pandapower/test/loadflow/test_facts.py
+++ b/pandapower/test/loadflow/test_facts.py
@@ -386,7 +386,7 @@ def test_tcsc_simple3():
 
     pp.create_tcsc(net, 1, 2, xl, xc, 5, 170, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180)
 
-    runpp_with_consistency_checks(net)
+    runpp_with_consistency_checks(net, init="dc")
 
     net_ref = copy_with_impedance(net)
     pp.runpp(net_ref)
@@ -422,7 +422,7 @@ def test_compare_to_impedance():
 
     pp.create_tcsc(net, 1, 2, xl, xc, -20, 170, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180)
 
-    runpp_with_consistency_checks(net)
+    runpp_with_consistency_checks(net, init="dc")
 
     pp.create_impedance(net_ref, 1, 2, 0, net.res_tcsc.x_ohm.at[0] / baseZ, baseMVA)
 
@@ -438,7 +438,7 @@ def test_compare_to_impedance():
     # compare when not controllable
     net.tcsc.thyristor_firing_angle_degree = net.res_tcsc.thyristor_firing_angle_degree
     net.tcsc.controllable = False
-    runpp_with_consistency_checks(net)
+    runpp_with_consistency_checks(net, init="dc")
 
     compare_tcsc_impedance(net, net_ref, 0, 0)
     assert np.allclose(net._ppc["internal"]["J"].toarray(), net_ref._ppc["internal"]["J"].toarray(), rtol=0, atol=5e-5)
@@ -463,7 +463,7 @@ def test_tcsc_case_study():
     net_ref = net.deepcopy()
 
     pp.create_tcsc(net, f, aux, xl, xc, -100, 100, controllable=True)
-    pp.runpp(net)
+    pp.runpp(net, init="dc")
 
     pp.create_impedance(net_ref, f, aux, 0, net.res_tcsc.at[0, "x_ohm"] / baseZ, baseMVA)
     pp.runpp(net_ref)
@@ -607,14 +607,14 @@ def test_svc_tcsc_case_study():
 
     pp.create_svc(net, net.bus.loc[net.bus.name == "B7"].index.values[0], 1, -10, 1., 90)
 
-    pp.runpp(net)
+    pp.runpp(net, init="dc")
 
     net_ref = copy_with_impedance(net)
     pp.runpp(net_ref)
     compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index)
 
     net.gen.slack_weight = 1
-    pp.runpp(net, distributed_slack=True)
+    pp.runpp(net, distributed_slack=True, init="dc")
     net_ref = copy_with_impedance(net)
     pp.runpp(net_ref, distributed_slack=True)
     compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index)
diff --git a/pandapower/test/loadflow/test_runpp.py b/pandapower/test/loadflow/test_runpp.py
--- a/pandapower/test/loadflow/test_runpp.py
+++ b/pandapower/test/loadflow/test_runpp.py
@@ -124,7 +124,7 @@ def test_runpp_init():
     b3 = pp.create_bus(net, vn_kv=0.4)
     tidx = pp.create_transformer(net, hv_bus=b2, lv_bus=b3, std_type="0.25 MVA 20/0.4 kV")
     net.trafo.shift_degree.at[tidx] = 70
-    pp.runpp(net)
+    pp.runpp(net, calculate_voltage_angles="auto")
     va = net.res_bus.va_degree.at[4]
     pp.runpp(net, calculate_voltage_angles=True, init_va_degree="dc")
     assert np.allclose(va - net.trafo.shift_degree.at[tidx], net.res_bus.va_degree.at[4])
@@ -237,12 +237,12 @@ def z_switch_net():
 def test_z_switch(z_switch_net, numba):
     net = z_switch_net
     pp.runpp(net, numba=numba, switch_rx_ratio=1)
-    assert net.res_bus.vm_pu.at[1] == net.res_bus.vm_pu.at[2]
+    assert pytest.approx(net.res_bus.vm_pu.at[1], abs=1e-9) == net.res_bus.vm_pu.at[2]
 
     net_zero_z_switch = copy.deepcopy(net)
     net_zero_z_switch.switch.z_ohm = 0
     pp.runpp(net_zero_z_switch, numba=numba, switch_rx_ratio=1)
-    assert net_zero_z_switch.res_bus.vm_pu.at[0] == net_zero_z_switch.res_bus.vm_pu.at[2]
+    assert pytest.approx(net_zero_z_switch.res_bus.vm_pu.at[0], abs=1e-9) == net_zero_z_switch.res_bus.vm_pu.at[2]
 
 
 @pytest.fixture
@@ -566,11 +566,11 @@ def test_bsfw_algorithm_with_branch_loops():
                    std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line meshed")
     net.switch.loc[:, "closed"] = True
 
-    pp.runpp(net)
+    pp.runpp(net, calculate_voltage_angles="auto")
     vm_nr = net.res_bus.vm_pu
     va_nr = net.res_bus.va_degree
 
-    pp.runpp(net, algorithm='bfsw')
+    pp.runpp(net, algorithm='bfsw', calculate_voltage_angles="auto")
     vm_alg = net.res_bus.vm_pu
     va_alg = net.res_bus.va_degree
     assert np.allclose(vm_nr, vm_alg)
@@ -583,8 +583,8 @@ def test_pypower_algorithms_iter():
     for alg in alg_to_test:
         for net in result_test_network_generator(skip_test_impedance=True):
             try:
-                runpp_with_consistency_checks(net, enforce_q_lims=True, algorithm=alg)
-                runpp_with_consistency_checks(net, enforce_q_lims=False, algorithm=alg)
+                runpp_with_consistency_checks(net, enforce_q_lims=True, algorithm=alg, calculate_voltage_angles="auto")
+                runpp_with_consistency_checks(net, enforce_q_lims=False, algorithm=alg, calculate_voltage_angles="auto")
             except (AssertionError):
                 raise UserWarning("Consistency Error after adding %s" % net.last_added_case)
             except(LoadflowNotConverged):
@@ -928,12 +928,12 @@ def test_storage_pf():
 
 def test_add_element_and_init_results():
     net = simple_four_bus_system()
-    pp.runpp(net, init="flat")
+    pp.runpp(net, init="flat", calculate_voltage_angles="auto")
     pp.create_bus(net, vn_kv=20.)
     pp.create_line(net, from_bus=2, to_bus=3, length_km=1, name="new line" + str(1),
                    std_type="NAYY 4x150 SE")
     try:
-        pp.runpp(net, init="results")
+        pp.runpp(net, init="results", calculate_voltage_angles="auto")
         assert False
     except UserWarning:
         pass
diff --git a/pandapower/test/toolbox/test_grid_modification.py b/pandapower/test/toolbox/test_grid_modification.py
--- a/pandapower/test/toolbox/test_grid_modification.py
+++ b/pandapower/test/toolbox/test_grid_modification.py
@@ -565,7 +565,7 @@ def test_replace_ext_grid_gen():
     for i in range(2):
         net = nw.example_simple()
         net.ext_grid["uuid"] = "test"
-        pp.runpp(net)
+        pp.runpp(net, calculate_voltage_angles="auto")
         assert list(net.res_ext_grid.index.values) == [0]
         pp.create_group(net, ["line", "ext_grid"], [[0], [0]])