v0.10

Changelog of the v0.10 release series.

v0.10.2 - Rankine’s Renaissance (July, 15, 2026)

New Features

  • SubsystemInterface now supports optional power and heat pass-through ports via the new num_power_inter and num_heat_inter parameters. Setting these exposes symmetric inlet/outlet port pairs (power_in{n}/power_out{n} and heat_in{n}/heat_out{n}) and adds the corresponding energy-equality mandatory constraints (\(\dot E_\text{in} = \dot E_\text{out}\)). Subsystem subclasses can declare num_power_in, num_power_out, num_heat_in, and num_heat_out class attributes before calling super().__init__(), following the same pattern as the existing num_in/num_out fluid interface declaration. This makes it possible to route PowerConnection and HeatConnection instances across subsystem boundaries (PR #1014).

Bug Fixes

  • Default characteristic lines and maps were not available for inherited components. These fell back to x = [0, 1] and y = [1, 1]. Now instances of classes inherit the DEFAULT characteristic lines and maps of parent classes if there is no own DEFAULT (3e65ba3).

  • Network deserialization wrongly activated serialized but inactive Ref specifications. The is_set flags are now restored as exported (PR #1024).

  • Fix some typos in the heat exchanger tutorial (PR #1025).

Contributors

v0.10.1 - Rankine’s Renaissance (June, 14, 2026)

API Changes

  • The UA_cecchinato group and its parameters re_exp_r, re_exp_sf, and refrigerant_index on SectionedHeatExchanger and MovingBoundaryHeatExchanger are deprecated. Use the new UA_cecchinato_hc group with re_exp_hot and re_exp_cold instead. In the next major version UA_cecchinato will adopt the hot/cold convention of UA_cecchinato_hc. Setting the old parameters raises a FutureWarning (PR #985).

  • calc_sections() on HeatExchanger, SectionedHeatExchanger, and MovingBoundaryHeatExchanger is deprecated. Section data is now computed automatically after each solve and exposed as ComponentArrayProperties attributes directly on the component: Q_sections, T_hot_sections, T_cold_sections, Q_per_section, lmtd_per_section, and phases_per_section. Each attribute provides .val in the network’s user-specified units and .val_SI in SI units. The old return value of calc_sections() (a 5-tuple in user units) is still returned but raises a FutureWarning (PR #1001).

New Features

  • phase_ph() is now implemented across all fluid property wrappers, returning a consistent set of string identifiers: "l" (liquid), "g" (gas), "tp" (two-phase), and "sc" (supercritical).

  • Added heat transfer area calculation for the MovingBoundaryHeatExchanger following the moving-boundary method of [3].

  • A new ComponentArrayProperties data container has been introduced for array-valued component result properties. It exposes .val_SI (SI units) and .val (network user units, populated by the network after each solve via set_val_from_SI), following the same unit-routing pattern as ComponentProperties. This class is currently intended for result-only use and cannot be set by the user. Its API may change in future versions (PR #1001).

Bug Fixes

  • Fixed specific volume calculation for mixtures containing water in condensing conditions (PR #985).

  • Fixed _presolve() to use the actual vapor quality when determining saturation pressure from a simultaneous T and x specification. Previously p_sat_T (hardcoded Q=0.5) was used; the new p_sat_TQ() dispatches to the bubble or dew pressure as appropriate. For pure fluids there is no change in behavior (PR #1004).

  • Fixed Condenser to use the dew temperature at the hot-side inlet in calculate_td_log() and ttd_u_func() instead of the bubble temperature. For pure fluids there is no change in behavior (PR #1004).

  • Fixed PolynomialCompressor EN12900 polynomial evaluation to use T_dew_p() for the evaporation temperature and T_bubble_p() for the condensation temperature, consistent with how reference pressures are defined in the polynomial generation step. For pure fluids there is no change in behavior (PR #1004).

  • Fixed phase_ph() for mixture-type backends (e.g. REFPROP zeotropic mixtures) where calc_phase is not implemented. Phase is now determined by comparing enthalpy against the bubble and dew enthalpies at the given pressure (PR #1004).

Other Changes

  • All internal pint conversions of the form .to(...).magnitude have been replaced with the equivalent but more concise .m_as(...) across the codebase (PR #1001).

Contributors

v0.10.0 - Rankine’s Renaissance (June, 03, 2026)

API Changes

  • Passing per-quantity unit keyword arguments to set_attr() (e.g. T_unit, p_unit, h_unit, …) now raises a TypeError. Use set_defaults() instead, e.g. nw.units.set_defaults(temperature='degC', pressure='bar'). The shorthand "C" for Celsius is no longer accepted; use "degC" or "°C" instead (PR #968).

  • The power_connector_location attribute of SimpleHeatExchanger is deprecated and no longer required. Use HeatConnection together with the new HeatSource and HeatSink components instead - the inlet or outlet side is detected automatically from the connection (PR #961).

  • Several component parameters have been renamed for clarity (PR #989). Old names remain available as deprecated aliases: zetazeta_d4 (zeta1/zeta2zeta1_d4/zeta2_d4), kAUA (kA_charUA_char, kA_groupUA_group, kA_char_groupUA_char_group; kA_char1/kA_char2UA_char1/UA_char2 for two-sided exchangers), and td_loglmtd (logarithmic mean temperature difference).

  • The Bus class has been removed. Use PowerConnection together with PowerBus, Motor and Generator instead (PR #964).

  • The rpm parameter of PolynomialCompressor is deprecated in favour of frequency, which integrates with TESPy’s unit framework (e.g. set "1/min" as the network frequency unit). The rpm_displacement and rpm_poly keys in reference_state are deprecated in favour of frequency_displacement (Hz) and frequency_poly (Hz). The displacement key (m³/h) paired with frequency_displacement remains supported, or swept_volume (m³ per revolution) can be provided directly. A helper function swept_volume_from_displacement() is available to convert manufacturer displacement data to swept volume (PR #826).

  • Several previously deprecated features have been removed: the Td_bp parameter of Connection, the Q_diss_rel parameter of PolynomialCompressor, the zeta="var" option, the helper functions convert_to_SI and convert_from_SI, and fluid_property_data from global_vars (PR #973).

  • Setting a Ref on a Connection parameter now automatically unsets any previously specified numerical value for that parameter, and setting a numerical value automatically unsets any previously set Ref. Both could be set simultaneously before, which raised a FutureWarning.

  • The char_map_pr and char_map_eta_s parameters of Compressor are deprecated. Use TurboCompressor instead, which is the dedicated class providing characteristic map offdesign capability.

  • The pygmo compatibility interface of OptimizationProblem has been removed. The fitness, get_nobj, get_nic, get_bounds, run and _process_generation_data methods are no longer available. Use pymoo-based workflows instead (install via pip install tespy[opt]).

  • The built-in ExergyAnalysis class has been removed and its functionality moved to the external library exerpy. Use tespy.models.template.ModelTemplate.run_exergy_analysis() or call ExergyAnalysis.from_tespy(nw, Tamb, pamb) directly from exerpy (PR #963).

New Features

  • A new f_nox parameter has been added to CombustionChamber and derived combustion components. Setting it enables nitric oxide (NO) formation modelling: the value represents the mass-based NO generation rate (mass of NO created per unit mass of total fuel and air input). Requires pyromat being installed as fluid property backend (PR #904).

Other Changes

  • Internal Newton solver improvements (PR #987):

    • The CPU Jacobian solve now uses row- and column-scaled numpy.linalg.solve instead of explicit matrix inversion via numpy.linalg.inv, improving numerical stability and performance.

    • The dense incidence matrix is now built once before the Newton loop instead of being rebuilt on every iteration.

    • Jacobian singularity diagnosis has been extracted into a dedicated _diagnose_singularity method, separated from the matrix solve in _invert_jacobian.

    • Structural singularity detection now uses numpy.linalg.matrix_rank instead of numpy.linalg.det, which is numerically stable for arbitrarily sized matrices.

    • CoolPropWrapper now caches the last AS.update call and skips redundant updates when the same input pair and values are requested consecutively.

    • get_fluid_data() now caches and reuses the fluid data dict across calls, only rebuilding it when the fluid set changes (e.g. in combustion components).

    • calc_results() now skips the unit conversion for parameters that have not been fixed by the user, avoiding redundant pint conversions during postprocessing.

    • HeatExchanger now caches temperature values computed in _get_T_at_steps by (p, h) key, so that unperturbed sides of the heat exchanger are not recomputed during finite-difference Jacobian evaluation. The cache is cleared at the start of each solve via _preprocess.

  • Support for Python 3.10 has been dropped.

  • Installation instructions now recommend uv as the primary package manager (PR #967).

  • Companion print_* methods have been added for all debugging inspection methods on Network: print_variables_before_presolve(), print_presolved_variables(), print_variables(), print_presolved_equations(), print_equations(), print_equations_with_dependents(), and print_incidence_matrix(). Error messages that reference variables or equations now use the same human-readable formatting as these print methods (PR #969).

  • get_ude() has been added, analogous to get_comp() and get_conn(), to retrieve a UserDefinedEquation by label. Not found labels currently return None, they will raise a KeyError in a future version (PR #966).

  • save() now accepts an as_dict=True flag to return the network state as a plain dict, which can be passed directly as design_path or init_path in a subsequent solve() call without writing to disk. Passing None without as_dict=True still works but is deprecated (PR #962).

  • Mixing rules are now registered via a MixingRuleRegistry, making it possible to add custom mixing rules at runtime (PR #960).

  • You can now pass a postproc_func argument to sensitivity_analysis(), which accepts any callable postproc_func(model) -> dict | None to be executed after each solve step (PR #963).

  • The automatic y-axis limits of plot_Ts_diagram_matplotlib() and plot_logph_diagram_matplotlib() now extend to at least the fluid’s critical temperature or critical pressure respectively, so the two-phase dome is always fully visible when no explicit ylim is passed (PR #963).

  • Change outlet 1 description to saturated gas constraint for DropletSeparator (PR #977).

  • Component parameters can now have a calc method, which is automatically executed in postprocessing to assign the respective SI value to the parameter (PR #980).

  • Fix logging message in connection preprocessing (PR #988).

  • generate_component_schema() and generate_connection_schema() export a JSON description of all registered component and connection parameters - including container type, physical quantity and description - for use in external tooling (PR #938).

  • A docstring updater script has been added at docs/scripts/docstring_updater.py. It regenerates the Ports, Mandatory Equations, and Parameters sections of all registered component and connection class docstrings from live introspection of port_schema(), get_mandatory_constraints(), and get_parameters(), while preserving the introductory paragraph, Notes sections, and Example blocks verbatim (PR #938).

  • The isentropic calculation in compressor, pump, turbine and displacement machine components is now guarded against fluid property backend errors in the same way fluid property boundaries already are (PR #1000).

  • Component parameters whose Jacobian depends on multiple equations can now declare their scalar and vector dependents as separate keys ({"scalars": [...], "vectors": [...]}) in addition to the flat list form. The derivative dispatcher in _assign_dependents_and_eq_mapping() routes each form correctly, enabling selective finite-difference increments for grouped parameters with mixed scalar/vector dependencies (PR #1000).

Bug Fixes

  • export() and save() now create the target directory if it does not exist yet (PR #965).

  • save_csv() no longer writes Component CSV files inside the Connection subdirectory when both are exported together (PR #966).

  • _adjust_to_two_phase() was not working correctly with td_dew or td_bubble equal to zero (PR #971).

Contributors