def get_flux(self): """ This will calculate the total molar flux by integrating the area between the curve and the CO2 baseline """ # TODO implement more robust void space for labview # from void calculation of 200CCM (060310_flowtest_200_updated.xlsx) flow_ads = self.p.get('flow:rxn') mass = self.p.get('mass:act') # get this in cc Void_Ads = 0.0 Void_Des = 0.037 if self.prompt in [92,93,94]: Void_Ads = 0.037 elif flow_ads > 90 and flow_ads < 110: Void_Ads = 0.116 elif flow_ads > 190 and flow_ads < 210: # Void_Ads = 0.116 Void_Ads = 0.281 # 0.116+0.165 additional losses at higher flow # for the temperature only series, there shouldn't be any void space, right? if self.prompt in range(125,143): Void_Ads = 0.03 co2_mid = [] h2o_mid = [] co2_mid_flux, h2o_mid_flux = [],[] co2_norm_flux = [] dt_time = [] trap = [] simp = [] DT = [] equil_co2 = [] co2_baselines = [] h2o_baselines = [] stages = [ADSORPTION, DESORPTION_P, DESORPTION_T] old_flow = self.c.get('flow:dig')[0] co2 = self.c.get('conc:co2')[0]/100 # correct for mass flow meter correction with CO2 flows = old_flow / ((1- co2) + co2 / 1.1717) self.c.add('flow:act', flows, 'Flow (sccm)') VOID = [Void_Ads, Void_Des, 0] # print VOID for i, stage in enumerate(stages): old_time = self.c.get('time:sec',stage)[0] co2 = self.c.get('conc:co2',stage)[0]/100 water = self.c.get('conc:h2o',stage)[0]/100 flow = self.c.get('flow:act',stage)[0] # if length is 0, add one so we don't crap out the integration if len(co2) == 0: co2_mid.append(0.000001) co2_norm_flux.append(np.array([0,0],float)) co2_mid_flux.append(np.array([0,0],float)) h2o_mid.append(0.000001) h2o_mid_flux.append(np.array([0,0],float)) trap.append(0.0000001) simp.append(0.0000001) equil_co2.append(-1) DT.append(-1) h2o_baselines.append(np.array([0,0],float)) co2_baselines.append(np.array([0,0],float)) dt_time.append(np.array([0,0],float)) continue # set all timesteps as constant (5s) in order to plot Desorption P & T swing together dt = 5.0 #time = np.linspace(old_time[0], old_time[-1], len(old_time)) time = np.arange(old_time[0], old_time[-1], dt) # interpolate each curve to match time co2 = np.interp(time, old_time, co2) water = np.interp(time, old_time, water) flow = np.interp(time, old_time, flow) DT.append(time[1] - time[0]) #print 'dt for this calculation is: ', dt # Flow Calculations # correct for water in stream (recorded on dry basis flow = flow * 1 / (1 - water) flow_equil = flow[-5:].mean() # determine equilibrium co2 and water values h2o_equil = water[-5:].mean() if stage == 1: # or stage == 4: co2_equil = max(0.0,co2[-7:-2].mean()) # Define special desorption cases (10%) else: # this does not always go down to zero # co2_equil = max(0.0,self.c.get('conc:co2',stage=6)[0][-7:-2].mean()) co2_equil = self.p.get('co2:des') # Define baseline curve based on co2_baseline = np.ones(len(co2)) * co2_equil h2o_baseline = np.ones(len(co2)) * h2o_equil # Calc moles on a kg basis (mol / kg), so divide by mass to get total capacity # TODO fix this based on flow diagram #print 'flow rate is ', flow_equil #print 'Amount (ccm) of CO2 in stream is ', co2_equil #print 'flow is ', flow[-10] #print 'Amount close to end ', co2[-2] # 24.66 is if stage == 1: co2_calc = abs(flow * co2 - flow_equil * co2_baseline) / 60 / 24.66 else: co2_calc = (flow * co2 - flow_equil * co2_baseline) / 60 / 24.66 if co2_calc.any() < 0: print 'CO2 integration is less than zero, check it out' co2_calc[co2_calc < 0] = 0.00001 h2o_calc = abs(flow * water - flow_equil * h2o_baseline) / 60 / 24.66 # correct for mass of sample if self.p.has_key('mass:act'): co2_calc = co2_calc / self.p.get('mass:act') h2o_calc = h2o_calc / self.p.get('mass:act') flux_co2, mid_co2 = analysis.midpoint(time, co2_calc) flux_h2o, mid_h2o = analysis.midpoint(time, h2o_calc) # Calculation Results (for params) co2_mid.append(mid_co2) h2o_mid.append(mid_h2o) trap.append(analysis.trapezoid(time, co2_calc)) simp.append(analysis.simpson(time, co2_calc)) equil_co2.append(co2_equil) # curve composition co2_mid_flux.append(flux_co2) h2o_mid_flux.append(flux_h2o) co2_baselines.append(co2_baseline * 100) h2o_baselines.append(h2o_baseline * 100) dt_time.append(time) # TODO reinterpolate fluxes back to realtime co2_norm_flux.append(np.interp(old_time, time, flux_co2)) # print stage, 'completed' self.__check__('stage' , stage) self.__check__('midpoint : ' , co2_mid[i]) self.__check__('trapezoid : ' , trap[i]) self.__check__('simpson : ' , simp[i]) # In order to make the correction appear correct on the curves, we apply a gain to the entire curve in the stage of interest so that the integral over the total area is adjusted for our correction. An alternate method would be to take away the values at the beginning only, which makes the curve look odd # TODO see if the void space correction should be applied to the molar # amount of CO2 and not the capacity value mid_void = [max(co2_mid[0]-Void_Ads,0.000001), max(co2_mid[1]-Void_Des,0.000001), co2_mid[2]] mid_correction = [mid_void[i] / co2_mid[i] * co2_norm_flux[i] for i in range(3)] # Assign Curves self.c.compose('flux:dt:co2', co2_mid_flux , stages, 'Molar Flow (mol/kg*s)') # Reinterpolated flux values (to work with time:hr) self.c.compose('flux:co2', co2_norm_flux , stages, 'Molar Flow (mol/kg*s)') self.c.compose('flux:c:co2', mid_correction , stages, 'Molar Flow (mol/kg*s)') self.c.compose('conc:co2:baseline', co2_baselines, stages, 'Concentration (mol %)') self.c.compose('flux:h2o', h2o_mid_flux , stages, 'Molar Flow (mol/kg*s)') self.c.compose('conc:h2o:baseline', h2o_baselines, stages, 'Concentration (mo %)') # need a special normalized time to plot all these self.c.compose('time:dt:sec', dt_time, stages, 'Time (s)') self.c.compose('time:dt:hr', [i / 3600. for i in dt_time], stages, 'Time (hr)') # Save values in params self.p.set('cap:ads_mid', co2_mid[0]) self.p.set('cap:des_mid', co2_mid[1] + co2_mid[2]) self.p.set('cap:desp_mid', co2_mid[1]) self.p.set('cap:dest_mid', co2_mid[2]) self.p.set('capc:ads_mid' , mid_void[0]) self.p.set('capc:des_mid' , mid_void[1] + mid_void[2]) self.p.set('capc:desp_mid' , mid_void[1]) self.p.set('capc:dest_mid' , mid_void[2]) # self.p.set('cap:ads_trap', trap[0]) # self.p.set('cap:des_trap', trap[1] + trap[2]) # self.p.set('cap:desp_trap', trap[1]) # self.p.set('cap:dest_trap', trap[2]) # self.p.set('capc:ads_trap' , trap[0] - Void_Ads) # self.p.set('capc:des_trap' , trap[1] + trap[2] - Void_Des) # self.p.set('capc:desp_trap' , trap[1] - Void_Des) # self.p.set('capc:dest_trap' , trap[2]) # self.p.set('cap:ads_simp', simp[0]) # self.p.set('cap:des_simp', simp[1] + simp[2]) # self.p.set('cap:desp_simp', simp[1]) # self.p.set('cap:dest_simp', simp[2]) # self.p.set('capc:ads_simp' , simp[0] - Void_Ads) # self.p.set('capc:des_simp' , simp[1] + simp[2] - Void_Des) # self.p.set('capc:desp_simp' , simp[1] - Void_Des) # self.p.set('capc:dest_simp' , simp[2]) self.p.set('cap:ads_h2o_mid', h2o_mid[0]) self.p.set('cap:des_h2o_mid', h2o_mid[1] + h2o_mid[2]) self.p.set('cap:desp_h2o_mid', h2o_mid[1]) self.p.set('cap:dest_h2o_mid', h2o_mid[2]) self.p.set('co2:equil', equil_co2) self.p.set('dt', DT)
def get_flux(self): """ This will calculate the total molar flux by integrating the area between the curve and the CO2 baseline """ Void = self._params.get('Void') FlowRxn = self._params.get('flow:rxn') FlowIn = self._params.get('flow:in') Flows = [FlowRxn*0.9, FlowIn, FlowIn] mid = [] trap = [] simp = [] h2o_mid = [] stages = [ADSORPTION, DESORPTION_P, DESORPTION_T] for i, stage in enumerate(stages): time = self._curves.get('time:sec',stage)[0] co2 = self._curves.get('raw:co2',stage)[0]/100 water = self._curves.get('raw:h2o',stage)[0]/100 n2 = 1 - co2 - water flow = Flows[i] / n2 if len(co2) == 0: mid.append([np.array([0,0],float),0.000001]) trap.append(0.0000001) simp.append(0.0000001) h2o_mid.append([np.array([0,0],float),0.000001]) continue # determine equilibrium water and co2 values co2_init = co2[:2].mean() co2_finish = co2[-10:].mean() h2o_init = water[:2].mean() h2o_finish = water[-10:].mean() #co2_equil = max(co2_init, co2_finish) #h2o_equil = max(h2o_init, h2o_finish) flow_finish = Flows[i] / np.mean(n2[-5:]) if stage == 1: co2_baseline = np.ones(len(co2))* co2_finish #elif stage == 2: #co2_baseline = np.ones(len(co2)) * co2_init #water_baseline = np.ones(len(water)) * water_init #elif stage == 4: #co2_baseline = np.ones(len(co2)) * co2_finish #water_baseline = np.ones(len(water)) * water_finish else: co2_baseline = np.zeros(len(co2)) water_baseline = np.linspace(h2o_init, h2o_finish, len(water)) # TODO Assert error if large difference between initial and finish per_dif = abs(co2_init - co2_finish) / (1+co2_finish) if per_dif > 1.1: print 'Large variance between inital and final values of CO2 \n Difference = %s' % per_dif # Calc moles on a kg basis (mol / kg), so divide by mass to get total capacity calc = abs(flow * co2 - flow_finish * co2_baseline) / 60 / 24.66 h2o = abs(flow * water - flow_finish * water_baseline) / 60 / 24.66 #if i == 0: #calc = flow * (co2_baseline - co2) / 60 / 24.66 #h2o = flow * (water - h2o_equil) / 60 / 24.66 #else: #calc = flow * (co2) / 60 / 24.66 #h2o = flow * (water - h2o_equil) / 60 / 24.66 # if we are somehow getting negative fluxes calc[calc < 0] = 0 # correct for mass of sample if self._params.has_key('mass:act'): calc = calc / self._params.get('mass:act') mid.append(analysis.midpoint(time, calc)) trap.append(analysis.trapezoid(time, calc)) simp.append(analysis.simpson(time, calc)) h2o_mid.append(analysis.midpoint(time, h2o)) self.__check__('stage' , stage) self.__check__('midpoint : ' , mid[i][1]) self.__check__('trapezoid : ' , trap[i]) self.__check__('simpson : ' , simp[i]) # In order to make the correction appear correct on the curves, we apply a gain to the entire curve in the stage of interest so that the integral over the total area is adjusted for our correction. An alternate method would be to take away the values at the beginning only, which makes the curve look odd mid_flux = [i[0] for i in mid] mid1, mid2, mid3 = [i[1] for i in mid] mid_sum = [i[1] for i in mid] mid_sum_correction = [mid1-Void, mid2-Void, mid3] mid_gain = [mid_sum_correction[i] / mid_sum[i] for i in range(3)] for j, i in enumerate(mid_gain): if i < 0: mid_gain[j] = 0.01 mid_correction = [mid_gain[i] * mid_flux[i] for i in range(3)] h2o_mid_flux = [i[0] for i in h2o_mid] #h2o_mid1, h2o_mid2, h2o_mid3 = [i[1] for i in h2o_mid] h2o_mid_sum = [i[1] for i in h2o_mid] #h2o_mid_sum_correction = [h2o_mid1-Void, h2o_mid2-Void, h2o_mid3] #h2o_mid_gain = [h2o_mid_sum_correction[i] / h2o_mid_sum[i] for i in range(3)] #h2o_mid_correction = [h2o_mid_gain[i] * h2o_mid_flux[i] for i in range(3)] # Assign Curves self._curves.compose('flux', mid_flux , stages, 'Molar Flow / mol kg$^{-1}$s$^{-1}$') self._curves.compose('flux:corr', mid_correction , stages, 'Molar Flow / mol kg$^{-1}$s$^{-1}$') self._curves.compose('flux:h2o', h2o_mid_flux , stages, 'Molar Flow / mol kg$^{-1}$s$^{-1}$') # Save values in params # # TODO iterate over values to make more streamlined self._params.set('cap:ads_h2o_mid', h2o_mid_sum[0]) self._params.set('cap:des_h2o_mid', h2o_mid_sum[1] + h2o_mid_sum[2]) self._params.set('cap:desp_h2o_mid', h2o_mid_sum[1]) self._params.set('cap:dest_h2o_mid', h2o_mid_sum[2]) self._params.set('cap:ads_mid', mid_sum[0]) self._params.set('cap:des_mid', mid_sum[1] + mid_sum[2]) self._params.set('cap:desp_mid', mid_sum[1]) self._params.set('cap:dest_mid', mid_sum[2]) self._params.set('capc:ads_mid' , mid_sum_correction[0]) self._params.set('capc:des_mid' , mid_sum_correction[1] + mid_sum_correction[2]) self._params.set('capc:desp_mid' , mid_sum_correction[1]) self._params.set('capc:dest_mid' , mid_sum_correction[2]) self._params.set('cap:ads_trap', trap[0]) self._params.set('cap:des_trap', trap[1] + trap[2]) self._params.set('cap:desp_trap', trap[1]) self._params.set('cap:dest_trap', trap[2]) self._params.set('capc:ads_trap' , trap[0] - Void) self._params.set('capc:des_trap' , trap[1] + trap[2] - Void) self._params.set('capc:desp_trap' , trap[1] - Void) self._params.set('capc:dest_trap' , trap[2]) self._params.set('cap:ads_simp', simp[0]) self._params.set('cap:des_simp', simp[1] + simp[2]) self._params.set('cap:desp_simp', simp[1]) self._params.set('cap:dest_simp', simp[2]) self._params.set('capc:ads_simp' , simp[-1] - Void) self._params.set('capc:des_simp' , simp[1] + simp[2] - Void) self._params.set('capc:desp_simp' , simp[1] - Void) self._params.set('capc:dest_simp' , simp[2])