public RateBasedSection Ignore(params string[] components) { foreach (var compId in components) { var comp = System.Components.FirstOrDefault(c => c.ID == compId); if (comp != null) { IgnoredComponents.Add(comp); } } return(this); }
void ApplyIgnoredComponents() { int NT = (int)(NumberOfElements); for (int c = 0; c < System.Components.Count; c++) { if (IgnoredComponents.Contains(System.Components[c])) { for (int i = 0; i < NT; i++) { _trays[i].x[c].FixValue(0); _trays[i].y[c].FixValue(0); _trays[i].yI[c].FixValue(0); _trays[i].xI[c].FixValue(0); _trays[i].x[c].IsConstant = true; _trays[i].y[c].IsConstant = true; _trays[i].yI[c].IsConstant = true; _trays[i].xI[c].IsConstant = true; } } } }
public override void FillEquationSystem(EquationSystem problem) { int NC = System.Components.Count; var VIn = FindMaterialPort("VIn").Streams[0]; var LIn = FindMaterialPort("LIn").Streams[0]; var VOut = FindMaterialPort("VOut").Streams[0]; var LOut = FindMaterialPort("LOut").Streams[0]; var pscale = 1e4; var hscale = 1e6; var L0 = LIn.Mixed.TotalMolarflow; var x0 = LIn.Mixed.ComponentMolarFraction; var VNT = VIn.Mixed.TotalMolarflow; var yNT = VIn.Mixed.ComponentMolarFraction; ApplyIgnoredComponents(); Action <Equation> EQ = (x) => AddEquationToEquationSystem(problem, x); for (var i = 0; i < NumberOfElements; i++) { var tray = _trays[i]; //Calculate average properties on stage, Divide molar weight by 1000 because unit is kg/kmol and not kg/mol as would be SI var TV = tray.TV; var p = tray.p; var rhoVMolar = System.EquationFactory.GetAverageVaporDensityExpression(System, TV, p, tray.y.ToList()); var rhoV = rhoVMolar * System.EquationFactory.GetAverageMolarWeightExpression(System, tray.y); var etaV = System.EquationFactory.GetAverageVaporViscosityExpression(System, tray.y, TV, p); var A = Math.PI / 4 * Sym.Pow(tray.d, 2); //Hydraulics //Effective exchange area EQ(tray.aeff.IsEqualTo(tray.h * A * tray.aspez)); //Superficial velocity EQ(tray.uV.IsEqualTo(tray.V / (rhoVMolar * A))); //Reynolds number tray.ReV.BindTo(rhoV * tray.uV * tray.dhyd / etaV); //Component (M)assbalance for (var comp = 0; comp < NC; comp++) { if (!IgnoredComponents.Contains(System.Components[comp])) { if (i == 0) { EQ((tray.V * tray.y[comp] - _trays[i + 1].V * _trays[i + 1].y[comp] + tray.N[comp]).IsEqualTo(0)); EQ((tray.L * tray.x[comp] - L0 * x0[comp] - _trays[i].N[comp]).IsEqualTo(0)); } else if (i == NumberOfElements - 1) { EQ((tray.V * tray.y[comp] - VNT * yNT[comp] + _trays[i].N[comp]).IsEqualTo(0)); EQ((tray.L * tray.x[comp] - _trays[i - 1].L * _trays[i - 1].x[comp] - tray.N[comp]).IsEqualTo(0)); } else { EQ((tray.V * tray.y[comp] - _trays[i + 1].V * _trays[i + 1].y[comp] + tray.N[comp]).IsEqualTo(0)); EQ((tray.L * tray.x[comp] - _trays[i - 1].L * _trays[i - 1].x[comp] - tray.N[comp]).IsEqualTo(0)); } } } //(E)quilibrium for (var comp = 0; comp < NC; comp++) { System.EquationFactory.EquilibriumCoefficient(System, tray.K[comp], tray.TI, p, tray.xI.ToList(), tray.yI.ToList(), comp); if (!IgnoredComponents.Contains(System.Components[comp])) { EQ((tray.yI[comp]).IsEqualTo(tray.K[comp] * tray.xI[comp])); } } //(R)ate Equation - Intefacial Mass Transfer for (var comp = 0; comp < NC; comp++) { if (!IgnoredComponents.Contains(System.Components[comp])) { if (NoContact) { EQ((_trays[i].N[comp]).IsEqualTo(0)); EQ((_trays[i].xI[comp]).IsEqualTo(tray.x[comp])); } else { if (!_massTransferResistanceOnLiquid) { EQ((_trays[i].xI[comp]).IsEqualTo(tray.x[comp])); } else { var x = tray.x; var xI = tray.xI; var n = tray.N; var ii = comp; var xiiq = 0.5 * Sym.Par(x[ii] + xI[ii]); EQ((rhoVMolar * _trays[i].aeff * Sym.Par(tray.xI[ii] - tray.x[ii])).IsEqualTo(Sym.SumX(0, NC, comp, j => (0.5 * Sym.Par(x[j] + xI[j]) * n[ii] - xiiq * n[j]) / tray.BetaL[ii, j]))); } if (!_massTransferResistanceOnVapor) { EQ((_trays[i].yI[comp]).IsEqualTo(tray.y[comp])); } else { //Simplified Stefan-Maxwell Equation for Film model var y = tray.y; var yI = tray.yI; var n = tray.N; var ii = comp; var yiiq = 0.5 * Sym.Par(y[ii] + yI[ii]); EQ((rhoVMolar * _trays[i].aeff * Sym.Par(tray.y[ii] - tray.yI[ii])).IsEqualTo(Sym.SumX(0, NC, comp, j => (0.5 * Sym.Par(y[j] + yI[j]) * n[ii] - yiiq * n[j]) / tray.BetaV[ii, j]))); } } } } //Heat Transfer coefficient calcluation if (!BetaVIsConstant) { for (int k = 0; k < NC; k++) { for (int j = 0; j < NC; j++) { if (k != j) { var parameterSet = System.BinaryParameters.FirstOrDefault(ps => ps.Name == "DVIJ0"); if (parameterSet == null) { throw new ArgumentNullException("No Diffusion coefficients defined"); } //Estimate Diffusion coefficient at system temperature and pressure using the approach by Fuller, Schettler, Giddings var DVij0 = parameterSet.Matrices["A"][k, j]; var DVij = Sym.Pow(Sym.Par(TV / 273.15), 1.75) / (p / 1e5) * DVij0; //Schmidt Number var Scij = etaV / Sym.Par(rhoV * DVij); //Sherwood Number var Shij = SherwoodParameter[0] * Sym.Pow(tray.ReV, SherwoodParameter[1]) * Sym.Pow(Scij, SherwoodParameter[2]); tray.BetaV[k, j].BindTo(Shij * DVij / tray.dhyd); } else { tray.BetaV[k, j].BindTo(0); } } } } //(R)ate Equation - Interfacial Heat Transfer if (NoContact) { EQ((tray.E).IsEqualTo(0)); EQ((tray.TI).IsEqualTo(0.5 * Sym.Par(tray.TL + tray.TV))); } else { if (!_heatTransferResistanceOnLiquid) { EQ((tray.TI).IsEqualTo(tray.TL)); } if (!_heatTransferResistanceOnVapor) { EQ((tray.TI).IsEqualTo(tray.TV)); } } //(S)ummation EQ(Sym.Sum(0, NC, (j) => Sym.Par(tray.x[j])).IsEqualTo(1)); EQ(Sym.Sum(0, NC, (j) => Sym.Par(tray.y[j])).IsEqualTo(1)); //Ent(H)alpy tray.HL.BindTo(Sym.Sum(0, NC, (idx) => tray.x[idx] * System.EquationFactory.GetLiquidEnthalpyExpression(System, idx, tray.TL))); tray.HV.BindTo(Sym.Sum(0, NC, (idx) => tray.y[idx] * System.EquationFactory.GetVaporEnthalpyExpression(System, idx, tray.TV))); if (i == 0) { EQ((Sym.Par(_trays[i].V * _trays[i].HV - _trays[i + 1].V * _trays[i + 1].HV + _trays[i].E) / hscale).IsEqualTo(0)); EQ((Sym.Par(_trays[i].L * _trays[i].HL - L0 * LIn.Mixed.SpecificEnthalpy - _trays[i].E + tray.Q) / hscale).IsEqualTo(0)); } else if (i == NumberOfElements - 1) { EQ((Sym.Par(_trays[i].V * _trays[i].HV - VNT * VIn.Mixed.SpecificEnthalpy + _trays[i].E) / hscale).IsEqualTo(0)); EQ((Sym.Par(_trays[i].L * _trays[i].HL - _trays[i - 1].L * _trays[i - 1].HL - _trays[i].E + tray.Q) / hscale).IsEqualTo(0)); } else { EQ((Sym.Par(_trays[i].V * _trays[i].HV - _trays[i + 1].V * _trays[i + 1].HV + _trays[i].E) / hscale).IsEqualTo(0)); EQ((Sym.Par(_trays[i].L * _trays[i].HL - _trays[i - 1].L * _trays[i - 1].HL - _trays[i].E + tray.Q) / hscale).IsEqualTo(0)); } //Pressure profile if (i == NumberOfElements - 1) { EQ((tray.p / pscale).IsEqualTo((VIn.Mixed.Pressure - _trays[NumberOfElements - 1].DP) / pscale)); } else { EQ((tray.p / pscale).IsEqualTo(Sym.Par(_trays[i + 1].p - _trays[i].DP) / pscale)); } } //Setting outlet stream conditions for (var comp = 0; comp < NC; comp++) { EQ(VOut.Mixed.ComponentMolarflow[comp].IsEqualTo(_trays[0].V * _trays[0].y[comp])); EQ(LOut.Mixed.ComponentMolarflow[comp].IsEqualTo(_trays[NumberOfElements - 1].L * _trays[NumberOfElements - 1].x[comp])); } EQ((VOut.Mixed.SpecificEnthalpy / 1e6).IsEqualTo(_trays[0].HV / 1e6)); EQ(VOut.Mixed.Pressure.IsEqualTo(_trays[0].p)); EQ(LOut.Mixed.Temperature.IsEqualTo(_trays[NumberOfElements - 1].TL)); EQ(LOut.Mixed.Pressure.IsEqualTo(_trays[NumberOfElements - 1].p)); base.FillEquationSystem(problem); }