From d9c6669d709d307a27200df46e2a6fd409978b49 Mon Sep 17 00:00:00 2001 From: Yeongdo Park Date: Mon, 12 Dec 2022 23:15:13 +0900 Subject: [PATCH] multiprocessing working on progress --- Battery.py | 131 +++++++++++++++----- CokeOvenBrickWall-Scales.ipynb | 210 +++++++++++++++++++++++++++++++++ 2 files changed, 309 insertions(+), 32 deletions(-) create mode 100644 CokeOvenBrickWall-Scales.ipynb diff --git a/Battery.py b/Battery.py index db2103f..174495e 100644 --- a/Battery.py +++ b/Battery.py @@ -1,6 +1,11 @@ from functools import reduce +import logging +import pickle +import multiprocessing as mp +from multiprocessing import Pool import numpy as np +import numba as nb import pde import cantera as ct from scipy import optimize @@ -17,6 +22,7 @@ class CombustionChamber: self.X0 = X0 # Composition in mole fractions, Fuel + Air self.h0 = self.gas.enthalpy_mass # inlet enthalpy self.hA = hA # HTC x Area + self.T1 = T0 self.Twall0 = 1100 + 273.15 self.Twall1 = 1100 + 273.15 self.Area = 6.7 * 16.7 @@ -64,6 +70,19 @@ class CokeCharge: def end_baking (self, t): self.t_push = t +brick_thickness = 0.14 # m, +n_grid_brick = 16 # Number of Grid points inside +wall_grid = pde.CartesianGrid([[0, brick_thickness]], n_grid_brick, periodic=False) +wall_area = 6.7 * 16.7 # m^2 , Oven cross section area + +# op_grad2 = wall_grid.make_operator_no_bc('gradient_squared', backend='scipy') +# op_grad = wall_grid.make_operator_no_bc('gradient', backend='scipy') +# op_lap = wall_grid.make_operator_no_bc('laplace', backend='scipy') + +# op_info_grad2 = wall_grid._get_operator_info('gradient_squared') +# op_info_grad = wall_grid._get_operator_info('gradient') +# op_info_lap = wall_grid._get_operator_info('laplace') + class CokeOvenBrickHeatEqn(pde.PDEBase): """Implementation of the Heat equation""" @@ -90,20 +109,46 @@ class CokeOvenBrickHeatEqn(pde.PDEBase): def evolution_rate(self, state, t=0): """implement the python version of the evolution equation""" - state_lap = state.laplace(bc=self.bc) - state_grad = state.gradient(bc=self.bc) - + state_lap = state.laplace(bc=self.bc) # , backend="auto") + # state_grad = state.gradient(bc=self.bc, backend="scipy") + state_grad2 = state.gradient_squared(bc=self.bc) # , backend="auto") + + ''' + # out_cls_grad2 = state.get_class_by_rank(op_info_grad2.rank_out) + out_cls_grad = state.get_class_by_rank(op_info_grad.rank_out) + out_cls_lap = state.get_class_by_rank(op_info_lap.rank_out) + # state_grad2 = out_cls_grad2(state.grid, data="empty", dtype=state.dtype) + state_grad = out_cls_grad(state.grid, data="empty", dtype=state.dtype) + state_lap = out_cls_lap(state.grid, data="empty", dtype=state.dtype) + state.set_ghost_cells(self.bc) + # op_grad2(state._data_full, state_grad2.data) + op_grad(state._data_full, state_grad.data) + op_lap(state._data_full, state_lap.data) + ''' k = self.kCoef1 * state + self.kCoef0 cp = self.cpCoef1 * state + self.cpCoef0 - k_grad = self.kCoef1 * state_grad + state_grad_k_grad = self.kCoef1 * state_grad2 # state_grad.dot(state_grad) - return (state_grad.dot(k_grad) + k * state_lap) / self.rho / cp + return (state_grad_k_grad + k * state_lap) / cp / self.rho -brick_thickness = 0.14 # m, -n_grid_brick = 32 # Number of Grid points inside -wall_grid = pde.CartesianGrid([[0, brick_thickness]], n_grid_brick, periodic=False) -wall_area = 6.7 * 16.7 # m^2 , Oven cross section area + ''' + def _make_pde_rhs_numba(self, state): + """implement the python version of the evolution equation""" + lap = state.grid.make_operator("laplace", bc=self.bc) + # grad = state.grid.make_operator("gradient", bc=self.bc) + grad2 = state.grid.make_operator("gradient_squared", bc=self.bc) + rho = self.rho + kCoef0 = self.kCoef0 + kCoef1 = self.kCoef1 + cpCoef0 = self.cpCoef0 + cpCoef1 = self.cpCoef1 + @nb.jit + def pde_rhs(data, t): + return (((kCoef1*grad2(data)) + (kCoef1*data + kCoef0)*lap(data)) / rho / (cpCoef1 * data + cpCoef0)) + + return pde_rhs +''' class RefractoryWall: def __init__ (self, T0): @@ -125,7 +170,8 @@ class RefractoryWall: def solve (self, dt): # solution = self.eqn.solve (eqn, bc) - self.T_internal = self.eqn.solve(self.T_internal, t_range=dt, dt=1., tracker='consistency') + self.T_internal = self.eqn.solve( + self.T_internal, t_range=dt, dt=30., tracker='consistency', backend="numpy") self.T_chamber = self.T_internal.get_boundary_values(axis=0, upper=False, bc=self.eqn.bc) def heat_to_oven (self): @@ -166,6 +212,10 @@ class OvenChamber: """ Update content with fresh coal is charged """ self.content = coal_charge +def wall_solve_wrapper(t_range, wall): + wall.solve(t_range) + return wall.T_internal, wall.T_chamber + class Battery: def __init__ (self, name, size, heat_program, charge_program, burned_gas_state, hv): @@ -185,6 +235,9 @@ class Battery: self.X0 = X0 self.sequence_idx = 0 # Integer, 0 ~ (size-1), progress index for oven sequence array + self.wall_t_history = [] + self.gas_t_history = [] + self.hv = hv # Base unit heat J/kg self.normal_heat = self.heat_program.f(-1) # GJ / rev @@ -220,7 +273,7 @@ class Battery: # 정상 상태 만들기: 모든 문에 n_cycle 회 장입 n_cycle = 3 # 모든 문 장입 반복 횟수 - period_over_dt = 11. # period/dt, 장입 간격 / 초기화 time step 크기 + period_over_dt = 6. # period/dt, 장입 간격 / 초기화 time step 크기 normal_period = self.charge_program.period(-1) # 감산 전 장입 간격 (주기) dt = normal_period / period_over_dt # Simulation Time Step @@ -229,6 +282,7 @@ class Battery: # initialization time loop for i in range(int(np.ceil(self.size * period_over_dt * n_cycle))): + # for i in range(3): """ Fill battety with normal charge rate """ self.update(dt) # Time adavancement @@ -251,22 +305,22 @@ class Battery: # update chamber wall temperatures and mass flow rates # solve for equilibrium heat to walls for i_chamber, chmbr in enumerate(self.chambers): - try: + if i_chamber > 0: wall_lower = self.walls_1[i_chamber-1] - except IndexError: + else: wall_lower = None - try: + if i_chamber < self.size: wall_upper = self.walls_0[i_chamber] - except IndexError: + else: wall_upper = None chmbr.update_mdot(self.mdot(self.t)) chmbr.update_Twall( - wall_lower.T_chamber if wall_lower else wall_upper.T_chamber, - wall_upper.T_chamber if wall_upper else wall_lower.T_chamber, + Twall0=(wall_lower.T_chamber if wall_lower else wall_upper.T_chamber), + Twall1=(wall_upper.T_chamber if wall_upper else wall_lower.T_chamber), ) - print(f"t={self.t} - C{i_chamber} with {chmbr.Twall0} K and {chmbr.Twall1} K ") + print(f"t={self.t:6.2} : {chmbr.Twall0} K | Chamber {i_chamber} | {chmbr.Twall1} K ") chmbr.solve() Q1, Q2 = chmbr.heat() # W (J/s) if wall_lower: wall_lower.update_bc(Q=Q1) @@ -282,13 +336,22 @@ class Battery: wall_lower.update_bc(T_oven=T_oven) wall_upper.update_bc(T_oven=T_oven) - wall_lower.solve(dt * 60 * 60) - wall_upper.solve(dt * 60 * 60) + with Pool(16) as pool: + wall_sln = pool.starmap(wall_solve_wrapper, [((dt*60*60), w) for w in self.walls_0+self.walls_1]) + # wall_lower.solve(dt * 60 * 60) # convert hours to seconds + # wall_upper.solve(dt * 60 * 60) # convert hours to seconds + for ws, wall in zip(wall_sln, self.walls_0+self.walls_1): + T_internal, T_chamber = ws + wall.T_internal = T_internal + wall.T_chamber = T_chamber + + ''' ql = wall_lower.heat_to_oven() qu = wall_upper.heat_to_oven() - oven.bake(ql+qu) + oven.bake(ql+qu) + ''' # advance time oven brick # from chamber heat flux boundary condition @@ -296,12 +359,6 @@ class Battery: # integrate heat to oven # 오븐 벽면 온도 우선 시간 함수로 - '''dQ = self.dQ(dt) # array, dQ pairs of all oven taking from both walls - - for cc in self.processing: - cc.bake(dQ) # bake.(dQ[cc.idx_oven]) - ''' - def push_and_charge (self, coke_charge): if len(self.processing) >= self.size: self.push(coke_charge.t_charge) @@ -339,10 +396,6 @@ class Battery: # t_last + period 가 t, t + dt 사이에 들어오는 것 검사 # t + dt 가 다음 추출/장입 시각 이후일 때 => 이번 time step 에 추출/장입을 실행해야함 if self.t + dt >= period + self.t_last : - print(f"P/C within [ {self.t:7.3} , {self.t + dt:7.3} ].", - f"{self.t + dt - latest_coke_charge:7.3} since last P/C. ", - f"period = {self.charge_program.period(self.t):7.3}",) - # 마지막 장입 시각 + 장입 시간 간격 이 이번 time step 에 포함됨 # 일정한 간격으로 장입 진행 중, 마지막 장입 시간 += 장입 간격 if self.t < self.t_last + period: @@ -357,10 +410,18 @@ class Battery: # oven = self.ovens[i_oven] fresh_coal = CokeCharge(self.t + dt, i_oven) self.push_and_charge(fresh_coal) + + print(f"On {i_oven} P/C within [ {self.t:7.3} , {self.t + dt:7.3} ].", + f"{self.t + dt - latest_coke_charge:7.3} since last P/C. ", + f"period = {self.charge_program.period(self.t):7.3}",) + # 시뮬레이션 시간 업데이트 self.t += dt + self.gas_t_history.append((self.t, [chmbr.T1 for chmbr in self.chambers])) + self.wall_t_history.append((self.t, [(wl.T_chamber, wl.T_internal.data, wl.T_oven, wu.T_oven, wu.T_internal.data, wu.T_chamber) for wl, wu in zip(self.walls_0, self.walls_1)])) + def coke_oven_exhaust_stoichiometry (phi=1.0, return_unburned=False): # Define the oxidizer composition, here air with 21 mol-% O2 and 79 mol-% N2 @@ -487,4 +548,10 @@ if __name__ == "__main__": charging_plan = ChargeSchedule( 81, 9, 9, 1e-12, 24+13, 3, 1e-12 ) n_doors = 66 - bat3A = Battery("3A", n_doors, heating_plan, charging_plan, gas_in_state, hv) \ No newline at end of file + bat3A = Battery("3A", n_doors, heating_plan, charging_plan, gas_in_state, hv) + + with open('gas.history', 'wb') as gas_history_file: + pickle.dump(bat3A.gas_t_history, gas_history_file) + + with open('wall.history', 'wb') as wall_history_file: + pickle.dump(bat3A.wall_t_history, wall_history_file) \ No newline at end of file diff --git a/CokeOvenBrickWall-Scales.ipynb b/CokeOvenBrickWall-Scales.ipynb new file mode 100644 index 0000000..4348767 --- /dev/null +++ b/CokeOvenBrickWall-Scales.ipynb @@ -0,0 +1,210 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "a48ca14c", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import cantera as ct\n", + "\n", + "import ipywidgets as widgets\n", + "\n", + "from matplotlib import pyplot as plt\n", + "%matplotlib widget" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "3efb72e3", + "metadata": {}, + "outputs": [], + "source": [ + "rho = 1900 # kg / m3\n", + "kCoef0 = 0.93 # W / m / K\n", + "kCoef1 = 0.698e-3 # W / m / K2\n", + "cpCoef0 = 837.2 # J / kg / K\n", + "cpCoef1 = 251.2e-3 # J / kg / K2" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e098d30f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.0, 8.751177742052907e-07)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1f391b6625084e539ed2f05764f170e8", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure()\n", + "T = np.linspace(800, 1600, 100)\n", + "k = kCoef0 + kCoef1 * T\n", + "Cp = cpCoef0 + cpCoef1 * T\n", + "plt.plot(T, k / rho / Cp)\n", + "plt.ylim(ymin=0)" + ] + }, + { + "cell_type": "markdown", + "id": "9cc2c8cf", + "metadata": {}, + "source": [ + "# Mean thermal diffusivity of refractory wall (800K~1600K)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "8c99e09d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8.15323821121732e-07 m/s2\n" + ] + } + ], + "source": [ + "alpha = ( k / rho / Cp).mean()\n", + "print(f'{alpha} m/s2')" + ] + }, + { + "cell_type": "markdown", + "id": "83e89a43", + "metadata": {}, + "source": [ + "# Grid spacing" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "34cd3a29", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.004375 m\n" + ] + } + ], + "source": [ + "grid_size = 0.14 / 32\n", + "print(f'{grid_size} m')" + ] + }, + { + "cell_type": "markdown", + "id": "3cb9310c", + "metadata": {}, + "source": [ + "# Time step constraint" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "287b9df7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11.73805088490246" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "0.5 *( grid_size **2) / alpha" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "191dd97b", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}