1
|
|
# Copyright (c) 2020 by Fraunhofer Institute for Energy Economics
|
2
|
|
# and Energy System Technology (IEE), Kassel. All rights reserved.
|
3
|
|
# Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
|
4
|
|
|
5
|
1
|
import tempfile
|
6
|
|
|
7
|
1
|
import pandapipes as ppipes
|
8
|
1
|
from pandapipes.pipeflow import PipeflowNotConverged
|
9
|
1
|
from pandapower.control.util.diagnostic import control_diagnostic
|
10
|
1
|
from pandapower.timeseries.output_writer import OutputWriter
|
11
|
1
|
from pandapower.timeseries.run_time_series import init_time_series as init_time_series_pp, cleanup, run_loop
|
12
|
|
|
13
|
1
|
try:
|
14
|
1
|
import pplog as logging
|
15
|
1
|
except ImportError:
|
16
|
1
|
import logging
|
17
|
|
|
18
|
1
|
logger = logging.getLogger(__name__)
|
19
|
1
|
logger.setLevel(level=logging.WARNING)
|
20
|
|
|
21
|
|
|
22
|
1
|
def init_default_outputwriter(net, time_steps, **kwargs):
|
23
|
|
"""
|
24
|
|
Creates a default output writer for the time series calculation.
|
25
|
|
|
26
|
|
:param net: The pandapipes format network
|
27
|
|
:type net: pandapipesNet
|
28
|
|
:param timesteps: Time steps to calculate as list
|
29
|
|
:type timesteps: list
|
30
|
|
:return: ow - The default output writer
|
31
|
|
:rtype: pandapower.timeseries.output_writer.OutputWriter
|
32
|
|
"""
|
33
|
1
|
output_writer = kwargs.get("output_writer", None)
|
34
|
1
|
if output_writer is not None:
|
35
|
|
# write the output_writer to net
|
36
|
0
|
logger.warning("deprecated: output_writer should not be given to run_timeseries(). "
|
37
|
|
"This overwrites the stored one in net.output_writer.")
|
38
|
0
|
net.output_writer.iat[0, 0] = output_writer
|
39
|
1
|
if "output_writer" not in net or net.output_writer.iat[0, 0] is None:
|
40
|
1
|
ow = OutputWriter(net, time_steps, output_path=tempfile.gettempdir(), log_variables=[])
|
41
|
1
|
ow.log_variable('res_sink', 'mdot_kg_per_s')
|
42
|
1
|
ow.log_variable('res_source', 'mdot_kg_per_s')
|
43
|
1
|
ow.log_variable('res_ext_grid', 'mdot_kg_per_s')
|
44
|
1
|
ow.log_variable('res_pipe', 'v_mean_m_per_s')
|
45
|
1
|
ow.log_variable('res_junction', 'p_bar')
|
46
|
1
|
ow.log_variable('res_junction', 't_k')
|
47
|
1
|
logger.info("No output writer specified. Using default:")
|
48
|
1
|
logger.info(ow)
|
49
|
|
|
50
|
|
|
51
|
1
|
def pf_not_converged(time_step, ts_variables):
|
52
|
|
"""
|
53
|
|
|
54
|
|
:param time_step: Time step to be calculated
|
55
|
|
:type time_step: int
|
56
|
|
:param ts_variables: Contains settings for controller and time series simulation. \n
|
57
|
|
See init_time_series()
|
58
|
|
:type ts_variables: dict
|
59
|
|
:return: No output
|
60
|
|
"""
|
61
|
0
|
logger.error('PipeflowNotConverged at time step %s' % time_step)
|
62
|
0
|
if not ts_variables["continue_on_divergence"]:
|
63
|
0
|
raise PipeflowNotConverged
|
64
|
|
|
65
|
|
|
66
|
1
|
def init_time_series(net, time_steps, continue_on_divergence=False,
|
67
|
|
verbose=True, **kwargs):
|
68
|
|
"""
|
69
|
|
Initializes the time series calculation. Creates the dict ts_variables, which includes
|
70
|
|
necessary variables for the time series / control function.
|
71
|
|
|
72
|
|
:param net: The pandapipes format network
|
73
|
|
:type net: pandapipesNet
|
74
|
|
:param time_steps: Time steps to calculate as list or tuple (start, stop). If None, all time
|
75
|
|
steps from provided data source are simulated.
|
76
|
|
:type time_steps: list or tuple
|
77
|
|
:param continue_on_divergence: If True, time series calculation continues in case of errors.
|
78
|
|
:type continue_on_divergence: bool, default False
|
79
|
|
:param verbose: Prints progress bar or logger debug messages
|
80
|
|
:type verbose: bool, default True
|
81
|
|
:param kwargs: Keyword arguments for run_control and runpp
|
82
|
|
:type kwargs: dict
|
83
|
|
:return: ts_variables, kwargs
|
84
|
|
:rtype: dict, dict
|
85
|
|
"""
|
86
|
|
|
87
|
1
|
run = kwargs.get("run", ppipes.pipeflow)
|
88
|
1
|
init_default_outputwriter(net, time_steps, **kwargs)
|
89
|
|
|
90
|
1
|
ts_variables = init_time_series_pp(net, time_steps, continue_on_divergence, verbose, run=run, **kwargs)
|
91
|
|
|
92
|
1
|
ts_variables["errors"] = (PipeflowNotConverged)
|
93
|
|
|
94
|
1
|
return ts_variables
|
95
|
|
|
96
|
|
|
97
|
1
|
def run_timeseries(net, time_steps=None, continue_on_divergence=False, verbose=True, **kwargs):
|
98
|
|
"""
|
99
|
|
Time Series main function
|
100
|
|
|
101
|
|
Execution of pipe flow calculations for a time series using controllers.
|
102
|
|
Optionally other functions than pipeflow can be called by setting the run function in kwargs.
|
103
|
|
|
104
|
|
.. note:: Refers to pandapower power flow.
|
105
|
|
|
106
|
|
:param net: The pandapipes format network
|
107
|
|
:type net: pandapipesNet
|
108
|
|
:param time_steps: Time steps to calculate as list or tuple(start, stop). If None, all time steps
|
109
|
|
from provided data source are simulated.
|
110
|
|
:type time_steps: list or tuple, default None
|
111
|
|
:param continue_on_divergence: If True, time series calculation continues in case of errors.
|
112
|
|
:type continue_on_divergence: bool, default False
|
113
|
|
:param verbose: Prints progress bar or if *logger.level == Debug*, it prints debug messages
|
114
|
|
:type verbose: bool, default True
|
115
|
|
:param kwargs: Keyword arguments for run_control and runpp
|
116
|
|
:type kwargs: dict
|
117
|
|
:return: No output
|
118
|
|
"""
|
119
|
1
|
ts_variables = init_time_series(net, time_steps, continue_on_divergence, verbose, **kwargs)
|
120
|
|
|
121
|
1
|
control_diagnostic(net)
|
122
|
1
|
run_loop(net, ts_variables, **kwargs)
|
123
|
|
|
124
|
|
# cleanup functions after the last time step was calculated
|
125
|
1
|
cleanup(ts_variables)
|