Пример #1
0
        // Given the pressure, P, and the mole fraction of THIS sorbate in the
        // gas phase, YA, returns the selectivity of THIS sorbate vs sorbate B.
        public double selectivity(Isotherm B, double P, double YA)
        {
            double XA = x(B, P, YA);
            double XB = 1 - XA;
            double YB = 1 - YA;

            return(((XA) / (YA)) / ((XB) / (YB)));
        }
Пример #2
0
        public void getN_forEachComponent(Isotherm B, double P, double YA, out double NA, out double NB)
        {
            double XA, XB, YB;

            get_SorbedAndBulkMoleRatios_fromYA(B, P, YA, out XA, out YB, out XB);
            double NA_stp   = n(P * YA / XA);
            double NB_stp   = B.n(P * YB / XB);
            double Ntot_stp = (NA_stp * NB_stp) / (NB_stp * XA + NA_stp * XB);

            NA = XA * Ntot_stp;
            NB = XB * Ntot_stp;
        }
Пример #3
0
        // Given a pressure, P, the mole fraction of sorbate A (THIS sorbate) in the
        // gas phase, X_A the mole fraction of sorbate A (THIS sorbate) in the sorbed
        // phase, Y_A, and isotherm model for species B, spreading_pressure_diff()
        // calculates the difference in spreading pressure between species A (the
        // species for THIS isotherm) & B.
        double spreading_pressure_diff(
            Isotherm B,       // isotherm for species B
            double P,         // pressure
            double X_A,       // mole fraction of sorbate A in the gas phase
            double Y_A        // mole fraction of sorbate A in the sorbed phase
            )
        {
            double spreadingPressure_A = pi(P * Y_A / X_A);
            double spreadingPressure_B = B.pi(P * (1.0 - Y_A) / (1.0 - X_A));

            return(spreadingPressure_B - spreadingPressure_A);
        }
Пример #4
0
        // Qst( A_T1, A_T2, n ) returns the heat of adsorption associated with a molar uptake, n, given two isotherms
        // for a single species, recorded at temperatures T1 and T2
        public static double Qst(Isotherm Isotherm_T1, Isotherm Isotherm_T2, double n)
        {
            const double R = .008314462175;  // kJ/(mol*K)

            double P1 = Isotherm_T1.P(n);
            double T1 = Isotherm_T1.temp;

            double P2 = Isotherm_T2.P(n);
            double T2 = Isotherm_T2.temp;

            double numerator = -R *Math.Log(P2 / P1);

            double denominator = (T1 - T2) / (T1 * T2);

            return(numerator / denominator);
        }
Пример #5
0
 public void get_SorbedAndBulkMoleRatios_fromYA(Isotherm B, double P, double YA, out double XA, out double YB, out double XB)
 {
     XA = x(B, P, YA);
     XB = 1 - XA;
     YB = 1 - YA;
 }
Пример #6
0
        // Given a pressure, P, the mole fraction of sorbate A in the sorbed phase, Y_A, and
        // isotherm model for species B, x() narrows in on a gas phase mole fraction for sorbate
        // A (THIS sorbate), X_A, accurate to the limits of machine precision.
        double x(
            Isotherm B,       // isotherm for species B
            double P,         // pressure
            double Y_A        // mole fraction of sorbate A in the sorbed phase
            )
        {
            // Bracket the root
            double x    = 0;
            double lo_x = 1E-14;        // 0 + dx
            double hi_x = 1.0 - 1E-14;  // 1 - dx


            const double STEPS = 100;
            // factor will invert the value of the spreading pressure difference
            // function in the event that the values start out negative and go
            // positive.
            double factor = ((spreading_pressure_diff(B, P, lo_x, Y_A) >= 0)?(1.0):(-1.0));


            if (factor * spreading_pressure_diff(B, P, hi_x, Y_A) > 0)
            {
                bool foundInterval = false;
                for (int dx = 1; dx < 100; dx++)
                {
                    double diff = factor * spreading_pressure_diff(B, P, dx * 0.01 * (hi_x - lo_x), Y_A);
                    if (diff <= 0)
                    {
                        foundInterval = true;
                        hi_x          = dx * 0.01;
                    }
                }
                if (!foundInterval)
                {
                    throw(new System.Data.ConstraintException("No equilibrium condition found for pressure " + P));
                }
            }

            // Test values of x in range (0,1 (or hi_x)) until the sign changes.
            //
            // (We are looking for a root and are trying to find the X_A
            // value where the difference in the spreading pressure for A & B
            // is 0, i.e. the equilibrium point.)
            //
            // Each time the sign changes, test values of x in the range of x
            // just before the sign of delta_of_spreading_pressure (spDiff)
            // changed, and the x that caused the spDiff sign to change.
            // We will narrow this testing region by a factor of 'steps' a
            // total of MAX_ITER times.

            const int MAX_ITER = 10;

            for (int j = 0; j < MAX_ITER; j++)
            {
                int    i      = 0;
                double spDiff = factor * spreading_pressure_diff(B, P, lo_x, Y_A);

                // Go until we've reached "steps" iterations or until spDiff
                // changes sign.
                while (i <= STEPS && spDiff > 0)
                {
                    x      = lo_x + (hi_x - lo_x) * (double)(i) / (double)(STEPS);
                    spDiff = factor * spreading_pressure_diff(B, P, x, Y_A);
                    i++;
                }

                lo_x = lo_x + (hi_x - lo_x) * (double)(i - 2) / (double)(STEPS);
                hi_x = x;
            }

            double mid_x = (lo_x + hi_x) / 2.0;

            double lo  = Math.Abs(spreading_pressure_diff(B, P, lo_x, Y_A));
            double mid = Math.Abs(spreading_pressure_diff(B, P, mid_x, Y_A));
            double hi  = Math.Abs(spreading_pressure_diff(B, P, hi_x, Y_A));

            if (lo < mid)
            {
                if (lo < hi)
                {
                    return(lo_x);
                }
            }
            else
            {
                if (mid < hi)
                {
                    return(mid_x);
                }
            }

            return(hi_x);
        }