Exergoeconomic Analysis

Exergoeconomic analysis provides a systematic methodology to quantify both the thermodynamic performance and the associated economic costs of energy‐conversion systems. Building upon exergy analysis, which accounts for irreversibilities and the quality of energy, exergoeconomics introduces cost formulation rules to allocate monetary values to all exergy streams entering and leaving each component [2]. This approach enables the identification of cost‐intensive inefficiencies, guiding optimal design and operation decisions to minimize total exergy consumption and expenses. The theory described in this section follows the Specific Exergy Costing (SPECO) method as presented by Lazzaretto and Tsatsaronis (2006) [33].

Where this step fits: step 5 of the workflow
From the model to the cost of the product

Step

Needs

Gives

Examples

1

Exergy analysis

a model from Ebsilon, Aspen Plus, TESPy or JSON; fuel, product and loss of the plant

\(\dot{E}_\mathrm{F}\), \(\dot{E}_\mathrm{P}\), \(\dot{E}_\mathrm{D}\) and \(\varepsilon\) of every component

Exergy analysis examples

2

Component sizing, only where a cost is estimated from the size

the analysed plant; heat transfer coefficients for the heat exchangers

the size a cost function takes, for example power, heat transfer area or heat flow

Purchased equipment costs

3

Purchased equipment costs

known costs, costs of reference components, user-defined cost equations or the correlations of OpenPyTEA

the purchased equipment cost of every component and its reference year

Purchased equipment costs

4

Economic analysis

the purchased equipment costs; rate of return, lifetime, operating hours, fuel prices

the cost rate \(\dot{Z}\) of every component and the levelized costs of the fuels

From equipment costs to the cost of the product

5

Exergoeconomic analysis

the results of steps 1 and 4

the cost of every stream; \(c_\mathrm{F}\), \(c_\mathrm{P}\), \(\dot{C}_\mathrm{D}\), \(f\) and \(r\) of every component

Exergoeconomic analysis examples

Steps 1 and 5 are enough where the cost rates \(\dot{Z}\) are known; steps 2 to 4 obtain them from the equipment costs.

Fundamentals of exergoeconomic analysis

Exergoeconomic analysis couples the first and second laws of thermodynamics with cost accounting principles. Each exergy stream—whether associated with material, work, or heat transfer—is assigned a cost rate, and cost balances are formulated for every component.

In this framework, we define:

  • \(\dot{C}_{i}\) and \(\dot{C}_{e}\) as the cost rates associated with exergy streams entering and exiting a component, respectively,

  • \(\dot{C}_{w}\) as the cost rate associated with work flow,

  • \(\dot{C}_{q}\) as the cost rate associated with heat transfer.

The component cost balance is [2]:

\[\sum_i \dot{C}_{i,k} + \dot{C}_{q,k} + \dot{Z}_k = \sum_e \dot{C}_{e,k} + \dot{C}_{w,k}\]

where \(\dot{Z}_k\) represents the total charges due to capital investment and operating and maintenance costs.

Two fundamental principles govern the auxiliary costing equations [33]:

  • F principle: For each exergy removal from a fuel stream, the unit cost remains equal to the average cost at which that exergy was supplied by upstream components.

  • P principle: All exergy added to product streams is assigned the same unit cost, denoted \(c_P\), determined from the component cost balance and the F equations.

Costs are assigned to exergy, \(\dot{C} = c \cdot \dot{E}\) [33], so a stream without exergy of a share \(x\) (thermal, mechanical, physical or chemical) carries no cost of that share. Where an auxiliary equation equates specific costs and one of the two streams has no exergy of the share, ExerPy writes \(\dot{C}^{x}_\mathrm{out} = 0\) instead, for the outlet without exergy, or for the outlet of the equation if the inlet has none. An inlet is never fixed, since its cost is set upstream. In the mixing rule of a mixer or deaerator, an inlet without exergy of the share adds nothing, and an outlet without it gets \(\dot{C}^{x}_\mathrm{out} = 0\).

Terminology

The definitions and symbols used in exergoeconomic analysis are summarized below:

Terminology

Variable

Name

Symbol

Description

c_i, C_i

(specific) inlet cost

\(c_i\), \(\dot{C}_i\)

(specific) cost flow rate of an entering exergy stream

c_e, C_e

(specific) outlet cost

\(c_e\), \(\dot{C}_e\)

(specific) cost flow rate of an exiting exergy stream

c_w, C_w

(specific) work cost

\(c_w\), \(\dot{C}_w\)

(specific) cost rate associated with work flow

c_q, C_q

(specific) heat cost

\(c_q\), \(\dot{C}_q\)

(specific) cost rate associated with heat transfer

c_P, C_P

(specific) product cost

\(c_P\), \(\dot{C}_P\)

(specific) cost rate of the product exergy stream

c_F, C_F

(specific) fuel cost

\(c_F\), \(\dot{C}_F\)

(specific) cost rate of the fuel exergy stream

C_D

cost of exergy destruction

\(\dot{C}_D\)

cost rate associated with exergy destruction

C_L

cost of exergy loss

\(\dot{C}_L\)

cost rate associated with exergy loss

f

exergoeconomic factor

\(f_k\)

ratio of non-thermodynamic costs to total component cost

r

relative cost difference

\(r_k\)

normalized increase of product over fuel unit cost

Z

charges

\(\dot{Z}\)

sum of capital and O&M cost rates

Z_diss

charged dissipative cost

\(\dot{Z}_\mathrm{diss}\)

share of the cost of the dissipative components charged to the component

Note

The auxiliary costing equations derived from the F and P principles, together with the component cost balance, form a solvable linear system that yields the cost rates for all exergy streams in the system, see How the equation system is built and solved.

Exergoeconomic metrics and indicators

After solving the SPECO equations for all cost rates, several exergoeconomic indicators are computed to assess the economic impact of irreversibilities in each component. Three key metrics are:

  • Cost rate of exergy destruction

The cost associated with thermodynamic inefficiencies in component k is

\[\dot{C}_{\mathrm{D},k} = c_{\mathrm{F},k}\,\dot{E}_{\mathrm{D},k}\]

where \(c_{\mathrm{F},k}\) is the specific cost of the fuel exergy of component k and \(\dot{E}_{\mathrm{D},k}\) its exergy destruction rate [2].

  • Exergoeconomic factor

The fraction of a component’s total cost arising from investment and O&M (non-thermodynamic) charges is

\[f_k = \frac{\dot{Z}_k}{\dot{Z}_k + \dot{C}_{\mathrm{D},k}}\]

with the investment and O&M cost rate \(\dot{Z}_k\) of the component only [2]. The share \(\dot{Z}_{\mathrm{diss},k}\) of the cost of the dissipative components that is charged to component k, in proportion to its exergy destruction, enters its cost balance and thus its \(c_{\mathrm{P},k}\) and \(r_k\) [33]. It is not part of \(f_k\), since it is neither the investment of the component nor the cost of its exergy destruction.

A high \(f_k\) indicates that capital and O&M dominate the cost, suggesting a focus on reducing \(\dot{Z}_k\). A low \(f_k\) signals that inefficiencies (exergy destruction) are the primary cost drivers [2].

  • Relative cost difference

The relative increase in specific cost from fuel to product exergy for component k is

\[r_k = \frac{c_{\mathrm{P},k} - c_{\mathrm{F},k}}{c_{\mathrm{F},k}}\]

where \(c_{\mathrm{P},k}\) and \(c_{\mathrm{F},k}\) are the specific product and fuel costs. Lowering \(r_k\) through efficiency improvements is recommended for cost optimization [2].

How the equation system is built and solved

The cost rates of all streams follow from one linear equation system \(A\,\dot{C} = b\), with one unknown per cost variable and one row per equation. ExerPy builds it from the analysed plant and the cost dictionary, solves it and then derives the indicators of every component.

The cost variables

Every stream that touches a component of the plant carries cost variables:

  • a material stream one per share of its exergy: \(\dot{C}^\mathrm{T}\) and \(\dot{C}^\mathrm{M}\) with split physical exergy, \(\dot{C}^\mathrm{PH}\) without it, and \(\dot{C}^\mathrm{CH}\) in addition when chemical exergy is enabled;

  • a heat or power stream one, \(\dot{C}^\mathrm{TOT}\);

  • a dissipative component one more, the cost \(\dot{C}_\mathrm{diff}\) of the exergy it destroys without a product, and a storage one for the exergy it puts into or takes out of its store.

The equations

The rows of the equation system

Kind

Rows

What the row states

cost_balance

one per component with a cost balance

\(\sum \dot{C}_\mathrm{in} - \sum \dot{C}_\mathrm{out} = -\dot{Z}\); the splitter, the power bus, the cycle closer, the storage and dissipative components have none

boundary

one per cost variable of every material or heat stream entering the plant, and of every power stream entering it with a given cost

