Example #1
7
    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)
Example #2
0
File: pfr.py Project: ralesi/rex
    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])