casualguitar

fluid_packed_bed

Feb 22nd, 2022
655
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.08 KB | None | 0 0
  1. import numpy as np
  2. from scipy.integrate import solve_ivp
  3. import matplotlib.pyplot as plt
  4. from chemicals import normalize
  5. from thermo import ChemicalConstantsPackage, CEOSGas, CEOSLiquid, PRMIXTranslatedConsistent, FlashVL
  6. from thermo.interaction_parameters import IPDB
  7. import math
  8. from thermo.chemical import Mixture
  9.  
  10. ##Setup of the fluid mixture properties (air)
  11. constants, properties = ChemicalConstantsPackage.from_IDs(['nitrogen', 'oxygen', 'argon'])
  12. kijs = IPDB.get_ip_asymmetric_matrix('ChemSep PR', constants.CASs, 'kij')
  13. eos_kwargs = {'Pcs': constants.Pcs, 'Tcs': constants.Tcs, 'omegas': constants.omegas, 'kijs': kijs}
  14. gas = CEOSGas(PRMIXTranslatedConsistent, eos_kwargs=eos_kwargs, HeatCapacityGases=properties.HeatCapacityGases)
  15. liquid = CEOSLiquid(PRMIXTranslatedConsistent, eos_kwargs=eos_kwargs, HeatCapacityGases=properties.HeatCapacityGases)
  16. flasher = FlashVL(constants, properties, liquid=liquid, gas=gas)
  17. zs = normalize([78.08, 20.95, .93])
  18. ################################################################
  19.  
  20. numberBeds = 10
  21. diameterBed = 0.0779 #metres
  22. heightBed = 0.27
  23. areaBed = ((math.pi)/4)*diameterBed**2
  24. volumeBed = areaBed*heightBed
  25. vTotal = volumeBed * numberBeds #total bed volume (m^3)
  26.  
  27. diameterParticle = 0.005
  28. volumeParticle = (1/6)*math.pi*(diameterParticle**3)
  29. particleNumber = math.floor(vTotal/volumeParticle)
  30. saParticle = 4*math.pi*((diameterParticle/2)**2)
  31. saTotal = saParticle*particleNumber #total surface area (m^2)
  32.  
  33. rhoAlumina = 3950
  34. mAluminakg = volumeParticle*particleNumber*rhoAlumina # total mass of alumina (kg)
  35. mWAlumina = 101.96
  36. mAluminaTotal = mAluminakg*1000/mWAlumina #total mass of alumina (mol)
  37.  
  38. cpAlumina = 89.72
  39. kAlumina = 5
  40.  
  41. mWAir = 29
  42.  
  43. minkg = 0.0022*10
  44. min = minkg*1000/mWAir #mol/s
  45.  
  46. T0 = 80  # initial fluid temp (K)
  47. Ts0 = 80  # initial solid temp (K)
  48.  
  49. Tin = 300  # Inlet fluid temperature (K)
  50. P = 3000000  # Pa
  51.  
  52. n = 3 # number of elements in spatial array
  53. V = vTotal/n
  54. sa = saTotal/n #surface area per unit volume
  55. mAlumina = mAluminaTotal/n #alumina mass per unit volume
  56.  
  57.  
  58. ## Using thermo
  59. hIn = flasher.flash(T=Tin, P=P, zs=zs, retry = True).H()  # Inlet fluid enthalpy (J/mol)
  60. H0 = flasher.flash(T=T0, P=P, zs=zs, retry = True).H() # bed fluid starting enthalpy (J/mol)
  61.  
  62. def temp(H,P):
  63.     # returns temperature given enthalpy (after processing function)
  64.     T = flasher.flash(H=H, P=P, zs=zs, retry=True).T
  65.     return T
  66.  
  67. def mass(H, P):
  68.     # returns mass holdup in mol
  69.     m = flasher.flash(H=H, P=P, zs=zs, retry=True).rho()*V
  70.     return m
  71.  
  72. def dpdh(H, P):
  73.     #derivative of density w.r.t enthalpy at constant pressure
  74.     res = flasher.flash(H=H, P=P, zs=zs, retry=True)
  75.     if res.phase_count == 1:
  76.         if res.phase == 'L':
  77.             drho_dTf = res.liquid0.drho_dT()
  78.         else:
  79.             drho_dTf = res.gas.drho_dT()
  80.     else:
  81.         drho_dTf = res.bulk._equilibrium_derivative(of='rho', wrt='T', const='P')
  82.     dpdh = drho_dTf/res.dH_dT_P()
  83.     return dpdh
  84.  
  85. def U(H,P,m):
  86.     # Given T, P, m, calculate heat transfer coefficient (function of T,P, mass flow)
  87.     air = Mixture(['nitrogen', 'oxygen'], Vfgs=[0.79, 0.21], H=H, P=P)
  88.     mu = air.mu*1000/mWAir #mol/m.s
  89.     cp = air.Cpm #J/mol.K
  90.     kg = air.k #W/m.K
  91.     g0 = m/areaBed #mol/m2.s
  92.     a = sa*n/vTotal #m^2/m^3 #QUESTIONABLE
  93.     psi = 1
  94.     beta = 10
  95.     pr = (mu*cp)/kg
  96.     re = (6*g0)/(a*mu*psi)
  97.     hfs = ((2.19*(re**1/3)) + (0.78*(re**0.619)))*(pr**1/3)*(kg)/diameterParticle
  98.  
  99.     h = 1/((1/hfs) + ((diameterParticle/beta)/kAlumina))
  100.  
  101.     return h
  102.  
  103. # time steps
  104. t_max = 100
  105. t = (0, t_max)  # time range
  106. # t_eval = np.linspace(0, t_max, 1000 * t_max)  # optional
  107.  
  108.  
  109. def my_system(t, y, n, hIn, min, mAlumina, cpAlumina, sa, V):
  110.    
  111.     #setup of differential equations in algebraic form
  112.    
  113.     dydt = np.zeros(3 * n) #setting up zeros array for solution (solving for [H0,Ts0,m0,H1,Ts1,m1,H2,Ts2,m2,..Hn,Tsn,mn])
  114.  
  115.     # y = [h_0, Ts_0, m_0, ... h_n, Ts_n, m_n]
  116.     # y[0] = hin
  117.     # y[1] = Ts0
  118.     # y[2] = minL
  119.  
  120.     i=0
  121.  
  122.     ## Using thermo
  123.     T = temp(y[i],P) #initial T
  124.     m = mass(y[i],P) #initial m
  125.  
  126.     #initial values
  127.     dydt[i] = (min * (hIn - y[i]) + (U(hIn,P,min) * sa * (y[i + 1] - T))) / m # dH/dt (eq. 2)
  128.     dydt[i + 1] = -(U(hIn,P,min) * sa * (y[i + 1] - T)) / (mAlumina * cpAlumina) # dTs/dt from eq.3
  129.     dmdt = dydt[i] * dpdh(y[i], P) * V # dm/dt (holdup variation) eq. 4b
  130.     dydt[i + 2] = min - dmdt # mass flow out (eq.4a)
  131.     # print("H fluid 0: ", dydt[i])
  132.     # print("Ts 0: ", dydt[i+1])
  133.     # print("m dot: ", dydt[i+2])
  134.  
  135.  
  136.     for i in range(3, 3 * n, 3): #starting at index 3, and incrementing by 3 because we are solving for 'triplets' [h,Ts,m] in each loop
  137.  
  138.         ## Using thermo
  139.         T = temp(y[i],P)
  140.         m = mass(y[i],P)
  141.         # print("T check: ", T)
  142.  
  143.         # [h, TS, mdot]
  144.         dydt[i] = (dydt[i-1] * (y[i - 3] - y[i]) + (U(y[i-3], P, dydt[i-1]) * sa * (y[i + 1] - T))) /  m # dH/dt (eq.2), dydt[i-1] is the mass of the previous tank
  145.         dydt[i + 1] = -(U(y[i-3], P, dydt[i-1]) * sa * (y[i + 1] - T)) / (mAlumina * cpAlumina) # dTs/dt eq. (3)
  146.         dmdt = dydt[i] * dpdh(y[i], P) * V # Equation 4b
  147.         dydt[i + 2] = dydt[i-1] - dmdt # Equation 4a
  148.  
  149.         # print("H fluid: ", dydt[i])
  150.         # print("Ts: ", dydt[i + 1])
  151.         # print("m dot: ", dydt[i + 2])
  152.     return dydt
  153.  
  154. y0 = np.copy(np.asarray([H0, Ts0, min] * n)) #setting up initial condition array (H0,Ts0 and m_dot at all points
  155. print("yo")
  156. print(y0)
  157. y0[0] = H0 # initial fluid bed enthalpy
  158. y0[1] = Ts0 # initial solid bed temperature
  159. y0[2] = min #initial mass holdup
  160.  
  161. parameters = (n, hIn, min, mAlumina, cpAlumina, sa, V)
  162.  
  163. solution = solve_ivp(my_system, t, y0, args=parameters, method='Radau')
  164.  
  165. ##FROM HERE TO BELOW IS AFTER PROCESSING (EXTRACTION OF SOLUTION ARRAYS, PLOTTING, ETC)
  166. h_arr = solution.y[0::3]
  167. Ts_arr = solution.y[1::3]
  168. m_arr = solution.y[2::3]
  169.  
  170. time = solution.t
  171. # dt = 2*(time[2:]-time[:-2])
  172.  
  173. dydt = np.zeros((3 * n, time.size))
  174. for i in range(time.size):
  175.     dydt[:, i] = my_system(t, solution.y[:, i], n, hIn, min, mAlumina, cpAlumina, sa, V)
  176.  
  177. dhdt_arr = dydt[0::3]
  178. dTsdt_arr = dydt[1::3]
  179. mdot_arr = dydt[2::3]
  180.  
  181. dmdt_arr = np.zeros_like(mdot_arr) #
  182. T_arr = np.zeros_like(mdot_arr) # fluid temperature
  183. m_hold_arr = np.zeros_like(mdot_arr) # mass hold up
  184. U_arr = np.zeros_like(mdot_arr) # mass hold up
  185.  
  186. for i in range(time.shape[0]):
  187.     for j in range(n):
  188.         # T = temp(h_arr[j,i])
  189.  
  190.         ## Using thermo
  191.         T = temp(h_arr[j,i],P)
  192.  
  193.         T_arr[j,i] = T
  194.  
  195.         ## Using thermo
  196.         m_hold_arr[j,i] = mass(h_arr[j,i],P)
  197.  
  198.         dmdt_arr[j,i] = dhdt_arr[j,i] * dpdh(h_arr[j,i], P) * V
  199.  
  200.         U_arr[j,i] = mAlumina*cpAlumina*dTsdt_arr[j,i]/(sa*(T_arr[j,i] - Ts_arr[j,i]))
  201.  
  202. # creating the fluid array from the solid array
  203. Tf_arr = np.zeros_like(Ts_arr)
  204. Tf_arr = Ts_arr + dTsdt_arr * (mAlumina * cpAlumina) / (U_arr * sa)
  205. # Tf_arr[:, 0] = Ts0  # I.C cannot be calculated as there is no derivative at the boundary. Manually entering here
  206. #data1 = np.concatenate([np.array([time]), h_arr]).transpose()
  207. # data1 = np.stack((data1,data1),axis=2)
  208.  
  209. #np.savetxt("data1.txt",data1)
  210. print("simulation omplete")
  211.  
  212.  
  213. #print(x_arr)
  214.  
  215.  
  216. '''
  217. snapshot = 1000  # snapshot time spacing: 1000=1s
  218. style = ['-', '--', '-.', ':', '-','-', '--', '-.', ':', '-','-', '--']
  219. color = ['b','r','g','c','b','r','g','c','b','r','g','c']
  220. for i in range(len(style)):
  221.    plt.plot(mdot_arr[:, i*snapshot], style[i],
  222.             color=color[i],
  223.             label="t="+str(i*snapshot/1000)+"s")
  224.  
  225. plt.ylabel(r'm (kg/s)')
  226. plt.xlabel(r'position(j)')
  227. plt.legend(loc='lower left')
  228. plt.show()
  229. '''
  230. # plt.plot(time,h_arr[0, :], '-.', color='b', label="position 0 h")
  231. # plt.plot(time,h_arr[1, :], '--', color='b', label="position 1")
  232. # plt.plot(time,h_arr[2, :], ':', color='b', label="position 2")
  233. # plt.plot(time,Tf_arr[0, :], '-.', color='g', label="position 0 T")
  234. #plt.plot(time,x_arr[0, :], '-.', color='r', label="tank 1 quality")
  235. #plt.plot(time,x_arr[1, :], '-.', color='g', label="tank 2 quality")
  236. #plt.plot(time,x_arr[2, :], '-.', color='b', label="tank 3 quality")
  237. '''
  238. plt.figure()
  239. plt.plot(time,dmdt_arr[0, :], '-', color='r', label="tank 1 dm/dt")
  240. plt.plot(time,dmdt_arr[1, :], '--', color='g', label="tank 2 dm/dt")
  241. plt.plot(time,dmdt_arr[2, :], '-.', color='b', label="tank 3 dm/dt")
  242. plt.plot(time,dmdt_arr[3, :], '--', color='m', label="tank 4 dm/dt")
  243. plt.plot(time,dmdt_arr[4, :], '-.', color='c', label="tank 5 dm/dt")
  244.  
  245. # plt.plot(time,Tf_arr[1, :], '--', color='g', label="position 1")
  246. # plt.plot(time,Tf_arr[2, :], ':', color='g', label="position 2")
  247. # from plot_together import plot_together
  248. # plot_together(data1[:,[0,1]:], '--', color='b', label="position 0")
  249. # plot_together(data1[:,[0,2],:], '--', color='b', label="position 1")
  250. # plot_together(data1[:,[0,3],:], ':', color='b', label="position 2")
  251. plt.ylabel(r'dm/dt')
  252. plt.xlabel(r'Time')
  253. # plt.ylim((80, 91))
  254. plt.grid('both')
  255. plt.title("dm/dt for all tanks")
  256. plt.legend(loc='lower right')
  257. '''
  258.  
  259. plt.figure()
  260. plt.plot(time,mdot_arr[0, :], '-', color='b', label="tank 1 mdot")
  261. plt.plot(time,mdot_arr[1, :], '--', color='b', label="tank 2 mdot")
  262. plt.plot(time,mdot_arr[2, :], '-.', color='b', label="tank 3 mdot")
  263. #plt.plot(time,mdot_arr[3, :], '--', color='b', label="tank 4 mdot")
  264. #plt.plot(time,mdot_arr[4, :], '-.', color='b', label="tank 5 mdot")
  265.  
  266. plt.ylabel(r'Mass Flow (kg/s)')
  267. plt.xlabel(r'Time')
  268. # plt.ylim((80, 91))
  269. plt.grid('both')
  270. plt.title("m dot for all tanks")
  271. plt.legend(loc='lower right')
  272.  
  273. #########################################################
  274. plt.figure()
  275. plt.plot(time,m_arr[0, :], '-', color='b', label="tank 1  m_flow")
  276. plt.plot(time,m_arr[1, :], '--', color='b', label="tank 2 m_flow")
  277. plt.plot(time,m_arr[2, :], '-.', color='b', label="tank 3 m_flow")
  278. #plt.plot(time,m_arr[3, :], '--', color='b', label="tank 4 m_flow")
  279. #plt.plot(time,m_arr[4, :], '-.', color='b', label="tank 5 m_flow")
  280.  
  281. plt.ylabel(r'Mass flow')
  282. plt.xlabel(r'Time')
  283. # plt.ylim((80, 91))
  284. plt.grid('both')
  285. plt.title("Mass flow for all tanks")
  286. plt.legend(loc='lower right')
  287.  
  288. ###########################################################
  289. plt.figure()
  290. plt.plot(time,T_arr[0, :], '-', color='b' , label="tank 1 Fluid temp", marker = "x")
  291. plt.plot(time,T_arr[1, :], '--', color='b', label="tank 2 Fluid temp")
  292. plt.plot(time,T_arr[2, :], '-.', color='b', label="tank 3 Fluid temp")
  293. #plt.plot(time,T_arr[3, :], '--', color='b', label="tank 4 Fluid temp")
  294. #plt.plot(time,T_arr[4, :], '-.', color='b', label="tank 5 Fluid temp")
  295.  
  296. plt.ylabel(r'Fluid temp')
  297. plt.xlabel(r'Time')
  298. # plt.ylim((80, 91))
  299. plt.grid('both')
  300. plt.title("Fluid temperature for all tanks")
  301. plt.legend(loc='lower right')
  302.  
  303. ###########################################################
  304. plt.figure()
  305. plt.plot(time,m_hold_arr[0, :], '-', color='b' , label="tank 1 Mass hold up")
  306. plt.plot(time,m_hold_arr[1, :], '--', color='b', label="tank 2 Mass hold up")
  307. plt.plot(time,m_hold_arr[2, :], '-.', color='b', label="tank 3 Mass hold up")
  308. #plt.plot(time,m_hold_arr[3, :], '--', color='b', label="tank 4 Mass hold up")
  309. #plt.plot(time,m_hold_arr[4, :], '-.', color='b', label="tank 5 Mass hold up")
  310.  
  311. plt.ylabel(r'Mass hold up')
  312. plt.xlabel(r'Time')
  313. # plt.ylim((80, 91))
  314. plt.grid('both')
  315. plt.title("Mass hold up for all tanks")
  316. plt.legend(loc='lower right')
  317.  
  318. ###########################################################
  319. plt.figure()
  320. plt.plot(time,mdot_arr[0, :], '-', color='b' , label="tank 1 Mass flow rate")
  321. plt.plot(time,mdot_arr[1, :], '--', color='b', label="tank 2 Mass flow rate")
  322. plt.plot(time,mdot_arr[2, :], '-.', color='b', label="tank 3 Mass flow rate")
  323. #plt.plot(time,mdot_arr[3, :], '--', color='b', label="tank 4 Mass flow rate")
  324. #plt.plot(time,mdot_arr[4, :], '-.', color='b', label="tank 5 Mass flow rate")
  325.  
  326. plt.ylabel(r'Mass flow rate')
  327. plt.xlabel(r'Time')
  328. # plt.ylim((80, 91))
  329. plt.grid('both')
  330. plt.title("Mass flow rate for all tanks")
  331. plt.legend(loc='lower right')
  332.  
  333. ###########################################################
  334. plt.figure()
  335. plt.plot(time,Ts_arr[0, :], '-', color='b' , label="tank 1 Solid Temperature")
  336. plt.plot(time,Ts_arr[1, :], '--', color='b', label="tank 2 Solid Temperature")
  337. plt.plot(time,Ts_arr[2, :], '-.', color='b', label="tank 3 Solid Temperature")
  338. #plt.plot(time,Ts_arr[3, :], '--', color='b', label="tank 4 Solid Temperature")
  339. #plt.plot(time,Ts_arr[4, :], '-.', color='b', label="tank 5 Solid Temperature")
  340.  
  341. plt.ylabel(r'Solid Temperature')
  342. plt.xlabel(r'Time')
  343. # plt.ylim((80, 91))
  344. plt.grid('both')
  345. plt.title("Solid Temperature for all tanks")
  346. plt.legend(loc='lower right')
  347.  
  348. ###########################################################
  349. plt.figure()
  350. plt.plot(time,h_arr[0, :], '-', color='b', label="tank 1 h")
  351. plt.plot(time,h_arr[1, :], '--', color='b', label="tank 2 h")
  352. plt.plot(time,h_arr[2, :], '-.', color='b', label="tank 3 h")
  353. #plt.plot(time,h_arr[3, :], '--', color='b', label="tank 4 mdot")
  354. #plt.plot(time,h_arr[4, :], '-.', color='b', label="tank 5 mdot")
  355.  
  356. plt.ylabel(r'h (J/mol.K)')
  357. plt.xlabel(r'Time')
  358. # plt.ylim((80, 91))
  359. plt.grid('both')
  360. plt.title("h for all tanks")
  361. plt.legend(loc='lower right')
  362.  
  363. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment