Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
junzis
GitHub Repository: junzis/openap
Path: blob/master/openap/emission.py
592 views
1
"""OpenAP Emission model."""
2
3
from typing import Any, Optional, Tuple
4
5
from openap import prop
6
from openap.backends import BackendType
7
8
# Type alias for numeric inputs (scalar, array, or symbolic)
9
Numeric = Any
10
from openap.extra import ndarrayconvert
11
12
from .base import EmissionBase
13
14
15
class Emission(EmissionBase):
16
"""Emission model based on ICAO emission databank."""
17
18
def __init__(
19
self,
20
ac: str,
21
eng: Optional[str] = None,
22
backend: Optional[BackendType] = None,
23
**kwargs,
24
):
25
"""Initialize Emission object.
26
27
Args:
28
ac: ICAO aircraft type (for example: A320).
29
eng: Engine type (for example: CFM56-5A3).
30
Leave empty to use the default engine specified
31
by in the aircraft database.
32
backend: Math backend to use. Defaults to NumpyBackend.
33
"""
34
super().__init__(ac, eng, backend=backend, **kwargs)
35
36
self.aircraft = prop.aircraft(ac, **kwargs)
37
self.n_eng = self.aircraft["engine"]["number"]
38
39
if eng is None:
40
eng = self.aircraft["engine"]["default"]
41
42
self.engine = prop.engine(eng)
43
44
def _fl2sl(
45
self, ffac: Numeric, tas: Numeric, alt: Numeric, dT: Numeric = 0
46
) -> Tuple[Numeric, Numeric]:
47
"""Convert to sea-level equivalent."""
48
b = self.backend
49
50
M = self.aero.tas2mach(tas * self.aero.kts, alt * self.aero.ft, dT=dT)
51
beta = b.exp(0.2 * (M**2))
52
theta = (self.aero.temperature(alt * self.aero.ft, dT=dT) / 288.15) / beta
53
delta = (1 - 0.0019812 * alt / 288.15) ** 5.255876 / b.power(beta, 3.5)
54
ratio = (theta**3.3) / (delta**1.02)
55
# Boeing Fuel Flow Method 2 (BFFM2) - DuBois & Paynter (2006)
56
ff_sl = (ffac / self.n_eng) * theta**3.8 / delta * beta
57
58
return ff_sl, ratio
59
60
@ndarrayconvert
61
def co2(self, ffac: Numeric) -> Numeric:
62
"""Compute CO2 emission with given fuel flow.
63
64
Args:
65
ffac: Fuel flow for all engines (unit: kg/s).
66
67
Returns:
68
CO2 emission from all engines (unit: g/s).
69
70
"""
71
# IATA: jet fuel -> co2
72
return ffac * 3160
73
74
@ndarrayconvert
75
def h2o(self, ffac: Numeric) -> Numeric:
76
"""Compute H2O emission with given fuel flow.
77
78
Args:
79
ffac: Fuel flow for all engines (unit: kg/s).
80
81
Returns:
82
H2O emission from all engines (unit: g/s).
83
84
"""
85
# kerosene -> water
86
return ffac * 1230
87
88
@ndarrayconvert
89
def soot(self, ffac: Numeric) -> Numeric:
90
"""Compute soot emission with given fuel flow.
91
92
Args:
93
ffac: Fuel flow for all engines (unit: kg/s).
94
95
Returns:
96
Soot emission from all engines (unit: g/s).
97
98
"""
99
# Barrett et al. 2010
100
return ffac * 0.03
101
102
@ndarrayconvert
103
def sox(self, ffac: Numeric) -> Numeric:
104
"""Compute SOx emission with given fuel flow.
105
106
Args:
107
ffac: Fuel flow for all engines (unit: kg/s).
108
109
Returns:
110
SOx emission from all engines (unit: g/s).
111
112
"""
113
# Barrett et al. 2010
114
return ffac * 1.2
115
116
@ndarrayconvert
117
def nox(
118
self,
119
ffac: Numeric,
120
tas: Numeric,
121
alt: Numeric = 0,
122
dT: Numeric = 0,
123
) -> Numeric:
124
"""Compute NOx emission with given fuel flow, speed, and altitude.
125
126
Args:
127
ffac: Fuel flow for all engines (unit: kg/s).
128
tas: Speed (unit: kt).
129
alt: Aircraft altitude (unit: ft). Defaults to 0.
130
dT: Temperature shift (unit: K or degC). Defaults to 0.
131
132
Returns:
133
NOx emission from all engines (unit: g/s).
134
135
"""
136
b = self.backend
137
138
ff_sl, ratio = self._fl2sl(ffac, tas, alt, dT=dT)
139
140
nox_sl = b.interp(
141
ff_sl,
142
[
143
self.engine["ff_idl"],
144
self.engine["ff_app"],
145
self.engine["ff_co"],
146
self.engine["ff_to"],
147
],
148
[
149
self.engine["ei_nox_idl"],
150
self.engine["ei_nox_app"],
151
self.engine["ei_nox_co"],
152
self.engine["ei_nox_to"],
153
],
154
)
155
156
# convert back to actual flight level
157
omega = 10 ** (-3) * b.exp(-0.0001426 * (alt - 12900))
158
159
# Boeing Fuel Flow Method 2 (BFFM2) - DuBois & Paynter (2006)
160
nox_fl = nox_sl * b.sqrt(1 / ratio) * b.exp(-19 * (omega - 0.00634))
161
162
# convert g/(kg fuel) to g/s for all engines
163
nox_rate = nox_fl * ffac
164
return nox_rate
165
166
@ndarrayconvert
167
def co(
168
self,
169
ffac: Numeric,
170
tas: Numeric,
171
alt: Numeric = 0,
172
dT: Numeric = 0,
173
) -> Numeric:
174
"""Compute CO emission with given fuel flow, speed, and altitude.
175
176
Args:
177
ffac: Fuel flow for all engines (unit: kg/s).
178
tas: Speed (unit: kt).
179
alt: Aircraft altitude (unit: ft). Defaults to 0.
180
dT: Temperature shift (unit: K or degC). Defaults to 0.
181
182
Returns:
183
CO emission from all engines (unit: g/s).
184
185
"""
186
b = self.backend
187
188
ff_sl, ratio = self._fl2sl(ffac, tas, alt, dT=dT)
189
190
co_sl = b.interp(
191
ff_sl,
192
[
193
self.engine["ff_idl"],
194
self.engine["ff_app"],
195
self.engine["ff_co"],
196
self.engine["ff_to"],
197
],
198
[
199
self.engine["ei_co_idl"],
200
self.engine["ei_co_app"],
201
self.engine["ei_co_co"],
202
self.engine["ei_co_to"],
203
],
204
)
205
206
# Boeing Fuel Flow Method 2 (BFFM2) - DuBois & Paynter (2006)
207
# convert back to actual flight level
208
co_fl = co_sl * ratio
209
210
# convert g/(kg fuel) to g/s for all engines
211
co_rate = co_fl * ffac
212
return co_rate
213
214
@ndarrayconvert
215
def hc(
216
self,
217
ffac: Numeric,
218
tas: Numeric,
219
alt: Numeric = 0,
220
dT: Numeric = 0,
221
) -> Numeric:
222
"""Compute HC emission with given fuel flow, speed, and altitude.
223
224
Args:
225
ffac: Fuel flow for all engines (unit: kg/s).
226
tas: Speed (unit: kt).
227
alt: Aircraft altitude (unit: ft). Defaults to 0.
228
dT: Temperature shift (unit: K or degC). Defaults to 0.
229
230
Returns:
231
HC emission from all engines (unit: g/s).
232
233
"""
234
b = self.backend
235
236
ff_sl, ratio = self._fl2sl(ffac, tas, alt, dT=dT)
237
238
hc_sl = b.interp(
239
ff_sl,
240
[
241
self.engine["ff_idl"],
242
self.engine["ff_app"],
243
self.engine["ff_co"],
244
self.engine["ff_to"],
245
],
246
[
247
self.engine["ei_hc_idl"],
248
self.engine["ei_hc_app"],
249
self.engine["ei_hc_co"],
250
self.engine["ei_hc_to"],
251
],
252
)
253
# Boeing Fuel Flow Method 2 (BFFM2) - DuBois & Paynter (2006)
254
# convert back to actual flight level
255
hc_fl = hc_sl * ratio
256
257
# convert g/(kg fuel) to g/s for all engines
258
hc_rate = hc_fl * ffac
259
return hc_rate
260
261