casualguitar

James - Script

Feb 28th, 2022
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.40 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. #BED
  21. NUMBER_BEDS = 10 #Physical packed beds
  22. DIAMETER_BED = 0.0779 #metres
  23. HEIGHT_BED = 0.27 #metres
  24. AREA_BED = ((math.pi)/4)*DIAMETER_BED**2 #m^2
  25. VOLUME_BED = AREA_BED*HEIGHT_BED #m^3
  26. V_TOTAL = VOLUME_BED * NUMBER_BEDS #total beds volume (m^3)
  27.  
  28. #PARTICLE
  29. DIAMETER_PARTICLE = 0.005 #metres
  30. VOLUME_PARTICLE = (1/6)*math.pi*(DIAMETER_PARTICLE**3) #particle volume m^3
  31. PARTICLE_NUMBER = math.floor(V_TOTAL/VOLUME_PARTICLE) #total number of particles
  32. SA_PARTICLE = 4*math.pi*((DIAMETER_PARTICLE/2)**2) #m^2
  33. SA_TOTAL = SA_PARTICLE*PARTICLE_NUMBER #total surface area (m^2)
  34. RHO_ALUMINA = 3950 #kg/m3
  35. M_ALUMINA_KG = VOLUME_PARTICLE*PARTICLE_NUMBER*RHO_ALUMINA # total mass of alumina (kg)
  36. MW_ALUMINA = 101.96 #g/mol
  37. M_ALUMINA_MOL = M_ALUMINA_KG*1000/MW_ALUMINA #total mass of alumina (mol)
  38. CP_ALUMINA = 89.72 #J/mol.K
  39. K_ALUMINA = 5 #W/m.K
  40.  
  41. #FLUID
  42. MW_AIR = 29 #g/mol
  43.  
  44. #INITIAL CONDITIONS
  45. T0 = 80  # initial fluid temperature (K)
  46. Ts0 = 80  # initial solid temperature (K)
  47. P = 3000000  # Pa
  48. H0 = flasher.flash(T=T0, P=P, zs=zs, retry = True).H() # bed fluid starting enthalpy (J/mol)
  49.  
  50.  
  51. #BOUNDARY CONDITIONS
  52. Tin = 300  # Inlet fluid temperature (K)
  53. minkg = 0.022 #kg/s
  54. min = minkg*1000/MW_AIR #mol/s
  55. hIn = flasher.flash(T=Tin, P=P, zs=zs, retry = True).H()  # Inlet fluid enthalpy (J/mol)
  56.  
  57. #SPATIAL DEPENDENCE OF QUANTITIES
  58. n = 3 # number of elements in spatial array
  59. V = V_TOTAL/n
  60. sa = SA_TOTAL/n #surface area per unit volume
  61. mAlumina = M_ALUMINA_MOL/n #alumina mass per unit volume
  62.  
  63. def temperature(H,P):
  64.     # returns temperature given enthalpy (after processing function)
  65.     T = flasher.flash(H=H, P=P, zs=zs, retry=True).T #K
  66.     return T
  67.  
  68. def mass(H, P):
  69.     # returns mass holdup in mol (mass in an element n)
  70.     m = flasher.flash(H=H, P=P, zs=zs, retry=True).rho()*V #mol
  71.     return m
  72.  
  73. def dpdh(H, P):
  74.     #returns the derivative of density w.r.t enthalpy at constant pressure
  75.     res = flasher.flash(H=H, P=P, zs=zs, retry=True)
  76.     if res.phase_count == 1:
  77.         if res.phase == 'L':
  78.             drho_dTf = res.liquid0.drho_dT()
  79.         else:
  80.             drho_dTf = res.gas.drho_dT()
  81.     else:
  82.         drho_dTf = res.bulk._equilibrium_derivative(of='rho', wrt='T', const='P')
  83.     dpdh = drho_dTf/res.dH_dT_P()
  84.     return dpdh
  85.  
  86. def U(H,P,m):
  87.     # Given T, P, m_dot returns U W/m2.K
  88.     air = Mixture(['nitrogen', 'oxygen'], Vfgs=[0.79, 0.21], H=H, P=P)
  89.     mu = air.mu*1000/MW_AIR #mol/m.s
  90.     cp = air.Cpm #J/mol.K
  91.     kg = air.k #W/m.K
  92.     g0 = m/AREA_BED #mol/m2.s
  93.     a = sa*n/V_TOTAL #m^2/m^3 #QUESTIONABLE
  94.     psi = 1
  95.     beta = 10
  96.     pr = (mu*cp)/kg
  97.     re = (6*g0)/(a*mu*psi)
  98.     hfs = ((2.19*(re**1/3)) + (0.78*(re**0.619)))*(pr**1/3)*(kg)/DIAMETER_PARTICLE
  99.  
  100.     h = 1/((1/hfs) + ((DIAMETER_PARTICLE/beta)/K_ALUMINA))
  101.  
  102.     return h
  103.  
  104. # def vapourfraction(H,P):
  105. #     x = flasher.flash(H=H, P=P, zs=zs, retry=True).VF # mol basis
  106. #     return x
  107.  
  108. # time steps
  109. TIME = 1000
  110. t = (0, TIME)  # time range
  111. # t_eval = np.linspace(0, TIME, 1000 * TIME)  # optional
  112.  
  113.  
  114. def my_system(t, y, n, hIn, min, mAlumina, CP_ALUMINA, sa, V):
  115.     dydt = np.zeros(2 * n) #setting up zeros array
  116.  
  117.     i=0
  118.  
  119.     ## Using thermo
  120.     T = temperature(y[i],P) #initial fluid temperature
  121.     m = mass(y[i],P) #initial mass holdup
  122.     print("T = ", T)
  123.     print("M = ", m)
  124.  
  125.     #initial boundary values
  126.     dydt[i] = (min * (hIn - y[i]) + (U(y[i],P,min) * sa * (y[i + 1] - T))) / m # dH/dt (eq. 2)
  127.     dydt[i + 1] = -(U(y[i],P,min) * sa * (y[i + 1] - T)) / (mAlumina * CP_ALUMINA) # dTs/dt from eq.3
  128.     dmdt = dydt[i] * dpdh(y[i], P) * V # dm/dt eq. 4b
  129.     mj = min - dmdt # mass flow out (eq.4a)
  130.  
  131.     #Solution array y will look like [h0,Ts0,mdot0, h1, Ts1, mdot1,...hn,Tsn,mdotn] at all values of t
  132.     for i in range(2, 2 * n, 2): #starting at index 2, and incrementing by 2 because we are solving for 'triplets' [h,Ts] in each loop
  133.  
  134.         ## Using thermo
  135.         T = temperature(y[i],P)
  136.         m = mass(y[i],P)
  137.  
  138.         # [h, TS, mdot]
  139.         dydt[i] = (mj * (y[i - 2] - y[i]) + (U(y[i], P, mj) * sa * (y[i + 1] - T))) / m # dH/dt (eq.2)
  140.         dydt[i + 1] = -(U(y[i], P, mj) * sa * (y[i + 1] - T)) / (mAlumina * CP_ALUMINA) # dTs/dt eq. (3)
  141.         dmdt = dydt[i] * dpdh(y[i], P) * V # Equation 4b
  142.         mj = mj - dmdt # Equation 4a
  143.  
  144.     return dydt
  145.  
  146.  
  147. y0 = np.copy(np.asarray([H0, Ts0] * n)) #setting up initial condition array (H0,Ts0 and m at all points
  148. y0[0] = H0 # initial fluid bed enthalpy
  149. y0[1] = Ts0 # initial solid bed temperature
  150.  
  151.  
  152. parameters = (n, hIn, min, mAlumina, CP_ALUMINA, sa, V)
  153.  
  154. solution = solve_ivp(my_system, t, y0, args=parameters, method='Radau')
  155.  
  156. h_arr = solution.y[0::2]
  157. Ts_arr = solution.y[1::2]
  158.  
  159. time = solution.t
  160. # dt = 2*(time[2:]-time[:-2])
  161.  
  162. dydt = np.zeros((2 * n, time.size))
  163. for i in range(time.size):
  164.     dydt[:, i] = my_system(t, solution.y[:, i], n, hIn, min, mAlumina, CP_ALUMINA, sa, V)
  165.  
  166. dhdt_arr = dydt[0::2]
  167. dTsdt_arr = dydt[1::2]
  168.  
  169. dmdt_arr = np.zeros_like(dhdt_arr) #change in mass holdup
  170. T_arr = np.zeros_like(dhdt_arr) # fluid temperature
  171. m_hold_arr = np.zeros_like(dhdt_arr) # mass hold up
  172. U_arr = np.zeros_like(dhdt_arr) # heat transfer coefficient array
  173. mj_arr = np.zeros_like(dhdt_arr) # heat transfer coefficient array
  174. x_arr = np.zeros_like(dhdt_arr)
  175.  
  176. for i in range(time.shape[0]): #iteratung through 2D array time x #positions
  177.     for j in range(n): #yep
  178.  
  179.         T = temperature(h_arr[j,i],P)
  180.  
  181.         dmdt_arr[j, i] = dhdt_arr[j, i] * dpdh(h_arr[j, i], P) * V
  182.         T_arr[j,i] = T
  183.         m_hold_arr[j, i] = mass(h_arr[j, i], P)
  184.         U_arr[j,i] = mAlumina*CP_ALUMINA*dTsdt_arr[j,i]/(sa*(T_arr[j,i] - Ts_arr[j,i]))
  185.         #x_arr[j,i] = vapourfraction(h_arr[j,i], P)
  186.  
  187.  
  188. # creating Tf_arr from Ts_arr
  189. Tf_arr = np.zeros_like(dhdt_arr)
  190. Tf_arr = Ts_arr + dTsdt_arr * (mAlumina * CP_ALUMINA) / (U_arr * sa)
  191. # Tf_arr[:, 0] = Ts0  # I.C cannot be calculated as there is no derivative at the boundary. Manually entering here
  192.  
  193. print("simulation complete")
  194.  
  195. ###########################################################
  196. plt.figure()
  197. plt.plot(time,Tf_arr[0, :], '-', color='r' , label="tank 1 Fluid temperature")
  198. plt.plot(time,Tf_arr[1, :], '--', color='r', label="tank 2 Fluid temperature")
  199. plt.plot(time,Tf_arr[2, :], '-.', color='r', label="tank 3 Fluid temperature")
  200. #plt.plot(time,T_arr[3, :], '--', color='b', label="tank 4 Fluid temperature")
  201. #plt.plot(time,T_arr[4, :], '-.', color='b', label="tank 5 Fluid temperature")
  202.  
  203. plt.ylabel(r'Fluid temperature')
  204. plt.xlabel(r'Time')
  205. # plt.ylim((80, 91))
  206. plt.grid('both')
  207. plt.title("Fluid temperature for all tanks")
  208. plt.legend(loc='lower right')
  209.  
  210. ###########################################################
  211. plt.figure()
  212. plt.plot(time,m_hold_arr[0, :], '-', color='b' , label="tank 1 Mass hold up")
  213. plt.plot(time,m_hold_arr[1, :], '--', color='b', label="tank 2 Mass hold up")
  214. plt.plot(time,m_hold_arr[2, :], '-.', color='b', label="tank 3 Mass hold up")
  215. #plt.plot(time,m_hold_arr[3, :], '--', color='b', label="tank 4 Mass hold up")
  216. #plt.plot(time,m_hold_arr[4, :], '-.', color='b', label="tank 5 Mass hold up")
  217.  
  218. plt.ylabel(r'Mass hold up (mol)')
  219. plt.xlabel(r'Time')
  220. # plt.ylim((80, 91))
  221. plt.grid('both')
  222. plt.title("Mass hold up for all tanks")
  223. plt.legend(loc='lower right')
  224.  
  225. ###########################################################
  226. plt.figure()
  227. plt.plot(time,Ts_arr[0, :], '-', color='b' , label="tank 1 Solid Temperature")
  228. plt.plot(time,Ts_arr[1, :], '--', color='b', label="tank 2 Solid Temperature")
  229. plt.plot(time,Ts_arr[2, :], '-.', color='b', label="tank 3 Solid Temperature")
  230. #plt.plot(time,Ts_arr[3, :], '--', color='b', label="tank 4 Solid Temperature")
  231. #plt.plot(time,Ts_arr[4, :], '-.', color='b', label="tank 5 Solid Temperature")
  232.  
  233. plt.ylabel(r'Solid Temperature')
  234. plt.xlabel(r'Time')
  235. # plt.ylim((80, 91))
  236. plt.grid('both')
  237. plt.title("Solid Temperature for all tanks")
  238. plt.legend(loc='lower right')
  239.  
  240. ###########################################################
  241. plt.figure()
  242. plt.plot(time,h_arr[0, :], '-', color='b', label="tank 1 h")
  243. plt.plot(time,h_arr[1, :], '--', color='b', label="tank 2 h")
  244. plt.plot(time,h_arr[2, :], '-.', color='b', label="tank 3 h")
  245. #plt.plot(time,h_arr[3, :], '--', color='b', label="tank 4 mdot")
  246. #plt.plot(time,h_arr[4, :], '-.', color='b', label="tank 5 mdot")
  247.  
  248. plt.ylabel(r'h (J/mol)')
  249. plt.xlabel(r'Time')
  250. # plt.ylim((80, 91))
  251. plt.grid('both')
  252. plt.title("h for all tanks")
  253. plt.legend(loc='lower right')
  254.  
  255. plt.show()
  256.  
Advertisement
Add Comment
Please, Sign In to add comment