Internal Combustion Engine Combined Heat & Power
See also
Note
An internal combustion Engine consists of an element and a controller. The element defines it’s physical parameters, while the controller governs the operational logic.
The create_controlled function creates both and connects them.
Create Controlled Function
- pandaprosumer.create_controlled_ice_chp(prosumer, size, fuel, altitude, name=None, index=None, in_service=True, level=0, order=0, period=0, **kwargs)[source]
Creates an ICE CHP element in prosumer[“ice_chp”] and an ICE CHP controller
- INPUT:
prosumer - The prosumer within this ice_chp should be created
size (float) - ICE CHP rating [kW]
fuel (string) - Type of the fuel used in the calculation
altitude (float) - Altitude above sea level of the ICE CHP installation site [m]
- OPTIONAL:
name (string, default None) - The name of the ICE CHP instance
index (int, default None) - Force a specified ID if it is available. If None, the index one higher than the highest already existing index is selected.
in_service (boolean, default True) - True for in_service or False for out of service
level (int, default 0) - The level of the controller
order (int, default 0) - The order of the controller
period (int, default 0) - Index of the period, default is 0
- OUTPUT:
index (int) - The unique ID of the created ICE CHP
- EXAMPLE:
create_controlled_ice_chp(prosumer, 350, “ng”, 0, “example_ice_chp”)
Controller
Input Static Data
Parameter |
Description |
Unit |
|---|---|---|
size |
Size of the system |
m³ |
fuel |
Type of fuel used |
N/A |
altitude |
Altitude in meters |
m |
in_service |
Indicates if the system is in service |
N/A |
name |
Custom name for the instance |
N/A |
Input Time Series
Parameter |
Description |
Unit |
|---|---|---|
cycle |
Cycle number of the process |
N/A |
t_intake_k |
Intake temperature in Kelvin |
K |
Output Time Series
Parameter |
Description |
Unit |
|---|---|---|
load |
Load on the system |
N/A |
p_in_kw |
Input power in kilowatts |
kW |
p_el_out_kw |
Electrical output power in kilowatts |
kW |
p_th_out_kw |
Thermal output power in kilowatts |
kW |
p_rad_out_kw |
Radiative output power in kilowatts |
kW |
ice_chp_efficiency |
ICE CHP efficiency |
% |
mdot_fuel_in_kg_per_s |
Mass flow rate of fuel input |
kg/s |
acc_m_fuel_in_kg |
Accumulated fuel input mass |
kg |
acc_co2_equiv_kg |
Accumulated CO2 equivalent emissions |
kg |
acc_co2_inst_kg |
Instantaneous CO2 emissions |
kg |
acc_nox_mg |
Accumulated NOx emissions |
mg |
acc_time_ice_chp_oper_s |
Accumulated operational time of ICE CHP |
s |
Mapping
The Internal Combustion Engine model uses Generic Mapping Scheme.
Model
- class pandaprosumer.controller.models.ice_chp.IceChpController(prosumer, chp_object, order=0, level=0, in_service=True, index=None, **kwargs)[source]
- calculate_air_density(temperature_k: float, altitude_m: float, pressure_ref_pa=101325, m_molar_air_kg_per_mol=0.0289652, g_m_per_s2=9.81, gas_const_universal_j_per_molk=8.314) float[source]
Calculates air density according to the ideal gas law.
- param temperature_k:
air temperature in K
- param altitude_m:
the altitude of the CHP location in m
- param pressure_ref_pa:
reference pressure in Pa
- param m_molar_air_kg_per_mol:
air molar mass in kg/mol
- param g_m_per_s2:
gravitational acceleration in m/s2
- param gas_const_universal_j_per_molk:
universal gas constant in J/molK
- return density:
air density in kg/m3
- calculate_co2_equiv_mass_flow(p_in_kw: float, fuel_type: str, map_fuel: dict) float[source]
Calculates equivalent CO2 emissions.
- param p_in_kw:
input energy flow in kW
- param fuel_type:
selected fuel type (options: ng, sng1, sng2, sng3, sng4, sng5, sng6)
- param map_fuel:
data for the chosen CHP size from the map in the JSON file
- return mdot_co2_inst_kg_per_s:
mass flow of CO2 emissions at the location of the ICE CHP in kg/s
- calculate_co2_instant_mass_flow(mdot_fuel_kg_per_s: float, fuel_type: str, map_fuel: dict) float[source]
Calculates CO2 emissions at the location of the ICE CHP (instantaneous emissions).
- param mdot_fuel_kg_per_s:
fuel mass flow in kg/s
- param r_oxidised_c:
fraction of fully oxidised carbon
- param fuel_type:
selected fuel type (options: ng, sng1, sng2, sng3, sng4, sng5, sng6)
- param map_fuel:
data for the chosen CHP size from the map in the JSON file
- return mdot_co2_inst_kg_per_s:
mass flow of CO2 emissions at the location of the ICE CHP in kg/s
- calculate_density_ratio(temperature_act_k: float, altitude_act_m: float, map_chp: dict) float[source]
Calculates the ratio between the reference density for which the CHP maps were designed and the actual density of the air at intake.
- param temperature_act_k:
actual air temperature at CHP intake in K
- param altitude_act_m:
the actual altitude of the CHP location in m
- param map_engine:
data for the chosen CHP size
- return ratio:
ratio between map reference density and actual density
- calculate_efficiency(p_in_kw: float, p_loss_kw: float) float[source]
Calculates the efficiency of the entire ICE CHP.
- param p_in_kw:
input energy flow in kW
- param p_loss_kw:
lost energy flow in kW
- return efficiency:
efficiency of the ICE CHP in %
- calculate_electrical_power_out(load: float, map_chp: dict) float[source]
Calculates the generated electrical power.
- param load:
CHP load in %
- param map_chp:
data for the chosen CHP size from the map in the JSON file
- return p_el_out_kw:
output electrical power on the generator in kW
- calculate_energy_flow_loss(p_in_kw: float, p_out_kw: float, p_el_kw: float) float[source]
Calculates the amount of energy flow that is lost —> wasted heat.
- param p_in_kw:
input energy flow in kW
- param p_out_kw:
total recovered energy flow on the output side in kW
- param p_el_kw:
generated electrical power in kW
- return p_loss_kw:
wasted heat flow from the ICE CHP in kW
- calculate_fuel_input_mass_flow(p_in_kw: float, fuel_type: str, map_fuel: dict) float[source]
Determines the required fuel mass flow.
- param p_in_kw:
required energy flow into the CHP in kW
- param fuel_type:
selected fuel type (options: ng, sng1, sng2, sng3, sng4, sng5, sng6)
- param map_fuel:
data for the fuels in the fuels JSON file
- return mdot_fuel_in_kg_per_s:
required fuel mass flow in kg/s
- calculate_input_energy_flow(load: float, map_chp: dict) float[source]
Determines the input energy flow into the engine.
- param load_calc:
CHP load in %
- param map_engine:
data for the chosen CHP size
- return p_in_kw:
required energy flow for the defined load/output power in kW
- calculate_load(cycle: int, demand_kw: float, temperature_k: float, altitude_m: float, map_chp: dict, time) float[source]
Calculates the engine load based on the desired output.
- param cycle:
defines output priority (electrical power = 1, heat = 2)
- param demand_kw:
current demand value in kW
- param temperature_k:
current air temperature at intake in K
- param altitude_m:
the altitude of the CHP location in m
- param map_chp:
data for the chosen CHP size
- param time:
the current step’s simulation time
- returns:
load - CHP load under reference conditions in %
load_actual - CHP load under actual conditions in %
- calculate_nox_mass_flow(load: float, map_chp: dict) float[source]
Determines the amount of NOx emissions.
- param load:
CHP load in %
- param map_chp:
data for the chosen CHP size from the map in the JSON file
- return mdot_nox_mg_per_s:
mass flow of NOx emissions at the location of the ICE CHP in mg/s
- calculate_radiation(load: float, map_chp: dict) float[source]
Determines the amount of radiation from the ICE CHP unit into the sorounding space.
- param load:
CHP load in %
- param map_chp:
data for the chosen CHP size from the map in the JSON file
- return p_rad_out_kw:
radiation int in kW
- calculate_recovered_heat_flow(load: float, map_chp: dict) float[source]
Calculates the recovered energy (heat) flow.
- param load:
CHP load in %
- param map_chp:
data for the chosen CHP size from the map in the JSON file
- return p_th_out_kw:
useful heat flow extracted from the ICE CHP in kW
- control_step(prosumer)[source]
Executes the control step for the controller.
- Parameters:
prosumer – The prosumer object
- is_converged(container)[source]
This method is calculated whether or not the controller converged. This is where any target values are being calculated and compared to the actual measurements. Returns convergence of the controller.
- Parameters:
container (_type_) – _description_
- q_requested_kw(prosumer)[source]
Calculates the heat to deliver in kW.
- Parameters:
prosumer – The prosumer object
- Returns:
Heat to deliver in kW
- read_json_maps(map_filename: str) dict[source]
Opens a JSON file and reads data from it.
- param map_filename:
name of the file with maps to import
- return jason_data:
contains all data in the JSON file
The ICE CHP module is map based. Its engine response is read from tabulated data contained in a map associated with the chosen size of the ICE CHP. Maps for three sizes are provided:
350 kWe,
700 kWe,
1400 kWe.
They are stored in a dedicated JSON file in pandaprosumer/library/chp_maps/ice_chp_maps.json to make modifications to the maps easier if required. If maps are added or removed, their sizes must be added to or removed from the “chp_ice_size_kw” list. All sizes should be in kW. The file should not contain two or more maps of the same size. The minimum information in an ICE CHP map should include the following:
temperature_reference_k: the temperature at which values in the map were measured (in K)
altitude_reference_m: the altitude at which values in the map were measured (in m)
pressure_reference_pa: air intake pressure at which values in the map were measured (in Pa)
air_molar_mass_kg_per_mol: average molar mass of intake air at the location of measurement (in kg/mol)
gravitational_acc_m_per_s2: gravitational acceleration at the location of measurement (in m/s2)
universal_gas_const_j_per_molk: the value of the universal gas constant (in J/molK)
load_limits_percent: minimum and maximum limits below and above which the CHP should not operate (in % of maximum load)
engine_load_percent: a list of load values at which measurements were taken (in % of maximum load)
power_el_kw: a list of values for the power on the electrical generator at each load (in kW)
energy_flow_input_kw: required input energy flow for each load value (in kW)
heat_flow_radiation_kw: the amount of radiation emitted at each load (in kW)
heat_flow_recovered_kw: total recovered heat flow at each load (in kW); provided maps include contributions from the jacket water (cooling) and the exhaust recovered to 150°C
exhaust_flow_rate_m3n_per_h: the rate of the exhaust flow (in m3N/h)
emiss_rate_nox_mg_per_m3n: an average rate of NOx emissions (in mg/m3N)
Except for temperature_reference_k, if data for the parameters above is not available, a value of zero should be used. For temperature_reference_k a value of 293 is recommended instead of zero. Other information can be included for completeness, but will not be used by the program.
Similarly to the engine, properties of available fuels is stored in a dedicated JSON file in pandaprosumer/library/chp_maps/fuel_maps.json. Data for seven types of gaseous fuels is provided.
Code |
Fuel type |
Production method |
Ref. |
|---|---|---|---|
ng |
Natural gas |
[GFM+21] |
|
sng1 |
Sythetic natural gas 1 |
Biogas catalytic methanation with 38% renewable electricity mix |
[GFM+21] |
sng2 |
Sythetic natural gas 2 |
Biogas catalytic methanation with 100% renewable electricity mix |
[GFM+21] |
sng3 |
Sythetic natural gas 3 |
Catalytic methanation from green H2 and CO2 sourced from iron/steel processing |
[LSE+24] |
sng4 |
Sythetic natural gas 4 |
Catalytic methanation from green H2 and CO2 sourced from direct air capture |
[LSE+24] |
sng5 |
Sythetic natural gas 5 |
Catalytic methanation from green H2 and CO2 sourced from ethanol production |
[LSE+24] |
sng6 |
Sythetic natural gas 6 |
Catalytic methanation from green H2 and CO2 sourced from ammonia production |
[LSE+24] |
Data in the fuel map can also be modified if required. It should include at leat the following:
fuel_types: a list of available fuel types
lower_heating_value_kwh_per_kg: a list of lower heating value parameters associated with each type of fuel (in kWh/kg)
carbon_fraction: the percentage of carbon weight to total molecule weight for each type of fuel
co2eq_kg_per_kwh: CO2 equivalent emissions for each fuel type (in kg/kWh)
An instance of the ICE CHP is defined by its size, fuel type, and altitude. A CHP map is selected based on the size.
An example of reading data from an ICE CHP map. (source: Faculty of Mechanical Engineering, University of Ljubljana)
The evaporator of the heat pump should get heat from a District Heating Network or from the ambient air.
The condenser should be connected to downstream elements in the prosumer or to a District Heating Network.
Schematic representation of a thermal-based heat pump considered by EIFER during modeling (source: own creation)
To understand the thermal-based heat pump model developed by EIFER, it is first necessary to have an overview of the technologies and parameters involved in the modelling of a heat pump. Figure 4 offers a schematic representation of a thermal-based heat pump considered by EIFER during modelling.
The thermal-based heat pump modelled includes a compressor, a condenser, an expansion valve, and an evaporator. In general terms, a heat pump requires a certain amount of power \(P_\text{comp}\), it transfers a certain amount of heat \(Q_\text{cond}\) to the heat sink, and it absorbs a certain amount of heat \(Q_\text{evap}\) from the heat source.
The thermal-based heat pump model developed by EIFER calculates the required heat pump mass flow on the evaporator (\(\dot{m}_\text{evap}\)) to produce enough heat (Qcond) to meet the requirements of the network in terms of temperature increase (\(T_{\text{out}_\text{cond}} - T_{\text{in}_\text{cond}}\)) with a given mass flow (\(\dot{m}_\text{cond}\)).
To do so, a series of parameters are required as a given input from the model developed:
\(T_{\text{out}_\text{cond}}\): target temperature need from the network.
\(T_{\text{in}_\text{cond}}\): return temperature from the network to the considered HP.
\(\dot{m}_\text{cond}\): mass flow in the network, which for simplicity is considered water.
\(T_{\text{in}_\text{evap}}\): temperature of the heat source at the inlet of the evaporator.
\(\Delta T_\text{evap}\): it is the temperature difference between the inlet and outlet of the evaporator on the heat source side.
\(Pinch\): it is a small temperature difference, usually in between 5-10 K, to account for temperature difference between the heat pump side and the heat source (or heat sink) side.
\(\eta_\text{C}\): Carnot efficiency, usually between 0.4-0.6, used to simplify the calculation of the heat pump COP
\(T_{\text{out}_{\text{cond}_\text{max}}}\): it is the maximum temperature that can be achieved at the outlet of the condenser on the heat sink side, it is usually given from the HP manufacturer and it depends on the refrigerant chosen.
Then, the calculation steps modelled follow the equations presented below:
The first step is to calculate the condenser thermal demand \(Q_\text{cond}\), meaning the thermal need from the network
Where \(Cp_\text{cond}\) is the specific heat capacity at constant pressure of the fluid used in the heat network, which is usually water
Then the temperature at the outlet of the evaporator is calculated (\(T_{\text{out}_\text{evap}}\))
Thanks to step n°2 it is possible to calculate the Carnot COP (\(COP_\text{C}\))
Which allows a simplified calculation of the heat pump COP (\(COP_\text{HP}\))
The required electrical power \(P_\text{comp}\) to provide \(Q_\text{cond}\) is also calculated
From which it is possible to derive the heat required from the heat source \(Q_\text{evap}\)
And finally the mass flow \(\dot{m}_\text{evap}\) needed at the evaporator for the HP to provide the required \(Q_\text{cond}\) Where \(Cp_\text{evap}\) is the specific heat capacity at constant pressure of the fluid used in the heat sink
It is important to check that the temperature at the outlet of the condenser is not above the maximum temperature achievable from the considered HP with the given refrigerant, otherwise that means that the maximum heat that can be provided to the network is lower than the requirement
If the COP is higher than the maximum COP of the HP, the power consumption is set to the maximum power, \(T_{\text{out}_\text{cond}}\) is also recalculated based on the maximum COP.
If the power consumption is higher than the maximum power of the HP, \(\dot{m}_\text{cond}\) is recalculated so that the power consumption is set to the maximum power.
If the power consumption is lower than the minimum power of the HP, the heat pump is considered off and the power consumption is set to zero,
Note
Limitations of the model:
Assume a constant \(\Delta T_\text{evap}\)
Assume a constant \(\eta_\text{C}\)