Exemplo n.º 1
0
        public void CanSolveMaxProblem()
        {
            var problem = new EquationSystem();
            var x1      = new Variable("x1", 10);

            problem.AddVariables(x1);
            problem.AddConstraints((Sym.Max(x1, 5)).IsEqualTo(25));
            var solver = new Newton();

            solver.Solve(problem);
            Assert.AreEqual(25, x1.ValueInSI, 1e-5);
            Assert.AreEqual(true, solver.IsConverged);
        }
Exemplo n.º 2
0
        public void Test_MinMax()
        {
            var x = new Variable {
                Name = "x", ValueInSI = 3
            };
            var y = new Variable {
                Name = "y", ValueInSI = 6
            };

            var eval = new Evaluator();

            Assert.AreEqual(3, Sym.Min(x, y).Eval(eval), 1e-5);
            Assert.AreEqual(6, Sym.Max(x, y).Eval(eval), 1e-5);
        }
Exemplo n.º 3
0
        public void CanSolveMinMaxProblem()
        {
            var problem = new EquationSystem();
            var x1      = new Variable("x1", 0);
            var x2      = new Variable("x2", 6);
            var x3      = new Variable("x3", 25);

            problem.AddVariables(x2);
            problem.AddConstraints((Sym.Max(x1, Sym.Min(x2, x3))).IsEqualTo(5));
            var solver = new Newton();

            solver.Solve(problem);
            Assert.AreEqual(5, x2.ValueInSI, 1e-5);
            Assert.AreEqual(true, solver.IsConverged);
        }
        /// <summary>
        /// Creates a new instance of the liquid phase activity coefficient calculation object
        /// </summary>
        /// <param name="sys">Thermodynamic system to take parameters from</param>
        /// <param name="T">Temperature variable</param>
        /// <param name="x">Vector of composition variables (molar fractions)</param>
        /// <param name="idx">Index of the active variables to calculate for</param>
        public ActivityCoefficientUNIQUAC(ThermodynamicSystem sys, Variable T, List <Variable> x, int idx)
        {
            Symbol  = "UNIQUAC_GAMMA";
            _system = sys;
            index   = idx;
            //Bind variables to this instance
            this.T = T;
            this.x = x;
            Parameters.Add(T);
            foreach (var comp in x)
            {
                Parameters.Add(comp);
            }
            NC  = _system.Components.Count;
            tau = new Expression[NC, NC];

            int i = index;

            var parameterSet = _system.BinaryParameters.FirstOrDefault(ps => ps.Name == "UNIQUAC");

            if (parameterSet == null)
            {
                throw new ArgumentNullException("No UNIQUAC parameters defined");
            }

            double[,] a = parameterSet.Matrices["A"];
            double[,] b = parameterSet.Matrices["B"];
            double[,] c = parameterSet.Matrices["C"];
            double[,] d = parameterSet.Matrices["D"];
            double[,] e = parameterSet.Matrices["E"];

            for (int ii = 0; ii < NC; ii++)
            {
                for (int j = 0; j < NC; j++)
                {
                    tau[ii, j] = Sym.Exp(a[ii, j] + b[ii, j] / T + c[ii, j] * Sym.Ln(T) + d[ii, j] * T + e[ii, j] / Sym.Pow(T, 2));
                }
            }
            Expression lnGamma     = 0.0;
            Expression lnGammaComb = 0.0;
            Expression lnGammaRes  = 0.0;
            Expression Vi          = 0;
            Expression Fi          = 0;
            Expression FiP         = 0;
            Expression Sxl         = 0;

            var ri  = _system.Components.Select(co => co.GetParameter(MethodTypes.Uniquac, "R").ValueInSI).ToList();
            var qi  = _system.Components.Select(co => co.GetParameter(MethodTypes.Uniquac, "Q").ValueInSI).ToList();
            var qpi = _system.Components.Select(co => co.GetParameter(MethodTypes.Uniquac, "Q'").ValueInSI).ToList();

            double[] li = new double[NC];
            for (int j = 0; j < NC; j++)
            {
                li[j] = 5 * (ri[j] - qi[j]) - (ri[j] - 1);
            }

            Vi  = ri[i] * x[i] / Sym.Sum(0, NC, (j) => ri[j] * x[j]);
            Fi  = qi[i] * x[i] / Sym.Sum(0, NC, (j) => qi[j] * x[j]);
            FiP = qpi[i] * x[i] / Sym.Sum(0, NC, (j) => qpi[j] * x[j]);

            //Sxl = Sym.Sum(0, NC, (j) => (5 * (_system.Components[j].GetParameter(MethodTypes.Uniquac, "R").ValueInSI - _system.Components[j].GetParameter(MethodTypes.Uniquac, "Q").ValueInSI) - (_system.Components[j].GetParameter(MethodTypes.Uniquac, "R").ValueInSI - 1)) * x[j]);

            lnGammaComb = Sym.Ln(Vi / Sym.Max(1e-10, x[i])) + 5 * qi[i] * Sym.Ln(Fi / Vi) + li[i] - Vi / Sym.Max(1e-10, x[i]) * Sym.Sum(0, NC, j => x[j] * li[j]);

            Expression[] FPj = new Expression[_system.Components.Count];
            for (int j = 0; j < NC; j++)
            {
                FPj[j] = qpi[j] * x[j] / Sym.Sum(0, NC, (kj) => qpi[kj] * x[kj]);
            }

            var doubleSum = Sym.Sum(0, NC, (j) => FPj[j] * tau[i, j] / (Sym.Sum(0, NC, (k) => FPj[k] * tau[k, j])));
            var SFP       = Sym.Sum(0, NC, (j) => FPj[j] * tau[j, i]);

            lnGammaRes = qpi[i] * (1.0 - Sym.Ln(SFP) - doubleSum);
            lnGamma    = lnGammaComb + lnGammaRes;
            _gamma_exp = Sym.Exp(lnGamma);

            _dgamma_dx = new Expression[NC];

            DiffFunctional = (cache, v) => _gamma_exp.Diff(cache, v);
            EvalFunctional = (cache) => _gamma_exp.Eval(cache);
        }
Exemplo n.º 5
0
        public override void FillEquationSystem(EquationSystem problem)
        {
            int NC = System.Components.Count;

            var vliq = Sym.Sum(0, NC, i => Liquid.ComponentMolarflow[i] * Liquid.ComponentMolarVolume[i]);
            var vvap = Vapor.TotalMolarflow / Vapor.DensityMolar;

            MW.BindTo(System.EquationFactory.GetAverageMolarWeightExpression(System, Mixed.ComponentMolarFraction.ToArray()));
            Liquid.TotalVolumeflow.BindTo(vliq);
            Vapor.TotalVolumeflow.BindTo(vvap);
            Mixed.TotalVolumeflow.BindTo(vliq + vvap);

            Mixed.TotalMassflow.BindTo(Sym.Sum(Mixed.ComponentMassflow));
            Liquid.TotalMassflow.BindTo(Sym.Sum(Liquid.ComponentMassflow));
            Vapor.TotalMassflow.BindTo(Sym.Sum(Vapor.ComponentMassflow));

            //Liquid.SpecificEnthalpy.BindTo(Sym.Par(Sym.Sum(0, NC, (idx) => Liquid.ComponentMolarFraction[idx] * Liquid.ComponentEnthalpy[idx])));
            //Vapor.SpecificEnthalpy.BindTo(Sym.Par(Sym.Sum(0, NC, (idx) => Vapor.ComponentMolarFraction[idx] * Vapor.ComponentEnthalpy[idx])));

            Liquid.SpecificEnthalpy.BindTo(new EnthalpyRoute(System, Mixed.Temperature, Mixed.Pressure, Liquid.ComponentMolarFraction, PhaseState.Liquid));
            Vapor.SpecificEnthalpy.BindTo(new EnthalpyRoute(System, Mixed.Temperature, Mixed.Pressure, Vapor.ComponentMolarFraction, PhaseState.Vapour));


            Mixed.Density.BindTo(Mixed.TotalMassflow / Mixed.TotalVolumeflow);
            Liquid.Density.BindTo(Liquid.TotalMassflow / Liquid.TotalVolumeflow);
            Vapor.Density.BindTo(Vapor.TotalMassflow / Vapor.TotalVolumeflow);

            Mixed.DensityMolar.BindTo(Mixed.TotalMolarflow / Mixed.TotalVolumeflow);
            Liquid.DensityMolar.BindTo(Liquid.TotalMolarflow / Liquid.TotalVolumeflow);
            Vapor.DensityMolar.BindTo(System.EquationFactory.GetAverageVaporDensityExpression(System, Mixed.Temperature, Mixed.Pressure, Vapor.ComponentMolarFraction));


            for (int i = 0; i < NC; i++)
            {
                Mixed.ComponentMassflow[i].BindTo(Mixed.ComponentMolarflow[i] * Sym.Convert(System.Components[i].GetConstant(ConstantProperties.MolarWeight), SI.kg / SI.mol));
                Mixed.ComponentMassFraction[i].BindTo(Mixed.ComponentMassflow[i] / Sym.Max(1e-12, Mixed.TotalMassflow));

                Liquid.ComponentMassflow[i].BindTo(Liquid.ComponentMolarflow[i] * Sym.Convert(System.Components[i].GetConstant(ConstantProperties.MolarWeight), SI.kg / SI.mol));
                Liquid.ComponentMassFraction[i].BindTo(Liquid.ComponentMassflow[i] / Sym.Max(1e-12, Liquid.TotalMassflow));

                Liquid.ComponentMolarVolume[i].BindTo((1.0 / System.EquationFactory.GetLiquidDensityExpression(System, System.Components[i], Mixed.Temperature, Mixed.Pressure)));
                Liquid.ComponentEnthalpy[i].BindTo(System.EquationFactory.GetLiquidEnthalpyExpression(System, i, Mixed.Temperature));

                Vapor.ComponentMassflow[i].BindTo(Vapor.ComponentMolarflow[i] * Sym.Convert(System.Components[i].GetConstant(ConstantProperties.MolarWeight), SI.kg / SI.mol));
                Vapor.ComponentMassFraction[i].BindTo(Vapor.ComponentMassflow[i] / Sym.Max(1e-12, Vapor.TotalMassflow));


                Vapor.ComponentEnthalpy[i].BindTo(System.EquationFactory.GetVaporEnthalpyExpression(System, i, Mixed.Temperature));
            }

            Mixed.TotalEnthalpy.BindTo(((Mixed.TotalMolarflow * Mixed.SpecificEnthalpy)));
            Liquid.TotalEnthalpy.BindTo(((Liquid.TotalMolarflow * Liquid.SpecificEnthalpy)));
            Vapor.TotalEnthalpy.BindTo(((Vapor.TotalMolarflow * Vapor.SpecificEnthalpy)));


            if (!Mixed.SpecificEnthalpy.IsFixed)
            {
                Mixed.SpecificEnthalpy.BindTo((Sym.Par(Vapor.TotalMolarflow * Vapor.SpecificEnthalpy + Liquid.TotalMolarflow * Liquid.SpecificEnthalpy) / Mixed.TotalMolarflow));
            }
            else
            {
                AddEquationToEquationSystem(problem, (Mixed.SpecificEnthalpy * Mixed.TotalMolarflow).IsEqualTo(Vapor.TotalMolarflow * Vapor.SpecificEnthalpy + Liquid.TotalMolarflow * Liquid.SpecificEnthalpy), "Enthalpy Balance");
            }


            AddEquationToEquationSystem(problem, Mixed.TotalMolarflow.IsEqualTo(Sym.Sum(Mixed.ComponentMolarflow)), "Mass Balance");

            for (int i = 0; i < NC; i++)
            {
                // AddEquationToEquationSystem(problem, (Mixed.ComponentMolarFraction[i] * Mixed.TotalMolarflow).IsEqualTo(Liquid.ComponentMolarFraction[i] * Liquid.TotalMolarflow + Vapor.ComponentMolarFraction[i] * Vapor.TotalMolarflow));
                AddEquationToEquationSystem(problem, (Mixed.ComponentMolarflow[i]).IsEqualTo(Liquid.ComponentMolarflow[i] + Vapor.ComponentMolarflow[i]));
                // Mixed.ComponentMolarflow[i].BindTo(Liquid.ComponentMolarflow[i] + Vapor.ComponentMolarflow[i]);
            }
            for (int i = 0; i < NC; i++)
            {
                AddEquationToEquationSystem(problem, (Mixed.ComponentMolarFraction[i] * Mixed.TotalMolarflow).IsEqualTo(Mixed.ComponentMolarflow[i]));
                //Mixed.ComponentMolarFraction[i].BindTo(Mixed.ComponentMolarflow[i]/ Mixed.TotalMolarflow);
            }
            for (int i = 0; i < NC; i++)
            {
                AddEquationToEquationSystem(problem, (Liquid.ComponentMolarFraction[i] * Liquid.TotalMolarflow).IsEqualTo(Liquid.ComponentMolarflow[i]));
                //Liquid.ComponentMolarFraction[i].BindTo(Liquid.ComponentMolarflow[i] / Sym.Max(1e-12, Liquid.TotalMolarflow));
            }
            for (int i = 0; i < NC; i++)
            {
                AddEquationToEquationSystem(problem, (Vapor.ComponentMolarFraction[i] * Vapor.TotalMolarflow).IsEqualTo(Vapor.ComponentMolarflow[i]));
                // Vapor.ComponentMolarFraction[i].BindTo(Vapor.ComponentMolarflow[i] / Sym.Max(1e-12, Vapor.TotalMolarflow));
            }

            AddEquationToEquationSystem(problem, (Vfmolar * Mixed.TotalMolarflow).IsEqualTo((Vapor.TotalMolarflow)), "Vapor Fraction");

            switch (State)
            {
            case PhaseState.BubblePoint:
                AddEquationToEquationSystem(problem, (Sym.Sum(Liquid.ComponentMolarFraction) - Sym.Sum(Vapor.ComponentMolarFraction)).IsEqualTo(Beta), "Equilibrium");
                AddEquationToEquationSystem(problem, Beta.IsEqualTo(0), "Equilibrium");
                AddEquationToEquationSystem(problem, Liquid.TotalMolarflow.IsEqualTo(Sym.Sum(Liquid.ComponentMolarflow)), "Mass Balance");
                break;

            case PhaseState.DewPoint:
                AddEquationToEquationSystem(problem, (Sym.Sum(Liquid.ComponentMolarFraction) - Sym.Sum(Vapor.ComponentMolarFraction)).IsEqualTo(Beta), "Equilibrium");
                AddEquationToEquationSystem(problem, Beta.IsEqualTo(0), "Equilibrium");
                AddEquationToEquationSystem(problem, Vapor.TotalMolarflow.IsEqualTo(Sym.Sum(Vapor.ComponentMolarflow)), "Mass Balance");
                break;

            default:
                if (Vfmolar.IsFixed)
                {
                    AddEquationToEquationSystem(problem, (Sym.Sum(Liquid.ComponentMolarFraction) - Sym.Sum(Vapor.ComponentMolarFraction)).IsEqualTo(Beta), "Equilibrium");
                    AddEquationToEquationSystem(problem, Beta.IsEqualTo(0), "Equilibrium");
                }
                else
                {
                    AddEquationToEquationSystem(problem, (Sym.Sum(Liquid.ComponentMolarFraction) - Sym.Sum(Vapor.ComponentMolarFraction)).IsEqualTo(Beta), "Equilibrium");
                    AddEquationToEquationSystem(problem, Sym.Mid(Vfmolar, Beta, Vfmolar - 1).IsEqualTo(0), "Equilibrium");
                }
                AddEquationToEquationSystem(problem, (Mixed.TotalMolarflow).IsEqualTo(Vapor.TotalMolarflow + Liquid.TotalMolarflow), "Mass Balance");
                break;
            }

            for (int i = 0; i < NC; i++)
            {
                System.EquationFactory.EquilibriumCoefficient(System, KValues[i], Mixed.Temperature, Mixed.Pressure, Liquid.ComponentMolarFraction, Vapor.ComponentMolarFraction, i);
                AddEquationToEquationSystem(problem, Vapor.ComponentMolarFraction[i].IsEqualTo(KValues[i] * Liquid.ComponentMolarFraction[i]), "Equilibrium");
            }

            base.FillEquationSystem(problem);
        }