the cost given in the cost dictionary, \(\dot{C} = c\,\dot{E}\); a material stream gets the same specific cost for each of its shares

aux_power_eq

one less than the number of power streams entering the plant

all purchased power has the same specific cost

aux_f_rule, aux_f_rule_hot, aux_f_rule_cold

written by the components

F principle: exergy removed from a stream leaves at the specific cost it entered with

aux_p_rule

written by the components

P principle: every exergy added to the products of a component has the same specific cost

aux_equality

written by the components

a share that only passes through keeps its specific cost, for example the chemical exergy through a component without a reaction

aux_mixing

written by mixer, deaerator and combustion chamber

the rules of a component that mixes streams, for the shares its cost balance does not cover

dis_equality, dis_balance

written by dissipative components

the main working fluid keeps its specific cost, the auxiliary fluid, such as cooling water, leaves without cost, and the cost of the destroyed exergy and of the auxiliary fluid, \(\dot{C}_\mathrm{diff}\), is charged to the productive components in proportion to their exergy destruction [33]

The system is square by construction. A component with a cost balance writes one auxiliary row per cost variable of its outlets, less one, since its cost balance determines the last one; a dissipative component writes one row more and has no cost balance. Every stream inside the plant is the outlet of exactly one component, and every stream entering the plant gets its boundary rows, so the number of rows equals the number of cost variables. For the CGAM process with chemical exergy, for example:

The equation system of the CGAM process

split physical exergy

without the split

material streams × cost variables

12 × 3 (T, M, CH)

12 × 2 (PH, CH)

heat and power streams

3

3

dissipative component

0

0

cost variables and rows

39

27

of which cost balances, boundary rows, auxiliary rows

7, 9, 23

7, 6, 14

The variables and the rows of a run can be listed by name:

eco.run(costs)
eco.print_variables()   # {0: "C_1_PH", 1: "C_1_CH", 2: "C_10_PH", ...}
eco.print_equations()   # {0: {"kind": "cost_balance", "object": ["CC"], ...}, ...}

Solving

run() solves the system with numpy.linalg.solve and then

  1. charges the cost of the exergy destroyed in dissipative components to the productive ones;

  2. assigns every stream its cost rates and specific costs, \(c = \dot{C}/\dot{E}\) per share, and with the split \(\dot{C}^\mathrm{PH} = \dot{C}^\mathrm{T} + \dot{C}^\mathrm{M}\);

  3. computes \(\dot{C}_\mathrm{F}\), \(\dot{C}_\mathrm{P}\), \(\dot{C}_\mathrm{D}\), \(r\) and \(f\) of every component;

  4. checks the cost balance of every component and warns where one is not closed;

  5. charges the cost of the loss streams to the product streams, in proportion to their net exergy (Bejan et al., Example 8.1) [2]. A stream subtracted in E_P, such as the feedwater of a boiler, is paired with the product stream it turns into downstream, such as the steam. If it reaches no product stream or more than one, the gross exergy of the products is used and a warning names the stream;

  6. checks the cost balance of the whole plant, \(\dot{C}_\mathrm{P,tot} = \dot{C}_\mathrm{F,tot} + \sum \dot{Z}\), and raises an error where it is not closed.

What changes with the split of the physical exergy

With split_physical_exergy=True, the thermal and the mechanical exergy of a stream are costed separately; without it, the physical exergy is costed as a whole.

  • Variables: a material stream has \(\dot{C}^\mathrm{T}\) and \(\dot{C}^\mathrm{M}\) instead of \(\dot{C}^\mathrm{PH}\), so the system has one variable more per stream, 39 instead of 27 for the CGAM process.

  • Rules: with the split, a component writes a rule for each share. A heat exchanger, for example, follows the F principle for the thermal exergy its hot stream gives off, while the mechanical exergy passes at its own specific cost. Without the split, the rules for the mechanical exergy fall away and the thermal rules apply to the physical exergy instead.

  • Results: the split lets the two shares of a stream carry different specific costs. A pump, for example, adds mechanical exergy at the cost of its product, while the thermal exergy of the stream keeps the cost it had. Without the split, both are averaged into one specific cost. The cost balances are met either way, but the specific costs of streams and components differ, see Split Physical Exergy in Exergoeconomics.

  • Below the ambient temperature only the split credits the cold exergy of a stream to the product of the component that produces it. Models whose streams lack the thermal and mechanical shares, such as a JSON input with the physical exergy only, are analysed without it.

Getting started with exergoeconomic analysis

Prerequisites

