coke-oven-maintenance-plan/AF-Calculator.ipynb
2022-12-07 20:48:26 +09:00

594 lines
17 KiB
Text

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "9e47daa3",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import cantera as ct\n",
"import pde\n",
"\n",
"import ipywidgets as widgets\n",
"\n",
"from matplotlib import pyplot as plt\n",
"%matplotlib widget"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "c49236bf",
"metadata": {},
"outputs": [],
"source": [
"from scipy import optimize as opt"
]
},
{
"cell_type": "markdown",
"id": "4b1f191f",
"metadata": {},
"source": [
"# 이론공연비 계산"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "60f9c29b",
"metadata": {},
"outputs": [],
"source": [
"def stoich_AF (fuel_compostion, mole_fraction=True):\n",
" \"Stoichiometric Air/Fuel ratio (volume)\"\n",
" \n",
" gas = ct.Solution('gri30.xml')\n",
"\n",
" if mole_fraction:\n",
" gas.TPX = 600 + 273.15, ct.one_atm, fuel_compostion\n",
" else:\n",
" gas.TPY = 600 + 273.15, ct.one_atm, fuel_compostion\n",
" \n",
" fuel_comp = gas.X\n",
"\n",
" # 연료의 원자 1 몰 완전 연소에 필요한 산소 원자 몰 수\n",
" coef_O = gas.elemental_mole_fraction('C') * 2 + gas.elemental_mole_fraction('H') / 2 - (gas.elemental_mole_fraction('O'))\n",
"\n",
" # 연료의 원자 1 몰 완전 연소에 필요한 공기 원자 몰 수 = 산소 원자 몰 수 X (1 + 3.762)\n",
" coef_N = coef_O * 3.762\n",
"\n",
" # 공기 1몰의 원자 몰수 = 2 ; O2 + N2 만으로 구성되었으면\n",
" mean_natoms_air = 2\n",
"\n",
" # 연료 기체 1몰의 원자 몰수 (평균 분자당 원자 수)\n",
" mean_natoms_fuel = sum([(gas.X[i] * sum([v for v in gas.species(i).composition.values()])) for i in range(gas.n_species)])\n",
"\n",
" # 연료 기체 1몰에 필요한 공기 몰수 ()\n",
" air_fuel_ratio_st = mean_natoms_fuel * (coef_N + coef_O) / mean_natoms_air\n",
"\n",
" return (air_fuel_ratio_st)\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "c633e758",
"metadata": {},
"outputs": [],
"source": [
"coke_oven_fuel = \"H2:6.42, O2:0.39, N2:47.28, CH4:1.79, CO:24.25, CO2:19.72, C2H4:0.13, C2H6:0.04\"\n",
"\n",
"air = ct.Solution('gri30.xml')\n",
"air.X = \"O2:1, N2:3.762\"\n",
"air_comp = air.X\n",
"\n",
"fuel = ct.Solution('gri30.xml')\n",
"fuel.X = coke_oven_fuel\n",
"fuel_comp = fuel.X"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "a20ce147",
"metadata": {},
"outputs": [],
"source": [
"def exhaust_stoichiometry (phi = 1, fuel=fuel_comp, return_unburned=False):\n",
"\n",
" mix = ct.Solution('gri30.xml')\n",
"\n",
" # mix.TPX = 25+273.15, ct.one_atm, phi * fuel_comp + st_AF * air_comp\n",
" \n",
" mix.set_equivalence_ratio(phi, fuel=fuel_comp, oxidizer=\"O2:0.21, N2:0.79\")\n",
" \n",
" element_X = {ename: mix.elemental_mole_fraction(ename) for ename in mix.element_names}\n",
" \n",
" exhaust = ct.Solution('gri30.xml')\n",
" exhaust.X = {\n",
" \"CO2\" : element_X['C'],\n",
" \"H2O\" : element_X['H']/2,\n",
" \"O2\" : (element_X['O'] - 2*element_X['C'] - element_X['H']/2)/2,\n",
" \"N2\" : element_X['N']/2,\n",
" }\n",
" \n",
" if return_unburned:\n",
" return mix.mole_fraction_dict(threshold=-1), exhaust.mole_fraction_dict(threshold=-1)\n",
" else:\n",
" return exhaust.mole_fraction_dict(threshold=-1)\n",
"\n",
"def exhaust_equilibrium (phi = 1):\n",
"\n",
" mix = ct.Solution('gri30.xml')\n",
"\n",
" mix.TPX = 25+273.15, ct.one_atm, phi * fuel_comp + st_AF * air_comp\n",
" \n",
" mix.equilibrate(\"HP\")\n",
" \n",
" return mix.mole_fraction_dict(threshold=-1)\n"
]
},
{
"cell_type": "markdown",
"id": "75feeff2",
"metadata": {},
"source": [
"# A/F 계산기"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "bf8c7fe0",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6a0200388bb241a4bc4c75fb070af441",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Textarea(value='H2:6.42, O2:0.39, N2:47.28, CH4:1.79, CO:24.25, CO2:19.72, C2H4:0.13, C2…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"@widgets.interact(\n",
" composition=widgets.Textarea(\n",
" value='H2:6.42, O2:0.39, N2:47.28, CH4:1.79, CO:24.25, CO2:19.72, C2H4:0.13, C2H6:0.04',\n",
" placeholder='\"species_name_0:X0, species_name_1:X1, species_name_2:X2, ... \"',\n",
" description='''Fuel Composition:''',\n",
" disabled=False\n",
"),\n",
" O2_in_exhaust=widgets.FloatSlider(\n",
" value=0,\n",
" min=0,\n",
" max=21.0,\n",
" step=0.1,\n",
" description='excess O2(%)',\n",
" readout=True,\n",
" readout_format='.1f',\n",
")\n",
")\n",
"def calculate_AF (composition, O2_in_exhaust):\n",
" gas = ct.Solution('gri30.xml')\n",
" try:\n",
" gas.TPX = 300, ct.one_atm, composition\n",
" except ct.CanteraError:\n",
" gas.TPX = 300, ct.one_atm, \"H2:1\"\n",
" \n",
" print(\"Fuel Gas\")\n",
" gas()\n",
" \n",
" AF_st = stoich_AF(composition)\n",
" \n",
" print(f'stoichiometric A/F = {AF_st}')\n",
" \n",
" f_found = opt.root_scalar(lambda x: exhaust_stoichiometry(x, fuel=composition)[\"O2\"] - O2_in_exhaust/100, \n",
" bracket=[1e-1, 1])\n",
" \n",
" # print(f_found)\n",
" \n",
" phi = f_found.root\n",
" print(f_found)\n",
" print(f'phi for {O2_in_exhaust}% O2 in exhaust gas = {phi}')\n",
" print(f'A/F(vol) for {O2_in_exhaust}% O2 in exhaust gas = {AF_st / phi}')\n",
" # mean molecular weight needed to calc mass A/F\n",
"\n",
" gas.TPX = 300, ct.one_atm, exhaust_stoichiometry(phi)\n",
" gas()"
]
},
{
"cell_type": "markdown",
"id": "4c6c962f",
"metadata": {},
"source": [
"# 발열량 계산"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "6c0407fe",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" converged: True\n",
" flag: 'converged'\n",
" function_calls: 9\n",
" iterations: 8\n",
" root: 0.6547411452355204\n"
]
}
],
"source": [
"f_found = opt.root_scalar(lambda x: exhaust_stoichiometry(x)[\"O2\"] - 4.5/100, bracket=[1e-1, 1])\n",
"print(f_found)\n",
"phi_O2_045 = f_found.root"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "2f732468",
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"Xu, Xb = exhaust_stoichiometry(phi=phi_O2_045, return_unburned=True)"
]
},
{
"cell_type": "markdown",
"id": "f7c5063d",
"metadata": {},
"source": [
"## 배가스 산소 농도 4.5% 연료+공기 혼합 기체 "
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "53b2c1b9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" gri30:\n",
"\n",
" temperature 298.15 K\n",
" pressure 1.0133e+05 Pa\n",
" density 1.1869 kg/m^3\n",
" mean mol. weight 29.039 kg/kmol\n",
" phase of matter gas\n",
"\n",
" 1 kg 1 kmol \n",
" --------------- ---------------\n",
" enthalpy -1.5255e+06 -4.43e+07 J\n",
" internal energy -1.6109e+06 -4.6779e+07 J\n",
" entropy 6999.5 2.0326e+05 J/K\n",
" Gibbs function -3.6124e+06 -1.049e+08 J\n",
" heat capacity c_p 1027.5 29837 J/K\n",
" heat capacity c_v 741.17 21523 J/K\n",
"\n",
" mass frac. Y mole frac. X chem. pot. / RT\n",
" --------------- --------------- ---------------\n",
" H2 0.0018679 0.026906 -19.333\n",
" O2 0.1362 0.12361 -26.764\n",
" CH4 0.0041445 0.0075019 -57.401\n",
" CO 0.09803 0.10163 -70.646\n",
" CO2 0.12525 0.082647 -186.95\n",
" C2H4 0.00052635 0.00054483 -12.715\n",
" C2H6 0.00017359 0.00016764 -70.088\n",
" N2 0.6338 0.657 -23.453\n",
" [ +45 minor] 0 0 \n",
"\n"
]
}
],
"source": [
"gas_u = ct.Solution('gri30.xml')\n",
"gas_u.TPX = 25 + 273.15, ct.one_atm, Xu\n",
"gas_u()"
]
},
{
"cell_type": "markdown",
"id": "1d54eebc",
"metadata": {},
"source": [
"## 배가스 산소 농도 4.5% 완전 연소 배가스"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "a1bc3d15",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" gri30:\n",
"\n",
" temperature 298.15 K\n",
" pressure 1.0132e+05 Pa\n",
" density 1.2684 kg/m^3\n",
" mean mol. weight 31.031 kg/kmol\n",
" phase of matter gas\n",
"\n",
" 1 kg 1 kmol \n",
" --------------- ---------------\n",
" enthalpy -2.9804e+06 -9.2483e+07 J\n",
" internal energy -3.0603e+06 -9.4962e+07 J\n",
" entropy 6565.1 2.0372e+05 J/K\n",
" Gibbs function -4.9377e+06 -1.5322e+08 J\n",
" heat capacity c_p 997.71 30960 J/K\n",
" heat capacity c_v 729.77 22645 J/K\n",
"\n",
" mass frac. Y mole frac. X chem. pot. / RT\n",
" --------------- --------------- ---------------\n",
" O2 0.046403 0.045 -27.775\n",
" H2O 0.026988 0.046486 -123.33\n",
" CO2 0.29281 0.20646 -186.03\n",
" N2 0.6338 0.70206 -23.387\n",
" [ +49 minor] 0 0 \n",
"\n"
]
}
],
"source": [
"gas_b = ct.Solution('gri30.xml')\n",
"gas_b.TPX = 25 + 273.15, ct.one_atm, Xb\n",
"gas_b()"
]
},
{
"cell_type": "markdown",
"id": "3e537f99",
"metadata": {},
"source": [
"## 배가스 산소 농도 4.5% 혼합 기체 kg 당 저위발열량 (J/kg)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "067ae187",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'1.454846654525596 MJ/kg'"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"heating_value_J_kg = gas_u.enthalpy_mass - gas_b.enthalpy_mass\n",
"f'{heating_value_J_kg*1e-6} MJ/kg'"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "f8713062",
"metadata": {},
"outputs": [],
"source": [
"heat_to_battery = 80 # GJ / Rev"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "42f68b81",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'3636.3636363636365 MJ / hr to a combustion chamber'"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"heat_to_chamber = heat_to_battery * 1000 * 3 / 66 # MJ / hr\n",
"f'{heat_to_chamber} MJ / hr to a combustion chamber'"
]
},
{
"cell_type": "markdown",
"id": "30be4bfc",
"metadata": {},
"source": [
"## 연소실당 질량 유량 kg/hr"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "fd85f6dc",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'2499.482419712063 (kg/hr) = 3636.3636363636365 (MJ/hr) / 1.454846654525596 (MJ/kg)'"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mfr_to_chamber = heat_to_chamber * 1e6 / heating_value_J_kg # kg / hr\n",
"f'{mfr_to_chamber} (kg/hr) = {heat_to_chamber} (MJ/hr) / {heating_value_J_kg * 1e-6} (MJ/kg)'"
]
},
{
"cell_type": "markdown",
"id": "ed0ec84b",
"metadata": {},
"source": [
"# 단열 화염 온도 (평형 계산)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "fa7ef7a2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" gri30:\n",
"\n",
" temperature 1990.3 K\n",
" pressure 1.0133e+05 Pa\n",
" density 0.18983 kg/m^3\n",
" mean mol. weight 31.002 kg/kmol\n",
" phase of matter gas\n",
"\n",
" 1 kg 1 kmol \n",
" --------------- ---------------\n",
" enthalpy -8.933e+05 -2.7694e+07 J\n",
" internal energy -1.4271e+06 -4.4242e+07 J\n",
" entropy 8783.1 2.723e+05 J/K\n",
" Gibbs function -1.8374e+07 -5.6964e+08 J\n",
" heat capacity c_p 1347.2 41767 J/K\n",
" heat capacity c_v 1079 33452 J/K\n",
"\n",
" mass frac. Y mole frac. X chem. pot. / RT\n",
" --------------- --------------- ---------------\n",
" O 6.6906e-05 0.00012965 -15.939\n",
" O2 0.045092 0.043688 -31.879\n",
" OH 0.00048958 0.00089246 -30.541\n",
" H2O 0.026691 0.045932 -45.143\n",
" CO 0.0010791 0.0011944 -41.097\n",
" CO2 0.29111 0.20507 -57.036\n",
" NO 0.0031141 0.0032175 -29.575\n",
" N2 0.63235 0.6998 -27.272\n",
" [ +45 minor] 8.9238e-06 7.3926e-05 \n",
"\n"
]
}
],
"source": [
"gas_chamber = ct.Solution('gri30.xml')\n",
"gas_chamber.TPX = 600 + 273.15, ct.one_atm, Xu\n",
"gas_chamber.equilibrate(\"HP\")\n",
"gas_chamber(threshold=1e-4)\n",
"\n",
"eq_state = gas_chamber.TPX\n",
"\n",
"Tad, P0, X0 = eq_state"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "1d6c95a7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tad = 1717.118741092177 `C\n"
]
}
],
"source": [
"print(f'Tad = {eq_state[0] - 273.15} `C')"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "e437f3b4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"NO: 3217.4895678195617 ppm\n"
]
}
],
"source": [
"print(f'NO: {gas_chamber.mole_fraction_dict()[\"NO\"] * 1e6} ppm')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {
"height": "calc(100% - 180px)",
"left": "10px",
"top": "150px",
"width": "384px"
},
"toc_section_display": true,
"toc_window_display": true
}
},
"nbformat": 4,
"nbformat_minor": 5
}