示例#1
0
 Expression GetFactor(MaterialStream stream)
 {
     switch (Type)
     {
     case ReactionType.EQLA:
         Expression lnK = Coefficients[0];
         if (Coefficients.Count > 1)
         {
             lnK += Coefficients[1] / stream.Mixed.Temperature;
         }
         if (Coefficients.Count > 2)
         {
             lnK += Coefficients[2] * Sym.Ln(stream.Mixed.Temperature);
         }
         if (Coefficients.Count > 3)
         {
             lnK += Coefficients[3] * stream.Mixed.Temperature;
         }
         if (Coefficients.Count > 4)
         {
             lnK += Coefficients[4] * Sym.Pow(stream.Mixed.Temperature, 2.0);
         }
         if (Coefficients.Count > 5)
         {
             lnK += Coefficients[5] * Sym.Pow(stream.Mixed.Temperature, 3.0);
         }
         return(Sym.Exp(lnK));
     }
     return(1);
 }
示例#2
0
        public void Can_Log6()
        {
            var x = new Variable {
                Name = "x", ValueInSI = 6
            };
            var evaluator = new Evaluator();

            Assert.AreEqual(Math.Log(6), Sym.Ln(x).Eval(evaluator));
        }
        public MixtureHenryCoefficient(ThermodynamicSystem system, Variable T, List<Variable> x, int idx)
        {
            index = idx;
            _system = system;

            var parameterSet = _system.BinaryParameters.FirstOrDefault(ps => ps.Name == "HENRY");
            if (parameterSet == null)
                throw new ArgumentNullException("No HENRY parameters defined");

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


            Symbol = "HENRY";

            this.T = T;
            this.x = x;

            Parameters.Add(T);
            foreach (var comp in x)
                Parameters.Add(comp);

            NC = system.Components.Count;

            Expression sumxj = 0;
            Expression _lnHenry = 0;

            for (int j = 0; j < system.Components.Count; j++)
            {
                if (!system.Components[j].IsInert)
                {

                    Expression lnHij = a[idx, j];
                    if (b[idx, j] != 0.0)
                        lnHij += b[idx, j] / T;
                    if (c[idx, j] != 0.0)
                        lnHij += c[idx, j] * Sym.Ln(T);
                    if (d[idx, j] != 0.0)
                        lnHij += d[idx, j] * T;

                    sumxj += x[j];
                    _lnHenry += x[j] * Sym.Par(lnHij);
                }
            }

            _lnHenry = _lnHenry / Sym.Par(sumxj);

            _henry = Sym.Exp(_lnHenry);

            _dhenryDx = new Expression[NC];

            DiffFunctional = (cache, v) => _henry.Diff(cache, v);
            EvalFunctional = (cache) => _henry.Eval(cache);
        }
        public ActivityCoefficientWilson(ThermodynamicSystem system, Variable T, List <Variable> x, int idx)
        {
            Symbol  = "WILSON_GAMMA";
            _system = system;
            index   = idx;

            Parameters.Add(T);
            foreach (var comp in x)
            {
                Parameters.Add(comp);
            }

            NC     = system.Components.Count;
            this.T = T;
            this.x = x;

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

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

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

            var lambda = new Expression[NC, NC];

            for (int i = 0; i < NC; i++)
            {
                for (int j = 0; j < NC; j++)
                {
                    lambda[i, j] = Sym.Exp(a[i, j] + b[i, j] / T + c[i, j] * Sym.Ln(T) + d[i, j] * T);
                }
            }
            Expression H1 = Sym.Sum(0, NC, (k) => x[k] * lambda[index, k]);
            Expression H2 = Sym.Sum(0, NC, (k) => x[k] * lambda[k, index] / Sym.Sum(0, NC, (j) => x[j] * lambda[k, j]));

            _gammaExp = Sym.Exp(1 - Sym.Ln(H1) - H2);
            _dgammaDx = new Expression[NC];

            DiffFunctional = (cache, v) => _gammaExp.Diff(cache, v);
            EvalFunctional = (cache) => _gammaExp.Eval(cache);
        }
示例#5
0
        public K_EOS_SRK(ThermodynamicSystem system, Variable T, Variable p, List <Variable> x, List <Variable> y, int idx)
        {
            index   = idx;
            _system = system;

            this.T = T;
            this.p = p;
            this.x = x;
            this.y = y;
            Symbol = "EQ_SRK";

            Parameters.Add(T);
            Parameters.Add(p);
            foreach (var c in x)
            {
                Parameters.Add(c);
            }
            foreach (var c in y)
            {
                Parameters.Add(c);
            }

            NC = system.Components.Count;


            var ai  = new double[NC];
            var bi  = new double[NC];
            var Ai  = new Expression[NC];
            var aij = new Expression[NC, NC];
            var bij = new double[NC, NC];

            double[,] kij  = new double[NC, NC];
            double[,] kbij = new double[NC, NC];

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

            if (parameterSet != null)
            {
                kij = parameterSet.Matrices["kij"];

                if (parameterSet.Matrices.ContainsKey("kbij"))
                {
                    kbij = parameterSet.Matrices["kbij"];
                }
            }

            for (int i = 0; i < system.Components.Count; i++)
            {
                var comp = system.Components[i];
                var TC   = comp.GetConstant(ConstantProperties.CriticalTemperature);
                var PC   = comp.GetConstant(ConstantProperties.CriticalPressure);
                var AC   = comp.GetConstant(ConstantProperties.AcentricFactor);

                if (comp.HasParameter(MethodTypes.RKS, "A"))
                {
                    ai[i] = comp.GetParameter(MethodTypes.RKS, "A").ValueInSI;
                }
                else
                {
                    ai[i] = 0.42748 * Math.Pow(R.ValueInSI, 2.0) * Math.Pow(TC.ValueInSI, 2.0) / PC.ValueInSI;
                }

                if (comp.HasParameter(MethodTypes.RKS, "B"))
                {
                    bi[i] = comp.GetParameter(MethodTypes.RKS, "B").ValueInSI;
                }
                else
                {
                    bi[i] = 0.0867 * R.ValueInSI * TC.ValueInSI / PC.ValueInSI;
                }

                var mi     = 0.48 + 1.574 * AC.ValueInSI - 0.176 * Math.Pow(AC.ValueInSI, 2);
                var TR     = Sym.Binding("TR", T / TC);
                var alphai = Sym.Pow(1.0 + mi * (1 - Sym.Sqrt(TR)), 2.0);
                Ai[i] = alphai * ai[i];
            }


            for (int i = 0; i < system.Components.Count; i++)
            {
                for (int j = 0; j < system.Components.Count; j++)
                {
                    aij[i, j] = Sym.Sqrt(Ai[i] * Ai[j]) * (1 - kij[i, j]);
                    bij[i, j] = (bi[i] + bi[j]) / 2.0 * (1 - kbij[i, j]);
                }
            }


            for (int ph = 0; ph < 2; ph++)
            {
                var z = x;
                if (ph == 1)
                {
                    z = y;
                }

                var am  = Sym.Sum(0, NC, i => z[i] * Sym.Sum(0, NC, j => z[j] * aij[i, j]));
                var asi = Sym.Sum(0, NC, j => z[j] * aij[idx, j]);
                var bm  = Sym.Sum(0, NC, i => z[i] * Sym.Sum(0, NC, j => z[j] * bij[i, j]));
                var bsi = Sym.Sum(0, NC, j => z[j] * bij[idx, j]);
                var vme = new VOL_SRK(T, p, am, bm, ph == 0 ? PhaseState.Liquid : PhaseState.Vapour);
                var vm  = Sym.Binding("vm", vme);
                var Bi  = 2 * bsi - bm;
                var zm  = p * vm / (R * T);

                var eterm     = -am / (bm * R * T) * (2 * asi / am - Bi / bm) * Sym.Ln(1 + bm / vm) + Bi / bm * (zm - 1);
                var eVariable = Sym.Binding("RKS_E", eterm);

                //PHI[ph] = (R * T) / ((vm - bm) * p) * Sym.Exp(eVariable);
                PHI[ph] = 1.0 / ((vm - bm)) * Sym.Exp(eVariable);
            }
            //_kEOS_SRK = Sym.Exp(lnPHI[0] - lnPHI[1]);
            _kEOS_SRK = PHI[0] / PHI[1];
            _dphiDx   = new Expression[NC];
            _dphiDy   = new Expression[NC];

            DiffFunctional = (cache, v) => _kEOS_SRK.Diff(cache, v);
            EvalFunctional = (cache) => Evaluate(cache);
        }
        public ActivityCoefficientNRTL(ThermodynamicSystem system, Variable T, List <Variable> x, int idx)
        {
            index   = idx;
            _system = system;

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

            if (parameterSet == null)
            {
                throw new ArgumentNullException("No NRTL 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"];
            double[,] f = parameterSet.Matrices["F"];

            Symbol = "NRTL_GAMMA";

            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];
            G   = new Expression[NC, NC];

            int i = index;

            for (int ii = 0; ii < NC; ii++)
            {
                for (int j = 0; j < NC; j++)
                {
                    tau[ii, j] = a[ii, j];

                    if (b[ii, j] != 0.0)
                    {
                        tau[ii, j] += b[ii, j] / T;
                    }
                    if (e[ii, j] != 0.0)
                    {
                        tau[ii, j] += e[ii, j] * Sym.Ln(T);
                    }
                    if (f[ii, j] != 0.0)
                    {
                        tau[ii, j] += f[ii, j] * T;
                    }

                    Expression sij = c[ii, j];
                    if (d[ii, j] != 0.0)
                    {
                        sij += d[ii, j] * (T - 273.15);
                    }

                    if (c[ii, j] == 0.0 && d[i, j] == 0.0)
                    {
                        G[ii, j] = 1.0;
                    }
                    else
                    {
                        G[ii, j] = (Sym.Exp(-sij * tau[ii, j]));
                    }
                }
            }
            Expression lnGamma = 0.0;
            Expression S1      = 0.0;

            Expression[] S2 = new Expression[NC];
            Expression   S3 = 0.0;

            for (int j = 0; j < NC; j++)
            {
                if (a[j, i] == 0.0 && b[j, i] == 0.0)
                {
                    continue;
                }
                if (c[j, i] == 0.0 && d[j, i] == 0.0)
                {
                    continue;
                }

                S1 += x[j] * tau[j, i] * G[j, i];
            }

            for (int ii = 0; ii < NC; ii++)
            {
                S2[ii] = 0.0;
                for (int k = 0; k < NC; k++)
                {
                    S2[ii] += x[k] * G[k, ii];
                }
            }
            for (int j = 0; j < NC; j++)
            {
                Expression S5 = 0.0;

                for (int m = 0; m < NC; m++)
                {
                    if (a[m, j] == 0.0 && b[m, j] == 0.0)
                    {
                        continue;
                    }


                    S5 += x[m] * tau[m, j] * G[m, j];
                }

                S3 += x[j] * G[i, j] / Sym.Par(S2[j]) * (tau[i, j] - S5 / Sym.Par(S2[j]));
            }

            lnGamma = S1 / S2[i] + S3;

            _gammaExp = Sym.Exp(lnGamma);
            _dgammaDx = new Expression[NC];

            DiffFunctional = (cache, v) => _gammaExp.Diff(cache, v);
            EvalFunctional = (cache) => _gammaExp.Eval(cache);
        }
        /// <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);
        }
示例#8
0
        public Expression CreateExpression(FunctionType typeToCreate, PropertyFunction func, Variable T, Variable TC, Variable PC)
        {
            Expression expr = null;

            switch (typeToCreate)
            {
            case FunctionType.Polynomial:

                //if (func.NumberOfCoefficients < 1)
                //   throw new InvalidOperationException("Not enough coefficients to create an expression");
                EnsureCoefficients(func.Coefficients, 1);

                expr = func.Coefficients[0];

                for (int i = 1; i < func.NumberOfCoefficients; i++)
                {
                    expr += func.Coefficients[i] * Sym.Pow(T, i);
                }
                break;

            case FunctionType.PolynomialIntegrated:

                EnsureCoefficients(func.Coefficients, 1);
                expr = func.Coefficients[0] * T;

                for (int i = 1; i < func.NumberOfCoefficients; i++)
                {
                    expr += 1.0 / (double)(i + 1) * func.Coefficients[i] * Sym.Pow(T, i + 1);
                }
                break;

            case FunctionType.Dippr106:
                if (System.Math.Abs(TC.ValueInSI - func.Coefficients[0].ValueInSI) < 1e-6)
                {
                    EnsureCoefficients(func.Coefficients, 6);
                    var TR = Sym.Par(T / func.Coefficients[0]);
                    var h  = func.Coefficients[2] + func.Coefficients[3] * TR + func.Coefficients[4] * Sym.Pow(TR, 2) + func.Coefficients[5] * Sym.Pow(TR, 3);
                    expr = func.Coefficients[1] * Sym.Pow(Sym.Par(1 - TR), h);
                }
                else
                {
                    EnsureCoefficients(func.Coefficients, 6);
                    var TR = Sym.Par(T / TC);
                    var h  = func.Coefficients[2] + func.Coefficients[3] * TR + func.Coefficients[4] * Sym.Pow(TR, 2) + func.Coefficients[5] * Sym.Pow(TR, 3);
                    expr = func.Coefficients[1] * Sym.Pow(Sym.Par(1 - TR), h);
                }
                break;

            case FunctionType.Dippr117:
            {
                EnsureCoefficients(func.Coefficients, 5);

                var Tcon = Sym.Convert(T, func.XUnit);
                expr = func.Coefficients[0] * Tcon + func.Coefficients[1] * func.Coefficients[2] * Sym.Coth(func.Coefficients[2] / Tcon) - func.Coefficients[3] * func.Coefficients[4] * Sym.Tanh(func.Coefficients[4] / Tcon);
                break;
            }

            case FunctionType.AlyLee:
            {
                EnsureCoefficients(func.Coefficients, 5);

                Expression Tcon = T;
                if (!Unit.AreEquivalent(SI.K, func.XUnit))
                {
                    Tcon = Sym.Convert(T, func.XUnit);
                }

                expr = func.Coefficients[0] + func.Coefficients[1] * Sym.Pow(Sym.Par((func.Coefficients[2] / Tcon) / Sym.Sinh(func.Coefficients[2] / Tcon)), 2) + func.Coefficients[3] * Sym.Pow(Sym.Par((func.Coefficients[4] / Tcon) / Sym.Cosh(func.Coefficients[4] / Tcon)), 2);
                break;
            }

            case FunctionType.Antoine:
            {
                EnsureCoefficients(func.Coefficients, 3);
                Expression CT = T;
                if (!Unit.AreEquivalent(SI.K, func.XUnit))
                {
                    CT = Sym.Convert(T, func.XUnit);
                }


                expr = Sym.Exp(func.Coefficients[0] - func.Coefficients[1] / Sym.Par(func.Coefficients[2] + CT));
                break;
            }

            case FunctionType.ExtendedAntoine:
            {
                EnsureCoefficients(func.Coefficients, 7);
                Expression CT = T;
                if (!Unit.AreEquivalent(SI.K, func.XUnit))
                {
                    CT = Sym.Convert(T, func.XUnit);
                }

                expr = (Sym.Exp(func.Coefficients[0] + func.Coefficients[1] / Sym.Par(func.Coefficients[2] + CT) + func.Coefficients[3] * CT + func.Coefficients[4] * Sym.Ln(CT) + func.Coefficients[5] * Sym.Pow(CT, func.Coefficients[6])));

                break;
            }

            case FunctionType.Rackett:
            {
                EnsureCoefficients(func.Coefficients, 4);
                var TR = Sym.Convert(T, func.XUnit) / func.Coefficients[2];
                expr = func.Coefficients[0] / (Sym.Pow(func.Coefficients[1], 1 + Sym.Pow(Sym.Par(1 - TR), func.Coefficients[3])));

                break;
            }

            case FunctionType.Wagner:
            {
                EnsureCoefficients(func.Coefficients, 6);

                if (TC == null || PC == null)
                {
                    throw new InvalidOperationException("Not enough coefficients to create an expression");
                }
                var TR  = Sym.Convert(T, func.XUnit) / TC;
                var tau = Sym.Par(1 - TR);
                expr = Sym.Exp(Sym.Ln(PC) + 1 / TR * Sym.Par(func.Coefficients[2] * tau + func.Coefficients[3] * Sym.Pow(tau, 1.5) + func.Coefficients[4] * Sym.Pow(tau, 3) + func.Coefficients[5] * Sym.Pow(tau, 6)));

                break;
            }

            case FunctionType.Watson:
            {
                EnsureCoefficients(func.Coefficients, 4);

                expr = func.Coefficients[0] * Sym.Pow(func.Coefficients[2] - T, func.Coefficients[1]) + func.Coefficients[3];
                break;
            }

            case FunctionType.Dippr102:
            {
                EnsureCoefficients(func.Coefficients, 4);

                expr = func.Coefficients[0] * Sym.Pow(T, func.Coefficients[1]) / (1 + func.Coefficients[2] / T + func.Coefficients[3] / T);
                break;
            }

            case FunctionType.Kirchhoff:
            {
                EnsureCoefficients(func.Coefficients, 3);

                expr = (Sym.Exp(func.Coefficients[0] - func.Coefficients[1] / T + func.Coefficients[2] * Sym.Ln(T)));
                break;
            }

            case FunctionType.Sutherland:
            {
                EnsureCoefficients(func.Coefficients, 2);

                expr = (func.Coefficients[0] * Sym.Sqrt(T)) / (1 + func.Coefficients[1] / T);
                break;
            }

            case FunctionType.Chemsep16:
            {
                EnsureCoefficients(func.Coefficients, 5);
                var a = func.Coefficients[0];
                var b = func.Coefficients[1];
                var c = func.Coefficients[2];
                var d = func.Coefficients[3];
                var e = func.Coefficients[4];
                expr = a + Sym.Exp(b / T + c + d * T + e * Sym.Pow(T, 2));
                break;
            }

            case FunctionType.Chemsep101:
            {
                EnsureCoefficients(func.Coefficients, 5);
                var a = func.Coefficients[0];
                var b = func.Coefficients[1];
                var c = func.Coefficients[2];
                var d = func.Coefficients[3];
                var e = func.Coefficients[4];
                expr = (Sym.Exp(a + b / T + c * Sym.Ln(T) + d * Sym.Pow(T, 2.0)));
                break;
            }

            case FunctionType.Chemsep102:
            {
                EnsureCoefficients(func.Coefficients, 5);
                var a = func.Coefficients[0];
                var b = func.Coefficients[1];
                var c = func.Coefficients[2];
                var d = func.Coefficients[3];
                var e = func.Coefficients[4];
                expr = a * Sym.Pow(T, b) / (1 + c / T + d / Sym.Pow(T, 2));
                break;
            }

            case FunctionType.Chemsep106:
            {
                EnsureCoefficients(func.Coefficients, 6);
                var TR = Sym.Par(T / TC);
                var h  = func.Coefficients[1] + func.Coefficients[2] * TR + func.Coefficients[3] * Sym.Pow(TR, 2) + func.Coefficients[4] * Sym.Pow(TR, 3);
                expr = func.Coefficients[0] * Sym.Pow(Sym.Par(1 - TR), h);
            }
            break;

            default:
                throw new InvalidOperationException("Unknown function type" + typeToCreate);
            }
            return(expr);
        }
示例#9
0
        Expression HandleExpression(DAEProblem problem, ModelicaExpression expr)
        {
            switch (expr)
            {
            case BinaryExpression b:
            {
                switch (b.Operator)
                {
                case BinaryOperator.Add:
                    return(HandleExpression(problem, b.Left) + HandleExpression(problem, b.Right));

                case BinaryOperator.Subtract:
                    return(HandleExpression(problem, b.Left) - HandleExpression(problem, b.Right));

                case BinaryOperator.Multiply:
                    return(HandleExpression(problem, b.Left) * HandleExpression(problem, b.Right));

                case BinaryOperator.Divide:
                    return(HandleExpression(problem, b.Left) / HandleExpression(problem, b.Right));

                case BinaryOperator.Power:
                    return(Sym.Pow(HandleExpression(problem, b.Left), HandleExpression(problem, b.Right)));
                }
            }
            break;

            case UnaryExpression u:
            {
                switch (u.Operator)
                {
                case UnaryOperator.Negate:
                    return(-HandleExpression(problem, u.Child));

                case UnaryOperator.Parentheses:
                    return(Sym.Par(HandleExpression(problem, u.Child)));

                case UnaryOperator.TimeDerivative:
                    var y = HandleExpression(problem, u.Child) as Variable;
                    if (y == null)
                    {
                        throw new InvalidOperationException("Cannot handle expressions inside der operator yet.");
                    }

                    var dery = new Variable("der(" + y.Name + ")", 0);

                    var existingVar = problem.DifferentialVariables.FirstOrDefault(v => v.Name == dery.Name);
                    if (existingVar == null)
                    {
                        problem.DifferentialVariables.Add(dery);
                        problem.Mapping.Add(dery, y);
                        return(dery);
                    }
                    else
                    {
                        return(existingVar);
                    }

                default:
                    throw new InvalidOperationException("Unknown unary operator " + u.Operator.ToString());
                }
            }

            case BuiltinFunction u:
            {
                switch (u.Type)
                {
                case BuiltinFunctionType.Sin:
                    return(Sym.Sin(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Cos:
                    return(Sym.Cos(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Tan:
                    return(Sym.Tan(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Log:
                    return(Sym.Ln(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Exp:
                    return(Sym.Exp(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Sqrt:
                    return(Sym.Sqrt(HandleExpression(problem, u.Child)));

                default:
                    throw new InvalidOperationException("Unknown built-in fucntion " + u.Type.ToString());
                }
            }

            case DoubleLiteral l:
                return(new Variable(l.Value.ToString(), l.Value));

            case Reference r:
            {
                var vari = problem.ResolveReference(r.ToString());
                if (vari != null)
                {
                    return(vari);
                }
                else
                {
                    throw new NullReferenceException("Variable " + r.ToString() + " not defined.");
                }
            }

            default:
                throw new InvalidOperationException("Unknown expression " + expr.ToString());
            }
            return(null);
        }