Before performing an exergoeconomic analysis, you need:

  1. A completed exergy analysis

  2. Component investment cost rates and specific costs of the input streams, given directly or obtained from the purchased equipment costs with the economic analysis, whose compute_costs() returns them in the format below

Every component of ExerPy takes part in the exergoeconomic analysis. Two of them need an input that the thermodynamic model does not carry:

  • a combustion chamber needs the chemical exergy, so the exergy analysis has to run with a chemExLib;

  • a steam generator needs the temperature of its heat source in its T_hot attribute, since that source is usually outside the model.

A simple heat exchanger may be given the temperature of its heat source or its heat consumer as well, see Heat from or to outside the model.

Note

With split_physical_exergy=True, the cost of a material stream is allocated to its thermal and its mechanical exergy separately; with False, it is allocated to its physical exergy as a whole. Both are supported, so models whose streams lack the thermal and mechanical shares can be analysed as well. The two conventions do not give the same specific costs; see What changes with the split and Split Physical Exergy in Exergoeconomics.

Workflow overview

The exergoeconomic analysis in ExerPy follows four steps:

  1. Perform the exergy analysis, here with the physical exergy split:

from exerpy import ExergyAnalysis, ExergoeconomicAnalysis

ean = ExergyAnalysis.from_json(model_path, chemExLib="Ahrendts", split_physical_exergy=True)

fuel = {"inputs": ["1", "10"], "outputs": []}
product = {"inputs": ["E1", "9"], "outputs": ["8"]}
loss = {"inputs": ["7"], "outputs": []}

ean.analyse(E_F=fuel, E_P=product, E_L=loss)
  1. Create the exergoeconomic analysis instance:

eco = ExergoeconomicAnalysis(ean)
  1. Define costs and run the analysis:

costs = {
    # Component investment cost rates [EUR/h]
    "AC_Z": 80,
    "CC_Z": 30,
    "EXP_Z": 100,
    "GEN_Z": 40,
    # Input stream specific costs [EUR/GJ]
    "1_c": 0.0,    # Ambient air (free)
    "10_c": 10.0,   # Natural gas fuel
    "8_c": 0.5,     # Feedwater
}

eco.run(costs)

The cost rates \(\dot{Z}\) and the specific costs of the entering streams can be typed in, as above, or derived with the economic analysis: the purchased equipment costs come from one of the four sources (known costs, scaled costs of reference components, user-defined cost equations or the correlations of OpenPyTEA), the total revenue requirement method turns them into \(\dot{Z}\), and compute_costs() returns both in the format of the cost dictionary:

from exerpy import EconomicAnalysis

economic = EconomicAnalysis(
    PEC={
        "AC": 1.2e6,
        "CC": 4.0e5,
        # ... the other components
    },
    fuel_costs={"1": 0.0, "10": 10.0, "8": 0.5},   # EUR/GJ, the streams entering the plant
    # ... reference_year, base_year, cost_index and the parameters, see Economic Analysis
)
eco.run(economic.compute_costs(ean))   # the "_Z" and "_c" entries of the cost dictionary

From Equipment Costs to the Cost of the Product shows the whole way on a heat pump.

  1. View results:

eco.exergoeconomic_results()
eco.evaluate_results()

Cost input format

The cost dictionary passed to run() requires two types of entries:

Cost dictionary format

Key format

Type

Unit

Description

"<component_name>_Z"

Component cost

currency/h

Investment and O&M cost rate for each component

"<connection_name>_c"

Stream cost

currency/GJ

Specific cost for each input stream crossing the system boundary

A value can also be given in another unit, as long as it is in the currency of the analysis, e.g. "10_c": 90.0, "10_c_unit": "EUR / MWh" or "COMP_Z": 0.0222, "COMP_Z_unit": "EUR / s". A cost per day or per year is not accepted: turning it into a cost per hour of operation needs the operating hours, which EconomicAnalysis takes into account.

A material stream entering the plant can also have a cost for each form of its exergy. In the SPECO method, the cost rate of each exergy form (thermal, mechanical and chemical) of a material stream supplied to the plant from outside is a known value of its own [33]. The keys are "<connection_name>_c_T", "<connection_name>_c_M" and "<connection_name>_c_CH", and "<connection_name>_c_PH" stands for the thermal and the mechanical exergy together. Without the split of the physical exergy only "_c_PH" and "_c_CH" apply. "_c_CH" is used only when the chemical exergy is part of the analysis. A form without a cost of its own takes the "_c" of the stream, and each key can have its own unit, e.g. "10_c_CH_unit".

Mandatory costs:

  • All components must have a _Z cost, except the CycleCloser, the PowerBus and the Splitter. These pass their streams on without a cost balance of their own, so a cost given for one of them could not be charged to any stream and is rejected.

  • All material and power/heat streams entering the system boundary must have a _c cost. A material stream can have a cost for each of its exergy forms instead. For heat, what counts is the direction of its exergy, which below the ambient temperature is against the heat: heat that cools a stream below it (a chiller) needs a cost, heat taken in by such a stream (an evaporator) is priced by the component and needs none.

Examples:

  • "COMP_Z": 80.0 — compressor investment cost of 80 EUR/h

  • "1_c": 0.0 — ambient air enters the system at zero cost

  • "10_c": 25.0 — natural gas enters the system at 25 EUR/GJ

  • "10_c": 2.0, "10_c_CH": 10.0 — the chemical exergy of stream 10 costs 10 EUR/GJ, its thermal and mechanical exergy 2 EUR/GJ

Interpreting results

After running the analysis, use exergoeconomic_results() to display the full results, and evaluate_results() to identify the components with the highest cost improvement potential.

# Display all results (4 DataFrames)
df_comp, df_mat_props, df_mat_costs, df_non_mat = eco.exergoeconomic_results()

# Identify top components for optimization
eco.evaluate_results(sort_by="C_D+Z", top_n=5)

The component results table lists the cost rates and the indicators defined in Exergoeconomic metrics and indicators. The components with the largest total cost rate \(\dot{C}_\mathrm{D} + \dot{Z}\) are the most promising targets for an improvement. The column Z holds the given cost rate of a component and Z_diss the share of the cost of the dissipative components charged to it. C_D+Z and f leave Z_diss out, since C_D+Z of the dissipative component already contains it. In the row TOT, Z is the sum of the given cost rates only, since the charged shares stay inside the plant, and C_D is \(c_\mathrm{F,tot}\,\dot{E}_\mathrm{D,tot}\), not the sum of the column, since the cost of the exergy destruction of the plant cannot be found by adding the costs of the components [2].

The evaluate_results() method accepts the following sort_by options: "C_D+Z" (default), "C_D", "Z", "r", "f".

To verify the integrity of the solution, use check_cost_balance():

balances = eco.check_cost_balance(tol=1e-3)
for name, (residual, is_balanced) in balances.items():
    print(f"{name}: residual={residual:.6f}, balanced={is_balanced}")

Note

Results depend on the auxiliary equations, and those are a modelling choice. Check the cost balance of every component with check_cost_balance() and validate the results independently before basing a decision on them.

Troubleshooting

The messages below point to what is missing or wrong in the specification.

“Cost for component ‘…’” or “Cost for input connection ‘…’ is mandatory but not provided”

A "<name>_Z" or "<name>_c" entry is missing; Cost input format lists which components and streams need one. A stream entering free of charge is given 0.0.

“Exergoeconomic system is singular (rank r/n)”

The rows do not determine all cost variables. ExerPy prints a dependency report, which can also be called directly with print_dependency_report(). Read it as follows:

  • Equations with no variables are rows that stayed empty: the system has fewer equations than cost variables. Look for warnings of the components at the start of the run, such as “not implemented” for a case a component does not cover or “No auxiliary equations provided”. A power stream entering the plant without a cost, in a plant that exports no power, leaves a row empty as well; give it a "<name>_c".

  • Variables never used are cost variables no row contains: a stream between components that have no cost balance, for example.

  • Exactly collinear pairs are two rows that state the same thing, for example two conditions on the same stream.

  • SVD dependencies list a group of rows that together are dependent. The components and streams named in these rows are where a rule is missing or doubled.

run(costs, allow_singular=True) returns a least-squares solution instead of an error. It is not unique and may not be physically consistent; use it to inspect the system, not as a result.

“Exergoeconomic cost balance of the entire system is not satisfied”

Fuel, product and loss of the plant do not cover every stream that crosses the system boundary. The exergy analysis warns about such streams (“The following system boundary connections are not included in E_F, E_P, or E_L”); add each of them to E_F, E_P or E_L.

“Balance for component … not fulfilled”

The cost balance of a component is not closed after the solution, which points to a rule of that component that contradicts its balance. Check it with check_cost_balance().

“The solution of the cost matrix contains NaN values”

A stream carries no valid exergy value, for example a NaN in the export of the model. Check the exergy of the streams in exergy_results().