What’s New

Notable new features and improvements of the current release series. The changelogs of the earlier series are linked at the bottom of this page.

v0.11.2 - Rankine’s Renaissance (September, 3, 2026)

New Features

Bug Fixes

  • The starting value generation split the total mass balance of combustion components arbitrarily, since the stoichiometry and the energy balance cannot enter the presolve on a guessed fluid composition. The CombustionChamber and its subclasses now contribute an approximate air to fuel proportion - based on the oxygen supply and demand of the inlets and on lamb, where it is specified - to the flow presolve, which leads to more reasonable initial guesses for the individual mass flows (PR #1058).

Other Changes

  • Three new example models are available in the Model Library (PR #1059):

  • The documentation has been restructured into the main sections “Get started”, “Explore”, “Build”, “Project” and “Reference”. The former advanced features, integration and knowledge center pages are now split into the how-to guides, extend and integrate sections and the complete simulation models moved from the tutorials to the Model Library (PR #1059).

  • The new publications page lists the works using or citing tespy. If your work is missing, please open an issue or a pull request (PR #1059).

Contributors

v0.11.1 - Rankine’s Renaissance (August, 16, 2026)

New Features

  • New UserDefinedVariable class: a standalone solver variable that is not attached to any connection or component. It is referenced from the function and dependents of a UserDefinedEquation, which closes the degree of freedom the variable adds. See the user defined variables section for an example (PR #1034).

  • The SectionedHeatExchanger reports the required hot-side heat transfer area area_hot as a result, in case area_ratio, R_cond and the alpha values of all phases occurring in the solution are set (PR #1035).

  • Presolving logs every determination: which specification (or previously presolved value) eliminates which variables, both as solver debug messages and as a structured record. Network.get_presolve_log returns the records in order of occurrence, with the originating specifications of each determination resolved transitively (PR #1040).

  • New NTUHeatExchanger component: the heat transfer coefficient UA is linked to the heat transferred through the effectiveness-NTU relation of a specifiable flow_arrangement (counterflow, parallelflow, crossflow with any mixing combination and shell and tube with an arbitrary number of shell passes). eps, NTU and the capacity rate ratio C_r are reported as results (PR #1045).

  • The specifications of a network can be saved, cleared and restored with the new methods save_specifications(), clear_specifications() and restore_specifications(). This allows switching between different parametrizations of a topologically unchanged network (PR #1047).

  • The cycle diagram handling of the ModelTemplate class can be customized now (PR #1046):

    • The new create_diagram() method is a public hook for diagram creation. Override it to adjust e.g. the isoline ranges to the operating envelope of your model.

    • Pre-configured diagrams can be registered per fluid with register_diagram() or passed directly to the plotting methods via the new diagram keyword, which is especially useful in interactive sessions.

    • Fluids not supported by fluprodia (mixtures, incompressibles or fluids outside the default isoline range) no longer raise an error in the plotting methods. Instead a warning is logged and the plot falls back to showing the state points only. An is raised if strict=True is passed to the respective method.

  • The delta of a Ref can be specified as pint.Quantity as well (PR #1051).

  • Connections, components and their data containers provide readable repr and print output now, which can be controlled globally with tespy.set_display_mode:

    • "compact" (default)

    • "extensive"

    • "none"

    See the general configuration section for an example (PR #1052).

  • A Network can be converted into a Subsystem with the new from_network() method. The boundary components of the Network instance, e.g. Source and Sink, are automatically by the SubsystemInterface to allow embedding the subsystem into another network. The keep parameter controls which state is carried into the subsystem instance (PR #1021):

    • full parametrization ("specifications", default),

    • starting values only ("starting_values")

    • nothing ("nothing")

Bug Fixes

  • The enthalpy to temperature inversion of the IncompressibleFluidWrapper returned wrong temperatures for (nearly) constant heat capacity data. The quadratic formula is now evaluated in its numerically stable form.

  • The section result arrays of the ParallelFlowHeatExchanger (T_hot_sections, T_cold_sections, Q_sections, lmtd_per_section) paired the temperature profiles in counterflow orientation. Both profiles now run from the common inlet end (maximum temperature difference at zero heat transferred) to the common outlet end, aligned on the cumulative heat axis of the parallel flow configuration (PR #1043).

  • After solving and a difference in results between the specified input and the calculated property, the component results tables were not updated while the connection results tables were. Both now report the state of the latest solve (PR #1051).

  • The delta of a referenced property specification was reinterpreted in the current default units at every solve. Changing the default units between two solves silently changed its value (PR #1051).

Other Changes

  • Changing the default units through set_defaults() after a network has been solved is now well defined and warns about its consequences:

    • Values specified as plain numbers and results are converted from their SI value to the updated default units from the next solve on.

    • New plain number specifications are interpreted in the new default units.

    • Values specified as pint.Quantity keep their unit.

    Previously, already converted values silently kept their old unit while re-specified values picked up the new one, mixing unit systems within a single network (PR #1051).

  • Support for importing networks exported with tespy v0.8 or earlier through from_json() has been removed. The same applies to design and initialisation state files written with tespy v0.9 or earlier. To migrate such files, load and re-save them with an intermediate tespy version, e.g. v0.10.0 (PR #1021).

  • The determination error and debug messages on the problem reduction report the number of directly specified variables, so the difference between the original and the reduced problem size becomes traceable (PR #1034).

  • Adding a connection or component, which is already part of a different network, now raises an error. To use the same model in a second network, create an independent copy of it, e.g. with export() and from_json() (PR #1021).

  • The postprocessing overhead per solve has been reduced (PR #1051):

    • Unit strings are parsed into pint objects only once per unit and registry instead of once per converted value.

    • The results DataFrames are built lazily on first access of Network.results.

Documentation

  • New advanced tutorial on a CO2 transcritical booster refrigeration system of the kind used in supermarkets. The model is implemented on top of the ModelTemplate class and demonstrates log(p)-h and QT diagram plotting, a sensitivity analysis of the gas cooler pressure and the optimization of the COP with pymoo. See the tutorial for details.

Contributors

v0.11.0 - Rankine’s Renaissance (July, 27, 2026)

The solver was restructured from the ground up for this release. The new solver section in the documentation describes the full solution process. This page lists the changes relevant for updating existing models and custom components.

API Changes

  • Everything deprecated with a FutureWarning in this release will be removed or changed in version 0.12; each warning names its replacement.

  • The solver state of the Network class has moved to the new Problem class. A fresh instance is created with every call of solve() and remains accessible through the new read-only Network.problem property afterwards. Accessing solver attributes directly on the network, e.g. variables_dict, residual, jacobian, increment, residual_history, lin_dep, iter, max_iter, is deprecated and raises a FutureWarning, use Network.problem.<name> instead. The public inspection API, e.g. print_residuals(), and the status and converged attributes are unaffected.

  • The convergence check operates on scaled residuals now: every residual is related to the response of its equation, every increment to the magnitude of its variable, which makes the acceptance independent of the physical scale of the plant. residual_history and the residual column of the iteration information display the largest scaled residual instead of the norm of the raw residual vector, print_residuals() shows both. See the solving section.

  • The starting value generation was reworked, see the starting values section for the new process. Custom components may need updates in the hooks that contribute starting value information:

    • initialise_source and initialise_target are only consulted as a last fallback for a generic pressure value anymore. Their enthalpy branches are never called; starting enthalpies are generated by the automatic machinery instead.

    • Components can override _initial_affine_edges() (approximate pressure and enthalpy relations between the ports, used to propagate known values through the network), _initial_temperature_edges() (approximate temperature relations, reconciled into one starting temperature per connection) and initial_state() (expected phase at a port, turned into saturation pressure anchors and phase consistent enthalpies). The base class defaults cover components with a single inlet and a single outlet.

  • The dependency declarations of equations are load-bearing for the new block decomposition: an incomplete declaration of a custom equation can render the problem structurally singular for block-wise solving. The error message points to nw.solve(mode, block_solve=False) for that case.

  • The power_connector_location parameter of SimpleHeatExchanger (and its subclasses) has been removed. It was deprecated and without effect. Loading a network export containing removed component parameters does not fail anymore: unknown parameters are skipped with a warning, so files from older versions stay loadable.

New Features

  • The equation system is solved block-wise by default: a Dulmage-Mendelsohn decomposition brings it into block lower triangular form and the blocks are solved in precedence order. Failures escalate in stages up to the simultaneous solution of the full system from its initial state, which reproduces the behavior of previous versions exactly - the block phase can therefore never degrade robustness. The simultaneous solution can be enforced with nw.solve(mode, block_solve=False). Networks with variable fluid composition are always solved simultaneously for now, block-wise solving for them is planned for a future release. See the decomposition and solving sections.

  • Under- and over-determination errors and structural singularities name the specific equations and variables of the defective part of the model, interactively available through print_structural_analysis().

  • The solution process can be staged: presolve() prepares the problem and stops before solving, so variables can be inspected and modified, solve_continue() then runs the solver. With nw.solve(mode, pause_on_block_failure=True) the solver pauses at the first failing block (status 20) for interactive debugging of that exact state. See the section on interacting with the solver.

  • Starting values can be provided as temperature and vapor quality guesses now, e.g. conn.set_attr(T0=75, x0=0.5): the temperature guess anchors the starting temperature estimation and both are converted into enthalpy and saturation pressure starting values. The guesses override values of a previous solution and are consumed by a successful solve (#622).

  • New inspection methods report the mathematical structure of the problem: the variable space reduction and the provenance of presolved values (print_presolved_variables()), the block decomposition (print_blocks(), print_incidence_matrix() with block_order=True) and the state of a failed block (print_block_jacobian(), print_block_states()). See the problem reduction section.

Bug Fixes

  • The residual of the \(\zeta/D^4\) pressure loss equation saturated with vanishing derivatives when the pressure difference approached zero or the mass flow diverged. It is now formulated in terms of the pressure difference, which keeps gradient information exactly where the equation was most violated and removes the special case branch for zero mass flow.

  • Enthalpy starting values inside the two phase dome could fail with a linear dependency when a temperature equation sat on the residual plateau of the two phase region. The all-zero jacobian row recovery and its bracketing search handle these plateaus now, e.g. the SEGS model converges without its previous two stage initialization.

  • Exporting a network before solving it serialized plain numeric specifications with the global default units instead of the network’s default units, e.g. a temperature of 200 set under °C defaults was exported as 200 kelvin and misread on import. Solved networks were not affected.

  • set_attr() now actually emits its FutureWarning: the deprecation notice existed but was never raised.

  • Solver runs are bit-exact reproducible now. Two defects injected run to run varying floating point noise into the Jacobian: the numeric derivatives restored the perturbed value by arithmetic (leaving one ulp sized residues that depended on the evaluation order) and the evaluation order itself followed the per process iteration order of sets. Marginal models could converge in one run and fail in the next; results and iteration counts are now identical across repeated runs.

  • The postprocessing limit checks are noise aware now: a parameter value beyond its declared bound by less than a relative tolerance - related to the magnitude of the parameter itself or of a declared reference parameter, e.g. the thermal input for the heat dissipation of a combustion chamber - is snapped onto the bound instead of being reported. Converged solutions are no longer flagged with status = 1 for numerical noise on exact bounds.

  • Value ranges (m_range, p_range, h_range) are exported in the network’s default units now. Files exported with earlier versions hold raw SI magnitudes, which are reinterpreted in the default units on load - check or re-export old files carrying range specifications.

Other Changes

  • The solver detects when the residual alternates between two values and activates the oscillation damping automatically. The oscillation_damping parameter of solve() remains available to activate it from the first iteration. See the convergence stability section.

  • Convergence acceptance was modified. A solution is only accepted in an iteration in which no convergence heuristic modified any value, replacing the fixed min_iter floor. The default of min_iter dropped from 4 to 2 and warm started solves, e.g. in offdesign parameter sweeps, typically finish in two iterations.

  • Debug logging was reworked throughout preprocessing and solving: it reports the fluid domains, the design/offdesign switch, the problem reduction and the block decomposition, and console output is no longer doubled when console logging is enabled.

  • The construction of the mathematical problem moved from the network to Problem.build and the affine elimination graph is a persistent StructureGraph instance, available as Network.problem.structure_graph. The private network methods _build_graph, _find_cycles_in_graph, _raise_error_if_cycle and _find_linear_dependent_variables have been removed.

Contributors

Earlier releases