Release Notes#
Upcoming Release#
Warning
The features listed below are not released yet, but will be part of the next release! To use the features already you have to install the master branch, e.g. pip install git+https://github.com/pypsa/pypsa#egg=pypsa.
PyPSA 0.26.2 (31st December 2023)#
Bugfix in the definition of spillage variables for storage units. Previously, the spillage variable creation was skipped in some cases due to a wrong condition check even though there was a positive inflow.
PyPSA 0.26.1 (29th December 2023)#
The output attribute
n_modintroduced in the previous version was removed since it contains duplicate information. Calculate the number of expanded modules withp_nom_opt / p_nom_modinstead.Bugfix in MGA function to correctly parse the
sensekeyword argument.Fix strict type compatibility issues with
pandas>=2.1causing problems for clustering.Removed
numexprversion constraint.
PyPSA 0.26.0 (4th December 2023)#
New Features
The
Networkclass has a new component for geometric shapes undern.shapes. It consists of ageopandasdataframe which can be used to store network related geographical data (for plotting, calculating potentials, etc). The dataframe has the columns geometry, component, idx and type. The columns component, idx and type do not require specific values, but allow for storing information about which components the shapes belong to. The coordinate reference system (CRS) of the shapes can be accessed and set via a new attributen.crs. For a transition period, the attributen.srid, which independently refers to the projection of the bus coordinates, is kept.Improvements to the network statistics module:
The statistics module now supports the consideration of multi-port links. An additional argument bus_carrier was added to the statistics functions to select the components that are attached to buses of a certain carrier.
The statistics module now supports the consideration of multiple investment periods. As soon as
n.snapshotsis a MultiIndex, the network statistics are calculated separately for each investment period.A new function
transmissionwas added to the statistics accessor. This function considers all lines and links that connect buses of the same carrier.The statistics functions now support the selection of single components in the
compsargument.
The plotting function
n.plot()now supports plotting of only a subset of network components by allowing that arguments likebus_sizes,link_widthsorlink_colorsdo no longer require to contain the full set of indices of a component.Add option to specify time-varying ramp rates for generators and links (
ramp_limit_upandramp_limit_down, e.g. undern.links_t.ramp_limit_up).Added attributes
p_nom_mod,e_nom_mod, ands_nom_modto components to consider capacity modularity. When this attribute is non-zero and the component is extendable, the component’s capacity can only be extended in multiples of the capacity modularity. The optimal number of components is stored asn_mod(such thatp_nom_mod * n_mod == p_nom_opt). The default is kept such that extendable components can be expanded continuously.
Bugfixes and Compatibiliity
Bugfix: In rolling horizon optimisation with unit commitment constraints, the generator status of the previously optimized time step is now considered.
Bugfix: Allow optimising the network for just subset of investment periods by using
n.optimize(multi_investment_periods=True, snapshots=...).Bugfix: The function
n.import_from_netcdf()failed when trying to import data from anxarrayobject.Bugfix: Fix global constraints for primary energy and transmission volume limits for networks with multiple investment periods.
Bugfix: Fix stand-by-costs optimization for latest
linopyversion.Resolve performance regression for multi-decade optimisation in highly meshed networks.
Compatibility with
pandas==2.1.Added Python 3.12 to CI and supported Python versions.
PyPSA 0.25.2 (30th September 2023)#
Add option to enable or disable nice carrier name in the statistics module, e.g.
n.statistics(nice_name=False).Add example in documentation for the statistics module.
Add example for stochastic optimization with PyPSA to the documentation.
Extended documentation for multi-decade optimization.
Bugfix: Use of
nice_nameskeyword argument inn.statistics.energy_balance().Bugfix: Correctly handle
p_nomorp_nom_optin power flow distributed slack.Bugfix: After the optimization the right-hand side and sign of global constraints were previously overwritten by altered values.
Bugfix: In netCDF export, typecasting to float32 after setting the compression encoding led to ignored compression encodings.
Bugfix: Handle solver options for CBC and GLPK for
n.lopf(pyomo=False).Bugfix: Handle cases with multi-decade optimisation, activated transmission limit and an empty list of lines or DC links.
PyPSA 0.25.1 (27th July 2023)#
New Features
The function
get_clustering_from_busmaphas a new argumentline_strategies.The
n.optimize()function gets a new keyword argumentassign_all_duals=Falsewhich controls whether all dual values or only those that already have a designated place in the network are assigned. (PyPSA/PyPSA#635)
Changes
The function
get_buses_linemap_and_lineswas deprecated, in favor of direct use ofaggregatebusesandaggregate_lines.Improve logging printout for rolling horizon optimization. (PyPSA/PyPSA#697, PyPSA/PyPSA#699)
The CI environment handling was migrated to
micromamba(PyPSA/PyPSA#688).
Bugfixes
The aggregation functions in the clustering module were adjusted to correctly handle infinity values (see pandas-dev/pandas#54161 for more details). (PyPSA/PyPSA#684)
The unit commitment formulation with a rolling horizon horizon was fixed in case of non-committable and committable generators with ramp limits. (PyPSA/PyPSA#686)
The clustering functionality was fixed in case of passing a subset of carriers that should be aggregated. (PyPSA/PyPSA#696)
When clustering, allow safe clustering of component attributes which are both static and dynamic. (PyPSA/PyPSA#700)
When assigning a new user-defined variable to the underlying optimization model, the assignment of the solution resulted in an error if the variable name did not match the pattern
{Component}-{Varname}. This has been fixed by ignoring variables that do not match the pattern during solution assignment. (PyPSA/PyPSA#693)Multilinks are now also handled automatically when importing a network from file. (PyPSA/PyPSA#702)
Multilink default efficiencies are always set to 1.0. (PyPSA/PyPSA#701)
For linearized unit commitment relaxation, some tightening additional constraints are only valid if start-up and shut-down costs are equal. These constraints are now skipped if this is not the case and a warning message is printed. (PyPSA/PyPSA#690)
Fix division in capacity factor calculation in statistics module when not aggregating in the time dimension. (PyPSA/PyPSA#687)
PyPSA 0.25.0 (13th July 2023)#
New Features
Stand-by costs: PyPSA now supports stand-by cost terms. A new column
stand_by_costwas added to generators and links. The stand-by cost is added to the objective function when callingn.optimize(). (PyPSA/PyPSA#659)Rolling horizon function: The
n.optimizeaccessor now provides functionality for rolling horizon optimisation usingn.optimize.optimize_with_rolling_horizon()which splits whole optimization of the whole time span into multiple subproblems which are solved consecutively. This is useful for operational optimizations with a high spatial resolution. (PyPSA/PyPSA#668)Modelling-to-generate-alternatives (MGA) function The
n.optimizeaccessor now provides functionality for running modelling-to-generate-alternatives (MGA) on previously solved networks usingn.optimize.optimize_mga(slack=..., weights=...). This is useful for exploring the near-optimal feasible space of the network. (PyPSA/PyPSA#672)
Changes
Multilinks by default: Links with multiple inputs/outputs are now supported by default. The Link component attributes are automatically extended if a link with
bus2,bus3, etc. are added to the network. Overriding component attributes at network initialisation is no longer required. (PyPSA/PyPSA#669)Spatial clustering refactored: The spatial clustering module was refactored. The changes lead to performance improvements and a more consistent clustering API. (PyPSA/PyPSA#673)
The network object has a new accessor
clusterwhich allows accessing clustering routines from the network itself. For example,n.cluster.cluster_spatially_by_kmeansreturns a spatially clustered version of the network.The default clustering strategies were refined. Per default, columns like
efficiencyandp_max_puare now aggregated by the capacity weighted mean.The clustering module now applies the custom strategies to time-dependant data.
The function
pypsa.clustering.spatial.get_clustering_from_busmapandpypsa.clustering.spatial.aggregategeneratorsnow allows the passing of a list of buses for which aggregation of all carriers is desired. Generation from a carrier at a bus is aggregated now if: It is either in the passed list of aggregated carriers, or in the list of aggregated buses.Take generator strategies for time-series into account. Before, time-series would always be aggregated by summing. (PyPSA/PyPSA#670)
The deprecated
networkclusteringmodule was removed. (PyPSA/PyPSA#675)
A new function get_country_and_carrier was added to the statistics module in order to group statistics by country and carrier. (PyPSA/PyPSA#678)
NetCDF file compression is now disabled by default when exporting networks. (PyPSA/PyPSA#679)
Breaking Changes
The
Clusteringclass no longer contains a positive and negative linemap.Outdated examples were removed. (PyPSA/PyPSA#674)
Bugfixes
In the statistics module, the calculation of operational costs of storage units was corrected. (PyPSA/PyPSA#671)
PyPSA 0.24.0 (27th June 2023)#
PyPSA now supports quadratic marginal cost terms. A new column marginal_cost_quadratic was added to generators, links, stores and storage units. The quadratic marginal cost is added to the objective function when calling
n.optimize(). This requires a solver that is able to solve quadratic problems, for instance, HiGHS, Gurobi, Xpress, or CPLEX.The statistics function now allows calculating energy balances
n.statistics.energy_balance()and dispatchn.statistics.dispatch(), as well as time series (e.g.n.statistics.curtailment(aggregate_time=False)). The energy balance can be configured to yield energy balance time series for each bus.The statistics function
n.statistics()now also supports the calculation of the market values of components.The function
n.set_snapshots()now takes two optional keyword arguments;default_snapshot_weightingsto change the default snapshot weightings, andweightings_from_timedeltato compute the weights if snapshots are of typepd.DatetimeIndex.The function
n.lopf()is deprecated in favour of the linopy-based implementationn.optimize()and will be removed in PyPSA v1.0. We will have a generous transition period, but please start migrating yourextra_functionalityfunctions, e.g. by following our migration guide.The module
pypsa.networkclusteringwas moved topypsa.clustering.spatial. The modulepypsa.networkclusteringis now deprecated but all functionality will continue to be accessible until PyPSA v0.25.Bug fix in linearized unit commitment implementation correcting sign.
The minimum required version of
linopyis now0.2.1.Dropped support for Python 3.8. The minimum required version of Python is now 3.9.
PyPSA 0.23.0 (10th May 2023)#
Transmission losses can now be represented during optimisation with
n.optimize()orn.lopf()using a piecewise linear approximation of the loss parabola as presented in this paper. The number of segments can be chosen with the argumentn.optimize(transmission_losses=3). The default remains that transmission losses are neglected withn.optimize(transmission_losses=0), and analogously forn.lopf(pyomo=True)andn.lopf(pyomo=False). [#462]Efficiencies and standing losses of stores, storage units and generators can now be specified as time-varying attributes (
efficiency,efficiency_dispatch,efficiency_store,standing_loss). For example, this allows specifying temperature-dependent generator efficiencies or evaporation in hydro reservoirs. [#572]Unit commitment constraints (ramp limits, start up and shut down costs) can now also be applied to links in addition to generators. This is useful to model the operational restrictions of fuel synthesis plants. [#582]
Added implementation for a linearized unit commitment approximation (LP-based) that can be activated when calling
n.optimize(linearized_unit_commitment=True). The implementation follows Hua et al. (2017), 10.1109/TPWRS.2017.2735026. This functionality is not implemented forn.lopf(). [#472]NetCDF (
.nc) and HDF5 (.h5) network files can now be read directly from URL:pypsa.Network("https://github.com/PyPSA/PyPSA/raw/master/examples/scigrid-de/scigrid-with-load-gen-trafos.nc")[#569]Networks are now compressed when exporting the NetCDF
n.export_to_netcdf(...)step using the native compression feature of netCDF files. Additionally, a typecasting option from float64 to float 32 was added. Existing network files are not affected. To also compress existing networks, load and save them usingxarraywith compression specified, see the xarray documentation for details. The compression can be disabled withn.export_to_netcdf(compression=None). Usen.export_to_netcdf(float32=True, compression={'zlib': True, 'complevel': 9, 'least_significant_digit': 5})for high compression. [#583, #614]Time aggregation for OPEX, curtailment, supply, withdrawal, and revenue now default to ‘sum’ rather than ‘mean’.
A new type of
GlobalConstraintcalled operational_limit is now supported through then.optimize()function. It allows to limit the total production of a carrier analogous to primary_energy_limit with the difference that it applies directly to the production of a carrier rather than to an attribute of the primary energy use. [#618]The attributes
lifetimeandbuild_yearare now aggregated with a capacity-weighted mean when clustering the network. Previously, these attributes had to carry identical values for components that were to be merged. [#571]To enable better backwards compatibility with the
n.lopf()function, then.optimize()functions has now the explicit keyword argumentsolver_options. It takes a dictionary of options passed to the solver. Before, these were passed as keyword arguments to then.optimize()function. Note that both functionalities are supported. [#595]Fixed interference of io routines with linopy optimisation [#564, #567]
Fix a bug where time-dependant generator variables could be forgotten during aggregation in a particular case. [#576]
A new type of
GlobalConstraintcalled operational_limit is now supported through the Network.optimize function. It allows to limit the total production of a carrier analogous to primary_energy_limit with the difference that it applies directly to the production of a carrier rather than to an attribute of the primary energy use.Fix an issue appeared when processing networks which were reduced to a set of isolated nodes in course of clustering. Previously, an empty
Linecomponent has lead to problems when processing empty lines-related dataframes. That has been fixed by introducing special treatment in case a lines dataframe is empty. [#599]
PyPSA 0.22.1 (15th February 2023)#
The model creation for large, sector-coupled models is now much quicker.
The FICO Xpress solver interface now skips loading a basis if there is an error associated with the basis function and continues without it.
The colors of borders and coastlines can now be controlled with
n.plot(color_geomap=dict(border='b', coastline='r')).Plotting multiple legends was fixed for applying a tight layout with
matplotlib>=3.6.The plotting function now supports plotting negative and positive values separately per bus using the argument
`n.plot(bus_split_circles=...). This results in drawing separate half circles for positive and negative values.
PyPSA 0.22.0 (3rd February 2023)#
Python 3.11 is now tested. The support of Python 3.7 was dropped. The minimum supported python version is now 3.8.
The linopy based optimization (
n.optimize()) now allows to limit the carrier’s growth by an additional linear term, so that one can limit an expansion growth by multiples of what was installed in the preceding investment period.The linopy based optimization now requires
linopyversion 0.1.1 or higher. The new version eases the creation of custom constraint through a better display of linear expression and variables.Wrapped functions defined by the
Network.optimizeaccessor are now wrapping meta information of the original functions more coherently. This enables better feedback in interactive sessions.Checking of datatypes in the
consistency_checkis now deactivated by default. Setn.consistency_check(check_dtypes=True)to activate it.The plotting functionality
n.plot()now supports setting alpha values on the branch components individually.The plotting functionality
n.plot()now allows independent control of arrow size and branch width usingline_widthsandflowin conjunction.The documentation shines in a new look using the
sphinx-book-theme. Limitsphinxto versions below 6.Address various deprecation warnings.
PyPSA 0.21.3 (16th December 2022)#
Bugfix: Time-varying marginal cost of a component were removed if at least one of its value was zero.
Bugfix: Due to xarray’s
groupbyoperation not fully supporting multi-indexes in recent version (see pydata/xarray#6836), parts of the multi investment optimization code was adjusted.Update HiGHS parsing function in linopt for HiGHS version 1.4.0. Minimum version of HiGHS is v1.3.0. Older versions have not been tested.
Update of gas boiler example to
linopy.New standard line types for DC lines.
Included code of conduct.
PyPSA 0.21.2 (30th November 2022)#
Compatibility with
pyomo>=6.4.3.
PyPSA 0.21.1 (10th November 2022)#
Default of
n.lopf()changed ton.lopf(pyomo=False).Bugfix in calculating statistics of curtailment.
Bugfix in IO of netCDF network files for datetime indices.
Bugfix for warning about imports from different PyPSA versions.
Add linopy and statistics module to API reference.
PyPSA 0.21.0 (7th November 2022)#
A new optimization module optimization based on Linopy was introduced. It aims at being as fast as the in-house optimization code and as flexible as the optimization with
Pyomo. A introduction to the optimization can be found at the examples section a migration guide for extra functionalities can be found at hereA new module for a quick calculation of system relevant quantities was introduced. It is directly accessible via the new accessor Network.statistics which returns a table of values often calculated manually. At the same time Network.statistics allows to call individual functions, as capex, opex, capacity_factor etc.
Add reference to Discord server for support and discussion.
Restore import of pandapower networks. Issues regarding the transformer component and indexing as well as missing imports for shunts are fixed. [#332]
The import performance of networks was improved. With the changes, the import time for standard netcdf imports decreased by roughly 70%.
PyPSA 0.20.1 (6th October 2022)#
The representation of networks was modified to show the number of components and snapshots.
The performance of the consistency check function was improved. The consistency check was extended by validating the capacity expansion limits as well as global constraint attributes.
When applying network clustering algorithms, per unit time series are now aggregated using a capacity-weighted average and default aggregation strategies were adjusted.
The value of
n.objectiveis now set to NaN for failed optimisation runs.Added example notebook on how to model redispatch with PyPSA.
Added new network plotting example.
Bugfix for non-pyomo version of
n.sclopf().Accept
pathlib.Pathobjects when importing networks withpypsa.Network().Addressed
.iteritems()deprecations.
PyPSA 0.20.0 (26th July 2022)#
This release contains new features for plotting and storing metadata with Network objects.
A new attribute
n.metawas added to the Network object. This can be an arbitrary dictionary, and is used to store meta data about the network.Improved support for individually normed colorbars in
n.plot()for buses, lines, links, transformers with keyword argumentsbus_norm,line_norm,link_norm,transformer_norm.Colorbar plotting example#import pypsa import matplotlib.pyplot as plt n = pypsa.examples.ac_dc_meshed() norm = plt.Normalize(vmin=0, vmax=10) n.plot( bus_colors=n.buses.x, bus_cmap='viridis', bus_norm=norm ) plt.colorbar(plt.cm.ScalarMappable(cmap='viridis', norm=norm))
New utility functions to add legends for line widths (
pypsa.plot.add_legend_lines()), circles and pie chart areas (pypsa.plot.add_legend_circles()), and patch colors (pypsa.plot.add_legend_patches()). See the following example:Legend plotting example#import pypsa import matplotlib.pyplot as plt import cartopy.crs as ccrs from pypsa.plot import add_legend_circles n = pypsa.examples.ac_dc_meshed() fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) n.plot(ax=ax, bus_sizes=1) add_legend_circles( ax, [1, 0.5], ["reference size", "reference size 2"], legend_kw=dict(frameon=False, bbox_to_anchor=(1,0.1)) )
When iterating over components of a Subnetwork, only a those assets are included in the dataframes which are included in the subnetwork.
In
n.plot(), compute boundaries in all cases for consistent circle sizes. This is realised by setting a new default margin of 0.05.Compatibility with pyomo 6.4.1.
Removed
pypsa.statsmodule.Extended defaults for the clustering of attributes in
pypsa.networkclustering.Removed deprecated clustering algorithms in
pypsa.networkclustering.Improved documentation and README.
Fix a few deprecations.
Improved test coverage, e.g. when copying networks.
Testing:
pypoweris not importable with newest numpy versions. Skip test if import fails.
Special thanks for this release to @Cellophil, @txelldm and @rockstaedt for improving test coverage and documentation.
PyPSA 0.19.3 (22nd April 2022)#
Apply pre-commit formats to support development (incl. black formatting, jupyter cleanup, import sorting, preventing large file uploads). This will distort
git blamefunctionality, which can be fixed by runninggit config blame.ignoreRevsFile .git-blame-ignore-revsinside the PyPSA repository. Runpre-commit installto set up locally.Change message when exporting and importing networks without a set
network_name. Fixes [#381].Greedy Modularity Maximisation was introduced as new spatial clustering method [#377].
PyPSA 0.19.2 (7th March 2022)#
Add standard line type for 750 kV transmission line.
PyPSA 0.19.1 (18th February 2022)#
When setting ramp limits for links and calling
Network.lopfwithpyomo=False, an unexpected KeyError was raised. This was fixed by correctly accessing the data frame referring to the power dispatch of links.
PyPSA 0.19.0 (11th February 2022)#
This release contains new features for ramping constraints in link components, hierarchical network clustering functionality, and an interface to the open-source HiGHS solver.
New Features
Ramp limits for
Links. TheLinkcomponent has two new attributes,ramp_limit_upandramp_limit_down, which limits the marginal power increase equivalent to the implementation for generators. The new attributes are only considered when runningnetwork.lopf(pyomo=False).Hierarchical Agglomerative Clustering (HAC) was introduced as new spatial clustering method [#289].
Clustering networks now also supports the clustering of time-series associated to lines.
Add open-source HiGHS solver.
A new convenience function
Network.get_committable_iwas added. This returns an index containing all committable assets of componentc. In case that componentcdoes not support committable assets, it returns an empty dataframe.A warning message is shown if a network contains one or more links with an
efficiencysmaller than 1 and a negative value forp_min_pu[#320].New example for spatial clustering.
Speed-up of
network.plot()by only plotting buses with non-zero size.Increased test coverage.
Changes
The names of the indexes in static dataframes are now set to the component names. So, the index of
n.generatorshas the name ‘Generator’. The same accounts for the columns of the timeseries.The snapshot levels of a multi-indexed snapshot were renamed to [‘period’, ‘timestep’], the name of the index was set to ‘snapshot’. This makes the snapshot name coherent for single and multi-indexed snapshots.
Bugs and Compatibility
Compatibility with
pandas>=1.4.Drop support for Python 3.6 in accordance with its [end-of-life](https://endoflife.date/python).
Use
nx.Graphinstead ofnx.OrderedGraphwhich guarantees order is preserved for Python 3.7 and above.Add assert: CBC solver does not work with ‘>’ and ‘<’.
When running
network.lopf(pyomo=False), the ramp limits did not take the time step right before the optimization horizon into account (relevant for rolling horizon optimization). This is now fixed.Fix bug when multi-links are defined but the network has no links.
Special thanks for this release to Samuel Matthew Dumlao (@smdumlao) for implementing the ramp limits for Links in PyPSA, Martha Frysztacki (@martacki) for implementing the hierarchical network clustering, and Max Parzen (@pz-max) for implementing the HiGHS solver interface.
PyPSA 0.18.1 (15th October 2021)#
Compatibility with
pyomo>=6.1.Bugfix: specifying the
solver_logfileis no longer mandatory with CPLEX forn.lopf(pyomo=False).The distance measures for the network clustering functions
busmap_by_spectral()andbusmap_by_louvain()were adapted to use electrical distance (s_nom/|r+i*x|) (before:num_parallel).Deprecations: The functions
busmap_by_linemask(),busmap_by_length(),length_clustering(),busmap_by_spectral_clustering(),spectral_clustering(),busmap_by_louvain(),louvain_clustering(),busmap_by_rectangular_grid(),rectangular_grid_clustering()andstubs_clustering()were deprecated and will be removed in v0.20.Distance measures for function
busmap_by_spectral()andbusmap_by_louvain()were adapted to electrical distance (s_nom/|r+i*x|) (before:num_parallel)In
pypsa.networkclustering, strip the string of the clustered component name. Not doing this had caused troubles for components with an empty carrier column.Various documentation updates.
PyPSA 0.18.0 (12th August 2021)#
This release contains new features for pathway optimisation, improvements of the documentation’s examples section as well as compatibility and bug fixes.
Licensing
With this release, we have changed the licence from the copyleft GPLv3 to the more liberal MIT licence with the consent of all contributors (for the reasoning why, see the pull request).
New features
Added support for the optimisation of multiple investment periods, also known as pathway optimization. With this feature, snapshots can span over multiple years or decades which are divided into investment periods. Within each investment period, assets can be added to the network. The optimization only works with
pyomo=False. For more information see the documentation at Optimising investment and operation over multiple investment periods and the example notebook. Endogenous learning curves can be applied asextra_functionality.n.snapshot_weightingsis now apandas.DataFramerather than apandas.Serieswith weightings now subdivided into weightings for the objective function, generators and stores/storage units. This separation of weightings is relevant for temporal snapshot clustering, where the weight in the objective function may differ from the number of hours represented by each snapshot for storage purposes.Objective weightings determine the multiplier of the marginal costs in the objective function of the LOPF.
Generator weightings specify the impact of generators in a
GlobalConstraint(e.g. in a carbon dioxide emission constraint).Store weightings define the elapsed hours for the charge, discharge, standing loss and spillage of storage units and stores in order to determine the current state of charge.
PyPSA still supports setting
n.snapshot_weightingswith apandas.Series. In this case, the weightings are uniformly applied to all columns of the newn.snapshot_weightingspandas.DataFrame.All functionalities except for optimisation with
pyomo=Truenow work with multi-indexed snapshots.Many example notebooks are now also integrated in the documentation. See Basic Usage, Power System Optimization, Sector Coupling and Other Examples.
A new module
exampleswas added which contains frontend functions for retrieving/loading example networks provided by the PyPSA project.When solving
n.lopf(pyomo=False), PyPSA now supports setting lower and upper capacity bounds per bus and carrier. These are specified in the columnsn.buses['nom_min_{carrier}']andn.buses['nom_max_{carrier}']respectively. For example, if multiple generators of carrierwindare at busbus1, the combined capacity is limited to 1000 MW by settingn.buses.loc['bus1', 'nom_max_wind'] = 1000(a minimal capacity is forced by settingn.buses.loc['bus1', 'nom_min_wind']). In the same manner the combinedp_nomof componentsStorageUnitande_nomof componentsStorecan be limited.Add new attribute
carrierto the componentsLine,Link,StoreandLoad, defining the energy carrier of the components. Its default is an empty string. When callingn.calculate_dependent_values(), empty carriers are replaced by the carriers of the buses to which the components are attached.Add new descriptive attribute
unittobuscomponent.Automated upload of code coverage reports for pull requests.
Changes
When using iterative LOPF with
n.ilopf()to consider impedance updates of reinforced transmission lines, the attributesp_nomands_nomof lines and links are reset to their original values after final iteration.n.snapshotsare now a property, hence assigning values withn.snapshots = valuesis the same asn.set_snapshots(values).Remove deprecated function
geo.area_from_lon_lat_poly.
Deprecations
The function
geo.area_from_lon_lat_poly()was deprecated and will be removed in v0.19.The deprecated argument
csv_folder_nameinpypsa.Networkwas removed.The deprecated column names
source,dispatch,p_max_pu_fixed,p_min_pu_fixedfor the classGenerator,current_typefor the classBusands_nomfor the classLinkwere removed.
Bugs and Compatibility
Added support for
pandasversion 1.3.Adjust log file creation for CPLEX version 12.10 and higher.
n.snapshot_weightingsis no longer copied forn.copy(with_time=False).Bugfix in
n.ilopf()where previously all links were fixed in the final iteration when it should only be the HVDC links.Fix setting
marginandboundarieswhen plotting a network withgeomap=False.
Special thanks for this release to Lisa Zeyen (@lisazeyen) for implementing the multi-horizon investment in PyPSA and to Fabian Hofmann (@FabianHofmann) for thoroughly reviewing it and adding the example notebooks to the documentation.
PyPSA 0.17.1 (15th July 2020)#
This release contains bug fixes and extensions to the features for optimization when not using Pyomo.
N-1 security-constrained linear optimal power flow is now also supported without pyomo by running
network.sclopf(pyomo=False).Added support for the FICO Xpress commercial solver for optimization without pyomo, i.e.
pyomo=False.There was a bug in the LOPF with
pyomo=Falsewhereby if some Links were defined with multiple outputs (i.e. bus2, bus3, etc. were defined), but there remained some Links without multiple outputs (bus2, bus3, etc. set to""), then the Links without multiple outputs were assigned erroneous non-zero values for p2, p3, etc. in the LOPF withpyomo=False. Now p2, p3, etc. revert to the default value for Links where bus2, bus3, etc. are not defined, just like for the LOPF withpyomo=True.Handle double-asterisk prefix in
solution_fnwhen solvingn.lopf(pyomo=False)using CBC.When solving
n.lopf(pyomo=False, store_basis=True, solver_name="cplex")an error raised by trying to store a non-existing basis is caught.Add compatibility for Pyomo 5.7. This is also the new minimum requirement.
Fixed bug when saving dual variables of the line volume limit. Now using dual from the second last iteration in
pypsa.linopf, because last iteration returns NaN (no optimisation of line capacities in final iteration).Added tracking of iterations of global constraints in the optimisation.
When solving
n.lopf(pyomo=False), PyPSA now constrains the dispatch variables for non extendable components with actual constraints, not with standard variable bounds. This allows retrieving shadow prices for all dispatch variables when runningn.lopf(pyomo=False, keep_shadowprices=True).Can now cluster lines with different static
s_max_puvalues. Time-varyings_max_puare not supported in clustering.Improved handling of optional dependencies for network clustering functionalities (
sklearnandcommunity).
Thanks to Pietro Belotti from FICO for adding the Xpress support, to Fabian Neumann (KIT) and Fabian Hofmann (FIAS) for all their hard work on this release, and to all those who fixed bugs and reported issues.
PyPSA 0.17.0 (23rd March 2020)#
This release contains some minor breaking changes to plotting, some new features and bug fixes.
For plotting geographical features
basemapis not supported anymore. Please usecartopyinstead.Changes in the plotting functions
n.plot()andn.iplot()include some breaking changes:A set of new arguments were introduced to separate style parameters of the different branch components:
link_colors,link_widths,transformer_colors,transformer_widths,link_cmap,transformer_cmapline_widths,line_colors, andline_cmapnow only apply for lines and can no longer be used for other branch types (links and transformers). Passing a pandas.Series with a pandas.MultiIndex will raise an error.Additionally, the function n.iplot() has new arguments
line_text,link_text,transformer_textto configure the text displayed when hovering over a branch component.The function
directed_flow()now takes only a pandas.Series with single pandas.Index.The argument
bus_colorscaleinn.iplot()was renamed tobus_cmap.The default colours changed.
If non-standard output fields in the time-dependent
network.components_t(e.g.network.links_t.p2when there are multi-links) were exported, then PyPSA will now also import them automatically without requiring the use of theoverride_component_attrsargument.Deep copies of networks can now be created with a subset of snapshots, e.g.
network.copy(snapshots=network.snapshots[:2]).When using the
pyomo=Falseformulation of the LOPF (network.lopf(pyomo=False)):It is now possible to alter the objective function. Terms can be added to the objective via
extra_functionalityusing the functionpypsa.linopt.write_objective(). When a pure custom objective function needs to be declared, one can setskip_objective=True. In this case, only terms defined throughextra_functionalitywill be considered in the objective function.Shadow prices of capacity bounds for non-extendable passive branches are parsed (similar to the
pyomo=Truesetting)Fixed
pypsa.linopf.define_kirchhoff_constraints()to handle exclusively radial network topologies.CPLEX is now supported as an additional solver option. Enable it by installing the cplex package (e.g. via
pip install cplexorconda install -c ibmdecisionoptimization cplex) and settingsolver_name='cplex'
When plotting,
bus_sizesare now consistent when they have apandas.MultiIndexor apandas.Index. The default is changed tobus_sizes=0.01because the bus sizes now relate to the axis values.When plotting,
bus_alphacan now be used to add an alpha channel which controls the opacity of the bus markers.The argument
bus_colorscan a now also be a pandas.Series.The
carriercomponent has two new columns ‘color’ and ‘nice_name’. The color column is used by the plotting function ifbus_sizesis a pandas.Series with a MultiIndex andbus_colorsis not explicitly defined.The function
pypsa.linopf.ilopf()can now track the intermediate branch capacities and objective values for each iteration using thetrack_iterationskeyword.Fixed unit commitment:
when
min_up_timeof committable generators exceeds the length of snapshots.when network does not feature any extendable generators.
Fixed import from pandapower for transformers not based on standard types.
The various Jupyter Notebook examples are now available on the binder platform. This allows new users to interactively run and explore the examples without the need of installing anything on their computers.
Minor adjustments for compatibility with pandas v1.0.0.
After optimizing, the network has now an additional attribute
objective_constantwhich reflects the capital cost of already existing infrastructure in the network referring top_nomands_nomvalues.
Thanks to Fabian Hofmann (FIAS) and Fabian Neumann (KIT) for all their hard work on this release, and to all those who reported issues.
PyPSA 0.16.1 (10th January 2020)#
This release contains a few minor bux fixes from the introduction of nomopyomo in the previous release, as well as a few minor features.
When using the
nomopyomoformulation of the LOPF withnetwork.lopf(pyomo=False), PyPSA was not correcting the bus marginal prices by dividing by thenetwork.snapshot_weightings, as is done in thepyomoformulation. This correction is now applied in thenomopyomoformulation to be consistent with thepyomoformulation. (The reason this correction is applied is so that the prices have a clear currency/MWh definition regardless of the snapshot weightings. It also makes them stay roughly the same when snapshots are aggregated: e.g. if hourly simulations are sampled every n-hours, and the snapshot weighting is n.)The
status, termination_conditionthat thenetwork.lopfreturns is now consistent between thenomopyomoandpyomoformulations. The possible return values are documented in the LOPF docstring, see also the LOPF documentation. Furthermore in thenomopyomoformulation, the solution is still returned when gurobi finds a suboptimal solution, since this solution is usually close to optimal. In this case the LOPF returns astatusofwarningand atermination_conditionofsuboptimal.For plotting with
network.plot()you can override the bus coordinates by passing it alayouterfunction fromnetworkx. See the docstring for more information. This is particularly useful for networks with no defined coordinates.For plotting with
network.iplot()a background from mapbox can now be integrated.
Please note that we are still aware of one implementation difference
between nomopyomo and pyomo, namely that nomopyomo doesn’t read
out shadow prices for non-extendable branches, see the github issue.
PyPSA 0.16.0 (20th December 2019)#
This release contains major new features. It is also the first release to drop support for Python 2.7. Only Python 3.6 and 3.7 are supported going forward. Python 3.8 will be supported as soon as the gurobipy package in conda is updated.
A new version of the linear optimal power flow (LOPF) has been introduced that uses a custom optimization framework rather than Pyomo. The new framework, based on nomoypomo, uses barely any memory and is much faster than Pyomo. As a result the total memory usage of PyPSA processing and gurobi is less than a third what it is with Pyomo for large problems with millions of variables that take several gigabytes of memory (see this graphical comparison for a large network optimization). The new framework is not enabled by default. To enable it, use
network.lopf(pyomo=False). Almost all features of the regularnetwork.lopfare implemented with the exception of minimum down/up time and start up/shut down costs for unit commitment. If you use theextra_functionalityargument fornetwork.lopfyou will need to update your code for the new syntax. There is documentation for the new syntax as well as a Jupyter notebook of examples.Distributed active power slack is now implemented for the full non-linear power flow. If you pass
network.pf()the argumentdistribute_slack=True, it will distribute the slack power across generators proportional to generator dispatch by default, or according to the distribution scheme provided in the argumentslack_weights. Ifdistribute_slack=Falseonly the slack generator takes up the slack. There is further documentation.Unit testing is now performed on all of GNU/Linux, Windows and MacOS.
NB: You may need to update your version of the package
six.
Special thanks for this release to Fabian Hofmann for implementing the nomopyomo framework in PyPSA and Fabian Neumann for providing the customizable distributed slack.
PyPSA 0.15.0 (8th November 2019)#
This release contains new improvements and bug fixes.
The unit commitment (UC) has been revamped to take account of constraints at the beginning and end of the simulated
snapshotsbetter. This is particularly useful for rolling horizon UC. UC now accounts for up-time and down-time in the periods before thesnapshots. The generator attributeinitial_statushas been replaced with two attributesup_time_beforeanddown_time_beforeto give information about the status beforenetwork.snapshots. At the end of the simulatedsnapshots, minimum up-times and down-times are also enforced. Ramping constraints also look before the simulation at previous results, if there are any. See the unit commitment documentation for full details. The UC example has been updated with a rolling horizon example at the end.Documentation is now available on readthedocs, with information about functions pulled from the docstrings.
The dependency on cartopy is now an optional extra.
PyPSA now works with pandas 0.25 and above, and networkx above 2.3.
A bug was fixed that broke the Security-Constrained Linear Optimal Power Flow (SCLOPF) constraints with extendable lines.
Network plotting can now plot arrows to indicate the direction of flow by passing
network.plotanflowargument.The objective sense (
minimizeormaximize) can now be set (default remainsminimize).The
network.snapshot_weightingsis now carried over when the network is clustered.Various other minor fixes.
We thank colleagues at TERI for assisting with testing the new unit commitment code, Clara Büttner for finding the SCLOPF bug, and all others who contributed issues and pull requests.
PyPSA 0.14.1 (27th May 2019)#
This minor release contains three small bug fixes:
Documentation parses now correctly on PyPI
Python 2.7 and 3.6 are automatically tested using Travis
PyPSA on Python 2.7 was fixed
This will also be the first release to be available directly from conda-forge.
PyPSA 0.14.0 (15th May 2019)#
This release contains a new feature and bug fixes.
Network plotting can now use the mapping library cartopy as well as basemap, which was used in previous versions of PyPSA. The basemap developers will be phasing out basemap over the next few years in favour of cartopy (see their end-of-life announcement). PyPSA now defaults to cartopy unless you tell it explicitly to use basemap. Otherwise the plotting interface is the same as in previous versions.
Optimisation now works with the newest version of Pyomo 5.6.2 (there was a Pyomo update that affected the opt.py expression for building linear sums).
A critical bug in the networkclustering sub-library has been fixed which was preventing the capital_cost parameter of conventional generators being handled correctly when networks are aggregated.
Network.consistency_check() now only prints necessary columns when reporting NaN values.
Import from pandapower networks has been updated to pandapower 2.0 and to include non-standard lines and transformers.
We thank Fons van der Plas and Fabian Hofmann for helping with the cartopy interface, Chloe Syranidis for pointing out the problem with the Pyomo 5.6.2 update, Hailiang Liu for the consistency check update and Christian Brosig for the pandapower updates.
PyPSA 0.13.2 (10th January 2019)#
This minor release contains small new features and fixes.
Optimisation now works with Pyomo >= 5.6 (there was a Pyomo update that affected the opt.py LConstraint object).
New functional argument can be passed to Network.lopf: extra_postprocessing(network,snapshots,duals), which is called after solving and results are extracted. It can be used to get the values of shadow prices for constraints that are not normally extracted by PyPSA.
In the lopf kirchhoff formulation, the cycle constraint is rescaled by a factor 1e5, which improves the numerical stability of the interior point algorithm (since the coefficients in the constraint matrix were very small).
Updates and fixes to networkclustering, io, plot.
We thank Soner Candas of TUM for reporting the problem with the most recent version of Pyomo and providing the fix.
PyPSA 0.13.1 (27th March 2018)#
This release contains bug fixes for the new features introduced in 0.13.0.
Export network to netCDF file bug fixed (components that were all standard except their name were ignored).
Import/export network to HDF5 file bug fixed and now works with more than 1000 columns; HDF5 format is no longer deprecated.
When networks are copied or sliced, overridden components (introduced in 0.13.0) are also copied.
Sundry other small fixes.
We thank Tim Kittel for pointing out the first and second bugs. We thank Kostas Syranidis for not only pointing out the third issue with copying overridden components, but also submitting a fix as a pull request.
For this release we acknowledge funding to Tom Brown from the RE-INVEST project.
PyPSA 0.13.0 (25th January 2018)#
This release contains new features aimed at coupling power networks to other energy sectors, fixes for library dependencies and some minor internal API changes.
If you want to define your own components and override the standard functionality of PyPSA, you can now override the standard components by passing pypsa.Network() the arguments
override_componentsandoverride_component_attrs, see the section on Custom Components. There are examples for defining new components in the git repository inexamples/new_components/, including an example of overridingnetwork.lopf()for functionality for combined-heat-and-power (CHP) plants.The
Linkcomponent can now be defined with multiple outputs in fixed ratio to the power in the single input by defining new columnsbus2,bus3, etc. (busfollowed by an integer) innetwork.linksalong with associated columns for the efficienciesefficiency2,efficiency3, etc. The different outputs are then proportional to the input according to the efficiency; see sections Link with multiple outputs or inputs and Controllable branch flows: links and the example of a CHP with a fixed power-heat ratio.Networks can now be exported to and imported from netCDF files with
network.export_to_netcdf()andnetwork.import_from_netcdf(). This is faster than using CSV files and the files take up less space. Import and export with HDF5 files, introduced in PyPSA 0.12.0, is now deprecated.The export and import code has been refactored to be more general and abstract. This does not affect the API.
The internally-used sets such as
pypsa.components.all_componentsandpypsa.components.one_port_componentshave been moved frompypsa.componentstonetwork, i.e.network.all_componentsandnetwork.one_port_components, since these sets may change from network to network.For linear power flow, PyPSA now pre-calculates the effective per unit reactance
x_pu_efffor AC lines to take account of the transformer tap ratio, rather than doing it on the fly; this makes some code faster, particularly the kirchhoff formulation of the LOPF.PyPSA is now compatible with networkx 2.0 and 2.1.
PyPSA now requires Pyomo version greater than 5.3.
PyPSA now uses the Travis CI continuous integration service to test every commit in the PyPSA GitHub repository. This will allow us to catch library dependency issues faster.
We thank Russell Smith of Edison Energy for the pull request for the effective reactance that sped up the LOPF code and Tom Edwards for pointing out the Pyomo version dependency issue.
For this release we also acknowledge funding to Tom Brown from the RE-INVEST project.
PyPSA 0.12.0 (30th November 2017)#
This release contains new features and bug fixes.
Support for Pyomo’s persistent solver interface, so if you’re making small changes to an optimisation model (e.g. tweaking a parameter), you don’t have to rebuild the model every time. To enable this,
network_lopfhas been internally split intobuild_model,prepare_solverandsolveto allow more fine-grained control of the solving steps. Currently the new Pyomo PersistentSolver interface is not in the main Pyomo branch, see the pull request; you can obtain it withpip install git+https://github.com/Pyomo/pyomo@persistent_interfacesLines and transformers (i.e. passive branches) have a new attribute
s_max_puto restrict the flow in the OPF, just likep_max_pufor generators and links. It works by restricting the absolute value of the flow per unit of the nominal ratingabs(flow) <= s_max_pu*s_nom. For lines this can represent an n-1 contingency factor or it can be time-varying to represent weather-dependent dynamic line rating.The
marginal_costattribute of generators, storage units, stores and links can now be time dependent.When initialising the Network object, i.e.
network = pypsa.Network(), the first keyword argument is nowimport_nameinstead ofcsv_folder_name. Withimport_namePyPSA recognises whether it is a CSV folder or an HDF5 file based on the file name ending and deals with it appropriately. Example usage:nw1 = pypsa.Network("my_store.h5")andnw2 = pypsa.Network("/my/folder"). The keyword argumentcsv_folder_nameis still there but is deprecated.The value
network.objectiveis now read from the Pyomo results attributeUpper Boundinstead ofLower Bound. This is because for MILP problems under certain circumstances CPLEX records theLower boundas the relaxed value.Upper boundis correctly recorded as the integer objective value.Bug fix due to changes in pandas 0.21.0: A bug affecting various places in the code, including causing
network.lopfto fail with GLPK, is fixed. This is because in pandas 0.21.0 the sum of an empty Series/DataFrame returns NaN, whereas before it returned zero. This is a subtle bug; we hope we’ve fixed all instances of it, but get in touch if you notice NaNs creeping in where they shouldn’t be. All our tests run fine.Bug fix due to changes in scipy 1.0.0: For the new version of scipy,
csgraphhas to be imported explicit.Bug fix: A bug whereby logging level was not always correctly being seen by the OPF results printout is fixed.
Bug fix: The storage unit spillage had a bug in the LOPF, whereby it was not respecting
network.snapshot_weightingsproperly.
We thank René Garcia Rosas, João Gorenstein Dedecca, Marko Kolenc, Matteo De Felice and Florian Kühnlenz for promptly notifying us about issues.
PyPSA 0.11.0 (21st October 2017)#
This release contains new features but no changes to existing APIs.
There is a new function
network.iplot()which creates an interactive plot in Jupyter notebooks using the plotly library. This reveals bus and branch properties when the mouse hovers over them and allows users to easily zoom in and out on the network. See the (sparse) documentation Plotting Networks.There is a new function
network.madd()for adding multiple new components to the network. This is significantly faster than repeatedly callingnetwork.add()and uses the functionsnetwork.import_components_from_dataframe()andnetwork.import_series_from_dataframe()internally. Documentation and examples can be found at Adding and removing multiple components.There are new functions
network.export_to_hdf5()andnetwork.import_from_hdf5()for exporting and importing networks as single files in the Hierarchical Data Format.In the
network.lopf()function the KKT shadow prices of the branch limit constraints are now outputted as series calledmu_lowerandmu_upper.
We thank Bryn Pickering for introducing us to plotly and helping to hack together the first working prototype using PyPSA.
PyPSA 0.10.0 (7th August 2017)#
This release contains some minor new features and a few minor but important API changes.
There is a new component Global Constraints for implementing constraints that effect many components at once (see also the LOPF subsection Global constraints). Currently only constraints related to primary energy (i.e. before conversion with losses by generators) are supported, the canonical example being CO2 emissions for an optimisation period. Other primary-energy-related gas emissions also fall into this framework. Other types of global constraints will be added in future, e.g. “final energy” (for limits on the share of renewable or nuclear electricity after conversion), “generation capacity” (for limits on total capacity expansion of given carriers) and “transmission capacity” (for limits on the total expansion of lines and links). This replaces the ad hoc
network.co2_limitattribute. If you were using this, instead ofnetwork.co2_limit = my_capdonetwork.add("GlobalConstraint", "co2_limit", type="primary_energy", carrier_attribute="co2_emissions", sense="<=", constant=my_cap). The shadow prices of the global constraints are automatically saved innetwork.global_constraints.mu.The LOPF output
network.buses_t.marginal_priceis now defined differently ifnetwork.snapshot_weightingsare not 1. Previously if the generator at the top of the merit order hadmarginal_costc and the snapshot weighting was w, themarginal_pricewas cw. Now it is c, which is more standard. See also Nodal power balances.network.pf()now returns a dictionary of pandas DataFrames, each indexed by snapshots and sub-networks.convergedis a table of booleans indicating whether the power flow has converged;errorgives the deviation of the non-linear solution;n_iterthe number of iterations required to achieve the tolerance.network.consistency_check()now includes checking for potentially infeasible values ingenerator.p_{min,max}_pu.The PyPSA version number is now saved in
network.pypsa_version. In future versions of PyPSA this information will be used to upgrade data to the latest version of PyPSA.network.sclopf()has anextra_functionalityargument that behaves like that fornetwork.lopf().Component attributes which are strings are now better handled on import and in the consistency checking.
There is a new generation investment screening curve example showing the long-term equilibrium of generation investment for a given load profile and comparing it to a screening curve analysis.
There is a new logging example that demonstrates how to control the level of logging that PyPSA reports back, e.g. error/warning/info/debug messages.
Sundry other bug fixes and improvements.
All examples have been updated appropriately.
Thanks to Nis Martensen for contributing the return values of
network.pf() and Konstantinos Syranidis for contributing the
improved network.consistency_check().
PyPSA 0.9.0 (29th April 2017)#
This release mostly contains new features with a few minor API changes.
Unit commitment as a MILP problem is now available for generators in the Linear Optimal Power Flow (LOPF). If you set
committable == Truefor the generator, an addition binary online/offline status is created. Minimum part loads, minimum up times, minimum down times, start up costs and shut down costs are implemented. See the documentation at Unit commitment constraints for generators and links and the unit commitment example. Note that a generator cannot currently have both unit commitment and capacity expansion optimisation.Generator ramping limits have also been implemented for all generators. See the documentation at Ramping constraints for generators and links and the unit commitment example.
Different mathematically-equivalent formulations for the Linear Optimal Power Flow (LOPF) are now documented in Passive branch flow formulations and the arXiv preprint paper Linear Optimal Power Flow Using Cycle Flows. The new formulations can solve up to 20 times faster than the standard angle-based formulation.
You can pass the
network.lopffunction thesolver_ioargument for pyomo.There are some improvements to network clustering and graphing.
API change: The attribute
network.nowhas been removed since it was unnecessary. Now, if you do not pass asnapshotsargument to network.pf() or network.lpf(), these functions will default tonetwork.snapshotsrather thannetwork.now.API change: When reading in network data from CSV files, PyPSA will parse snapshot dates as proper datetimes rather than text strings.
João Gorenstein Dedecca has also implemented a MILP version of the transmission expansion, see jdedecca/MILP_PyPSA, which properly takes account of the impedance with a disjunctive relaxation. This will be pulled into the main PyPSA code base soon.
PyPSA 0.8.0 (25th January 2017)#
This is a major release which contains important new features and changes to the internal API.
Standard types are now available for lines and transformers so that you do not have to calculate the electrical parameters yourself. For lines you just need to specify the type and the length, see Line Types. For transformers you just need to specify the type, see Transformer Types. The implementation of PyPSA’s standard types is based on pandapower’s standard types. The old interface of specifying r, x, b and g manually is still available.
The transformer model has been substantially overhauled, see Transformer model. The equivalent model now defaults to the more accurate T model rather than the PI model, which you can control by setting the attribute
model. Discrete tap steps are implemented for transformers with types. The tap changer can be defined on the primary side or the secondary side. In the PF there was a sign error in the implementation of the transformerphase_shift, which has now been fixed. In the LPF and LOPF angle formulation thephase_shifthas now been implemented consistently. See the new transformer example.There is now a rudimentary import function for pandapower networks, but it doesn’t yet work with all switches and 3-winding transformers.
The object interface for components has been completely removed. Objects for each component are no longer stored in e.g.
network.lines["obj"]and the descriptor interface for components is gone. You can only access component attributes through the dataframes, e.g.network.lines.Component attributes are now defined in CSV files in
pypsa/component_attrs/. You can access these CSVs in the code via the dictionarynetwork.components, e.g.network.components["Line"]["attrs"]will show a pandas DataFrame with all attributes and their types, defaults, units and descriptions. These CSVs are also sourced for the documentation in Components, so the documentation will always be up-to-date.All examples have been updated appropriately.
PyPSA 0.7.1 (26th November 2016)#
This release contains bug fixes, a minor new feature and more warnings.
The unix-only library
resourceis no longer imported by default, which was causing errors for Windows users.Bugs in the setting and getting of time-varying attributes for the object interface have been fixed.
The
Linkattributeefficiencycan now be make time-varying so that e.g. heat pump Coefficient of Performance (COP) can change over time due to ambient temperature variations (see the heat pump example).network.snapshotsis now cast to apandas.Index.There are new warnings, including when you attach components to non-existent buses.
Thanks to Marius Vespermann for promptly pointing out the resource
bug.
PyPSA 0.7.0 (20th November 2016)#
This is a major release which contains changes to the API, particularly regarding time-varying component attributes.
network.generators_tare no longer pandas.Panels but dictionaries of pandas.DataFrames, with variable columns, so that you can be flexible about which components have time-varying attributes; please read Time-varying data carefully. Essentially you can either set a component attribute e.g.p_max_puofGenerator, to be static by setting it in the DataFramenetwork.generators, or you can let it be time-varying by defining a new column labelled by the generator name in the DataFramenetwork.generators_t["p_max_pu"]as a series, which causes the static value innetwork.generatorsfor that generator to be ignored. The DataFramenetwork.generators_t["p_max_pu"]now only includes columns which are specifically defined to be time-varying, thus saving memory.The following component attributes can now be time-varying:
Link.p_max_pu,Link.p_min_pu,Store.e_max_puandStore.e_min_pu. This allows the demand-side management scheme of https://arxiv.org/abs/1401.4121 to be implemented in PyPSA.The properties
dispatch,p_max_pu_fixedandp_min_pu_fixedofGeneratorandStorageUnitare now removed, because the ability to makep_max_puandp_min_pueither static or time-varying removes the need for this distinction.All messages are sent through the standard Python library
logging, so you can control the level of messages to be e.g.debug,info,warningorerror. All verbose switches and print statements have been removed.There are now more warnings.
You can call
network.consistency_check()to make sure all your components are well defined; see Troubleshooting.
All examples have been updated to accommodate the changes listed below.
PyPSA 0.6.2 (4th November 2016)#
This release fixes a single library dependency issue:
pf: A single line has been fixed so that it works with new pandas versions >= 0.19.0.
We thank Thorben Meiners for promptly pointing out this issue with the new versions of pandas.
PyPSA 0.6.1 (25th August 2016)#
This release fixes a single critical bug:
opf: The latest version of Pyomo (4.4.1) had a bad interaction with pandas when a pandas.Index was used to index variables. To fix this, the indices are now cast to lists; compatibility with less recent versions of Pyomo is also retained.
We thank Joao Gorenstein Dedecca for promptly notifying us of this bug.
PyPSA 0.6.0 (23rd August 2016)#
Like the 0.5.0 release, this release contains API changes, which complete the integration of sector coupling. You may have to update your old code. Models for Combined Heat and Power (CHP) units, heat pumps, resistive Power-to-Heat (P2H), Power-to-Gas (P2G), battery electric vehicles (BEVs) and chained hydro reservoirs can now be built (see the sector coupling examples). The refactoring of time-dependent variable handling has been postponed until the 0.7.0 release. In 0.7.0 the object interface to attributes may also be removed; see below.
All examples have been updated to accommodate the changes listed below.
Sector coupling#
components, opt: A new
Storecomponent has been introduced which stores energy, inheriting the energy carrier from the bus to which it is attached. The component is more fundamental than theStorageUnit, which is equivalent to aStoreand twoLinkfor storing and dispatching. TheGeneratoris equivalent to aStorewith a lossyLink. There is an example which shows the equivalences.components, opt: The
Sourcecomponent and theGeneratorattributegen.sourcehave been renamedCarrierandgen.carrier, to be consistent with thebus.carrierattribute. Please update your old code.components, opt: The
Linkattributeslink.s_nom*have been renamedlink.p_nom*to reflect the fact that the link can only dispatch active power. Please update your old code.components, opt: The
TransportLinkandConvertercomponents, which were deprecated in 0.5.0, have been now completely removed. Please update your old code to useLinkinstead.
Downgrading object interface#
The intention is to have only the pandas DataFrame interface for accessing component attributes, to make the code simpler. The automatic generation of objects with descriptor access to attributes may be removed altogether.
examples: Patterns of for loops through
network.components.objhave been removed.components: The methods on
Buslikebus.generators()andbus.loads()have been removed.components:
network.add()no longer returns the object.
Other#
components, opf: Unlimited upper bounds for e.g.
generator.p_nom_maxorline.s_nom_maxwere previous set usingnp.nan; now they are set usingfloat("inf")which is more logical. You may have to update your old code accordingly.components: A memory leak whereby references to
component.networkwere not being correctly deleted has been fixed.
PyPSA 0.5.0 (21st July 2016)#
This is a relatively major release with some API changes, primarily aimed at allowing coupling with other energy carriers (heat, gas, etc.). The specification for a change and refactoring to the handling of time series has also been prepared (see Time-varying data), which will be implemented in the next major release PyPSA 0.6.0 in the late summer of 2016.
An example of the coupling between electric and heating sectors can be
found in the GitHub repository at
pypsa/examples/coupling-with-heating/ and at
https://pypsa.readthedocs.io/en/latest/examples/lopf-with-heating.html.
components: To allow other energy carriers, the attribute
current_typefur buses and sub-neworks (sub-networks inherit the attribute from their buses) has been replaced bycarrierwhich can take generic string values (such as “heat” or “gas”). The values “DC” and “AC” have a special meaning and PyPSA will treat lines and transformers within these sub-networks according to the load flow equations. Other carriers can only have single buses in sub-networks connected by passive branches (since they have no load flow).components: A new component for a controllable directed link
Linkhas been introduced;TransportLinkandConverterare now deprecated and will be removed soon in an 0.6.x release. Please move your code over now. See Link for more details and a description of how to update your code to work with the newLinkcomponent. All the examples in the GitHub repository inpypsa/examples/have been updated to us theLink.graph: A new sub-module
pypsa.graphhas been introduced to replace most of the networkx functionality with scipy.sparse methods, which are more performant the the pure python methods of networkx. The discovery of network connected components is now significantly faster.io: The function
network.export_to_csv_folder()has been rewritten to only export non-default values of static and series component attributes. Static and series attributes of all components are not exported if they are default values. The functionality to selectively export series has been removed from the export function, because it was clumsy and hard to use. See Export to folder of CSV files for more details.plot: Plotting networks is now more performant (using matplotlib LineCollections) and allows generic branches to be plotted, not just lines.
test: Unit testing for Security-Constrained Linear Optimal Power Flow (SCLOPF) has been introduced.
PyPSA 0.4.2 (17th June 2016)#
This release improved the non-linear power flow performance and included other small refactorings:
pf: The non-linear power flow
network.pf()now accepts a list of snapshotsnetwork.pf(snapshots)and has been refactored to be much more performant.pf: Neither
network.pf()nornetwork.lpf()accept thenowargument anymore - for the power flow on a specific snapshot, either setnetwork.nowor pass the snapshot as an argument.descriptors: The code has been refactored and unified for each simple descriptor.
opt: Constraints now accept both an upper and lower bound with
><.opf: Sub-optimal solutions can also be read out of pyomo.
PyPSA 0.4.1 (3rd April 2016)#
This was mostly a bug-fixing and unit-testing release:
pf: A bug was fixed in the full non-linear power flow, whereby the reactive power output of PV generators was not being set correctly.
io: When importing from PYPOWER ppc, the generators, lines, transformers and shunt impedances are given names like G1, G2, …, L1, T1, S1, to help distinguish them. This change was introduced because the above bug was not caught by the unit-testing because the generators were named after the buses.
opf: A Python 3 dict.keys() list/iterator bug was fixed for the spillage.
test: Unit-testing for the pf and opf with inflow was improved to catch bugs better.
We thank Joao Gorenstein Dedecca for a bug fix.
PyPSA 0.4.0 (21st March 2016)#
Additional features:
New module
pypsa.contingencyfor contingency analysis and security-constrained LOPFNew module
pypsa.geofor basic manipulation of geographic data (distances and areas)Re-formulation of LOPF to improve optimisation solving time
New objects pypsa.opt.LExpression and pypsa.opt.LConstraint to make the bypassing of pyomo for linear problem construction easier to use
Deep copying of networks with
network.copy()(i.e. all components, time series and network attributes are copied)Stricter requirements for PyPI (e.g. pandas must be at least version 0.17.1 to get all the new features)
Updated SciGRID-based model of Germany
Various small bug fixes
We thank Steffen Schroedter, Bjoern Laemmerzahl and Joao Gorenstein Dedecca for comments and bug fixes.
PyPSA 0.3.3 (29th February 2016)#
Additional features:
network.lpfcan be called on an iterable ofsnapshotsi.e.network.lpf(snapshots), which is more performant that callingnetwork.lpfon each snapshot separately.Bug fix on import/export of transformers and shunt impedances (which were left out before).
Refactoring of some internal code.
Better network clustering.
PyPSA 0.3.2 (17th February 2016)#
In this release some minor API changes were made:
The Newton-Raphson tolerance
network.nr_x_tolwas moved to being an argument of the functionnetwork.pf(x_tol=1e-6)instead. This makes more sense and is then available in the docstring ofnetwork.pf.Following similar reasoning
network.opf_keep_fileswas moved to being an argument of the functionnetwork.lopf(keep_files=False).
PyPSA 0.3.1 (7th February 2016)#
In this release some minor API changes were made:
Optimised capacities of generators/storage units and branches are now written to p_nom_opt and s_nom_opt respectively, instead of over-writing p_nom and s_nom
The p_max/min limits of controllable branches are now p_max/min_pu per unit of s_nom, for consistency with generation and to allow unidirectional HVDCs / transport links for the capacity optimisation.
network.remove() and io.import_series_from_dataframe() both take as argument class_name instead of list_name or the object - this is now fully consistent with network.add(“Line”,”my line x”).
The booleans network.topology_determined and network.dependent_values_calculated have been totally removed - this was causing unexpected behaviour. Instead, to avoid repeated unnecessary calculations, the expert user can call functions with skip_pre=True.
PyPSA 0.3.0 (27th January 2016)#
In this release the pandas.Panel interface for time-dependent variables was introduced. This replaced the manual attachment of pandas.DataFrames per time-dependent variable as attributes of the main component pandas.DataFrame.
Release process#
Update
doc/release_notes.rstUpdate version in
setup.py,doc/conf.py,pypsa/__init__.pygit commitand put release notes in commit messagegit tag v0.x.0git pushandgit push --tagsThe upload to PyPI is automated in the Github Action
deploy.yml. To upload manually, runpython setup.py sdist, thentwine check dist/pypsa-0.x.0.tar.gzandtwine upload dist/pypsa-0.x.0.tar.gzTo update to conda-forge, check the pull request generated at the feedstock repository.
Making a GitHub release will trigger zenodo to archive the release with its own DOI.
Inform the PyPSA mailing list.