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); }
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); }
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); }
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); }
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); }