exergy module

The exergy module functionalities can be found in the energy package.

The exergy package serves the primary purpose of determining exergy destruction within a unit, and declaring it as an attribute (Quantity) of the unit, eligible as objective function for the optimizations. The package uses three main modules as pillars: ‘ElectricalExergy’, ‘ThermalExergy’ and ‘ExergyDestruction’. The first two identify, respectively, the electrical or thermal flows interacting with an energy unit, and determine the corresponding exergy flow accordingly. Then, the “ExergyDestruction” module reads the exergy flows assessed for the unit, and applies an exergy balance to determine its exergy destruction.

The module ‘ElectricalExergy’ determines the exergy flow associated to an input, output or accumulation of electricity in a consumption, production or storage unit respectively. ‘ElectricalExergy’ starts by verifying that the unit is indeed an electrical unit (energy_type = ‘elec’), raising a ‘TypeError’ otherwise. After this verification, it calculates the exergy flow and declares it as an attribute of the unit (energy_unit.exergy). The calculation is rather straightforward, as in the case of electricity, exergy equals energy.

The module ‘ThermalExergy’ determines the exergy flow associated to an input, output or accumulation of heat in a consumption, production or storage unit respectively. ‘ThermalExergy’ starts by verifying that the unit is indeed a thermal unit (energy_type = ‘thermal’), raising a ‘TypeError’ otherwise. After this verification, it calculates the exergy flow and declares it as an attribute of the unit (energy_unit.exergy). Then, it calculates thermal exergy based on the following general formulas (first one for production/consumption units, and second one for storage units):

{0}_exergy[t] == {0}_p[t]*(1 -({1}+273.15)/({1}+273.15))*time.DT

{0}_exergy[t] == {0}_e[t]*(1 -({1}+273.15)/({0}_t_heat+273.15))*time.DT’

with {0} the energy unit name, and {1} the dead state temperature.

The procedure is accompanied with several checks on correct values inputted for temperature.

Before carrying out their calculations, both ‘ElectricalExergy’ and ‘ThermalEnergy’ verify that the unit is indeed an energy unit, that exergy has not yet been assessed for it, and that its energy type corresponds to the target type. This is enforced through the methods named _check_energy_unit and _check_exergy_not_assessed.

The module named ‘ExergyDestruction’ allows determining exergy destruction within a unit, and enabling that magnitude as an optimization objective. This module requires as input the name of the target energy unit (‘energy_unit’), its exergy efficiency (‘exergy_eff’), the dead state temperature for exergy analysis (‘temp_ref’), and in the case of thermal storage units, their temperature level (‘temp_heat’). It also requires that the exergy flow of the unit have been determined preemptively, by the mean of either “ElectricalExergy” or “ThermalExergy”. The inputs named ‘energy_unit’ and ‘temp_heat’ default to ‘None’, since it is imperative that the user specifies them. Meanwhile, ‘exergy_eff’ defaults to 1, meaning that the module assumes perfect efficiency unless otherwise stated. The dead state temperature (’temp_ref’) defaults to 20 °C, as in the case of the “ThermalExergy” module. Users can change this value, but must be aware that all units in the study must have the same ’temp_ref’, for the sake of thermodynamic consistency.

First, ‘ExergyDestruction’ verifies that exergy destruction has not been already assessed for that unit, raising ‘AttributeError’ otherwise. Then, it declares three new attributes for ‘energy_unit’. The first two are the ‘Quantities’ named ‘exergy_dest’ and ‘exd_tot’, which represent exergy destroyed at each time step and throughout the whole timespan, respectively. The third attribute is a ‘DefinitionConstraint’ named ‘calc_exd_tot’ that ensures calculation of ‘exd_tot’, whose formulation is the same in all cases. Meanwhile, calculation of ‘exergy_dest’ is dynamic and has different formulations depending on the type of unit. Thus, this calculation is declared later in subsequent routines.

If the unit is a ‘ConsumptionUnit’, the module first checks that the user has provided a value for ‘exergy_eff’, and raises ‘ValueError’ otherwise. Then, it proceeds to the formulation of a ‘DefinitionDynamicConstraint’ named ‘calc_exergy_dest’, which enables calculation of ‘exergy_dest’ as mentioned above. For a consumption unit, exergy destruction is the product of its input exergy by the difference between 1 and its exergy efficiency. The equation has two formulations, one adapted for ‘exergy_eff’ being an int or float, and the other for it being a list. If it is none of those types, the module raises ‘TypeError’. Additionally, if it is a list the module verifies that its length matches that of the ‘time’ list, raising ‘IndexError’ otherwise. It also verifies that each element of the list is either an int or a float, raising ‘ValueError’ otherwise.

If the unit is a ‘ProductionUnit’, the module applies the same routines as for a ‘ConsumptionUnit’, with just two slight variations. The main variation occurs in the calculation of exergy destruction. For a production unit, exergy destruction is assessed as the product between its exergy output and the difference between the inverse of its efficiency and 1. This calculation means that a production unit is actually a conversion unit whose input is not necessary for energy modelling, but it is for exergy modelling. Lower exergy efficiency means that the production unit has needed a greater input of primary energy for delivering energy. The second variation stems from the first; the module needs to check that the user has entered values greater than zero for ‘exergy_eff’. Indeed, a production unit cannot produce if its efficiency is zero.

If the unit is a ‘StorageUnit’, its exergy destruction is directly related to its energy losses. Thus, the module multiplies those losses by the corresponding exergy factor. That factor equals one for electricity, while for heat it is a function of temperature. Thermal storage units are the only context where the “ExergyDestruction” module needs an input for ‘temp_heat’ and ‘temp_ref’.

If the unit is a ‘ConversionUnit’, the module reads the lists of production and consumption sub-units enclosed by the unit. For each sub-unit, it first verifies that its ‘exergy’ has been assessed, raising ‘AttributeError’ otherwise. Then, the module includes the sub-unit in the exergy balance of the overall unit. It does so by writing its ‘exergy’ attribute within the equation, preceded by a plus sign in the case of consumption sub-units, or a minus sign in the case of production sub-units. Once the full equation is ready, the module declares it as ‘calc_exergy_dest’.

If the unit provided to ‘ExergyDestruction’ is not a consumption, production, storage or conversion unit, the module returns ‘TypeError’. The implementation of newest unit types in the module might be in the developers’ portfolio in the future.

With both exergy and exergy destruction being assessed, the purpose of the exergy package is fulfilled.

Users should be aware of a few methodological simplifications within the exergy package. Firstly, it cannot assess the following forms of exergy: chemical, potential and kinetic. If the user aims at properly studying such types of energy, other tools are available elsewhere. Nevertheless, if units managing those sources are not the center of the study, it is theoretically possible to “pseudo-model” them. Users can declare them as thermal units, and adjust its temperature level so that the resulting exergy factor is equivalent to that of the chemical, potential or kinetic energy flow. Finding that equivalence requires advanced knowledge in exergy analysis; let users adopt this approach under their own responsibility. The proper modeling of chemical, potential or kinetic exergy might be in the developers’ portfolio in the future.

A second simplification concerns the assessment of thermal exergy. Namely, the exergy of transferred heat depends strongly on temperature levels. Despite that, the exergy module assesses thermal exergy assuming that temperature levels remain constant. If that is not true, deviations appear with respect to the most accurate assessment (based on physical exergy of the fluid carrier). Those deviations become larger as temperature changes in the carriers become larger. If a heat source undergoes a large temperature drop throughout the exchange of heat, then its exergy content may be largely overestimated. Moreover, deviations are amplified if temperature levels are close to the dead state temperature. In such instances, the developers recommend using the average of inlet-outlet temperatures of the source, instead of the inlet temperature. The dead state temperature typically receives the symbol T0 in exergy analyses, and was named temp_ref within the exergy package. Users with advanced knowledge on exergy can adjust the value of temperature so that deviations become minimal with respect to the most accurate assessment.

Lastly, users should be aware that the term “ExergyDestruction” assessed within the module aggregates two concepts: losses of energy (and thus of exergy) from the unit to its surroundings, and thermodynamic irreversibility within the unit itself. Experts in exergy analysis typically call the former ‘exergy losses’, the latter ‘exergy destruction’, and ‘irreversibility’ the aggregate thereof. Regardless, the exergy module assesses only the aggregate. This simplification is acceptable; energy planners focus mainly on overall efficiency, and do not need the details on the sources of irreversibility. The term “ExergyDestruction” determined in this module suffices for assessing exergy efficiency of units and systems. Besides, the module names that magnitude “ex_dest”, for “exergy destruction”, instead of ‘irreversibility’. The developers intentionally avoided using “Irreversibility” as class or variable name in this module. This was done to anticipate possible conflicts in nomenclature with respect to reversible energy units (“ReversibleUnit” class), which were under development at the time.