Python Logging Module¶
You can also control the verbosity of Python's logging messages by setting the logging level to ERROR, WARNING, INFO, or DEBUG. This can be configured independently for different modules.
Let's turn on INFO level messages for the optimization module:
import pypsa
network = pypsa.examples.ac_dc_meshed()
INFO:pypsa.network.io:Imported network 'AC-DC-Meshed' has buses, carriers, generators, global_constraints, lines, links, loads
import logging
pypsa.optimization.optimize.logger.setLevel(logging.INFO)
network.optimize()
/tmp/ipykernel_8874/1123755349.py:5: FutureWarning: The default value of `include_objective_constant` will change from True to False in version 2.0. Set `include_objective_constant` explicitly to suppress this warning. Using False improves LP numerical conditioning by not including the objective constant as a variable. network.optimize() WARNING:pypsa.consistency:The following lines have zero x, which could break the linear load flow: Index(['2', '3', '4'], dtype='object', name='name')
WARNING:pypsa.consistency:The following lines have zero r, which could break the linear load flow: Index(['0', '1', '5', '6'], dtype='object', name='name')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.model:Solver options: - log_to_console: False
INFO:linopy.io: Writing time: 0.07s
INFO:linopy.constants: Optimization successful: Status: ok Termination condition: optimal Solution: 188 primals, 468 duals Objective: -3.47e+06 Solver model: available Solver message: Optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-ext-p-lower, Generator-ext-p-upper, Line-ext-s-lower, Line-ext-s-upper, Link-ext-p-lower, Link-ext-p-upper, Kirchhoff-Voltage-Law were not assigned to the network.
('ok', 'optimal')
Now let's reduce verbosity by setting the optimization module to only show WARNING level messages.
pypsa.optimization.optimize.logger.setLevel(logging.WARNING)
network.optimize()
/tmp/ipykernel_8874/1121149820.py:3: FutureWarning: The default value of `include_objective_constant` will change from True to False in version 2.0. Set `include_objective_constant` explicitly to suppress this warning. Using False improves LP numerical conditioning by not including the objective constant as a variable. network.optimize() WARNING:pypsa.consistency:The following lines have zero x, which could break the linear load flow: Index(['2', '3', '4'], dtype='object', name='name')
WARNING:pypsa.consistency:The following lines have zero r, which could break the linear load flow: Index(['0', '1', '5', '6'], dtype='object', name='name')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.model:Solver options: - log_to_console: False
INFO:linopy.io: Writing time: 0.06s
INFO:linopy.constants: Optimization successful: Status: ok Termination condition: optimal Solution: 188 primals, 468 duals Objective: -3.47e+06 Solver model: available Solver message: Optimal
('ok', 'optimal')
Now let's turn on DEBUG level messages for the power flow module to see the most detailed output.
pypsa.network.power_flow.logger.setLevel(logging.DEBUG)
out = network.lpf()
DEBUG:pypsa.network.power_flow:Slack bus for sub-network 0 is Manchester
DEBUG:pypsa.network.power_flow:Slack bus for sub-network 1 is Norwich DC
DEBUG:pypsa.network.power_flow:Slack bus for sub-network 2 is Frankfurt
DEBUG:pypsa.network.power_flow:No slack generator found in sub-network 3, using Norway Wind as the slack generator
DEBUG:pypsa.network.power_flow:Slack bus for sub-network 3 is Norway
DEBUG:pypsa.network.power_flow:Slack bus for sub-network 0 is Manchester
INFO:pypsa.network.power_flow:Performing linear load-flow on AC sub-network <pypsa.SubNetwork object at 0x7aa17fb40270> for snapshot(s) DatetimeIndex(['2015-01-01 00:00:00', '2015-01-01 01:00:00',
'2015-01-01 02:00:00', '2015-01-01 03:00:00',
'2015-01-01 04:00:00', '2015-01-01 05:00:00',
'2015-01-01 06:00:00', '2015-01-01 07:00:00',
'2015-01-01 08:00:00', '2015-01-01 09:00:00'],
dtype='datetime64[ns]', name='snapshot', freq=None)
DEBUG:pypsa.network.power_flow:Slack bus for sub-network 1 is Norwich DC
INFO:pypsa.network.power_flow:Performing linear load-flow on DC sub-network <pypsa.SubNetwork object at 0x7aa17fb41370> for snapshot(s) DatetimeIndex(['2015-01-01 00:00:00', '2015-01-01 01:00:00',
'2015-01-01 02:00:00', '2015-01-01 03:00:00',
'2015-01-01 04:00:00', '2015-01-01 05:00:00',
'2015-01-01 06:00:00', '2015-01-01 07:00:00',
'2015-01-01 08:00:00', '2015-01-01 09:00:00'],
dtype='datetime64[ns]', name='snapshot', freq=None)
DEBUG:pypsa.network.power_flow:Slack bus for sub-network 2 is Frankfurt
INFO:pypsa.network.power_flow:Performing linear load-flow on AC sub-network <pypsa.SubNetwork object at 0x7aa17fb02550> for snapshot(s) DatetimeIndex(['2015-01-01 00:00:00', '2015-01-01 01:00:00',
'2015-01-01 02:00:00', '2015-01-01 03:00:00',
'2015-01-01 04:00:00', '2015-01-01 05:00:00',
'2015-01-01 06:00:00', '2015-01-01 07:00:00',
'2015-01-01 08:00:00', '2015-01-01 09:00:00'],
dtype='datetime64[ns]', name='snapshot', freq=None)
DEBUG:pypsa.network.power_flow:Slack bus for sub-network 3 is Norway
INFO:pypsa.network.power_flow:Performing linear load-flow on AC sub-network <pypsa.SubNetwork object at 0x7aa17fb03a50> for snapshot(s) DatetimeIndex(['2015-01-01 00:00:00', '2015-01-01 01:00:00',
'2015-01-01 02:00:00', '2015-01-01 03:00:00',
'2015-01-01 04:00:00', '2015-01-01 05:00:00',
'2015-01-01 06:00:00', '2015-01-01 07:00:00',
'2015-01-01 08:00:00', '2015-01-01 09:00:00'],
dtype='datetime64[ns]', name='snapshot', freq=None)
Finally, let's turn off messages for the power flow module by setting it back to ERROR level.
pypsa.network.power_flow.logger.setLevel(logging.ERROR)
out = network.lpf()
# Access a deprecated feature to see a warning
network.components.generators.component_names
/tmp/ipykernel_8874/1732202595.py:2: DeprecationWarning: c.component_names is deprecated, use c.names instead network.components.generators.component_names
Index(['Manchester Wind', 'Manchester Gas', 'Norway Wind', 'Norway Gas',
'Frankfurt Wind', 'Frankfurt Gas'],
dtype='object', name='name')
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
network.components.generators.component_names
Index(['Manchester Wind', 'Manchester Gas', 'Norway Wind', 'Norway Gas',
'Frankfurt Wind', 'Frankfurt Gas'],
dtype='object', name='name')
Solver Output¶
The log_to_console parameter controls whether the solver (e.g., HiGHS, Gurobi) prints its progress to the console. By default, pypsa.options.params.optimize.log_to_console is True, but in these documentation examples it's set to False for cleaner output.
Let's see the difference:
# With log_to_console=False (default in docs): only Python logging messages
network.optimize(log_to_console=False)
/tmp/ipykernel_8874/733640962.py:2: FutureWarning: The default value of `include_objective_constant` will change from True to False in version 2.0. Set `include_objective_constant` explicitly to suppress this warning. Using False improves LP numerical conditioning by not including the objective constant as a variable. network.optimize(log_to_console=False) WARNING:pypsa.consistency:Encountered nan's in varying data 'p0' for columns ['Norwich Converter', 'Norway Converter', 'Bremen Converter', 'DC link'] of component 'Link'.
WARNING:pypsa.consistency:Encountered nan's in varying data 'p1' for columns ['Norwich Converter', 'Norway Converter', 'Bremen Converter', 'DC link'] of component 'Link'.
WARNING:pypsa.consistency:The following lines have zero x, which could break the linear load flow: Index(['2', '3', '4'], dtype='object', name='name')
WARNING:pypsa.consistency:The following lines have zero r, which could break the linear load flow: Index(['0', '1', '5', '6'], dtype='object', name='name')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.model:Solver options: - log_to_console: False
INFO:linopy.io: Writing time: 0.06s
INFO:linopy.constants: Optimization successful: Status: ok Termination condition: optimal Solution: 188 primals, 468 duals Objective: -3.47e+06 Solver model: available Solver message: Optimal
('ok', 'optimal')
# With log_to_console=True (default setting): verbose solver output
network.optimize(log_to_console=True)
/tmp/ipykernel_8874/2160006920.py:2: FutureWarning: The default value of `include_objective_constant` will change from True to False in version 2.0. Set `include_objective_constant` explicitly to suppress this warning. Using False improves LP numerical conditioning by not including the objective constant as a variable. network.optimize(log_to_console=True) WARNING:pypsa.consistency:The following lines have zero x, which could break the linear load flow: Index(['2', '3', '4'], dtype='object', name='name')
WARNING:pypsa.consistency:The following lines have zero r, which could break the linear load flow: Index(['0', '1', '5', '6'], dtype='object', name='name')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.model:Solver options: - log_to_console: True
INFO:linopy.io: Writing time: 0.06s
INFO:linopy.constants: Optimization successful: Status: ok Termination condition: optimal Solution: 188 primals, 468 duals Objective: -3.47e+06 Solver model: available Solver message: Optimal
Running HiGHS 1.13.1 (git hash: 1d267d9): Copyright (c) 2026 under MIT licence terms
LP linopy-problem-_xw5vdda has 468 rows; 188 cols; 1007 nonzeros
Coefficient ranges:
Matrix [1e-02, 1e+00]
Cost [9e-03, 3e+03]
Bound [2e+07, 2e+07]
RHS [9e-01, 1e+03]
WARNING: Problem has some excessively large column bounds
WARNING: Consider scaling the bounds by 1e-2, or setting the user_bound_scale option to -5
Presolving model
391 rows, 187 cols, 930 nonzeros 0s
305 rows, 101 cols, 1042 nonzeros 0s
Dependent equations search running on 22 equations with time limit of 1000.00s
Dependent equations search removed 0 rows and 0 nonzeros in 0.00s (limit = 1000.00s)
303 rows, 99 cols, 1058 nonzeros 0s
Presolve reductions: rows 303(-165); columns 99(-89); nonzeros 1058(+51)
Solving the presolved LP
Using dual simplex solver
Iteration Objective Infeasibilities num(sum)
0 -2.1204510016e+07 Pr: 102(98953); Du: 0(4.73182e-11) 0.0s
126 -3.4742560405e+06 Pr: 0(0) 0.0s
Performed postsolve
Solving the original LP from the solution after postsolve
Model name : linopy-problem-_xw5vdda
Model status : Optimal
Simplex iterations: 126
Objective value : -3.4742560405e+06
P-D objective error : 1.3403192363e-16
HiGHS run time : 0.01
('ok', 'optimal')