Release Notes

pyMOR 2024.1 (July 8, 2025)

We are proud to announce the release of pyMOR 2024.1!

The main new features are:

  • vector fitting

  • successive constraints method

  • shifted Cholesky QR algorithm

  • improved randomized range finder

  • additional tutorials and MOR methods overview

pyMOR 2024.1 contains contributions by Maximilian Bindhak and Art Pelling. See here for more details.

Main new features

Vector fitting

We added an implementation of vector fitting [#2214], a least-squares data-driven method for frequency-response data of linear time-invariant systems. This addition complements our existing methods: interpolatory Loewner method (LoewnerReductor) and mixed greedy/least-squares AAA algorithm (PAAAReductor).

Successive constraints method

We implemented the successive constraints method, which allows to efficiently compute upper and lower bounds for the coercivity constant of parameter-separable and coercive problems by means of linear programs [#1989]. The respective ParameterFunctionals are constructed within a greedy algorithm that iteratively determines a set of parameters used in the construction of the estimates. The usage of the successive constraints method is showcased in a demo.

Shifted Cholesky QR algorithm

We added an implementation of the shifted Cholesky QR algorithm [#2177], which has potential to exploit higher performance linear algebra routines compared to the Gram-Schmidt algorithm (gram_schmidt).

Improved randomized range finder

The rand_la module has seen various improvements. In particular, the adaptive_rrf and rrf methods have been merged into a single RandomizedRangeFinder class, which supports both power iterations and adaptive error-estimator based range approximation [#1753].

Improved documentation

pyMOR’s user documentation now features an overview of the most important MOR methods implemented in the library. Each method is accompanied by a short code snippet demonstrating its use [#2266]. Additionally, we have added an in-depth tutorial on interpolatory MOR [#2153]. The PDE-constraint optimization tutorial has been enhanced with a section on trust-region methods [#2181].

Backward incompatible changes

Improved Model interface and implementation

For Model interface methods that return NumPy arrays, the shape of these arrays is now clearly defined [#2278]: estimate_error always returns a 1D NumPy array, where the index corresponds to time. estimate_output_error always returns a 2D NumPy array, where axis 0 corresponds to time and axis 1 corresponds to the output component. The return_vector parameter has been removed.

In order to have consistent behavior for time-dependent models, the solution_d_mu option of compute now returns a dict of the form {(parameter, index): sensitivity} instead of appending solution sensitivities for different parameter indices to a single array. output_d_mu now always returns a frozen dict-like object of the form {(parameter, index): sensitivity}, where sensitivity is a 2D NumPy array with axis 0 corresponding to time and axis 1 corresponding to output component. The returned object has a to_numpy method to convert it to a single array. The return_array parameter has been removed from output_d_mu.

Only compute keeps **kwargs, which are only allowed to be used to select additional quantities that are to be computed. To change the behavior of solve, etc., appropriate attributes of the Model instance have to be used in the future.

Finally, the internal interfaces for implementing compute and related methods have been significantly simplified. Models now only implement _compute, which can access default implementations via a super call. In particular, this new approach allows retrieving arbitrary intermediate compute quantities from the cache in subsequent computations. For further details, see [#2277].

Further notable improvements

pyMOR 2023.2 (December 7, 2023)

We are proud to announce the release of pyMOR 2023.2! This release features new and improved tutorials and new Operators which enable fast computation for certain structured problems.

Over 375 single commits have entered this release. For a full list of changes see here.

pyMOR 2023.2 contains contributions by Steffen Müller, Peter Oehme and Art Pelling. See here for more details.

Release highlights

New Tutorials

This release includes new tutorials and updates to existing tutorials on the following topics:

  • port-Hamiltonian systems [#2132]

  • VectorArray basics [#2176]

  • ANN reductors for time-dependent problems [#2231]

Additionally, the rendering of tutorial notebooks has been improved through [#2174] and [#2175]

DFT-based Operators

A previous pyMOR release added NumpyHankelOperator. This release adds the related NumpyCirculantOperator and NumpyToeplitzOperator (see [#2138]). These Operators allow for performing fast matrix vector multiplications by exploiting an underlying circulant or Toeplitz structure.

Additional new features

LTIModel iterable time-stepping

Previous pyMOR releases added time-domain analysis methods to LTIModel and iterable time-stepping. This release modifies the time-domain methods to use iterable time-stepping, improving performance when only system output is required. Additionally, it allows handling the feedthrough term (see [#2203]).

Returning right singular vectors in POD computations

It is now possible to also directly obtain the right singular vectors when calling the pod method in pyMOR. The behavior of the pod method with respect to returning the right singular vectors is controlled using the return_reduced_coefficients argument which was added in [#2114].

Creating BitmapFunctions from matrices or random data

BitmapFunction can now be instantiated directly from an existing data array. A random field can be generated with the new random factory method. The existing functionality to load the data from a given bitmap file is now provided by the from_file factory method (see [#2228]).

Backward incompatible changes

Renamed methods due to typos

The psd_cotengent_lift was renamed to psd_cotangent_lift ([#2131]). Furthermore, methods with “neighbour” in the name were renamed to use “neighbor” ([#2130]).

Deprecated pymess bindings

Due to pymess not supporting Python 3.11, it is deprecated in this release ([#2193]). Support will be removed with the 2024.1 release. has been removed

Since timing is supported by various other libraries we drop pyMOR’s timer with [#2194].

Further notable improvements

pyMOR 2023.1 (July 6, 2023)

We are proud to announce the release of pyMOR 2023.1! pyMOR now comes with three new MOR methods for port-Hamiltonian systems, a new data-driven MOR method, optimization methods for parametric problems, and an improved experience for Jupyter users.

Over 880 single commits have entered this release. For a full list of changes see here.

pyMOR 2023.1 contains contributions by Tim Keil, Steffen Müller, Mohamed Adel Naguib Ahmed, Jonas Nicodemus, and Peter Oehme. See here for more details.

Release highlights

Model reduction methods for port-Hamiltonian systems

The previous release added a PHLTIModel class for port-Hamiltonian systems. This release adds three MOR methods for port-Hamiltonian (or passive) systems:

  • port-Hamiltonian IRKA (pH-IRKA) [#1835],

  • positive real balanced truncation (PRBT) [#1847], and

  • passivity preserving model reduction via spectral factorization [#2033].

Additionally, PHLTIModel now inherits from LTIModel, supports the \(Q\) matrix and adds conversion to the Berlin form [#1836]. To enable some solvers for positive real Riccati equations, the S parameter was added to Riccati equation solvers [#1837].

Loewner reductor

A reductor based on Loewner matrices was added in [#1952] for data-driven (tangential) Lagrange interpolation. This extends and complements the available reductors for bitangential Hermite interpolation (TFBHIReductor) and the (P)AAA algorithm (PAAAReductor). The implementation supports various options for partitioning the data as well as handling MIMO systems. Additionally, the reductor is flexible as it works with a user provided data set or any model that has a associated transfer function.


In [#1924], an error-aware adaptive trust-region method was added. This method solves an optimization problem \(\min_{\mu \in C} J(\mu)\) for Models with an output \(J\) depending on a box-constrained \(\mu\). The main idea of the algorithm can be found in [YM13], and an RB application to box-constrained parameters with possible enlarging of the trust radius in [KMO+21]. This method contrasts itself from a standard trust region (TR) method in the computation of the trust region: standard TR implementations use a metric distance, whereas this function uses an error estimator obtained from the surrogate. Additionally, the cheap model function surrogate is only updated for each outer iteration, not entirely reconstructed.

Jupyter support

We have made several improvements to the user experience in Jupyter notebook environments. Apart from polishing the existing matplotlib-based notebook visualizers [#1949], [#1988], we have stabilized and improved our new K3D-based visualizations. In particular, the K3D-visualizer is now used in our online documentation. Due to an outstanding bug in K3D, which leads to empty plots unless the browser window is resized, the new backend is only enabled by default in notebooks when the upcoming version 2.15.3 of K3D is installed [#1937]. Further the new interact function allows to interactively explore pyMOR Models via a dynamically created ipywidgets-based user interface that shows the solution/output of a model depending on the selected inputs and parameters [#2061].

Additional new features

Quadratic output functionals

In [#1796], two classes, QuadraticFunctional and QuadraticProductFunctional, have been introduced to handle the cases of bilinear functionals of the form \(A(u, u) = u^T A u\) and \(A(u, u) = (a(u), b(u))\), respectively. These can now be used as reducible output functionals. Moreover, the builtin CG discretizer also supports a quadratic argument for defining bilinear outputs conveniently.

Time-stepping iterator

The iterate method was added to time-steppers, which returns a generator for solution snapshots [#2053]. Compared to the solve method, it allows iterating over solution snapshots without storing all computed snapshots.

Backward incompatible changes


The pythreejs-based visualizer has been removed in favor of our new K3D-based implementation.

Further notable improvements

pyMOR 2022.2 (December 18, 2022)

We are proud to announce the release of pyMOR 2022.2! pyMOR now comes with three new data-driven MOR methods and time domain analysis for linear time-invariant systems.

Over 500 single commits have entered this release. For a full list of changes see here.

pyMOR 2022.2 contains contributions by Tim Keil, Hendrik Kleikamp, Peter Oehme and Art Pelling. We are also happy to welcome Hendrik as a new main developer! See here for more details.

Release highlights

Eigensystem Realization Algorithm

The Eigensystem Realization Algorithm (aka. Ho-Kalman or Silverman Algorithm) can be used to identify LTIModels from Markov parameter data. With [#1587], an ERAReductor is added that implements the classical algorithm as well as the TERA extension that uses tangential projections of the Markov parameters for cases where there are many inputs and/or outputs. The SVD of the Hankel matrix as well as the tangential projectors are cached by the reductor such that LTIModels of different orders can be constructed efficiently.

Parametric AAA algorithm

The AAA algorithm allows for approximating rational functions in an iterative manner by combining the ideas of Vector-Fitting and Loewner interpolation. With this release, we are adding the parametric version of the algorithm ([#1756]) for data-driven approximation of TransferFunctions. The PAAAReductor can handle any models that have a transfer_function attribute or Numpy data as inputs. The implementation works in non-parametric, parametric, SISO as well as MIMO settings.

Long short-term memory neural networks

As an alternative neural network architecture for data-driven model order reduction of parametrized instationary problems, long short-term memory neural networks (LSTMs) with corresponding reductors and reduced order models were introduced in [#1460]. Similar to the already existing reductors based on neural networks, the map from parameter to reduced coefficients is approximated by a neural network, while the reduced basis itself is constructed using proper orthogonal decomposition. This results in a purely data-driven approach that is applicable to any given instationary full-order model.

Time domain analysis of LTIModels

With the introduction of time-dependent Parameters, LTIModels also support solve and output methods as does InstationaryModel [#1340]. Additionally, LTIModels also have methods for computing the impulse and step responses [#1054]. Time domain analysis for other system-theoretic Models (e.g., SecondOrderModel and PHLTIModel), will be done in future releases.

Additional new features

New approach to handling randomness in pyMOR

pyMOR now consistently uses a global random generator state, which is initialized with a configurable fixed seed value. This approach allowed us to remove the seed and random_state parameters from all methods in pyMOR. The spawn_rng wrapper ensures deterministic uncorrelated execution in concurrent code. In special cases where pyMOR shall execute code with a specific random state the new_rng context manager can be used to temporarily install another random state [#1736].

DWR reductor for output estimation with primal-dual approach

In [#1496], the DWRCoerciveRBReductor was added to support error estimation for linear output functionals with the dual-weighted residual (DWR) approach as proposed in [Haa17] (Definition 2.31, Proposition 2.32). After reduction, the reduced model includes the corrected output functional as well as the higher-order error estimator. The respective dual model can either be built on a fully discrete level or can be specified by the user.

Adaptive frequency domain analysis

The adaptive function was added for adaptive sampling of functions used in plotting. In particular, this was enabled for adaptive plotting of Bode-related plots [#1615].

LTIModel can compute LQG and BR Gramians

The gramian of the LTIModel so far could only compute the standard Lyapunov Gramians. With this release, the computation of linear quadratic Gaussian (LQG) and bounded-real (BR) Gramians was moved from the corresponding balanced truncation reductors to LTIModel. In particular, these Gramians are now cached, which can significantly speed up reductions for multiple orders [#995].

Caching of the dense LU decomposition for NumpyMatrixOperator

The NumpyMatrixOperator already caches the sparse LU decomposition when the underlying matrix is a SciPy sparse matrix. Now it also caches the dense LU decomposition when the matrix is a NumPy array [#1603]. This should significantly improve the runtime when solving the same dense system with different right-hand sides.

Further notable improvements

pyMOR 2022.1 (July 21, 2022)

We are proud to announce the release of pyMOR 2022.1! pyMOR now comes with support for discrete-time systems and structure-preserving MOR for symplectic systems. The neural network based reductors gained many new features, while the VectorArray implementation got simplified. We have added an experimental FEniCS discretizer and extended functionality for randomized linear algebra.

Over 760 single commits have entered this release. For a full list of changes see here.

pyMOR 2022.1 contains contributions by Patrick Buchfink, Monica Dessole, Hendrik Kleikamp, Peter Oehme, Art Pelling and Sven Ullmann. See here for more details.

Release highlights

Support for discrete-time systems

With [#1500], discrete-time LTIModels can now be instantiated by passing the sampling_time to the constructor. The computation of discrete-time gramians has been enabled in [#1525] by solving the associated Stein equations with solvers from either SciPy or SLICOT and [#1617] also allows for Balanced Truncation of discrete-time systems. In [#1614], a class for the construction and evaluation of Moebius transformations was added. Realizations of LTI systems can be transformed according to arbitrary MoebiusTransformations. The conversion of continuous-time and discrete-time systems with Tustin’s method (with optional frequency prewarping) is implemented on the basis of these MoebiusTransformations in dedicated to_continuous and to_discrete conversion methods. In preparation for data-driven reduced order modelling methods, a NumpyHankelOperator is added in [#1546] that avoids explicit matrix constructions by supplying FFT-accelerated matrix-vector multiplication routines that work on the Markov parameters directly.

Structure-preserving model reduction for symplectic systems

With [#1621] pyMOR now allows to formulate a quadratic Hamiltonian system as full-order model. Moreover, pyMOR implements multiple structure-preserving basis generation techniques [#1600]. In combination with a special reductor for quadratic Hamiltonian systems, a structure-preserving reduction, known as symplectic MOR, is available [#1678]. A demo script for the linear wave equation is included.

Additional new features

Lots of new features for the neural network based reductors

In [#1559], a couple of new features including support for learning rate schedulers, input and output scaling, regularization of weights and biases, a weighted MSE loss and logging of current losses have been added to improve the training of neural networks. These additions make the training process more flexible and all components can be combined as required. If no full-order model is available but only snapshot data, it is now also possible to use the neural network based reductors in a data-driven way. In [#1679], the reductors have been adjusted to allow for pairs of parameters and corresponding snapshot data as training set instead of only parameters. The resulting surrogate models can be used as before.

Randomized linear algebra algorithms

pyMOR’s numerical linear algebra algorithms have been extended by randomized methods: the new rand_la module includes a method for singular value decomposition of arbitrary linear pyMOR Operators, as well as an algorithm for solving generalized hermitian eigenproblems. The old randomized range approximation algorithms from the pymor.algorithms.randrangefinder module have been moved to the new module as well [#1552].

FEniCS discretizer

pyMOR’s symbolic Expressions can now be converted to equivalent UFL expressions. In particular, ExpressionFunction now has a to_fenics methods which utilizes this functionality under the hood [#1550]. Based on this feature an experimental discretizer converts pyMOR analytical problems to FEniCS-based Models [#1682].

Simplified VectorArray implementation

The VectorArray code in pyMOR has been refactored into a single user-facing interface class and backend-specific implementation classes. All error checking, as well as managing of copy-on-write semantics and views is handled by the interface class, which should significantly simplify the correct implementation of new VectorArrays [#1584].

Backward incompatible changes

Dropped Python 3.7 support

Following NumPy/SciPy we have dropped official support for Python 3.7. This means pyMOR now requires Python 3.8 to install and is no longer tested against 3.7.

Further notable improvements

pyMOR 2021.2 (December 22, 2021)

We are proud to announce the release of pyMOR 2021.2! New features in this release are the addition of Dynamic Mode Decomposition for data-driven model order reduction and the formalization of model inputs. Further, general output error bounds for Reduced Basis reductors and experimental scikit-fem support as an alternative to the builtin discretizers were added. Wachspress’ shifts accelerate the solution of Lyapunov equations for symmetric system matrices.

Over 300 single commits have entered this release. For a full list of changes see here.

pyMOR 2021.2 contains contributions by Tim Keil, Jonas Nicodemus and Henrike von Hülsen. See here for more details.

Release highlights

Data-driven model order reduction with Dynamic Mode Decomposition

Dynamic Mode Decomposition (DMD) is a well-established method for computing low-rank dynamics from observational or simulation data. In contrast to Proper Orthogonal Decomposition (POD) where the computed modes are weighted by energy content, DMD modes are associated with oscillation frequency and decay rate. In [#1424], both the ‘standard’ and ‘exact’ versions of DMD in the sense of [TRL+14] have been implemented as algorithms operating on arbitrary VectorArrays. As such, pymor.algorithms.dmd.dmd can be applied also to blocked or MPI-distributed datasets.

Formalization of Model inputs

In an ongoing effort to unify system-theoretic and Reduced Basis Models in pyMOR and to enable time-domain simulations for system-theoretic Models, we have formalized the notion of the input of a Model. Building on pyMOR’s recently introduced support for time-dependent parameter values, Models can now have an input parameter, for which time-dependent parameter values are passed to solve, output and related methods via the new input keyword argument. For instance, for an arbitrary InstationaryModel m we can interpret the rhs operator as an input-to-state map as follows:

m = m.with_(rhs=m.rhs * ProjectionParameterFunctional('input', 1))
U = m.solve(input='[sin(t[0])]', mu=mu)

For further details, see [#1469].

Additional new features

Basic RB output error estimates

pyMOR’s Reduced Basis reductors have been extended to compute a basic estimate for the output error. Given a linear output functional, this estimate is given by the product of the estimated state-space error and the dual norm of the output functional. The dual norm is computed efficiently online, also for parameter-dependent output functionals that are parameter-separable. For further details, see [#1474]. A DWR-based output error estimator is currently under development [#1496].

Experimental scikit-fem support

In [#1507], experimental support was added for building Models from pyMOR’s analyticalproblems using scikit-fem as a discretization backend. scikit-fem is a lightweight NumPy/SciPy-based finite-element library that offers more advanced features than pyMOR’s builtin discretization toolkit, such as 3d meshes or higher-order methods. Currently, only StationaryProblems can be discretized using, which supports most features of the corresponding builtin discretizer.

Wachspress’ shifts

When performing model order reduction with the balanced truncation method, the primary computational cost consists of solving two Lyapunov equations. In pyMOR, the low-rank ADI iteration is used to solve these matrix equations in a large-scale setting. In this method, shift parameter selection plays a crucial role in convergence speed. For general systems, a heuristic for computing sub-optimal shifts is implemented in pyMOR. Through [#1445], optimal shift parameter computation for LTI models with symmetric system matrices was added.

Backward incompatible changes

Transfer function restructuring

In the pursuit of unifying system-theoretic and Reduced Basis Models, the TransferFunction class is no longer a subclass of Model and is moved from pymor.models.iosys to pymor.models.transfer_function. Additionally, the InputOutputModel and InputStateOutputModel classes have been removed. Furthermore, the transfer function-related methods of LTIModel, SecondOrderModel and LinearDelayModel are deprecated and the attribute transfer_function should be used instead (e.g., m.bode_plot(...) should be replaced with m.transfer_function.bode_plot(...)). See [#1486] for more details.

Further notable improvements

pyMOR 2021.1 (September 24, 2021)

We are proud to announce the release of pyMOR 2021.1! This release includes several new reductors for LTI systems. In particular, methods for reducing and analyzing unstable systems have been added. ANNs can now be used in order to directly approximate output quantities. Furthermore, it is now possible to work with time-dependent parameters in pyMOR.

Over 700 single commits have entered this release. For a full list of changes see here.

pyMOR 2021.1 contains contributions by Tim Keil, Hendrik Kleikamp, Josefine Zeller and Meret Behrens. See here for more details.

Release highlights

Methods for unstable LTI systems

Many popular system-theoretic model order reduction methods are not applicable to unstable LTI systems out of the box. In [#1149] two reductors and several methods for working with and analyzing unstable LTIModels have been added. The FDBTReductor allows for applying the balanced truncation technique to unstable systems by performing a Bernoulli stabilization before using the classical BT method. The GapIRKAReductor aims to compute a reduced-order model such that the approximation error with respect to the \(\mathcal{H}_2\)-Gap norm is small. Additionally, a variety of numerical linear algebra methods have been a part of [#1149]: Riccati equation solvers for small and dense matrices, Bernoulli matrix equation solver, new options for for pyMOR’s eigensolver such as shift-and-invert mode and \(\mathcal{L}_2\)-norm computation for LTIModels. The new methods and reductors are showcased in Tutorial: Model order reduction for unstable LTI systems.

Time-dependent parameter values

We have extended the handling of Parameters in pyMOR to allow time-dependent parameter values. Such parameter values are specified by instantiating a Mu object with a Function that maps the current time to the respective parameter value. The function is automatically evaluated at mu['t'] and correspondingly updated in mu.with_(t=new_time) such that the time dependence of the values is completely transparent to their consumer. This allows existing ROMs to be used with time-dependent parameter values without any changes in the MOR algorithm. For further details, see [#1379].

Additional new features

Symbolic ExpressionFunctions

A simple symbolic math expression library has been added to pyMOR, which is now used by ExpressionFunction and ExpressionParameterFunctional to parse and evaluate the given expressions, see [#1277]. As immediate benefits, the shape of the expression is now automatically determined and the expression is automatically vectorized correctly. In particular, there is no longer a need to add ... to indexing expressions. Further, malformed expressions now lead to meaningful error messages at parse time.

In the future, conversion routines will be added to make the expression library usable for discretizers that use external PDE solvers, such that the same ExpressionFunction can be used for different PDE solver backends.

Output reductor using ANNs

To further extend the neural network based reductors, in [#1282] a reductor that only approximates the mapping from parameter space to output space using a neural network was added. Furthermore, a corresponding reductor for the instationary case was implemented. The new reductor for the stationary case is used in Tutorial: Model order reduction with artificial neural networks and compared to the NeuralNetworkReductor.

As part of [#1282], the ANN-reductors were refactored, and in [#1274], the neural network training routines have been separated from the reductors.

Improvements to the HAPOD algorithm

pyMOR’s implementation of the HAPOD algorithm has seen several significant improvements in [#1322]:

  • hapod now launches its own asyncio event loop in order to avoid conflicts with already running event loops (e.g. when running from jupyter).

  • It is now possible to explicitly specify that a node has to be processed after certain other nodes. In particular, this can be used to ensure the right execution order for incremental POD computations.

  • HAPOD trees are now created dynamically, which should significantly simplify specifying own tree topologies.

  • dist_hapod now has an arity argument, which allows to control the number of intermediate POD levels.

  • inc_hapod now accepts arbitrary iterables for the snapshot data, which makes it easy to incrementally compute the data while computing the POD.

Improved support for Empirical Interpolation of functions

The ei_greedy algorithm has been improved, in particular to make it more useful for the interpolation of coefficient Functions. Based on these improvements, an interpolate_function method has been added which creates an EmpiricalInterpolatedFunction from an arbitrary pyMOR Function. The function_ei demo script demonstrates the new functionality. For further details, see [#1240].

Methods for exporting matrices of system models

The system classes LTIModel and SecondOrderModel have had various from_* methods for constructing models from matrices. In [#1309], the corresponding to_* methods were added for exporting matrices from a model.

pyMOR is now a pure Python package

All Cython modules in pyMOR’s discretization toolkit have been replaced by equivalent NumPy code, see [#1314]. As a result, pyMOR is now a pure Python package, which should significantly simplify pyMOR’s installation when no pre-built binary wheels are available.

Backward incompatible changes

Drop python 3.6 support

Support for Python 3.6 has been dropped in pyMOR 2021.1 [#1302]. The minimum supported version now is Python 3.7.

Symbolic ExpressionFunctions

Due to the improvements in [#1277], the signature of ExpressionFunction has changed. To use existing code with pyMOR 2021.1, the shape_range argument has to be removed from all instantiations of ExpressionFunction. Further, all occurrences of ... have to be removed in indexing expressions.

Further notable improvements

pyMOR 2020.2 (December 10, 2020)

We are proud to announce the release of pyMOR 2020.2! This release extends pyMOR’s support for non-intrusive model reduction via artificial neural networks to non-stationary models. Built-in support for computing parameter sensitivities simplifies the use of pyMOR in PDE-constrained optimization applications. pyMOR’s documentation has been extended by three new tutorials, and all tutorial code can now easily be executed using binder.

Over 520 single commits have entered this release. For a full list of changes see here.

pyMOR 2020.2 contains contributions by Tim Keil and Hendrik Kleikamp. See here for more details.

Release highlights

Parameter derivatives of solutions and outputs

In [#1110] tools for PDE-constrained parameter optimization were added. These include parameter derivatives of the solutions and the output of a Model. In particular, solve_d_mu can now be used to compute partial parameter derivatives. Moreover, output_d_mu can be used to compute the parameter gradient of the output using the derivatives of the solutions. Alternatively, for a StationaryModel and a linear output, an adjoint variable can be used to speed up the computation of the gradient (see _compute_output_d_mu).

Neural network reductor for non-stationary problems

A reductor based on neural networks which deals with non-stationary problems was added in [#1120]. The implementation is an extension of the already existing approach for stationary problems in pyMOR. Here, the time component is treated as an ordinary parameter. The usage of the newly introduced reductor is presented in a corresponding demo where a Burgers’ type equation is solved. As in the stationary case, the implementation allows for several customizations regarding the network architecture and training parameters.

To make training of neural networks more robust, the available data is now shuffled randomly before splitting it into training and validation set [#1175].

New tutorials

A new tutorial on using pyMOR for accelerating the solution of linear PDE-constrained optimization problems has been added with [#1205]. This tutorial showcases the new features added in [#1110] and also discusses general questions on using model order reduction for a class of optimization problems.

The tutorial ‘Projecting a Model’ explains how to use pyMOR to build an online-efficient reduced order model via (Petrov-)Galerkin projection onto a given reduced space [#1084]. Alongside the mathematical foundation, the user is introduced to the core elements of pyMOR’s internal architecture that realize the projection.

A tutorial on linear time-invariant systems was added and the existing balanced truncation tutorial was appropriately simplified [#1141].

All tutorials now include a ‘launch binder’ button which allows to directly run the tutorial code in the web browser [#1181].

In order to consolidate our documentation all remaining Jupyter notebooks from the notebooks/ directory were converted to demo scripts [#1160], and the notebooks/ directory was removed [#1198].

Additional new features

Bode plot for input-output systems

The bode_plot method for creating a Bode plot was added [#1051], complementing the mag_plot method. Additionally, the bode method can be used to compute the magnitudes and phases over the imaginary axis (for continuous-time systems).

Iterable VectorArrays

VectorArrays became iterable sequences with [#1068], i.e., for v in V can be used to work on individual vectors (i.e. VectorArray views of length 1) when needed.

Expansion of ConcatenationOperators and improved projection algorithms

The new expand allows to recursively expand concatenations of LincombOperators in any given Model or Operator [#1098]. In particular, expand is now used in project to improve the projection of such constructs [#1102]. Moreover, several minor improvements have been made to project_to_subbasis [#1138].

Support for Python 3.9

Backward incompatible changes

Updated Model interface

To make the simultaneous computation of multiple Model output quantities such as internal state, output, or error estimates more efficient and better customizable a compute method was added to the Model interface which is now responsible for the computation of all relevant data that can be gathered from the simulation of a Model [#1113]. Existing interface methods such as pymor.models.interface.Model.solve or or pymor.models.interface.Model.output now act as convenience frontends for compute. Existing custom Models have to be adapted to the new architecture.

The estimate method has been renamed to estimate_error [#1041]. The old method is deprecated and will be removed in the next release.

Further, to simplify interoperability with third-party packages, the model outputs, i.e., the results of output, are no longer generic VectorArrays, but NumPy arrays. For consistency, input_space and output_space were removed and input_dim and output_dim were renamed to dim_input and dim_output in InputOutputModel [#1089].

Changes in methods for inner products and norms of VectorArrays

At first, VectorArrays only had dot and pairwise_dot methods for computing inner products between vectors. Later, more general methods inner and pairwise_inner were added to simplify computing non-Euclidean inner products. To reduce the list of methods for VectorArrays, the dot and pairwise_dot methods are now deprecated and will be removed in the next release [#1066]. In the same vein, the l2_norm and l2_norm2 methods are deprecated in favor of norm and norm2 [#1075] Finally, due to lack of usage and support in some external PDE solvers, the l1_norm method was deprecated [#1070].

Restructuring of grid classes

The inheritance structure of grid classes was simplified [#1044]. In particular,

  • ConformalTopologicalGridDefaultImplementations, ReferenceElementDefaultImplementations, AffineGridDefaultImplementations, and ConformalTopologicalGrid were removed,

  • AffineGrid was renamed to Grid,

  • AffineGridWithOrthogonalCenters was renamed to GridWithOrthogonalCenters.

Renaming of some Operators

For consistency in the naming of Operators, ComponentProjection, Concatenation and LinearAdvectionLaxFriedrichs were renamed to ComponentProjectionOperator, ConcatenationOperator and LinearAdvectionLaxFriedrichsOperator, respectively [#1046].

Minimal pip and Manylinux wheel version

In order to reduce special casing and infrastructure investment needed for maintaining compatibility with older versions we decided to increase the minimal required pip version to 19.0 (released Jan ‘19) and decided to no longer publish manylinux1 wheels. Pip 19.0 already understands the Manylinux 2010 tag, which going further is the oldest platform we will ship wheels for.

Further notable improvements

pyMOR 2020.1 (July 23, 2020)

We are proud to announce the release of pyMOR 2020.1! Highlights of this release are support for non-intrusive model order reduction using artificial neural networks, the subspace accelerated dominant pole algorithm (SAMDP) and the implicitly restarted Arnoldi method for eigenvalue computation. Parameter handling in pyMOR has been simplified, and a new series of hands-on tutorials helps getting started using pyMOR more easily.

Over 600 single commits have entered this release. For a full list of changes see here.

pyMOR 2020.1 contains contributions by Linus Balicki, Tim Keil, Hendrik Kleikamp and Luca Mechelli. We are also happy to welcome Linus as a new main developer! See here for more details.

Release highlights

Model order reduction using artificial neural networks

With this release, we introduce a simple approach for non-intrusive model order reduction to pyMOR that makes use of artificial neural networks [#1001]. The method was first described in [HU18] and only requires being able to compute solution snapshots of the full-order Model. Thus, it can be applied to arbitrary (nonlinear) Models even when no access to the model’s Operators is possible.

Our implementation internally wraps PyTorch for the training and evaluation of the neural networks. No knowledge of PyTorch or neural networks is required to apply the method.

New system analysis and linear algebra algorithms

The new eigs method [#880] computes smallest/largest eigenvalues of an arbitrary linear real Operator using the implicitly restarted Arnoldi method [Leh95]. It can also be used to solve generalized eigenvalue problems.

So far, computing poles of an LTIModel was only supported by its poles method, which uses a dense eigenvalue solver and converts the operators to dense matrices. The new samdp method [#834] implements the subspace accelerated dominant pole (SAMDP) algorithm [RM06], which can be used to compute the dominant poles operators of an LTIModel with arbitrary (in particular sparse) system Operators without relying on dense matrix operations.

Improved parameter handling

While pyMOR always had a powerful and flexible system for handling Parameters, understanding this system was often a challenge for pyMOR newcomers. Therefore, we have completely overhauled parameter handling in pyMOR, removing some unneeded complexities and making the nomenclature more straightforward. In particular:

  • The Parameter class has been renamed to Mu. ParameterType has been renamed to Parameters. The items of a Parameters dict are the individual parameters of the corresponding ParametricObject. The items of a Mu dict are the associated parameter values.

  • All parameters are now one-dimensional NumPy arrays.

  • Instead of manually calling build_parameter_type in __init__, the Parameters of a ParametricObject are now automatically inferred from the object’s __init__ arguments. The process can be customized using the new parameters_own and parameters_internal properties.

  • CubicParameterSpace was renamed to ParameterSpace and is created using

Further details can be found in [#923]. Also see [#949] and [#998].

pyMOR tutorial collection

Hands-on tutorials provide a good opportunity for new users to get started with a software library. In this release a variety of tutorials have been added which introduce important pyMOR concepts and basic model order reduction methods. In particular users can now learn about:

Additional new features

Improvements to ParameterFunctionals

Several improvements have been made to pyMOR’s ParameterFunctionals:

Extended Newton algorithm

Finding a proper parameter for the step size in the Newton algorithm can be a difficult task. In this release an Armijo line search algorithm is added which allows for computing adequate step sizes in every step of the iteration. Details about the line search implementation in pyMOR can be found in [#925].

Additionally, new options for determining convergence of the Newton method have been added. It is now possible to choose between the norm of the residual or the update vector as a measure for the error. Information about other noteworthy improvements that are related to this change can be found in [#956], as well as [#932].

initial_guess parameter for apply_inverse

The apply_inverse and apply_inverse_adjoint methods of the Operator interface have gained an additional initial_guess parameter that can be passed to iterative linear solvers. For nonlinear Operators the initial guess is passed to the newton algorithm [#941].

manylinux 2010+2014 wheels

In addition to manylinux1 wheels we are now also shipping wheels conforming with the manylinux2010 and manylinux2014 standards. The infrastructure for this was added in [#846].

Debugging improvements

The defaults decorator has been refactored to make stepping through it with a debugger faster [#864]. Similar improvements have been made to RuleTable.apply. The new breakpoint_for_obj and breakpoint_for_name methods allow setting conditional breakpoints in RuleTable.apply that match specific objects to which the table might be applied [#945].

WebGL-based visualizations

This release enables our pythreejs-based visualization module for Jupyter Notebook environments by default. It acts as a drop in replacement for the previous default, which was matplotlib based. This new module improves interactive performance for visualizations with a large number of degrees of freedom by utilizing the user’s graphics card via the browser’s WebGL API. The old behavior can be reactivated using

from pymor.basic import *
set_defaults({'pymor.discretizers.builtin.gui.jupyter.get_visualizer.backend': 'MPL'})

Backward incompatible changes

Renamed interface classes

The names of pyMOR’s interface classes have been shortened [#859]. In particular:

The base classes OperatorBase, ModelBase, FunctionBase were merged into their respective interface classes [#859], [#867].

Module cleanup

Modules associated with pyMOR’s builtin discretization toolkit were moved to the pymor.discretizers.builtin package [#847]. The domaindescriptions and functions packages were made sub-packages of pymor.analyticalproblems [#855], [#858]. The obsolete code in pymor.discretizers.disk was removed [#856]. Further, the playground package was removed [#940].

State ids removed and caching simplified

The unnecessarily complicated concept of state ids, which was used to build cache keys based on the actual state of a CacheableObject, has been completely removed from pyMOR. Instead, now a cache_id has to be manually specified when persistent caching over multiple program runs is desired [#841].

Further API changes

Further notable improvements

pyMOR 2019.2 (December 16, 2019)

We are proud to announce the release of pyMOR 2019.2! For this release we have worked hard to make implementing new models and reduction algorithms with pyMOR even easier. Further highlights of this release are an extended VectorArray interface with generic support for complex numbers, vastly extended and improved system-theoretic MOR methods, as well as builtin support for model outputs and parameter sensitivities.

Over 700 single commits have entered this release. For a full list of changes see here.

pyMOR 2019.2 contains contributions by Linus Balicki, Dennis Eickhorn and Tim Keil. See here for more details.

Release highlights

Implement new models and reductors more easily

As many users have been struggling with the notion of Discretization in pyMOR and to account for the fact that not every full-order model needs to be a discretized PDE model, we have decided to rename DiscretizationInterface to ModelInterface and all deriving classes accordingly [#568]. Consequently, the variable names m, rom, fom will now be found throughout pyMOR’s code to refer to an arbitrary ModelInterface, a reduced-order ModelInterface or a full-order ModelInterface.

Moreover, following the Zen of Python’s ‘Explicit is better than implicit’ and ‘Simple is better than complex’, we have completely revamped the implementation of ModelInterfaces and reductors to facilitate the implementation of new model types and reduction methods [#592]. In particular, the complicated and error-prone approach of trying to automatically correctly project the OperatorInterfaces of any given ModelInterface in GenericRBReductor and GenericPGReductor has been replaced by simple ModelInterface-adapted reductors which explicitly state with which bases each OperatorInterface shall be projected. As a consequence, we could remove the operators dict and the notion of special_operators in ModelBase, vastly simplifying its implementation and the definition of new ModelInterface classes.

Extended VectorArray interface with generic complex number support

The VectorArrayInterface has been extended to allow the creation of non-zero vectors using the ones and full methods [#612]. Vectors with random values can be created using the random method [#618]. All VectorArrayInterface implementations shipped with pyMOR support these new interface methods. As an important step to improve the support for system-theoretic MOR methods with external PDE solvers, we have implemented facilities to provide generic support for complex-valued VectorArrayInterfaces even for PDE solvers that do not support complex vectors natively [#755].

Improved and extended support for system-theoretic MOR methods

To increase compatibility between input-output models in iosys and the InstationaryModel, support for models with parametric operators has been added [#626], which also enables implementation of parametric MOR methods for such models. Furthermore, the state_space attribute was removed in favor of solution_space [#648] to make more explicit the result of the solve method. Further improvements in naming has been renaming attributes n, m, and p to order, input_dim, and output_dim [#578] and the bode method to freq_resp [#729]. Reductors in bt and h2 received numerous improvements ([#656], [#661], [#807]) and variants of one-sided IRKA have been added [#579]. As for Lyapunov equations, a low-rank solver for Riccati equations has been added [#736].

Model outputs and parameter sensitivities

The notion of a ModelInterface’s output has been formally added to the ModelInterface [#750]: The output of a ModelInterface is defined to be a VectorArrayInterface of the model’s output_space VectorSpaceInterface and can be computed using the new output method. Alternatively, solve method can now be called with return_output=True to return the output alongside the state space solution.

To compute parameter sensitivities, we have added d_mu methods to OperatorInterface and ParameterFunctionalInterface which return the partial derivative with respect to a given parameter component [#748].

Additional new features

Extended FEniCS bindings

FEniCS support has been improved by adding support for nonlinear OperatorInterfaces including an implementation of restricted to enable fast local evaluation of the operator for efficient empirical interpolation [#819]. Moreover the parallel implementations of amax and dofs have been fixed [#616] and solver_options are now correctly handled in _assemble_lincomb [#812].

Improved greedy algorithms

pyMOR’s greedy algorithms have been refactored into weak_greedy and adaptive_weak_greedy functions that use a common WeakGreedySurrogate to estimate the approximation error and extend the greedy bases. This allows these functions to be used more flexible, e.g. for goal-oriented basis generation, by implementing a new WeakGreedySurrogate [#757].

Numerical linear algebra algorithms

By specifying return_R=True, the gram_schmidt algorithm can now also be used to compute a QR decomposition of a given VectorArrayInterface [#577]. Moreover, gram_schmidt can be used as a more accurate (but often more expensive) alternative for computing the pod of a VectorarrayInterface. Both, the older method-of-snapshots approach as well as the QR decomposition are now available for computing a truncated SVD of a VectorArrayInterface via the newly added svd_va module [#718]. Basic randomized algorithms for approximating the image of a linear OperatorInterface are implemented in the randrangefinder module [#665].

Support for low-rank operators

Low-rank OperatorInterfaces and as well as sums of arbitrary OperatorInterfaces with a low-rank OperatorInterface can now be represented by LowRankOperator and LowRankUpdatedOperator. For the latter, apply_inverse and apply_inverse_adjoint are implemented via the Sherman-Morrison-Woodbury formula [#743].

Improved string representations of pyMOR objects

Custom __str__ special methods have been implemented for all ModelInterface classes shipped with pyMOR [#652]. Moreover, we have added a generic __repr__ implementation to BasicInterface which recursively prints all class attributes corresponding to an __init__ argument (with a non-default value) [#706].

Easier working with immutable objects

A new check in ImmutableMeta enforces all __init__ arguments of an immutable object to be available as object attributes, thus ensuring that with_ works reliably with all immutable objects in pyMOR [#694]. To facilitate the initialization of these attributes in __init__ the __auto_init method has been added to BasicInterface [#732]. Finally, with_ now has a new_type parameter which allows to change the class of the object returned by it [#705].

project and assemble_lincomb are easier to extend

In pyMOR 0.5, we have introduced RuleTables to make central algorithms in pyMOR, like the projection of an OperatorInterface via project, easier to trace and extend. For pyMOR 2019.2, we have further simplified project by removing the product argument from the underlying RuleTable [#785]. As the inheritance-based implementation of assemble_lincomb was showing similar complexity issues as the old inheritance-based implementation of projected, we moved all backend-agnostic logic into the RuleTable-based free function assemble_lincomb, leaving the remaining backend code in _assemble_lincomb [#619].

Improvements to pyMOR’s discretization toolbox

pyMOR’s builtin discretization toolbox as seen multiple minor improvements:

Backward incompatible changes

Dropped Python 3.5 support

As Python 3.6 or newer now ships with the current versions of all major Linux distributions, we have decided to drop support for Python 3.6 in pyMOR 2019.2. This allows us to benefit from new language features, in particular f-strings and class attribute definition order preservation [#553], [#584].

Global RandomState

pyMOR now has a (mutable) global default RandomState. This means that when sample_randomly is called repeatedly without specifying a random_state or seed argument, different Parameter samples will be returned in contrast to the (surprising) previous behavior where the same samples would have been returned. The same RandomState is used by the newly introduced random method of the VectorArrayInterface [#620].

Space id handling

The usage of VectorSpaceInterface ids in pyMOR has been reduced throughout pyMOR to avoid unwanted errors due to incompatible VectorSpaceInterfaces (that only differ by their id):

Further API Changes

Further notable improvements

pyMOR 0.5 (January 17, 2019)

After more than two years of development, we are proud to announce the release of pyMOR 0.5! Highlights of this release are support for Python 3, bindings for the NGSolve finite element library, new linear algebra algorithms, various VectorArrayInterface usability improvements, as well as a redesign of pyMOR’s projection algorithms based on RuleTables.

Especially we would like to highlight the addition of various system-theoretic reduction methods such as Balanced Truncation or IRKA. All algorithms are implemented in terms of pyMOR’s OperatorInterface and VectorArrayInterface interfaces, allowing their application to any model implemented using one of the PDE solver supported by pyMOR. In particular, no import of the system matrices is required.

Over 1,500 single commits have entered this release. For a full list of changes see here.

pyMOR 0.5 contains contributions by Linus Balicki, Julia Brunken and Christoph Lehrenfeld. See here for more details.

Release highlights

Python 3 support

pyMOR is now compatible with Python 3.5 or greater. Since the use of Python 3 is now standard in the scientific computing community and security updates for Python 2 will stop in less than a year (, we decided to no longer support Python 2 and make pyMOR 0.5 a Python 3-only release. Switching to Python 3 also allows us to leverage newer language features such as the @ binary operator for concatenation of OperatorInterfaces, keyword-only arguments or improved support for asynchronous programming.

System-theoretic MOR methods

With 386 commits, [#464] added systems-theoretic methods to pyMOR. Module pymor.discretizations.iosys contains new discretization classes for input-output systems, e.g. LTISystem, SecondOrderSystem and TransferFunction. At present, methods related to these classes mainly focus on continuous-time, non-parametric systems.

Since matrix equation solvers are important tools in many system-theoretic methods, support for Lyapunov, Riccati and Sylvester equations has been added in pymor.algorithms.lyapunov, pymor.algorithms.riccati and pymor.algorithms.sylvester. A generic low-rank ADI (Alternating Direction Implicit) solver for Lyapunov equations is implemented in pymor.algorithms.lradi. Furthermore, bindings to low-rank and dense solvers for Lyapunov and Riccati equations from SciPy, Slycot and Py-M.E.S.S. are provided in pymor.bindings.scipy, pymor.bindings.slycot and pymor.bindings.pymess. A generic Schur decomposition-based solver for sparse-dense Sylvester equations is implemented in pymor.algorithms.sylvester.

Balancing Truncation (BT) and Iterative Rational Krylov Algorithm (IRKA) are implemented in BTReductor and IRKAReductor. LQG and Bounded Real variants of BT are also available (LQGBTReductor, BRBTReductor). Bitangential Hermite interpolation (used in IRKA) is implemented in LTI_BHIReductor. Two-Sided Iteration Algorithm (TSIA), a method related to IRKA, is implemented in TSIAReductor.

Several structure-preserving MOR methods for second-order systems have been implemented. Balancing-based MOR methods are implemented in pymor.reductors.sobt, bitangential Hermite interpolation in SO_BHIReductor and Second-Order Reduced IRKA (SOR-IRKA) in SOR_IRKAReductor.

For more general transfer functions, MOR methods which return LTISystems are also available. Bitangential Hermite interpolation is implemented in TFInterpReductor and Transfer Function IRKA (TF-IRKA) in TF_IRKAReductor.

Usage examples can be found in the heat and string_equation demo scripts.

NGSolve support

We now ship bindings for the NGSolve finite element library. Wrapper classes for VectorArrayInterfaces and matrix-based OperatorInterfaces can be found in the pymor.bindings.ngsolve module. A usage example can be found in the thermalblock_simple demo script.

New linear algebra algorithms

pyMOR now includes an implementation of the HAPOD algorithm for fast distributed or incremental computation of the Proper Orthogonal Decomposition (pymor.algorithms.hapod). The code allows for arbitrary sub-POD trees, on-the-fly snapshot generation and shared memory parallelization via concurrent.futures. A basic usage example can be found in the hapod demo script.

In addition, the Gram-Schmidt biorthogonalization algorithm has been included in pymor.algorithms.gram_schmidt.

VectorArray improvements

VectorArrayInterfaces in pyMOR have undergone several usability improvements:

  • The somewhat dubious concept of a subtype has been superseded by the concept of VectorSpaceInterfaces which act as factories for VectorArrayInterfaces. In particular, instead of a subtype, VectorSpaceInterfaces can now hold meaningful attributes (e.g. the dimension) which are required to construct VectorArrayInterfaces contained in the space. The id attribute allows to differentiate between technically identical but mathematically different spaces [#323].

  • VectorArrayInterfaces can now be indexed to select a subset of vectors to operate on. In contrast to advanced indexing in NumPy, indexing a VectorArrayInterface will always return a view onto the original array data [#299].

  • New methods with clear semantics have been introduced for the conversion of VectorArrayInterfaces to (to_numpy) and from (from_numpy) NumPy arrays [#446].

  • Inner products between VectorArrayInterfaces w.r.t. to a given inner product OperatorInterface or their norm w.r.t. such an operator can now easily be computed by passing the OperatorInterface as the optional product argument to the new inner and norm methods [#407].

  • The components method of VectorArrayInterfaces has been renamed to the more intuitive name dofs [#414].

  • The l2_norm2 and norm2 have been introduced to compute the squared vector norms [#237].

RuleTable based algorithms

In pyMOR 0.5, projection algorithms are implemented via recursively applied tables of transformation rules. This replaces the previous inheritance-based approach. In particular, the projected method to perform a (Petrov-)Galerkin projection of an arbitrary OperatorInterface has been removed and replaced by a free project function. Rule-based algorithms are implemented by deriving from the RuleTable base class [#367], [#408].

This approach has several advantages:

  • Rules can match based on the class of the object, but also on more general conditions, e.g. the name of the OperatorInterface or being linear and non-parametric.

  • The entire mathematical algorithm can be specified in a single file even when the definition of the possible classes the algorithm can be applied to is scattered over various files.

  • The precedence of rules is directly apparent from the definition of the RuleTable.

  • Generic rules (e.g. the projection of a linear non-parametric OperatorInterface by simply applying the basis) can be easily scheduled to take precedence over more specific rules.

  • Users can implement or modify RuleTables without modification of the classes shipped with pyMOR.

Additional new features

  • Reduction algorithms are now implemented using mutable reductor objects, e.g. GenericRBReductor, which store and extend (extend_basis) the reduced bases onto which the model is projected. The only return value of the reductor’s reduce method is now the reduced discretization. Instead of a separate reconstructor, the reductor’s reconstruct method can be used to reconstruct a high-dimensional state-space representation. Additional reduction data (e.g. used to speed up repeated reductions in greedy algorithms) is now managed by the reductor [#375].

  • Linear combinations and concatenations of OperatorInterfaces can now easily be formed using arithmetic operators [#421].

  • The handling of complex numbers in pyMOR is now more consistent. See [#458], [#362], [#447] for details. As a consequence of these changes, the rhs OperatorInterface in StationaryDiscretization is now a vector-like OperatorInterface instead of a functional.

  • The analytical problems and discretizers of pyMOR’s discretization toolbox have been reorganized and improved. All problems are now implemented as instances of StationaryProblem or InstationaryProblem, which allows an easy exchange of data Functions of a predefined problem with user-defined Functions. Affine decomposition of Functions is now represented by specifying a LincombFunction as the respective data function [#312], [#316], [#318], [#337].

  • The pymor.core.config module allows simple run-time checking of the availability of optional dependencies and their versions [#339].

  • Packaging improvements

    A compiler toolchain is no longer necessary to install pyMOR as we are now distributing binary wheels for releases through the Python Package Index (PyPI). Using the extras_require mechanism the user can select to install either a minimal set:

    pip install pymor

    or almost all, including optional, dependencies:

    pip install pymor[full]

    A docker image containing all of the discretization packages pyMOR has bindings to is available for demonstration and development purposes:

    docker run -it pymor/demo:0.5 pymor-demo -h
    docker run -it pymor/demo:0.5 pymor-demo thermalblock --fenics 2 2 5 5

Backward incompatible changes

  • dim_outer has been removed from the grid interface [#277].

  • All wrapper code for interfacing with external PDE libraries or equation solvers has been moved to the pymor.bindings package. For instance, FenicsMatrixOperator can now be found in the pymor.bindings.fenics module. [#353]

  • The source and range arguments of the constructor of ZeroOperator have been swapped to comply with related function signatures [#415].

  • The identifiers discretization, rb_discretization, ei_discretization have been replaced by d, rd, ei_d throughout pyMOR [#416].

  • The _matrix attribute of NumpyMatrixOperator has been renamed to matrix [#436]. If matrix holds a NumPy array this array is automatically made read-only to prevent accidental modification of the OperatorInterface [#462].

  • The BoundaryType class has been removed in favor of simple strings [#305].

  • The complicated and unused mapping of local parameter component names to global names has been removed [#306].

Further notable improvements

pyMOR 0.4 (September 28, 2016)

With the pyMOR 0.4 release we have changed the copyright of pyMOR to

Copyright 2013-2016 pyMOR developers and contributors. All rights reserved.

Moreover, we have added a Contribution guideline to help new users with starting to contribute to pyMOR. Over 800 single commits have entered this release. For a full list of changes see here. pyMOR 0.4 contains contributions by Andreas Buhr, Michael Laier, Falk Meyer, Petar Mlinarić and Michael Schaefer. See here for more details.

Release highlights

FEniCS and deal.II support

pyMOR now includes wrapper classes for integrating PDE solvers written with the dolfin library of the FEniCS project. For a usage example, see pymordemos.thermalblock_simple.discretize_fenics. Experimental support for deal.II can be found in the pymor-deal.II repository of the pyMOR GitHub organization.

Parallelization of pyMOR’s reduction algorithms

We have added a parallelization framework to pyMOR which allows parallel execution of reduction algorithms based on a simple WorkerPool interface [#14]. The greedy [#155] and ei_greedy algorithms [#162] have been refactored to utilize this interface. Two WorkerPool implementations are shipped with pyMOR: IPythonPool utilizes the parallel computing features of IPython, allowing parallel algorithm execution in large heterogeneous clusters of computing nodes. MPIPool can be used to benefit from existing MPI-based parallel HPC computing architectures [#161].

Support classes for MPI distributed external PDE solvers

While pyMOR’s VectorArrayInterface, OperatorInterface and Discretization interfaces are agnostic to the concrete (parallel) implementation of the corresponding objects in the PDE solver, external solvers are often integrated by creating wrapper classes directly corresponding to the solvers data structures. However, when the solver is executed in an MPI distributed context, these wrapper classes will then only correspond to the rank-local data of a distributed VectorArrayInterface or OperatorInterface.

To facilitate the integration of MPI parallel solvers, we have added MPI helper classes [#163] in pymor.vectorarrays.mpi, pymor.operators.mpi and pymor.discretizations.mpi that allow an automatic wrapping of existing sequential bindings for MPI distributed use. These wrapper classes are based on a simple event loop provided by, which is used in the interface methods of the wrapper classes to dispatch into MPI distributed execution of the corresponding methods on the underlying MPI distributed objects.

The resulting objects can be used on MPI rank 0 (including interactive Python sessions) without any further changes to pyMOR or the user code. For an example, see pymordemos.thermalblock_simple.discretize_fenics.

New reduction algorithms

  • adaptive_greedy uses adaptive parameter training set refinement according to [HDO11] to prevent overfitting of the reduced model to the training set [#213].

  • reduce_parabolic reduces linear parabolic problems using reduce_generic_rb and assembles an error estimator similar to [GP05], [HO08]. The parabolic_mor demo contains a simple sample application using this reductor [#190].

  • The estimate_image and estimate_image_hierarchical algorithms can be used to find an as small as possible space in which the images of a given list of operators for a given source space are contained for all possible parameters mu. For possible applications, see reduce_residual which now uses estimate_image_hierarchical for Petrov-Galerkin projection of the residual operator [#223].

Copy-on-write semantics for VectorArrayInterfaces

The copy method of the VectorArrayInterface is now assumed to have copy-on-write semantics. I.e., the returned VectorArrayInterface will contain a reference to the same data as the original array, and the actual data will only be copied when one of the arrays is changed. Both NumpyVectorArray and ListVectorArray have been updated accordingly [#55]. As a main benefit of this approach, immutable objects having a VectorArrayInterface as an attribute now can safely create copies of the passed VectorArrayInterfaces (to ensure the immutability of their state) without having to worry about unnecessarily increased memory consumption.

Improvements to pyMOR’s discretization tookit

  • An unstructured triangular Grid is now provided by UnstructuredTriangleGrid. Such a Grid can be obtained using the discretize_gmsh method, which can parse Gmsh output files. Moreover, this method can generate Gmsh input files to create unstructured meshes for an arbitrary PolygonalDomain [#9].

  • Basic support for parabolic problems has been added. The discretize_parabolic_cg and discretize_parabolic_fv methods can be used to build continuous finite element or finite volume Discretizations from a given pymor.analyticalproblems.parabolic.ParabolicProblem. The parabolic demo demonstrates the use of these methods [#189].

  • The pymor.discretizers.disk module contains methods to create stationary and instationary affinely decomposed Discretizations from matrix data files and an .ini file defining the given problem.

  • EllipticProblems can now also contain advection and reaction terms in addition to the diffusion part. discretize_elliptic_cg has been extended accordingly [#211].

  • The continuous Galerkin module has been extended to support Robin boundary conditions [#110].

  • BitmapFunction allows to use grayscale image data as data Functions [#194].

  • For the visualization of time-dependent data, the colorbars can now be rescaled with each new frame [#91].

Caching improvements

  • state id generation is now based on deterministic pickling. In previous version of pyMOR, the state id of immutable objects was computed from the state ids of the parameters passed to the object’s __init__ method. This approach was complicated and error-prone. Instead, we now compute the state id as a hash of a deterministic serialization of the object’s state. While this approach is more robust, it is also slightly more expensive. However, due to the object’s immutability, the state id only has to be computed once, and state ids are now only required for storing results in persistent cache regions (see below). Computing such results will usually be much more expensive than the state id calculation [#106].

  • CacheRegions now have a persistent attribute indicating whether the cache data will be kept between program runs. For persistent cache regions the state id of the object for which the cached method is called has to be computed to obtain a unique persistent id for the given object. For non-persistent regions the object’s uid can be used instead. pymor.core.cache_regions now by default contains 'memory', 'disk' and 'persistent' cache regions [#182], [#121] .

  • defaults can now be marked to not affect state id computation. In previous version of pyMOR, changing any default value caused a change of the state id pyMOR’s defaults dictionary, leading to cache misses. While this in general is desirable, as, for instance, changed linear solver default error tolerances might lead to different solutions for the same Discretization object, it is clear for many I/O related defaults, that these will not affect the outcome of any computation. For these defaults, the defaults decorator now accepts a sid_ignore parameter, to exclude these defaults from state id computation, preventing changes of these defaults causing cache misses [#81].

  • As an alternative to using the @cached decorator, cached_method_call can be used to cache the results of a function call. This is now used in solve to enable parsing of the input parameter before it enters the cache key calculation [#231].

Additional new features

  • apply_inverse_adjoint has been added to the OperatorInterface interface [#133].

  • Support for complex values in NumpyVectorArray and NumpyMatrixOperator [#131].

  • New ProductParameterFunctional.

    This ParameterFunctionalInterface represents the product of a given list of ParameterFunctionalInterfaces.

  • New SelectionOperator [#105].

    This OperatorInterface represents one OperatorInterface of a given list of OperatorInterfaces, depending on the evaluation of a provided ParameterFunctionalInterface,

  • New block matrix operators [#215].

    BlockOperator and BlockDiagonalOperator represent block matrices of OperatorsInterfaces which can be applied to appropriately shaped BlockVectorArrays.

  • from_file factory method for NumpyVectorArray and NumpyMatrixOperator [#118].

    NumpyVectorArray.from_file and NumpyMatrixOperator.from_file can be used to construct such objects from data files of various formats (MATLAB, matrix market, NumPy data files, text).

  • ListVectorArray-based NumpyMatrixOperator [#164].

    The playground now contains NumpyListVectorArrayMatrixOperator which can apply NumPy/SciPy matrices to a ListVectorArray. This OperatorInterface is mainly intended for performance testing purposes. The thermalblock demo now has an option --list-vector-array for using this operator instead of NumpyMatrixOperator.

  • Log indentation support [#230].

    pyMOR’s log output can now be indented via the logger.block(msg) context manger to reflect the hierarchy of subalgorithms.

  • Additional INFO2 and INFO3 log levels [#212].

    Loggers now have additional info2 and info3 methods to highlight important information (which does fall in the ‘warning’ category).

  • Default implementation of OperatorInterface.as_vector

    for functionals [#107]. OperatorBase.as_vector now contains a default implementation for functionals by calling apply_adjoint.

  • pycontracts has been removed as a dependency of pyMOR [#127].

  • Test coverage has been raised to 80 percent.

Backward incompatible changes

  • VectorArrayInterface implementations have been moved to the pymor.vectorarrays sub-package [#89].

  • The dot method of the VectorArrayInterface interface has been split into

    dot and pairwise_dot [#76]. The pairwise parameter of dot has been removed, always assuming pairwise == False. The method pairwise_dot corresponds to the pairwise == True case. Similarly the pairwise parameter of the apply2 method of the OperatorInterface interface has been removed and a pairwise_apply2 method has been added.

  • almost_equal has been removed from the VectorArrayInterface interface [#143].

    As a replacement, the new method pymor.algorithms.basic.almost_equal can be used to compare VectorArrayInterfaces for almost equality by the norm of their difference.

  • lincomb has been removed from the OperatorInterface interface [#83].

    Instead, a LincombOperator should be directly instantiated.

  • Removal of the options parameter of apply_inverse

    in favor of solver_options attribute [#122]. The options parameter of OperatorInterface.apply_inverse has been replaced by the solver_options attribute. This attribute controls which fixed (linear) solver options are used when apply_inverse is called. See here for more details.

  • Renaming of reductors for coercive problems [#224].

    pymor.reductors.linear.reduce_stationary_affine_linear and pymor.reductors.stationary.reduce_stationary_coercive have been renamed to pymor.reductors.coercive.reduce_coercive and pymor.reductors.coercive.reduce_coercive_simple. The old names are deprecated and will be removed in pyMOR 0.5.

  • Non-parametric objects have now parameter_type {}

    instead of None [#84].

  • Sampling methods of ParameterSpaces now return iterables instead of iterators [#108].

  • Caching of solve

    is now disabled by default [#178]. Caching of solve must now be explicitly enabled by using pymor.core.cache.CacheableInterface.enable_caching.

  • The default value for extension_algorithm parameter of greedy has been removed [#82].

  • Changes to ei_greedy [#159], [#160].

    The default for the projection parameter has been changed from 'orthogonal' to 'ei' to let the default algorithm agree with literature. In addition a copy parameter with default True has been added. When copy is True, the input data is copied before executing the algorithm, ensuring, that the original VectorArrayInterface is left unchanged. When possible, copy should be set to False in order to reduce memory consumption.

  • The copy parameter of pymor.algorithms.gram_schmidt.gram_schmidt now defaults to True [#123].

  • with_ has been moved from BasicInterface to ImmutableInterface [#154].

  • BasicInterface.add_attributes has been removed [#158].

  • Auto-generated names no longer contain the uid [#198].

    The auto-generated name of pyMOR objects no longer contains their uid. Instead, the name is now simply set to the class name.

  • Python fallbacks to Cython functions have been removed [#145].

    In order to use pyMOR’s discretization toolkit, building of the _unstructured, inplace, relations Cython extension modules is now required.

Further improvements

pyMOR 0.3 (March 2, 2015)

  • Introduction of the vector space concept for even simpler integration with external solvers.

  • Addition of a generic Newton algorithm.

  • Support for Jacobian evaluation of empirically interpolated operators.

  • Greatly improved performance of the EI-Greedy algorithm. Addition of the DEIM algorithm.

  • A new algorithm for residual operator projection and a new, numerically stable a posteriori error estimator for stationary coercive problems based on this algorithm. (cf. A. Buhr, C. Engwer, M. Ohlberger, S. Rave, ‘A numerically stable a posteriori error estimator for reduced basis approximations of elliptic equations’, proceedings of WCCM 2014, Barcelona, 2014.)

  • A new, easy to use mechanism for setting and accessing default values.

  • Serialization via the pickle module is now possible for each class in pyMOR. (See the new ‘analyze_pickle’ demo.)

  • Addition of generic iterative linear solvers which can be used in conjunction with any operator satisfying pyMOR’s operator interface. Support for least squares solvers and PyAMG (

  • An improved SQLite-based cache backend.

  • Improvements to the built-in discretizations: support for bilinear finite elements and addition of a finite volume diffusion operator.

  • Test coverage has been raised from 46% to 75%.

Over 500 single commits have entered this release. A full list of all changes can be obtained under the following address:…0.3.0