Advertisement
EditorRUS

TG Atmos simulation

Oct 9th, 2015
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.96 KB | None | 0 0
  1. import turtle
  2. from math import floor
  3. from time import perf_counter
  4.  
  5. G = dict(P=0.0,O2=0.0,CO2=0.0)
  6. C = dict(P=200.0,O2=20.0,CO2=30.0)
  7. T = 0.0
  8. last_results = []
  9.  
  10. MHC = 0.0003
  11. PUT = 1370+273.15
  12. PMBT = 100+273.15
  13. POFB = 10.0
  14. FPER = 3000000.0
  15.  
  16. def heat_capacity():
  17.     return G["P"]*C["P"]+G["O2"]*C["O2"]+G["CO2"]*C["CO2"]
  18.  
  19. def energy():
  20.     return heat_capacity()*T
  21.  
  22. tick = 0
  23. plotting = turtle.Turtle(visible=False)
  24. turtle.tracer(None, None)
  25.  
  26. def zburn():
  27.     global G,T,tick
  28.  
  29.     tick = 0
  30.     the_process = []
  31.        
  32.     while (True):
  33.         fuel_burnt = 0
  34.         energy_released = 0
  35.         old_heat_capacity = heat_capacity()
  36.         if (G["P"] > MHC):
  37.             PBR = 0
  38.             OBR = 0
  39.             TS = 0
  40.             if (T > PUT):
  41.                 TS = 1
  42.             else:
  43.                 TS = (T-PMBT)/(PUT-PMBT)            
  44.             if (TS >= 0.0):
  45.                 OBR = 1.4 - TS
  46.                 if (G["O2"] > G["P"]*POFB):
  47.                     PBR = 0.25 * G["P"] * TS
  48.                 else:
  49.                     PBR = 0.25 * TS * (G["O2"] / POFB)
  50.                 if (PBR > MHC):
  51.                     G["P"] -= PBR
  52.                     G["O2"] -= PBR*OBR
  53.                     G["CO2"] += PBR
  54.                     energy_released += FPER*PBR
  55.                     fuel_burnt += PBR*(1+OBR)
  56.             if (energy_released > 0):
  57.                 NHC = heat_capacity()
  58.                 if (NHC > MHC):
  59.                     T = (T*old_heat_capacity + energy_released) / NHC
  60.                     the_process.append([G["P"], G["O2"], G["CO2"], T, energy_released])
  61.         if (fuel_burnt > 0):
  62.             tick += 1
  63.             continue
  64.         return the_process
  65.    
  66.  
  67. PFLAG = 1<<0
  68. OFLAG = 1<<1
  69. CFLAG = 1<<2
  70. TFLAG = 1<<3
  71. E0FLAG = 1<<4
  72. E1FLAG = 1<<5
  73. DFLAG = 1<<6
  74. PLOTFLAG = 1<<7
  75.  
  76. def make_sim(p0,o0,t,modes, give_process=0,c2=0):
  77.     global T,G,tick,last_results
  78.     G = dict(P=p0,O2=o0,CO2=c2)
  79.     T = float(t)
  80.     energy0 = energy()
  81.  
  82.     if (modes & PFLAG):
  83.         print(round(G["P"], 3), 'mol', end='')
  84.     if (modes & OFLAG):
  85.         print(' :', end=' ')
  86.         print(round(G["O2"], 3), 'mol', end='')
  87.     if (modes & E0FLAG):
  88.         print(' :', end=' ')
  89.         print(floor(energy0), 'J', end='')
  90.     last_results += G["P"], G["O2"], energy0
  91.     the_process = zburn()
  92.     if (modes and modes != PLOTFLAG): print(' --> ', end='')
  93.     if (modes & CFLAG):
  94.         print(round(G["CO2"], 3), 'mol', end='')
  95.     if (modes & TFLAG):
  96.         print(' :', end=' ')
  97.         print(round(T, 3), 'K', end='')
  98.     if (modes & E1FLAG):
  99.         print(' :', end=' ')
  100.         print(floor(energy()-energy0), 'J', end='')
  101.     if (modes & DFLAG):
  102.         print(' :', end=' ')
  103.         print(tick/2, 'seconds (normal conditions)', end='')
  104.     if (modes & PLOTFLAG):
  105.         maxTemp = 0
  106.         for tick in range(len(the_process)):
  107.             if the_process[tick][3] > maxTemp:
  108.                 maxTemp = the_process[tick][3]
  109.         turtle.setworldcoordinates(0, 0, len(the_process), maxTemp)
  110.         turtle.penup()
  111.         turtle.goto(0, t)
  112.         turtle.pendown()
  113.         for tick in range(len(the_process)):
  114.             turtle.goto(tick, the_process[tick][3])
  115.     last_results += G["CO2"], T, energy()-energy0, tick
  116.     if (give_process):
  117.         return the_process
  118.  
  119. TMODE = 1<<0
  120. EMODE = 1<<1
  121. SPMODE = 1<<2
  122. SNMODE = 1<<3
  123.  
  124. def find_ideal_ratio_for (mode, t=393.15, pconst=10, oupconst=1000):
  125.     global last_results
  126.     des_val = 0
  127.     ideal_ratio = 0
  128.     if (mode in (TMODE, EMODE)):
  129.         for x in range(oupconst):
  130.             curO2 = pconst*x/oupconst
  131.             make_sim(pconst, curO2, t, 0)
  132.             cur_val = 0
  133.             if (mode == TMODE): cur_val = last_results[4]
  134.             if (mode == EMODE): cur_val = last_results[5]
  135.             if (cur_val > des_val):
  136.                 ideal_ratio = curO2 / (curO2+pconst)
  137.                 des_val = cur_val
  138.             last_results = []
  139.     if (mode in (SPMODE, SNMODE)):
  140.         if (mode == SNMODE): des_val = 9e40
  141.         for x in range(15*pconst): #Getting higher than 1:15 is silly
  142.             curO2 = pconst*x/15
  143.             make_sim(pconst, curO2, t, 0)
  144.             cur_val = last_results[6]
  145.             if (mode == SNMODE):
  146.                 if (cur_val < des_val and cur_val != 0):
  147.                     ideal_ratio = curO2 / (curO2+pconst)
  148.                     des_val = cur_val
  149.             if (mode == SPMODE):
  150.                 if (cur_val > des_val and cur_val != 0):
  151.                     ideal_ratio = curO2 / (curO2+pconst)
  152.                     des_val = cur_val
  153.             last_results = []
  154.     print ('Ideal ratio is ', round(100*(1-ideal_ratio), 3), '%:', round(100*ideal_ratio, 3),'%', sep='')
  155.     print ('Desired value achieved:', floor(des_val))
  156.  
  157. def find_var(var):
  158.     if (var.upper() == "N"):
  159.         # 8.31 = pV / nT
  160.         # 1/8.31 = nT / pV
  161.         # pV / 8.31T
  162.         # p = 8.3nT / V
  163.         print ("p V T")
  164.     if (var.upper() == "P"):
  165.         print ("n T V")
  166.  
  167.     args = input()
  168.     args = args.split(",")
  169.  
  170.     for x in range(len(args)):
  171.         args[x] = float(args[x])
  172.        
  173.     if (var.upper() == "N"):
  174.         return (args[0] * args[1]) / (8.31 * args[2])
  175.     if (var.upper() == "P"):
  176.         return (8.31 * args[0] * args[1]) / args[2]
  177.  
  178. ONEATMOS = 101.325
  179.  
  180. def simulate_explosion(p0, t0, cp0, p1, t1, give_results=0, verbose=1, debug=0):
  181.     results = []
  182.     RAmt = 70*p0 / (8.31*t0)
  183.     PAmt = RAmt*cp0
  184.     CAmt = RAmt-PAmt
  185.     OAmt = 70*p1 / (8.31*t1)
  186.     # Merging this shit together
  187.     C0 = 200*PAmt + 30*CAmt
  188.     C1 = 20*OAmt
  189.     C2 = C0+C1
  190.     E0 = C0*t0
  191.     E1 = C1*t1
  192.     E2 = E0+E1
  193.     simul = list()
  194.     # E = CnT
  195.     T = E2 / C2
  196.     amt1 = RAmt+OAmt
  197.     p1 = 8.31*amt1*T / 140
  198.     if verbose:
  199.         print("Merging temp:     ", T)
  200.         print("Merging pressure: ", p1)
  201.     if (T > PMBT):
  202.         simul = make_sim(PAmt, OAmt, T, 0, 1, CAmt)
  203.     ft = 0
  204.     td = 0
  205.     p2 = p1
  206.     integrity = 3
  207.     for data in simul:
  208.         amt2 = data[0]+data[1]+data[2]
  209.         t2   = data[3]
  210.         p2   = 8.31*amt2*t2 / 140
  211.         if (p2 > 50*ONEATMOS):
  212.             ft += 3
  213.             break
  214.         elif (p2 > 40*ONEATMOS):
  215.             if (integrity <= 0):
  216.                 if verbose:
  217.                     print('Tank will rupture without explosion after {0} seconds'.format(td))
  218.                 return False
  219.             else:
  220.                 integrity -= 1
  221.         elif (p2 > 30*ONEATMOS):
  222.             if (integrity <= 0):
  223.                 if verbose:
  224.                     print('Tank will leak without explosion after {0} seconds'.format(td))
  225.                 return False
  226.             else:
  227.                 integrity -= 1
  228.         elif (integrity < 3):
  229.             integrity += 1
  230.         ft  += 1
  231.         td  += 0.5
  232.     ft = max(min(len(simul)-1, ft), 0)
  233.     if (ft):
  234.         EMD = simul[ft] # Explosion Moment Data
  235.         if verbose:
  236.             print("EMD:")
  237.             print("Plasma:           ", EMD[0])
  238.             print("Oxygen:           ", EMD[1])
  239.             print("CO2:              ", EMD[2])
  240.             print("T:                ", EMD[3])
  241.         amt2 = EMD[0]+EMD[1]+EMD[2]
  242.         t2  = EMD[3]
  243.         p2 = 8.31*amt2*t2 / 140
  244.         radius = (p2-50*ONEATMOS)/(10*ONEATMOS)
  245.         results.append(radius)
  246.         results.append(floor(td))
  247.         if verbose:
  248.             print(floor(0.25*radius), floor(0.5*radius), floor(radius), sep=', ')
  249.             print("Will explode after {0} seconds".format(td))
  250.         if (give_results):
  251.             return results
  252.         return True
  253.     if verbose:
  254.         print("Won\'t explode")
  255.     return False
  256.  
  257. def perform_cross_simulation(pw, pt, o2t, res=10):
  258.     st = perf_counter()
  259.    
  260.     cold_gas_maxamt = 70*10*ONEATMOS / (8.31*293.15)
  261.     hot_plsm_maxamt  = 70*10*ONEATMOS / (8.31*pt)
  262.     cold_gas_mult   = cold_gas_maxamt / res
  263.     hot_plsm_mult    = hot_plsm_maxamt / res
  264.  
  265.     co2mult = 30*(1-pw)
  266.     plsmmult = 200*pw
  267.     mixmult = co2mult+plsmmult
  268.  
  269.     cold_energy_mult = 293.15*200
  270.     hot_energy_mult = pt*mixmult
  271.  
  272.     bHPAmt = 0
  273.     bCPAmt = 0
  274.     bO2Amt = 0
  275.     bTemp  = 0
  276.     bRad   = 0
  277.     bTime  = 0
  278.    
  279.     for cold_plsm_iter in range(1, res+1):
  280.         cold_plsm_amt = cold_gas_mult*cold_plsm_iter
  281.         actual_cold_energy = cold_plsm_amt * cold_energy_mult
  282.         for hot_plsm_iter in range(1, res+1):
  283.             hot_plsm_amt = hot_plsm_mult*hot_plsm_iter
  284.             actual_hot_energy = hot_plsm_amt * hot_energy_mult
  285.             merging_temp = (actual_hot_energy + actual_cold_energy) / (hot_plsm_amt * mixmult + 200 * cold_plsm_amt)
  286.             merging_pres = 8.31 * (hot_plsm_amt+cold_plsm_amt) * merging_temp / 70
  287.             if (merging_pres > 10*ONEATMOS):
  288.                 break
  289.             for cold_oxygen_iter in range(1, res+1):
  290.                 cold_oxygen_amt = cold_gas_mult*cold_oxygen_iter
  291.                 oxygen_pres = 8.31*cold_oxygen_amt*o2t / 70
  292.                 actual_pw = (cold_plsm_amt+(hot_plsm_amt*pw)) / (cold_plsm_amt+hot_plsm_amt)
  293.                 result = simulate_explosion(merging_pres, merging_temp, actual_pw, oxygen_pres, o2t, 1, 0)
  294.                 if result:
  295.                     if result[0] > bRad:
  296.                         bHPAmt = hot_plsm_amt
  297.                         bTemp  = merging_temp
  298.                         bCPAmt = cold_plsm_amt
  299.                         bO2Amt = cold_oxygen_amt
  300.                         bRad = result[0]
  301.                         bTime = result[1]
  302.     bHPAmt = 8.31 * (bCPAmt+bHPAmt)*bTemp / 70
  303.     bCPAmt = 8.31 * bCPAmt * 293.15 / 70
  304.     bO2Amt = 8.31 * bO2Amt * o2t / 70
  305.     print("Statistics:")
  306.     print("Cold Plasma Pressure: {0}\nHot Plasma Pressure: {1}\nO2 Pressure: {2}\nTemp.: {3}".format(bCPAmt, bHPAmt, bO2Amt, bTemp))
  307.     print("Expected radius:")
  308.     print("{0} {1} {2}".format(floor(0.25*bRad), floor(0.5*bRad), floor(bRad)))
  309.     print("True radius:")
  310.     print(bRad)
  311.     print("Will take {0} seconds before explosion".format(bTime))
  312.     print(perf_counter() - st)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement