Skip to content

State not reset on failed run for run_timeseries with continue_on_divergence=True #3073

Description

@garctaedius

Bug report checklist

  • Searched the issues page for similar reports

  • Read the relevant sections of the documentation

  • Browse the tutorials and tests for usefull code snippets and examples of use

  • Reproduced the issue after updating with pip install --upgrade pandapower (or git pull)

  • Tried basic troubleshooting (if a bug/error) like restarting the interpreter and checking the pythonpath

Issue Description and Traceback

When running a timeseries using run_timeseries some part of the state (_pcc) become unstable after a non-converged run, but are then reused for the next step if continue_on_divergence=True. This can be avoided by setting recycle=None, but then recycling is never used, which causes a huge slowdown. I suggest the state is simply reset after every failed run.

In the current state, with some controllers in place, running a simulation where one time step does not converge causes all subsequent runs to also fail.

Expected Behavior

_pcc should be reset after a failed run. Right now, I have to monkey-patch the run_time_step function to add this functionality myself. See the example for my solution.

(as an aside, in creating the patch, I noticed that neither net.converged nor ts_variables["converged"] actually update to False when a run fails)

(another aside: as you can see in the example, logging simply prints the errors to the terminal by default, messing with the tqdm progress bar. Maybe consider making the logger use tqdm.write? Or maybe not, I just do it myself now which works fine. Maybe it's up to the user to log in their own way.)

Reproducible Example

import pandapower.timeseries.run_time_series as rts
import pandas as pd
from pandapower.timeseries.data_sources.frame_data import DFData
from pandapower.control import ConstControl, DiscreteTapControl
from pandapower.networks.create_examples import example_simple
from pandapower.timeseries import run_timeseries


def patch_run_time_step():
    # Currently, run_time_step does not reset the _ppc on a failed run.
    # This leads to a poor _ppc that means consecutive runs will also fail.
    # This can be avoided by setting recycle=None, but this means no data,
    # will be recycled, even on successful runs.
    # This wrapper checks if the network converged, and if it didn't,
    # resets the _ppc, preparing it for a new run.
    original = rts.run_time_step

    def wrapped(*args, **kwargs):
        net = args[0]
        try:
            return original(*args, **kwargs)
        finally:
            if not net._ppc["success"]:
                net._ppc = None

    rts.run_time_step = wrapped


load_ds = DFData(pd.DataFrame([2.0, 1000.0, 2.0]))
def create_example_net():
    net = example_simple()

    # Create ConstControl for three runs, the first and last with
    # reasonable values, and the middle one unreasonable.
    ConstControl(net, element="load", element_index=net.load.index,
                 variable="p_mw", data_source=load_ds,
                 profile_name=net.load.index)

    # Create a controller that will not be reset on a failed run.
    DiscreteTapControl(net=net, element_index=0, side="hv",
                       vm_lower_pu=0.99, vm_upper_pu=1.01)

    return net


net = create_example_net()

# Running the timeseries now will cause the second run to fail, creating an
# unstable _ppc state that will cause the last run to also fail.
run_timeseries(net, range(len(load_ds.df)), continue_on_divergence=True)

# OUTPUT:
# 67 % |██████████████████████████████████                   | 2/3 [00:03 < 00:01,  1.92s/it]
# CalculationNotConverged at time step 1
# CalculationNotConverged at time step 2
# 100 % |███████████████████████████████████████████████████ | 3/3 [00:03 < 00:00,  1.29s/it]


# Patch this by resetting _ppc after a failed run
patch_run_time_step()

# Now run timeseries
net = create_example_net()
run_timeseries(net, range(len(load_ds.df)), continue_on_divergence=True)

# OUTPUT:
# 67 % |██████████████████████████████████                   | 2/3 [00:00 < 00:00,  6.62it/s]
# CalculationNotConverged at time step 1
# 100 % |███████████████████████████████████████████████████ | 3/3 [00:00 < 00:00,  7.73it/s]

Installed Versions

  • Operating System name/version: Ubuntu
  • python version: 3.13.3
  • pandas version: 2.3.3
  • networkx version: 3.6.1
  • scipy version: 1.18.0
  • numpy version: 2.4.6
  • packaging version: 26.2
  • tqdm version: 4.68.4
  • deepdiff version: 9.1.0

Label

  • Relevant labels are selected

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions