Upcoming Release¶
Upcoming Release
The features listed below have not yet been released, but will be included in the
next update! If you would like to use these features in the meantime, you will need
to install the master branch, e.g. pip install git+https://github.com/pypsa/pypsa.
Features¶
- Add
statsas a shorthand alias for thestatisticsaccessor. Users can now usen.statsinterchangeably withn.statistics. ( 1448)
Bug Fixes¶
- Fix issue when assigning duals back to stochastic networks with global constraints. ( 1498)
- Fix incorrect application of ramp limit constraints to fixed components without defined ramp limits. ( 1494)
- Fix rolling horizon optimization with linearized unit commitment and ramp limits. ( 1489)
v1.0.5 4th December 2025¶
Bug Fixes¶
- Fix curtailment, capacity, and capex expressions returning zero for non-extendable generators. ( 1451)
- Fix using inactive generators in global carrier constraint. ( 1450)
- Fix CVaR optimization to handle networks with zero operational costs. ( 1457)
- Fix xarray broadcasting for rolling-horizon with linearized unit commitment optimization. ( 1464)
v1.0.4 21st November 2025¶
Bug Fixes¶
- Fix busmap clustering to correctly remap all bus ports in multi-port links. ( 1441)
- Fix handling of inactive
StorageUnitorStorecomponents ( 1442) - Fix snapshot selection in operational limit global constraint with investment period. ( 1437)
Documentation¶
- Added new example notebook demonstrating negative electricity prices in linearized unit commitment problem. ( 1434)
v1.0.3 6th November 2025¶
- Fix ramp_limit_up/down constraints: correctly detect components with ramp limits, handle rolling-horizon windows by using previous-window dispatch, and add unit tests for Link ramp limits and ramping constraints in rolling horizon mode. ( 1428)
v1.0.2 24th October 2025¶
Bug Fixes¶
- Fix infinite recursion error when pickling networks. ( 1421)
v1.0.1 20th October 2025¶
Bug Fixes¶
-
Fix
n.set_snapshotsto synchronize investment period weightings when snapshots with new periods are set. ( 1414) -
Fix scenario extraction methods (pypsa.Network.get_scenario and
n['scenario']) to properly handle empty components ( 1402) -
Fix bus validation when adding global constraints via pypsa.Network.add, eliminating false warnings for GlobalConstraints. ( 1413)
-
Fix dimension name consistency when adding investment period weightings. ( 1416)
v1.0.0 14th October 2025 🎉¶
PyPSA 1.0 is here!¶
Check out What's new in PyPSA v1.0.
Features¶
-
New optimization mode: Stochastic optimization problems ( 1154)
-
Two-stage stochastic optimization: stage 1 investment "here-and-now"; stage 2 operations "wait-and-see". Uncertainty via user-defined scenarios. Supports uncertain model parameters in both static and time-series format.
-
New API:
n.set_scenarios({name: weight, ...})to enable scenarios and probabilities (defaults to uniform if weights are not given). Component tables and time series gain a newscenariolevel (MultiIndex) for scenario-specific data. Inspect via methodsn.has_scenarios,n.scenariosandn.scenario_weightings.
-
-
New feature for stochastic optimization: CVaR-based risk-averse optimization ( 1345)
-
Risk-averse optimization mode augments expected operational costs with a Conditional Value at Risk (CVaR) penalty, controlled by
omega(trade-off between expectation and risk) andalpha(tail level). -
New API to enable risk preference:
n.set_risk_preference(alpha=..., omega=...). Inspect vian.has_risk_preferenceandn.risk_preference.
-
-
New feature for interactive map plotting: PyDeck-based interactive maps ( 1312)
-
New API:
n.explore(...)returns apydeck.Deckobject: Extending the previous folium/geopandas-based interactive html map by all static map plotting parameters. -
Interactive maps can be exported to self-contained HTML files by
n.explore(...).to_html("file.html", offline=True).
-
-
Introduces additional MGA functionality. Allows for solving a network in a direction given in the coordinate space of user-specified dimensions, and also introduces a parallelized function to solve in multiple directions at once. ( 1269, 1272)
-
New API:
n.optimize.optimize_mga_in_direction()andn.optimize.optimize_mga_in_multiple_directions() -
The optimization module was heavily refactored. While the underlying
pandas-based data structure remains the same, the optimization module now uses anxarrayview via pypsa.Components to write the optimization model. It allows for easier problem formulation with a single object which contains all components data across all dimensions and coordinates (e.g.name,snapshotswithtimestepsandperiodsandscenarios). Access it viac.da. ( 1154) -
Inactive components (see pypsa.Components.inactive_assets) are now excluded from the the optimization model entirely. This has no effect on the results, but it can reduce the memory footprint when solving the model. ( 1310)
-
New example networks: pypsa.examples.carbon_management and pypsa.examples.stochastic_network ( 1314)
-
Various new options to control PyPSA's behavior. See Options.
-
The option to set bus-level capacity expansion limits per carrier via
Busattributesnom_{min/max}_{carrier}_{period}is now deprecated. The global constraint type"tech_capacity_expansion_limit"offers identical functionality. ( 1294) -
Added utility function pypsa.common.annuity to calculate the annuity factor for a given discount rate and lifetime. Also known as capital recovery factor, it is used to convert a capital cost into an annualized cost. ( 1295)
-
Add additional standard line types from pandapower. ( 1342)
-
New network indexing methods:
n.get_network,n.get_scenario,n.slice_networkand enhancedn[...]for accessing networks. ( 1363) -
When using certain ambiguous attribute names or typos in the pypsa.Network.add method, a warning is now raised. ( 1259)
-
pypsa.Network.add now returns
Noneby default. Usereturn_names=Trueto get the previous behavior of returning component names which have been added. ( 1347) -
Refactored version attributes:
__version_semver__→__version_base__,__version_short__→__version_major_minor__. Removed tuple versions. Old names raiseDeprecationWarning. ( 1338) -
Refined statistic arguments across optimization expressions and plotting modules. Renamed
comps→components,aggregate_groups→groupby_method, andaggregate_time→groupby_timefor consistency. Old argument names are deprecated and will be removed in v2.0.0. ( 1358) -
Improve performance of loading networks by avoiding re-ordering dataframe columns and indices where unnecessary; especially impactful for networks with large numbers of components. ( 1362)
Bug Fixes¶
-
Fixed inconsistent period weighting application in primary energy and operational limit global constraints for non-cyclic storage units and stores. Previously, generators correctly applied period weightings to account for yearly repetition within investment periods, while storage components did not. This caused inconsistent constraint behavior between generators and storage in multi-investment period optimization. Non-cyclic storage units and stores now require the
state_of_charge_initial_per_periodande_initial_per_periodflags respectively to be set toTruewhen using primary energy or operational limit constraints. () -
The default values for
cyclic_state_of_charge_per_period(StorageUnit) ande_cyclic_per_period(Store) have been changed fromTruetoFalse. This is to be more consistent with single investment period optimization where cycling behavior defaults toFalse. Users who work with multi-investment period optimization and want per-period cycling behavior must now explicitly set these attributes toTrue. () -
Fix storage state-of-charge handling in multi-investment period optimizations. The constraint logic incorrectly determined when to apply per-period cycling vs. continuous storage state tracking, causing storage to behave unexpectedly regardless of flag settings. The fix ensures storage units and stores correctly preserve or reset their state across investment periods based on the
cyclic_state_of_charge_per_period/e_cyclic_per_periodandstate_of_charge_initial_per_period/e_initial_per_periodflags. (, ) -
Fixed issue when copying a solved network after setting
n.model.solver_modeltoNone. ( 1325) -
Correct use of snapshot weighting columns in statistics module. The doscstring for pypsa.Network.snapshot_weightings was clarified. ( 1326)
-
Resolved an issue where the network version was not correctly identified during I/O, resulting in false update information being logged. ( 1300)
-
Fix
get_transmission_carriers()to handle components without carrier attribute (e.g., Transformer). ( 1321)
Breaking Changes¶
For a summary of breaking changes, see What's new in PyPSA v1.0.
v0.35.2 15th August 2025¶
Bug Fixes¶
- Make compatible with xarray v2025.07 ( 1304)
v0.35.1 3rd July 2025¶
Bug Fixes¶
-
Fixed issue when copying a network with an unsolved model. ( 1265)
-
Fixed missing dependency issue for
typing-extensions. ( 1264) -
Fixed Excel import when snapshots sheet is missing. ( 1268)
v0.35.0 22th June 2025¶
Features¶
-
New interactive plotting library ( 1189)
pypsa.Network.statistics.energy_balance.iplot()to get the pre defined default plotpypsa.Network.statistics.energy_balance.iplot.bar()to get a bar plot. replacebarwithline,area,maporscatterto get the respective plot.
-
The function
n.statistics.opex()now includes all operational cost components: marginal costs, quadratic marginal costs, storage costs, spill costs, start-up costs, shut-down costs, and stand-by costs. Previously, only marginal costs were considered. A new parametercost_typesallows selecting which cost components to include. ( 1195) -
New method
n.equals() <pypsa.Network.equals>to compare two networks for equality. This is similar to the equality operator==but allows for more flexibility in the comparison which is useful for testing and debugging. ( 1194, 1205) -
The components subpackage was further restructured. The known API remains untouched. ( 1223)
-
New experimental NetworkCollection ( 1212)
- You can now create a container for multiple
Networkobjects. Use is withpypsa.NetworkCollection()and pass a list of networks. The feature is experimental and might change with the next release. Documentation and API reference will follow with a stable version of it.
- You can now create a container for multiple
-
Add new statistics function
n.statistics.prices()which can return time-averaged or consumption-weighted prices by bus or bus carrier.
Bug Fixes¶
-
Bugfix: The function
n.statistics.opex()now considers the correct snapshot weightingsn.snapshot_weightings.objective. ( 1247) -
Fixed unaligned statistics index names when
groupby=False( 1205) -
Fixed interactive area plots in stacked more with
facet_rowandfacet_col. ( 1212) -
The docstrings of the statistics function are now properly displayed again, ie. the output of
n.statistics.energy_balance?. ( 1212) -
Fixed various some I/O edge cases for better data preservation during import/export ( 1255, 1256, 1258)
v0.34.1 7th April 2025¶
Bug Fixes¶
-
The static map plots for statistics are fixed, e.g.
n.statistics.energy_balance.map(). ( 1201) -
The previous maps module under
pypsa/plotis now modularized. Instead of a monolithic module, the maps module is now split into several submodules. The submodules are:.maps.common,.maps.interactive, and.maps.static. ( 1190) -
Added new single node capacity expansion example in style of model.energy. It can be loaded with
pypsa.examples.model_energy(). -
Add new example for how to run MGA ('modelling-to-generate-alternatives') optimisation.
-
Added demand elasticity example.
v0.34.0 25th March 2025¶
Features¶
-
New supported file formats for import and export: Excel
-
Use
n.import_from_excelandn.export_to_excelto import and export Networks from and to Excel files. -
openpyxlandpython-calamineare required dependencies for this feature, but different engines can be passed. By default they are not installed, but can be installed viapip install pypsa[excel].
-
-
New plotting library
-
You can now create plots on any PyPSA statistic. Try them with:
n.statistics.energy_balance.plot()to get the pre defined default plotn.statistics.energy_balance.plot.bar()to get a bar plotn.statistics.energy_balance.plot.line()to get a line plotn.statistics.energy_balance.plot.area()to get a area plotn.statistics.energy_balance.plot.map()to get a map plot
-
n.plot()was moved ton.plot.map() -
n.explore()was moved ton.plot.explore()andn.iplot()was moved ton.plot.iplot()
-
-
Statistics module
-
All statistics functions now interpret the bus_carrier argument as a regular expression (regex), enabling more flexible filtering options. ( 1155)
-
All statistics functions have a new argument
carrierto filter by carriers. ( 1176) -
All statistics functions have two new arguments
drop_zeroandroundto control the output.drop_zerodrops all rows with zero values androundrounds the output to the specified number of decimal places. Those settings have been used before already via the statistics parameters, but are deprecated now. Use the new arguments or the module level settings instead (to set them globally). E.g.pypsa.options.params.statistics.nice_names = False. List all available parameter settings viapypsa.options.params.describe(). ( 1173)
-
Minor improvements¶
-
Ensuring that the created lp/mps file is deterministic by sorting the strongly meshed buses. ( 1174)
-
Added warning for consistent legend circle and semicirle sizes when combining plots on a geographical axis.
-
Add new statistic
n.statistics.system_cost()to calculate the total system cost from capital and operational expenditures. -
Added descriptive attribute "location" to Buses. This attribute does not influence the optimisation model but can be used for aggregation in the statistics module.
-
Added descriptive attribute "location" to Buses. This attribute does not influence the optimisation model but can be used for aggregation in the statistics module. ( 1182)
Bug fixes¶
- Fixed
pypsa.plot.add_legend_semicircles()circle sizing to be consistent withn.plot(bus_size=..., bus_split_circle=True)argument. ( 1179)
v0.33.2 12th March 2025¶
Bug fixes¶
-
Regression hotfix: Fixed a critical bug in statistics functions for multi-investment networks where built years and lifetimes were not being correctly considered. In version
v0.32.0, only components active in the first time period were being included in statistics calculations. The fix ensures all components are properly represented according to their respective built years and lifetimes across all investment periods. This issue was patched in version0.33.2. We also backported the fix to version0.32.2. ( 1172) -
The expressions function
n.optimize.expressions.capacitynow uses the absolute efficiency to calculate the capacity at link ports, unless abus_carrieris defined orat_portis set to True. This is in line with the behavior of the statistics functions (statistics.installed_capacity,statistics.optimal_capacity). Before, the efficiency was allowed to be negative, which lead to inconsistent results.
v0.33.1 3rd March 2025¶
Minor improvements¶
- Added a
quotecharparameter to pypsa.Network.import_from_csv_folder andn.export_to_csv_folderto handle non-standard field quoting in CSV import/export, aligning withpandas.read_csvandpandas.to_csv. ( 1143)
Bug fixes¶
-
pypsa[cloudpath]optional dependency will now only installcloudpathlibwithout extra cloud storage provider client libraries, these will be left to the user to install. ( 1139) -
n.import_from_netcdfandn.import_from_hdf5now work when a URI is passed as a string instead of a CloudPath object. ( 1139) -
Linearized unit commitment with equal startup and shutdown costs. ( 1157)
-
Fix pandas dtype warning. ( 1151)
v0.33.0 7th February 2025¶
Features¶
-
New component class structure ( 1075, 1130)
-
Major structural refactoring of how component data is stored and accessed. The new structure adds an extra layer to move all component-specific data from the network class to a new component class.
-
This is an experimental feature, will be developed further and is not yet recommended for general use. More features, documentation and examples will follow. Most users will not notice any changes.
-
The new additional layer makes it easy to add new features. If you wanna play around with the new components class, see the Components class example in the documentation. You will find an short introduction and some simple examples to show which other features could be added in the future. If you have any ideas, wishes, feedback or suggestions, please let us know via the issue tracker.
-
-
Breaking: Deprecation of custom components ( 1130)
-
This version of PyPSA deprecates custom components. While we don't see many use cases for them, they might be added in an improved way in future again. For a potential reimplementation we would be happy to hear your use case and requirements via the issue tracker.
-
If you don't know what this is or have never used the
override_componentsandoverride_component_attrsarguments during Network initialisation, you can safely ignore this deprecation.
-
-
Breaking: Behavior of
n.components-
Iterating over
n.componentsnow yields the values instead of keys. Usen.components.keys()to keep iterating over keys. -
Checking if a component is in
n.componentsusing the 'in' operator is deprecated. With the deprecation of custom components keys inn.componentsalso ever change.
-
-
PyPSA
0.33provides support for the recent Python 3.13 release and drops support for Python 3.9. While Python 3.9 still gets security updates until October 2025, core dependencies of PyPSA are dropping support for Python 3.9 (e.g.numpy) and active support is only provided for the most recent versions (see endoflife.date). It is recommended to upgrade to the latest Python version if possible. Note that there might be some issues with Windows and Python 3.13, which are not yet resolved. ( 1099) -
Added PyPSA options architecture via
pypsa.get_option,pypsa.set_option, andpypsa.option_context. This allows to set and get global options for PyPSA and mimics the options setting behavior of pandas. Currently there are not many options available, but this will be extended in future. ( 1134) -
New network attributes
n.timesteps,n.periodsandn.has_periodsto simplified level access of the snapshots dimension. ( 1113) -
Consistency checks can now be run with the parameter
strict, which will raise them asConsistenyError. Pass checks which should be strict inn.consistency_checkas e.g.strict=['unknown_buses'].n.optimizewill run some strict checks by default now. ( 1120 1112) -
New example in the documentation showing how to implement reserve power constraints. ( 1133)
-
Doctests are now run with the unit tests. They allow to test the documentation examples, which will improve the quality of docstrings and documentation in future releases. ( 1114)
Bug fixes¶
- The parameter threshold in function get_strong_meshed_buses was not considered in the function it self. A kwargs check has been added for providing a own threshold. E.g., get_strongly_meshed_buses (network, threshold=10)
v0.32.2 12th March 2025¶
Bug fixes¶
- Backported from version
v0.33.2: Fixed a critical bug in statistics functions for multi-investment networks where built years and lifetimes were not being correctly considered. In versionv0.32.0, only components active in the first time period were being included in statistics calculations. The fix ensures all components are properly represented according to their respective built years and lifetimes across all investment periods. ( 1172)
v0.32.1 23th January 2025¶
Bug fixes¶
-
The expression module now correctly includes the "Load" component in the energy balance calculation. Before the fix, the "Load" component was not considered. ( 1110)
-
The optimize/expression module now correctly assigns contributions from branch components in the
withdrawalandsupplyfunctions. Before, there was a wrong multiplication by -1 for branch components. ( 1123)
v0.32.0 5th December 2024¶
Features¶
-
Improvements to groupers in the statistics module ( 1093, 1078)
-
The
groupbyargument now accepts keys to allow for more granular and flexible grouping. For example,n.statistics.energy_balance(groupby=["bus_carrier", "carrier"])groups the energy balance by bus carrier and carrier.-
Build in groupers include:
-
-
Custom groupers can be registered on module level via
pypsa.statistics.groupers.add_grouper. The key will be used as identifier in thegroupbyargument. Check the API reference for more information. -
Accessing default groupers was moved to module level and an improved API was introduced.
n.statistics.get_carriercan now be accessed aspypsa.statistics.groupers.carrierand a combination of groupers can be accessed aspypsa.statistics.groupers['bus', 'carrier']instead ofn.statistics.groupers.get_bus_and_carrier.
-
-
A new module
pypsa.optimize.expressionswas added. It contains functions to quickly create expressions for the optimization model. The behavior of the functions is mirroring the behavior of thestatisticsmodule and allows for similar complexity in grouping and filtering. Use it with e.g.n.optimize.expressions.energy_balance(). ( 1044) -
pytablesis now an optional dependency for using the HDF5 format. Install it viapip install pypsa[hdf5]. Otherwise it is not installed by default anymore. ( 1100)
v0.31.2 27th November 2024¶
Bug fixes¶
- The constraint to account for
e_sum_max/e_sum_minis now skipped if not applied to any asset ( 1069, 1074)
v0.31.1 1st November 2024¶
Bug fixes¶
-
Abolishing
min_unitsin the post discretization. If the maximum capacity of a component is smaller than the specified unit size, the maximum capacity is built as soon as the threshold is passed ( 1052)
v0.31.0 1st October 2024¶
Features¶
-
New
activeattribute ( 1038)-
A new attribute for one-port and branch components
activewas added. If set to true (default), the asset is considered active for all functionality, including optimization and power flow calculation. If set to false, the asset is considered inactive and is excluded from the optimization, power flow and statistics modules. -
The active attribute can be thought of as a global filter on the components. When running a multi-horizon optimization, the active attribute is considered a global condition for each horizon. Then assets are considered active only if
activeis true and the investment period falls within the lifetime of the asset.
-
-
New attributes for the generator component ( 1047)
e_sum_minande_sum_maxadd a new constraint and allow to set the minimum and maximum total energy that can be generated by the generator over one optimization horizon.
-
-
n.addnow handles the addition of a single or multiple components, has more robust index alignment checks allows to overwrite existing components using the new argumentoverwrite. Because of the more strict alignment checks, this might be a breaking change for some users. -
Therefore the methods
n.maddandn.mremoveare now deprecated and will point to their generalised counterparts.
-
-
New function
n.optimize_and_run_non_linear_powerflowwas added to the set of abstract optimize functions. This function optimizes the network and runs a non-linear power flow calculation afterwards. ( 1038) -
API and structural changes:
- The
Componentobject is now a refactored stand-alone class. This is ongoing work and will change further in future releases. ( 1038) - The
pypsa.SubNetworkclass has new methodsdf,pnl,componentto ease the access of component data for a subnetwork. Use it with e.g.subnetwork.df("Generator")and alike. ( 1038) n.dfandn.pnlhave been renamed ton.staticandn.dynamic. Butn.dfandn.pnlare still available and can be used as aliases without any deprecation warning for now. ( 1028)
- The
v0.30.3 24th September 2024¶
- Bugfix in the post discretization for
Linkswith a maximum capacity. Furthermore, giving the option to build out only multiples of the specified unit_size or allowing to use the full maximum capacity. ( 1039)
v0.30.2 11th September 2024¶
- Bugfix in operational limit global constraints, which now directly uses the
carrier of the
Storerather than the carrier of the bus it is attached to. ( 1029)
v0.30.1 9th September 2024¶
-
Added option for importing and exporting CSV, netCDF and HDF5 files in cloud object storage. This requires the installation of the optional dependency
cloudpathlib, e.g. viapip install pypsa[cloudpath]. -
Bugfix of
n.plot()when single buses have no coordinates.
v0.30.0 30th August 2024¶
-
Added
n.explore()function based onfoliumandgeopandasto interactively explore networks. ( 1009) -
Added new
spill_costinput parameter for storage units which penalizes spilling excess energy. ( 1012) -
Added new
marginal_cost_storageinput parameter for stores and storage units to represent the cost of storing energy in currency/MWh/h. ( 603) -
Added type annotations to all functions. ( 1010)
-
Updated documentation. ( 1004)
v0.29.0 31st July 2024¶
-
Removed
n.lopf()pyomo-based and nomopyomo-based optimisation modules. Use linopy-based optimization withn.optimize()instead. ( 884) -
HiGHS becomes the new default solver for
n.optimize(). ( 884) -
Changes to the
statisticsmodule:-
The statistics functions
n.statistics.capex(),n.statistics.installed_capex(), andexpanded_capexnow have an optionalcost_attributeargument, which defaults tocapital_cost. The default behavior of the functions is not changed. ( 989) -
The functions
n.statistics.optimal_capacity()andn.statistics.expanded_capacity()now return positive and negative capacity values if abus_carrieris selected. Positive values correspond to production capacities, negative values to consumption capacities. ( 885) -
The statistics module now supports the
nice_nameargument for bus carriers. Previously, nice names were only supported for components carriers. ( 991) -
The statistics module now features functionality to set global style parameters (e.g.
nice_names,drop_zeroandround) which is then applied to all statistics methods without the need to set them individually. To set parameters one can runn.statistics.set_parameters(nice_names=False, round=2)and to view current parameters settingn.statistics.parameters. ( 886)
-
-
Changes to the
clusteringmodule:- Add attribute-based exemptions for clustering lines and links. With the
argument
custom_line_groupersin the functionaggregatelines()one can specify additional columns besidesbus0andbus1to consider as unique criteria for clustering. This is useful, for example, to avoid the aggregation of lines/links with differentbuild_yearorcarrier. ( 982)
- Add attribute-based exemptions for clustering lines and links. With the
argument
-
Changes to the
plotmodule: -
Bugfixes:
-
The security-constrained optimization via
n.optimize.optimize_security_constrained()was fixed to correctly handle multiple subnetworks. ( 946) -
The global constraint on the total transmission costs now includes the weight of the investment periods and persistence of investment costs of active assets in multi-horizon optimisations.
-
Retain investment periods and weightings when clustering networks. ( 891)
-
Removed performance regression of
statisticsmodule. ( 990) -
When adding bus ports on the fly with
addmethods, the dtype of the freshly created column is now fixed tostring. ( 893) -
Using timezone information in
n.snapshotsraises an error now, since it leads to issues withnumpy/xarray. ( 976)
-
-
Improvements to consistency checks and model debugging:
-
When adding components with bus ports greater than 1, e.g.
bus2, pypsa checks if the bus exists and prints a warning if it does not. ( 893) -
Also check for missing values of default attributes in the
n.consistency_check()function. ( 903) -
Add option
n.optimize(compute_infeasibilities=True)to compute Irreducible Inconsistent Subset (IIS) in case an infeasibility was encountered and Gurobi is installed. ( 978) -
Improved error messages. ( 897)
-
-
Add functionality to compare two networks for equality via equality operator (
==). ( 924) -
Add single-node electricity-only and sector-coupled capacity expansion example. ( 904)
-
Added new line type "Al/St 490/64 4-bundle 380.0". ( 887)
-
Restructured API reference. ( 960)
-
Compatibility with
numpy>=2.0. ( 932)
v0.28.0 8th May 2024¶
-
When using iterative optimisation functionality
n.optimize_transmission_expansion_iteratively(), add option to discretize optimised line and link capacities in the final iteration based on new keyword argumentsline_unit_size,link_unit_size,line_thresholdandlink_threshold. This allows to round the optimised capacities to a multiple of the unit size based on the threshold. ( 871) -
A new function
n.merge()was added allowing the components and time-dependent data of one network to be added to another network. The function is also available vian + mwith default settings. The function requires disjunct component indices and identical snapshots and snapshot weightings. ( 783) -
New features in the statistics module ( 860):
-
The statistics module introduces a new keyword argument
at_portto all functions. This allows considering the port of a component when calculating statistics. Depending on the function, the default ofat_portis set toTrueorFalse, for example for the dispatch all ports are considered. -
The statistics module now supports an optional
portargument ingroupbyfunctions. This allows to group statistics while considering the port of a component. -
The
statistics.revenuefunction introduces a new keyword argumentkindto optionally calculate the revenue based on theinputcommodity or theoutputcommodity of a component. -
The
statistics.energy_balancefunction introduces a new keyword argumentkindto optionally calculate thesupplyandwithdrawalof a component. -
Deprecation warnings are added to the statistics module for the functionalities that will be removed in the next major release.
-
-
Updated
environment_doc.ymlto include the latest requiredpipdependencies for the documentation environment. ( 862) -
Bugfix: calling
n.create_model()orn.optimize()when a global operational limit is defined will no longer set the carrier attribute of stores to the carrier of the bus they are attached to. ( 880) -
Added warning to
plot.pywith instructions to handle the case where therequestsdependency is missing. ( 882) -
Bugfix: calling
n.optimize.*functions (e.g.n.optimize.optimize_mga) now correctly returns each functions return values. ( 871)
v0.27.1 22nd March 2024¶
-
Fixed sometimes-faulty total budget calculation for single-horizon MGA optimisations.
-
Fixed assignment of active assets in multi-horizon optimisation with
n.optimize. -
Fixed setting of investment periods when copying a multi-horizon network.
-
Always use name and mask keys in variable and constraint assignment to protect against future changes in argument order.
-
Rewrite function
get_switchable_as_denseso that it consumes less memory when calling it with large dataframes. -
Fix of the capex description in the attribute CSV files.
v0.27.0 18th February 2024¶
-
Bugfix: If plotting a network map with split buses (
n.plot(bus_split_circle=True)), the bus sizes are now scaled by factor 2 to account for the fact that the bus sizes are split into half circles. This makes the area scaling of the buses consistent with the area of non-split buses. -
The global constraint
define_tech_capacity_expansion_limitnow also takes branch components into account. If defined per bus, thebus0of the branch is considered as a reference bus. -
Bugfixes in building of global constraints in multi-horizon optimisations.
-
Fixed total budget calculation for MGA on multi-horizon optimisations.
-
The
extra_functionalityargument is now also supported insolve_modelaccessor. -
optimize_mganow returns the solver termination status and condition. -
The deprecated functions
_make_consense,aggregategenerators,get_buses_linemap_and_linesandget_clustering_from_busmapwere removed. -
The minimum
networkxversion was bumped from1.10to2. -
pyomois no longer supported for Python 3.12 or higher.
v0.26.3 25th January 2024¶
-
Bugfix: With line transmission losses there was a sign error in the calculation of the line capacity constraints.
-
Approximated transmission losses of lines are now stored after optimisation as the difference between
n.lines_t.p0andn.lines_t.p1so that they appear in the energy balance (e.g.n.statistics.energy_balance()) and when calculating losses withn.lines_t.p0 + n.lines_t.p1.
v0.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.
v0.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.
v0.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 columnsgeometry,component,idxandtype. The columnscomponent,idxandtypedo 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_carrierwas 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_size,link_widthsorlink_colordo 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.
v0.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.
v0.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. ( 635)
Changes
-
The function
get_buses_linemap_and_lineswas deprecated, in favor of direct use ofaggregatebusesandaggregate_lines. -
Improve logging printout for rolling horizon optimization. ( 697, 699)
-
The CI environment handling was migrated to
micromamba( 688).
Bugfixes
-
The aggregation functions in the clustering module were adjusted to correctly handle infinity values (see https://github.com/pandas-dev/pandas/issues/54161 for more details). ( 684)
-
The unit commitment formulation with a rolling horizon horizon was fixed in case of non-committable and committable generators with ramp limits. ( 686)
-
The clustering functionality was fixed in case of passing a subset of carriers that should be aggregated. ( 696)
-
When clustering, allow safe clustering of component attributes which are both static and dynamic. ( 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. ( 693) -
Multilinks are now also handled automatically when importing a network from file. ( 702)
-
Multilink default efficiencies are always set to 1.0. ( 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. ( 690)
-
Fix division in capacity factor calculation in statistics module when not aggregating in the time dimension. ( 687)
v0.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(). ( 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. ( 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. ( 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. ( 669) -
Spatial clustering refactored: The spatial clustering module was refactored. The changes lead to performance improvements and a more consistent clustering API. ( 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. ( 670)
-
The deprecated
networkclusteringmodule was removed. ( 675) -
A new function
get_country_and_carrierwas added to the statistics module in order to group statistics by country and carrier. ( 678) -
NetCDF file compression is now disabled by default when exporting networks. ( 679)
Breaking Changes
-
The
Clusteringclass no longer contains a positive and negative linemap. -
Outdated examples were removed. ( 674)
Bugfixes
- In the statistics module, the calculation of operational costs of storage units was corrected. ( 671)
v0.24.0 27th June 2023¶
- PyPSA now supports quadratic marginal cost terms. A new column
marginal_cost_quadraticwas added to generators, links, stores and storage units. The quadratic marginal cost is added to the objective function when callingn.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.
v0.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
GlobalConstraintcalledoperational_limitis now supported through then.optimize()function. It allows to limit the total production of a carrier analogous toprimary_energy_limitwith 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
GlobalConstraintcalledoperational_limitis now supported through theNetwork.optimizefunction. It allows to limit the total production of a carrier analogous toprimary_energy_limitwith 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)
v0.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.
v0.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
linopyv0.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.
v0.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 https://github.com/pydata/xarray/issues/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.
v0.21.2 30th November 2022¶
- Compatibility with
pyomo>=6.4.3.
v0.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.
v0.21.0 7th November 2022¶
- A new optimization module
optimizationbased on Linopy was introduced. It aims at being as fast as the in-house optimization code and as flexible as the optimization withPyomo. A introduction to the optimization can be found at the examples section a migration guide for extra functionalities can be found at here - A new module for a quick calculation of system relevant quantities was introduced. It is directly accessible via the new accessor
Network.statisticswhich returns a table of values often calculated manually. At the same timeNetwork.statisticsallows to call individual functions, ascapex,opex,capacity_factoretc. - 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%.
v0.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.
v0.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.
v0.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).
v0.19.2 7th March 2022¶
- Add standard line type for 750 kV transmission line.
v0.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.
v0.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, :code:ramp_limit_upand :code:ramp_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 :code:
efficiencysmaller than 1 and a negative value for :code:p_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.
-
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.
v0.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.
v0.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 ( 274)).
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 multi-horizon documentation. 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_weightings with a pandas.Series.
In this case, the weightings are uniformly applied to all columns of the new
n.snapshot_weightings pandas.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 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.
v0.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.
v0.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_cmap line_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 argumentsline_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.
- A set of new arguments were introduced to separate style parameters of the different branch components:
-
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_constraintsto 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'
- It is now possible to alter the objective function.
Terms can be added to the objective via
-
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.ilopfcan 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.
- when
-
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.
v0.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
<https://github.com/PyPSA/PyPSA/issues/119>_.
v0.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.
v0.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.
v0.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.
v0.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.
v0.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.
v0.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.
v0.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 the Link component documentation and the LOPF documentation 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 v0.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.
v0.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 #223; you can obtain it withpip install git+https://github.com/Pyomo/pyomo@persistent_interfaces - Lines 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.
v0.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 documentation. - 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. - 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
<https://plot.ly/python/> and helping to hack together
<https://forum.openmod-initiative.org/t/breakout-group-on-visualising-networks-with-plotly/>
the first working prototype using PyPSA.
v0.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 GlobalConstraint for implementing
constraints that effect many components at once (see also the
LOPF global constraints documentation). 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 the nodal power balance documentation. 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().
v0.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 unit commitment documentation 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 ramping limits documentation and the unit commitment example.
- Different mathematically-equivalent formulations for the Linear Optimal Power Flow (LOPF) are now documented 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 https://github.com/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.
v0.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 the line types documentation. For transformers you just need to specify the type, see the transformer types documentation. 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
the transformer model documentation. 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/data/component_attrs/. You can access these CSVs in the code via the dictionarynetwork.components, e.g.network.components["Line"]"defaults"]will show a pandas DataFrame with all attributes and their types, defaults, units and descriptions. These CSVs are also sourced for the documentation in the Components documentation, so the documentation will always be up-to-date. - All examples have been updated appropriately.
v0.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.
v0.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 the section on time-varying attributes 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 the Troubleshooting documentation.
All examples have been updated to accommodate the changes listed below.
v0.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.
v0.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.
v0.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
<https://docs.pypsa.org/en/latest/examples-index/sector-coupling.html>_). 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.
v0.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 the section on time-varying attributes), which will be implemented in the next major release v0.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://docs.pypsa.org/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 the controllable link documentation 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 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. -
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.
v0.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.
v0.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.
v0.4.0 21st March 2016¶
Additional features:
- New module
pypsa.contingencyfor contingency analysis and security-constrained LOPF - New 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.
v0.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.
v0.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).
v0.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.
v0.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
docs/release-notes.md- Check if all major changes are documented
- Link PR's with badge (e.g. 1)
- You don't need to update the version number anywhere, this is done automatically.
- Commit:
git commit -m 'prepare release `vx.x.x`' - Add tag:
git tag vx.x.x - Direct push on master:
git push upstream master - Push tag:
git push upstream vx.x.x - The upload to PyPI is automated in the Github Action
deploy.yml, which is triggered by pushing a tag. To upload manually, runpython setup.py sdist, thentwine check dist/pypsa-0.x.0.tar.gzandtwine upload dist/pypsa-0.x.0.tar.gz - The GitHub release is also automated in the Github Action. Making a GitHub release will also trigger zenodo to archive the release with its own DOI.
- To update to conda-forge, check the pull request generated at the feedstock repository. A PR will be generated automatically after a couple of hours by the conda-forge bot, and needs to be merged by a maintainer.