Source code for exerpy.components.power_machines.generator

import logging

from exerpy.components.component import Component, component_registry


[docs] @component_registry class Generator(Component): r""" Class for exergy analysis of generators. This class performs exergy analysis calculations for generators, converting mechanical or thermal energy flow into electrical energy. The exergy product is defined as the electrical power output, while the exergy fuel is the input energy flow. Parameters ---------- **kwargs : dict Arbitrary keyword arguments passed to parent class. Attributes ---------- E_F : float Exergy fuel of the component :math:`\dot{E}_\mathrm{F}` in :math:`\mathrm{W}`. E_P : float Exergy product of the component :math:`\dot{E}_\mathrm{P}` in :math:`\mathrm{W}`. E_D : float Exergy destruction of the component :math:`\dot{E}_\mathrm{D}` in :math:`\mathrm{W}`. epsilon : float Exergetic efficiency of the component :math:`\varepsilon` in :math:`-`. inl : dict Dictionary containing inlet stream data with energy flow. outl : dict Dictionary containing outlet stream data with energy flow. Notes ----- The exergy analysis for a generator is straightforward as electrical energy is pure exergy. The equations are: .. math:: \dot{E}_\mathrm{P} & = \dot{W}_\mathrm{el} \dot{E}_\mathrm{F} & = \dot{W}_\mathrm{in} \dot{E}_\mathrm{D} & = \dot{E}_\mathrm{F} - \dot{E}_\mathrm{P} where: - :math:`\dot{W}_\mathrm{el}`: Electrical power output - :math:`\dot{W}_\mathrm{in}`: Input power """ def __init__(self, **kwargs): r"""Initialize generator component with given parameters.""" super().__init__(**kwargs) # Ex_C_col will be assigned by ExergoeconomicAnalysis.run() self.Ex_C_col = {}
[docs] def calc_exergy_balance(self, T0: float, p0: float, split_physical_exergy) -> None: r""" Calculate the exergy balance of the generator. Calculates the exergy product (electrical power output), exergy fuel (input power), and the resulting exergy destruction and efficiency. Parameters ---------- T0 : float Ambient temperature in :math:`\mathrm{K}`. p0 : float Ambient pressure in :math:`\mathrm{Pa}`. split_physical_exergy : bool Flag indicating whether physical exergy is split into thermal and mechanical components. """ # Exergy product is the electrical power output self.E_P = self.outl[0]["energy_flow"] # Exergy fuel is the input power self.E_F = self.inl[0]["energy_flow"] # Calculate exergy destruction self.E_D = self.E_F - self.E_P # Calculate exergy efficiency self.epsilon = self.calc_epsilon() # Log the results logging.info( f"Exergy balance of Generator {self.name} calculated: " f"E_P={self.E_P:.2f}, E_F={self.E_F:.2f}, E_D={self.E_D:.2f}, " f"Efficiency={self.epsilon:.2%}" )
[docs] def aux_eqs(self, A, b, counter, T0, equations, chemical_exergy_enabled): """ Auxiliary equations for the generator. This function adds rows to the cost matrix A and the right-hand-side vector b to enforce the auxiliary cost relations for the generator. Since the generator converts mechanical or thermal energy to electrical energy, the auxiliary equations typically enforce: - No additional auxiliary equations are needed for generators as electrical energy is pure exergy and the cost balance equations are sufficient. Parameters ---------- A : numpy.ndarray The current cost matrix. b : numpy.ndarray The current right-hand-side vector. counter : int The current row index in the matrix. T0 : float Ambient temperature. equations : dict Dictionary for storing equation labels. chemical_exergy_enabled : bool Flag indicating whether chemical exergy auxiliary equations should be added. Returns ------- A : numpy.ndarray The updated cost matrix. b : numpy.ndarray The updated right-hand-side vector. counter : int The updated row index. equations : dict Updated dictionary with equation labels. """ return [A, b, counter, equations]
[docs] def exergoeconomic_balance(self, T0, chemical_exergy_enabled=False): r""" Perform exergoeconomic cost balance for the generator (power-producing component). The generator is a power-producing component (e.g., electrical generator, turbine) where mechanical/electrical work is extracted from a flowing stream. The general exergoeconomic balance equation is: .. math:: \dot{C}_{\mathrm{in}}^{\mathrm{TOT}} - \dot{C}_{\mathrm{out}}^{\mathrm{TOT}} - \dot{C}_{\mathrm{P}} + \dot{Z} = 0 For a generator, the product is the power output (electrical or mechanical), and the fuel is the exergy decrease in the working fluid: .. math:: \dot{C}_{\mathrm{P}} = \dot{C}_{\mathrm{out}}^{\mathrm{TOT}} .. math:: \dot{C}_{\mathrm{F}} = \dot{C}_{\mathrm{in}}^{\mathrm{TOT}} **Calculated exergoeconomic indicators:** Specific cost of fuel: .. math:: c_{\mathrm{F}} = \frac{\dot{C}_{\mathrm{F}}}{\dot{E}_{\mathrm{F}}} Specific cost of product: .. math:: c_{\mathrm{P}} = \frac{\dot{C}_{\mathrm{P}}}{\dot{E}_{\mathrm{P}}} Cost rate of exergy destruction: .. math:: \dot{C}_{\mathrm{D}} = c_{\mathrm{F}} \cdot \dot{E}_{\mathrm{D}} Relative cost difference: .. math:: r = \frac{\dot{C}_{\mathrm{P}} - \dot{C}_{\mathrm{F}}}{\dot{C}_{\mathrm{F}}} Exergoeconomic factor: .. math:: f = \frac{\dot{Z}}{\dot{Z} + \dot{C}_{\mathrm{D}}} Parameters ---------- T0 : float Ambient temperature (K). chemical_exergy_enabled : bool, optional If True, chemical exergy is considered in the calculations. Default is False. Attributes Set -------------- C_P : float Cost rate of product (currency/time). C_F : float Cost rate of fuel (currency/time). c_P : float Specific cost of product (currency/energy). c_F : float Specific cost of fuel (currency/energy). C_D : float Cost rate of exergy destruction (currency/time). r : float Relative cost difference (dimensionless). f : float Exergoeconomic factor (dimensionless). Raises ------ ValueError If E_P or E_F is zero, preventing computation of specific costs. Notes ----- Unlike other components, the generator does not add Z_costs to close the cost balance in the C_P calculation. The cost balance is determined by the total exergy costs of inlet and outlet streams. The relative cost difference r is calculated using total cost rates (C_P and C_F) rather than specific costs (c_P and c_F), which is mathematically equivalent for this component type. The exergy destruction E_D must be computed prior to calling this method. """ self.C_P = self.outl[0].get("C_TOT", 0) self.C_F = self.inl[0].get("C_TOT", 0) if self.E_P == 0 or self.E_F == 0: raise ValueError(f"E_P or E_F is zero; cannot compute specific costs for component: {self.name}.") self.c_P = self.C_P / self.E_P self.c_F = self.C_F / self.E_F self.C_D = self.c_F * self.E_D # Ensure that self.E_D is computed beforehand. self.r = (self.C_P - self.C_F) / self.C_F self.f = self.Z_costs / (self.Z_costs + self.C_D) if (self.Z_costs + self.C_D) != 0 else 0