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 bool CalculatePQ(MaterialStream stream, double enthalpy) { var copy = new MaterialStream("copy", stream.System); copy.CopyFrom(stream); PrecalculateTP(copy); var problem2 = new EquationSystem() { Name = "PQ-Flash" }; copy.GetVariable("p").IsFixed = true; copy.GetVariable("T").IsFixed = false; copy.GetVariable("VF").IsFixed = false; copy.Init("VF", stream.Vfmolar.ValueInSI); foreach (var comp in stream.System.Components) { copy.GetVariable("n[" + comp.ID + "]").IsFixed = true; } problem2.AddConstraints((copy.Mixed.SpecificEnthalpy * copy.Mixed.TotalMolarflow).IsEqualTo(enthalpy)); copy.FillEquationSystem(problem2); var solver = new Decomposer(); solver.Solve(problem2); performMassBalance(copy, copy.KValues); performDensityUpdate(copy); performEnthalpyUpdate(copy); stream.CopyFrom(copy); return(true); }
EquationSystem GetEquationSystem(MaterialStream stream) { var eq = new EquationSystem(); eq.TreatFixedVariablesAsConstants = true; stream.FillEquationSystem(eq); return(eq); }
public TraySection ConnectFeed(MaterialStream stream, int stage, PhaseState phase = PhaseState.LiquidVapor) { _feeds.Add(new TrayConnectivity() { Stage = stage, Stream = stream, Phase = phase }); Connect("Feeds", stream); return(this); }
string GetStreamProperty(string property, MaterialStream stream) { // var connection = visual.GetStreamByName(stream.Name); switch (property) { case "Name": return(stream.Name); /* case "From Unit": * if (connection != null) * { * if (connection.Source == null) * return ""; * if (connection.Source.Owner != null) * return connection.Source.Owner.Name; * } * return ""; * case "From Port": * if (connection != null) * { * if (connection.Source != null) * return connection.Source.Name; * } * return ""; * case "To Unit": * if (connection != null) * { * if (connection.Sink == null) * return ""; * if (connection.Sink.Owner != null) * return connection.Sink.Owner.Name; * } * return ""; * case "To Port": * if (connection != null) * { * if (connection.Sink != null) * return connection.Sink.Name; * } * return ""; */ case "Temperature": return(stream.Mixed.Temperature.ValueInOutputUnit.ToString("G4")); case "Pressure": return(stream.Mixed.Pressure.ValueInOutputUnit.ToString("G4")); case "Vapour Fraction": return(stream.Vfmolar.ValueInOutputUnit.ToString("P1")); case "Enthalpy": return(stream.Mixed.SpecificEnthalpy.ValueInOutputUnit.ToString("G4")); } return(""); }
public StreamTableElement RemoveMaterialStream(MaterialStream stream) { if (Streams.Contains(stream)) { Streams.Remove(stream); } else { throw new InvalidOperationException("Stream " + stream.Name + " not included in streamtable"); } return(this); }
public TraySection ConnectVaporSidestream(MaterialStream stream, int stage, double factor) { var con = new TrayConnectivity() { Stage = stage, Stream = stream, Phase = PhaseState.Vapour }; con.Factor.ValueInSI = factor; _sidestream.Add(con); Connect("Sidestreams", stream); return(this); }
public StreamTableElement AddMaterialStream(MaterialStream stream) { if (!Streams.Contains(stream)) { Streams.Add(stream); } else { throw new InvalidOperationException("Stream " + stream.Name + " already included in streamtable"); } return(this); }
private void performMassBalance(MaterialStream stream, Variable[] K) { var NC = stream.System.Components.Count; stream.Vapor.TotalMolarflow.ValueInSI = stream.Vfmolar.ValueInSI * stream.Mixed.TotalMolarflow.ValueInSI; stream.Liquid.TotalMolarflow.ValueInSI = stream.Mixed.TotalMolarflow.ValueInSI - stream.Vapor.TotalMolarflow.ValueInSI; var eval = new Evaluator(); for (int i = 0; i < NC; i++) { eval.Reset(); stream.Liquid.ComponentMolarFraction[i].ValueInSI = (stream.Mixed.ComponentMolarFraction[i] / (1 + stream.Vfmolar * (K[i] - 1))).Eval(eval); stream.Vapor.ComponentMolarFraction[i].ValueInSI = (stream.Liquid.ComponentMolarFraction[i] * K[i]).Eval(eval); stream.Liquid.ComponentMolarflow[i].ValueInSI = stream.Liquid.ComponentMolarFraction[i].ValueInSI * stream.Liquid.TotalMolarflow.ValueInSI; stream.Vapor.ComponentMolarflow[i].ValueInSI = stream.Vapor.ComponentMolarFraction[i].ValueInSI * stream.Vapor.TotalMolarflow.ValueInSI; stream.Liquid.ComponentMassflow[i].ValueInSI = (stream.Liquid.ComponentMolarflow[i] * Sym.Convert(stream.System.Components[i].GetConstant(ConstantProperties.MolarWeight), stream.System.VariableFactory.Internal.UnitDictionary[PhysicalDimension.Mass] / stream.System.VariableFactory.Internal.UnitDictionary[PhysicalDimension.Mole])).Eval(eval); stream.Vapor.ComponentMassflow[i].ValueInSI = (stream.Vapor.ComponentMolarflow[i] * Sym.Convert(stream.System.Components[i].GetConstant(ConstantProperties.MolarWeight), stream.System.VariableFactory.Internal.UnitDictionary[PhysicalDimension.Mass] / stream.System.VariableFactory.Internal.UnitDictionary[PhysicalDimension.Mole])).Eval(eval); stream.Mixed.ComponentMassflow[i].ValueInSI = (stream.Mixed.ComponentMolarflow[i] * Sym.Convert(stream.System.Components[i].GetConstant(ConstantProperties.MolarWeight), stream.System.VariableFactory.Internal.UnitDictionary[PhysicalDimension.Mass] / stream.System.VariableFactory.Internal.UnitDictionary[PhysicalDimension.Mole])).Eval(eval); } stream.Mixed.TotalMassflow.ValueInSI = stream.Mixed.ComponentMassflow.Sum(v => v.ValueInSI); stream.Vapor.TotalMassflow.ValueInSI = stream.Vapor.ComponentMassflow.Sum(v => v.ValueInSI); stream.Liquid.TotalMassflow.ValueInSI = stream.Liquid.ComponentMassflow.Sum(v => v.ValueInSI); for (int i = 0; i < NC; i++) { eval.Reset(); if (stream.Liquid.TotalMassflow.ValueInSI <= 1e-8) { stream.Liquid.ComponentMassFraction[i].ValueInSI = 0; } else { stream.Liquid.ComponentMassFraction[i].ValueInSI = (stream.Liquid.ComponentMassflow[i] / stream.Liquid.TotalMassflow).Eval(eval); } if (stream.Vapor.TotalMassflow.ValueInSI <= 1e-8) { stream.Vapor.ComponentMassFraction[i].ValueInSI = 0; } else { stream.Vapor.ComponentMassFraction[i].ValueInSI = (stream.Vapor.ComponentMassflow[i] / stream.Vapor.TotalMassflow).Eval(eval); } stream.Mixed.ComponentMassFraction[i].ValueInSI = (stream.Mixed.ComponentMassflow[i] / stream.Mixed.TotalMassflow.ValueInSI).Eval(eval); } }
private void performDensityUpdate(MaterialStream stream) { var NC = stream.System.Components.Count; var eval = new Evaluator(); for (int i = 0; i < NC; i++) { stream.Liquid.ComponentMolarVolume[i].ValueInSI = 1.0 / stream.System.EquationFactory.GetLiquidDensityExpression(stream.System, stream.System.Components[i], stream.Mixed.Temperature, stream.Mixed.Pressure).Eval(eval); stream.Vapor.ComponentMolarVolume[i].ValueInSI = 1.0 / stream.System.EquationFactory.GetVaporDensityExpression(stream.System, stream.System.Components[i], stream.Mixed.Temperature, stream.Mixed.Pressure).Eval(eval); stream.Mixed.ComponentMolarVolume[i].ValueInSI = (stream.Liquid.ComponentMolarVolume[i] + stream.Vapor.ComponentMolarVolume[i]).Eval(eval); } }
public void FlashTrays() { var flash = new FlashRoutines(new Numerics.Solvers.Newton()); MaterialStream stageStream = new MaterialStream("Stage", System); var VIn = FindMaterialPort("VIn"); var LIn = FindMaterialPort("LIn"); for (int i = 0; i < NumberOfTrays; i++) { FlashCurrentStage(flash, stageStream, VIn, LIn, i); } for (int i = NumberOfTrays - 1; i >= 0; i--) { FlashCurrentStage(flash, stageStream, VIn, LIn, i); } }
private void performEnthalpyUpdate(MaterialStream stream) { var NC = stream.System.Components.Count; var eval = new Evaluator(); stream.Vapor.SpecificEnthalpy.ValueInSI = (Sym.Par(Sym.Sum(0, NC, (idx) => stream.Vapor.ComponentMolarFraction[idx] * stream.System.EquationFactory.GetVaporEnthalpyExpression(stream.System, idx, stream.Mixed.Temperature)))).Eval(eval); stream.Liquid.SpecificEnthalpy.ValueInSI = (Sym.Par(Sym.Sum(0, NC, (idx) => stream.Liquid.ComponentMolarFraction[idx] * stream.System.EquationFactory.GetLiquidEnthalpyExpression(stream.System, idx, stream.Mixed.Temperature)))).Eval(eval); if (Double.IsNaN(stream.Liquid.SpecificEnthalpy.ValueInSI)) { stream.Liquid.SpecificEnthalpy.ValueInSI = 0; } if (Double.IsNaN(stream.Vapor.SpecificEnthalpy.ValueInSI)) { stream.Vapor.SpecificEnthalpy.ValueInSI = 0; } stream.Mixed.SpecificEnthalpy.ValueInSI = ((stream.Vapor.TotalMolarflow * stream.Vapor.SpecificEnthalpy + stream.Liquid.TotalMolarflow * stream.Liquid.SpecificEnthalpy) / stream.Mixed.TotalMolarflow).Eval(eval); }
Expression GetDrivingForce(MaterialStream stream) { Expression drivingForce = 1; switch (Type) { case ReactionType.EQLA: { foreach (var stoic in Stoichiometry) { drivingForce *= Sym.Pow(Sym.Par(stream.Gamma[stoic.Index] * stream.Liquid.ComponentMolarFraction[stoic.Index]), stoic.StoichiometricFactor); } break; } default: break; } return(drivingForce); }
void PrecalculateZP(MaterialStream stream) { stream.Mixed.TotalMolarflow.ValueInSI = stream.Mixed.ComponentMolarflow.Sum(v => v.ValueInSI); var NC = stream.System.Components.Count; for (int i = 0; i < NC; i++) { stream.Mixed.ComponentMolarFraction[i].ValueInSI = stream.Mixed.ComponentMolarflow[i].ValueInSI / stream.Mixed.TotalMolarflow.ValueInSI; stream.Liquid.ComponentMolarFraction[i].ValueInSI = stream.Mixed.ComponentMolarFraction[i].ValueInSI; stream.Vapor.ComponentMolarFraction[i].ValueInSI = stream.Mixed.ComponentMolarFraction[i].ValueInSI; } var rachfordRice = Sym.Sum(0, NC, i => stream.Mixed.ComponentMolarFraction[i] * (1 - stream.KValues[i]) / (1 + stream.Vfmolar * (stream.KValues[i] - 1))); var rachfordRiceEq = rachfordRice.IsEqualTo(0); var problem2 = new EquationSystem() { Name = "Rachford-Rice" }; if (stream.Vfmolar.ValueInSI <= 1e-10) { problem2.AddConstraints(Sym.Sum(0, NC, i => stream.Mixed.ComponentMolarFraction[i] * stream.KValues[i]).IsEqualTo(1)); } else if (stream.Vfmolar.ValueInSI >= 1 - 1e-10) { problem2.AddConstraints(Sym.Sum(0, NC, i => stream.Mixed.ComponentMolarFraction[i] / stream.KValues[i]).IsEqualTo(1)); } else { problem2.AddConstraints(rachfordRiceEq); } problem2.AddVariables(stream.Mixed.Temperature); _solver.Solve(problem2); performMassBalance(stream, stream.KValues); performDensityUpdate(stream); performEnthalpyUpdate(stream); }
void PrecalculateTP(MaterialStream stream) { stream.Mixed.TotalMolarflow.ValueInSI = stream.Mixed.ComponentMolarflow.Sum(v => v.ValueInSI); var NC = stream.System.Components.Count; for (int i = 0; i < NC; i++) { stream.Mixed.ComponentMolarFraction[i].ValueInSI = stream.Mixed.ComponentMolarflow[i].ValueInSI / stream.Mixed.TotalMolarflow.ValueInSI; stream.Liquid.ComponentMolarFraction[i].ValueInSI = stream.Mixed.ComponentMolarFraction[i].ValueInSI; stream.Vapor.ComponentMolarFraction[i].ValueInSI = stream.Mixed.ComponentMolarFraction[i].ValueInSI; } //Solving Rachford Rice equation to get actual vapour fraction var x = stream.Mixed.ComponentMolarFraction; var K = stream.KValues; var a = stream.Vfmolar; var rachfordRice = Sym.Sum(0, NC, i => x[i] * (1 - K[i]) / (1 + a * (K[i] - 1))); //Evaluate Rachford-Rice at the edge cases of the VLE area stream.Vfmolar.ValueInSI = 0; var rrAt0 = rachfordRice.Eval(new Evaluator()); stream.Vfmolar.ValueInSI = 1; var rrAt1 = rachfordRice.Eval(new Evaluator()); stream.Vfmolar.ValueInSI = 0.5; if (rrAt0 > 0) { stream.Vfmolar.ValueInSI = 0; } else if (Math.Abs(rrAt0) < 1e-8) { stream.Vfmolar.ValueInSI = 0; } else if (Math.Abs(rrAt1) < 1e-8) { stream.Vfmolar.ValueInSI = 1; } else if (rrAt1 < 0) { stream.Vfmolar.ValueInSI = 1; } if (stream.Vfmolar.ValueInSI == 0.5 || (rrAt0 == 0 && rrAt1 == 0)) { for (int i = 0; i < NC; i++) { stream.Liquid.ComponentMolarFraction[i].ValueInSI = 0.95 * stream.Mixed.ComponentMolarFraction[i].ValueInSI; stream.Vapor.ComponentMolarFraction[i].ValueInSI = 1.05 * stream.Mixed.ComponentMolarFraction[i].ValueInSI; } stream.Vfmolar.ValueInSI = 0.5; var problem2 = new EquationSystem() { Name = "Rachford-Rice" }; stream.Vfmolar.LowerBound = -5; stream.Vfmolar.UpperBound = 5; problem2.AddConstraints(rachfordRice.IsEqualTo(0)); problem2.AddVariables(stream.Vfmolar); _solver.Solve(problem2); } if (Double.IsNaN(stream.Vfmolar.ValueInSI)) { stream.Vfmolar.ValueInSI = 0; } stream.Vfmolar.LowerBound = 0; stream.Vfmolar.UpperBound = 1; if (stream.Vfmolar.ValueInSI > 1) { stream.Vfmolar.ValueInSI = 1; } if (stream.Vfmolar.ValueInSI < 0) { stream.Vfmolar.ValueInSI = 0; } performMassBalance(stream, stream.KValues); performDensityUpdate(stream); performEnthalpyUpdate(stream); }
Dictionary <string, Compound> GenerateCompounds(IUnitsOfMeasure su) { //generate pseudos from number or temperature cuts int i = 0; int method = pseudomode; double[] tbp2 = null; double[] tbpx = null; var fittedt = new List <double>(); double[] coeff; object[] obj = null; double Tmin, Tmax; //generate polynomial from input data if (tbpcurvetype == 0) { //tbp tbp2 = tbp.ToArray(); tbpx = cb.ToArray(); } else if (tbpcurvetype == 1) { //d86 double T0 = 0; double T10 = 0; double T30 = 0; double T50 = 0; double T70 = 0; double T90 = 0; double T100 = 0; //interpolate to obtain points double[] w = null; ratinterpolation.buildfloaterhormannrationalinterpolant(cb.ToArray(), cb.Count, 1, ref w); T0 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.0d); T10 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.1d); T30 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.3d); T50 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.5d); T70 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.7d); T90 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.9d); T100 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 1.0d); //tbp tbp2 = DistillationCurveConversion.ASTMD86ToPEV_Riazi(new double[] { T0, T10, T30, T50, T70, T90, T100 }); tbpx = new double[] { 1E-06, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0 }; } else if (tbpcurvetype == 2) { //vacuum double T0 = 0; double T10 = 0; double T30 = 0; double T50 = 0; double T70 = 0; double T90 = 0; double T100 = 0; //interpolate to obtain points double[] w = null; ratinterpolation.buildfloaterhormannrationalinterpolant(cb.ToArray(), cb.Count, 1, ref w); T0 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0); T10 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.1); T30 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.3); T50 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.5); T70 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.7); T90 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.9); T100 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 1.0); //tbp tbp2 = DistillationCurveConversion.ASTMD1160ToPEVsub_Wauquier(new double[] { T0, T10, T30, T50, T70, T90, T100 }); double K = 12.0; tbp2[0] = DistillationCurveConversion.PEVsubToPEV_MaxwellBonnel(tbp2[0], 1333, K); tbp2[1] = DistillationCurveConversion.PEVsubToPEV_MaxwellBonnel(tbp2[1], 1333, K); tbp[22] = DistillationCurveConversion.PEVsubToPEV_MaxwellBonnel(tbp2[2], 1333, K); tbp2[3] = DistillationCurveConversion.PEVsubToPEV_MaxwellBonnel(tbp2[3], 1333, K); tbp2[4] = DistillationCurveConversion.PEVsubToPEV_MaxwellBonnel(tbp2[4], 1333, K); tbp2[5] = DistillationCurveConversion.PEVsubToPEV_MaxwellBonnel(tbp2[5], 1333, K); tbp2[6] = DistillationCurveConversion.PEVsubToPEV_MaxwellBonnel(tbp2[6], 1333, K); tbpx = new double[] { 1E-06, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0 }; } else if (tbpcurvetype == 3) { //simulated double T5 = 0; double T10 = 0; double T30 = 0; double T50 = 0; double T70 = 0; double T90 = 0; double T95 = 0; double T100 = 0; //interpolate to obtain points double[] w = null; ratinterpolation.buildfloaterhormannrationalinterpolant(cb.ToArray(), cb.Count, 1, ref w); T5 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.05); T10 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.1); T30 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.3); T50 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.5); T70 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.7); T90 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.9); T95 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 0.95); T100 = polinterpolation.barycentricinterpolation(cb.ToArray(), tbp.ToArray(), w, cb.Count, 1.0); //tbp tbp2 = DistillationCurveConversion.ASTMD2887ToPEV_Daubert(new double[] { T5, T10, T30, T50, T70, T90, T95, T100 }); tbpx = new double[] { 0.05, 0.1, 0.3, 0.5, 0.7, 0.9, 0.95, 1.0 }; } Tmin = tbp2.Min(); Tmax = tbp2.Max(); //y = 10358x5 - 15934x4 + 11822x3 - 4720,2x2 + 1398,2x + 269,23 //R² = 1 double[] inest = new double[7]; if (tbpcurvetype == 1) { double[] w2 = null; ratinterpolation.buildfloaterhormannrationalinterpolant(tbpx, tbpx.Length, 1, ref w2); inest[0] = polinterpolation.barycentricinterpolation(tbpx, tbp2, w2, tbpx.Length, 0); } else { inest[0] = Tmin; } inest[1] = 1398; inest[2] = 4720; inest[3] = 11821; inest[4] = 15933; inest[5] = 10358; inest[6] = -3000; DistillationCurveConversion.TBPFit lmfit = new DistillationCurveConversion.TBPFit(); obj = (object[])lmfit.GetCoeffs(tbpx, tbp2, inest, 1E-10, 1E-08, 1E-08, 1000); coeff = (double[])obj[0]; //TBP(K) = aa + bb*fv + cc*fv^2 + dd*fv^3 + ee*fv^4 + ff*fv^5 (fv 0 ~ 1) fittedt.Clear(); for (i = 0; i <= tbp2.Length - 1; i++) { fittedt.Add(cv.ConvertFromSI(su.temperature, coeff[0] + coeff[1] * tbpx[i] + coeff[2] * Math.Pow(tbpx[i], 2) + coeff[3] * Math.Pow(tbpx[i], 3) + coeff[4] * Math.Pow(tbpx[i], 4) + coeff[5] * Math.Pow(tbpx[i], 5) + coeff[6] * Math.Pow(tbpx[i], 6))); } //create pseudos if (method == 0) { int np = Convert.ToInt32(pseudocuts); double deltaT = (Tmax - Tmin) / (np); double t0 = 0; double fv0 = 0; t0 = Tmin; fv0 = tbpx.Min(); tccol.Clear(); for (i = 0; i <= np - 1; i++) { tmpcomp tc = new tmpcomp(); tc.tbp0 = t0; tc.tbpf = t0 + deltaT; tc.fv0 = GetFV(coeff, fv0, tc.tbp0); tc.fvf = GetFV(coeff, fv0, tc.tbpf); tc.fvm = tc.fv0 + (tc.fvf - tc.fv0) / 2; tc.tbpm = GetT(coeff, tc.fvm); tccol.Add(tc); t0 = t0 + deltaT; fv0 = tc.fvf; } } else { int np = cuttemps.Count + 1; double t0 = 0; double fv0 = 0; t0 = Tmin; fv0 = tbpx.Min(); tccol.Clear(); for (i = 0; i <= np - 1; i++) { tmpcomp tc = new tmpcomp(); tc.tbp0 = t0; if (i == np - 1) { tc.tbpf = Tmax; } else { tc.tbpf = cv.ConvertToSI(su.temperature, cuttemps[i]); } tc.fv0 = GetFV(coeff, fv0, tc.tbp0); tc.fvf = GetFV(coeff, fv0, tc.tbpf); tc.fvm = tc.fv0 + (tc.fvf - tc.fv0) / 2; tc.tbpm = GetT(coeff, tc.fvm); tccol.Add(tc); fv0 = tc.fvf; if (i < np - 1) { t0 = cv.ConvertToSI(su.temperature, cuttemps[i]); } } } DWSIM.Thermodynamics.Utilities.PetroleumCharacterization.Methods.GL methods2 = new DWSIM.Thermodynamics.Utilities.PetroleumCharacterization.Methods.GL(); Dictionary <string, Compound> ccol = new Dictionary <string, Compound>(); i = 0; foreach (tmpcomp tc in tccol) { ConstantProperties cprops = new ConstantProperties(); cprops.NBP = tc.tbpm; cprops.OriginalDB = "Petroleum Assay: " + assayname; cprops.CurrentDB = "Petroleum Assay: " + assayname; cprops.Name = assayname + "_" + (i + 1).ToString(); //SG if (!hassgc) { if (Math.Abs(cprops.PF_MM.GetValueOrDefault()) < 1e-10) { cprops.PF_MM = Math.Pow((1 / 0.01964 * (6.97996 - Math.Log(1080 - cprops.NBP.GetValueOrDefault()))), (3 / 2)); } cprops.PF_SG = PropertyMethods.d15_Riazi(cprops.PF_MM.GetValueOrDefault()); } else { double[] w = null; ratinterpolation.buildfloaterhormannrationalinterpolant(this.cb.ToArray(), cb.Count, 1, ref w); cprops.PF_SG = polinterpolation.barycentricinterpolation(cb.ToArray(), sgc.ToArray(), w, cb.Count(), tc.fvm); } //MW if (!hasmwc) { switch (type) { case SampleType.Light: cprops.PF_MM = PropertyMethods.MW_Winn(cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); break; case SampleType.Average: cprops.PF_MM = PropertyMethods.MW_Riazi(cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); break; case SampleType.Heavy: cprops.PF_MM = PropertyMethods.MW_LeeKesler(cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); break; } } else { double[] w = null; ratinterpolation.buildfloaterhormannrationalinterpolant(this.cb.ToArray(), cb.Count(), 1, ref w); cprops.PF_MM = polinterpolation.barycentricinterpolation(this.cb.ToArray(), mwc.ToArray(), w, cb.Count(), tc.fvm); } cprops.Molar_Weight = cprops.PF_MM.GetValueOrDefault(); i += 1; Compound subst = new Compound(cprops.Name, ""); subst.ConstantProperties = cprops; subst.Name = cprops.Name; subst.PetroleumFraction = true; ccol.Add(cprops.Name, subst); } CalculateMolarFractions(ccol); if (mwb > 1E-10) { double mixtMW = 0; foreach (var c in ccol.Values) { mixtMW += c.MoleFraction.GetValueOrDefault() * c.ConstantProperties.Molar_Weight; } double facm = mwb / mixtMW; foreach (var c in ccol.Values) { c.ConstantProperties.Molar_Weight *= facm; } } if (sgb > 1E-10) { double mixtD = 0; foreach (var c in ccol.Values) { mixtD += c.MassFraction.GetValueOrDefault() * c.ConstantProperties.PF_SG.GetValueOrDefault(); } double facd = 141.5 / (131.5 + sgb) / mixtD; foreach (var c in ccol.Values) { c.ConstantProperties.PF_SG *= facd; } } i = 0; foreach (var subst in ccol.Values) { ConstantProperties cprops = (ConstantProperties)subst.ConstantProperties; tmpcomp tc = tccol[i]; //VISC if (!hasvisc100c) { cprops.PF_Tv1 = 311; cprops.PF_Tv2 = 372; cprops.PF_v1 = PropertyMethods.Visc37_Abbott(cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); cprops.PF_v2 = PropertyMethods.Visc98_Abbott(cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); } else { double[] w = null; ratinterpolation.buildfloaterhormannrationalinterpolant(cb.ToArray(), visc100.Count, 1, ref w); cprops.PF_v1 = polinterpolation.barycentricinterpolation(cb.ToArray(), visc100.ToArray(), w, cb.Count, tc.fvm); ratinterpolation.buildfloaterhormannrationalinterpolant(cb.ToArray(), visc210.Count, 1, ref w); cprops.PF_v2 = polinterpolation.barycentricinterpolation(cb.ToArray(), visc210.ToArray(), w, cb.Count, tc.fvm); cprops.PF_Tv1 = (100 - 32) / 9 * 5 + 273.15; cprops.PF_Tv2 = (210 - 32) / 9 * 5 + 273.15; } cprops.PF_vA = PropertyMethods.ViscWaltherASTM_A(cprops.PF_Tv1.GetValueOrDefault(), cprops.PF_v1.GetValueOrDefault(), cprops.PF_Tv2.GetValueOrDefault(), cprops.PF_v2.GetValueOrDefault()); cprops.PF_vB = PropertyMethods.ViscWaltherASTM_B(cprops.PF_Tv1.GetValueOrDefault(), cprops.PF_v1.GetValueOrDefault(), cprops.PF_Tv2.GetValueOrDefault(), cprops.PF_v2.GetValueOrDefault()); //Tc switch (type) { case SampleType.Light: cprops.Critical_Temperature = PropertyMethods.Tc_RiaziDaubert(cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); break; case SampleType.Average: cprops.Critical_Temperature = PropertyMethods.Tc_LeeKesler(cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); break; case SampleType.Heavy: cprops.Critical_Temperature = PropertyMethods.Tc_Farah(cprops.PF_vA.GetValueOrDefault(), cprops.PF_vB.GetValueOrDefault(), cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); break; } //Pc switch (type) { case SampleType.Light: cprops.Critical_Pressure = PropertyMethods.Pc_RiaziDaubert(cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); break; case SampleType.Average: cprops.Critical_Pressure = PropertyMethods.Pc_LeeKesler(cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); break; case SampleType.Heavy: cprops.Critical_Pressure = PropertyMethods.Pc_Farah(cprops.PF_vA.GetValueOrDefault(), cprops.PF_vB.GetValueOrDefault(), cprops.NBP.GetValueOrDefault(), cprops.PF_SG.GetValueOrDefault()); break; } //Af switch (type) { case SampleType.Heavy: cprops.Acentric_Factor = PropertyMethods.AcentricFactor_LeeKesler(cprops.Critical_Temperature, cprops.Critical_Pressure, cprops.NBP.GetValueOrDefault()); break; case SampleType.Light: case SampleType.Average: cprops.Acentric_Factor = PropertyMethods.AcentricFactor_Korsten(cprops.Critical_Temperature, cprops.Critical_Pressure, cprops.NBP.GetValueOrDefault()); break; } cprops.Normal_Boiling_Point = cprops.NBP.GetValueOrDefault(); cprops.IsPF = 1; cprops.PF_Watson_K = Math.Pow((1.8 * cprops.NBP.GetValueOrDefault()), (1 / 3)) / cprops.PF_SG.GetValueOrDefault(); var tmp = (object[])methods2.calculate_Hf_Sf(cprops.PF_SG.GetValueOrDefault(), cprops.Molar_Weight, cprops.NBP.GetValueOrDefault()); cprops.IG_Enthalpy_of_Formation_25C = (double)tmp[0]; cprops.IG_Entropy_of_Formation_25C = (double)tmp[1]; cprops.IG_Gibbs_Energy_of_Formation_25C = (double)tmp[0] - 298.15 * (double)tmp[1]; DWSIM.Thermodynamics.Utilities.Hypos.Methods.HYP methods = new DWSIM.Thermodynamics.Utilities.Hypos.Methods.HYP(); cprops.HVap_A = methods.DHvb_Vetere(cprops.Critical_Temperature, cprops.Critical_Pressure, cprops.Normal_Boiling_Point) / cprops.Molar_Weight; cprops.Critical_Compressibility = DWSIM.Thermodynamics.PropertyPackages.Auxiliary.PROPS.Zc1(cprops.Acentric_Factor); cprops.Critical_Volume = 8314 * cprops.Critical_Compressibility * cprops.Critical_Temperature / cprops.Critical_Pressure; cprops.Z_Rackett = DWSIM.Thermodynamics.PropertyPackages.Auxiliary.PROPS.Zc1(cprops.Acentric_Factor); if (cprops.Z_Rackett < 0) { cprops.Z_Rackett = 0.2; } cprops.Chao_Seader_Acentricity = cprops.Acentric_Factor; cprops.Chao_Seader_Solubility_Parameter = Math.Pow(((cprops.HVap_A * cprops.Molar_Weight - 8.314 * cprops.Normal_Boiling_Point) * 238.846 * DWSIM.Thermodynamics.PropertyPackages.Auxiliary.PROPS.liq_dens_rackett(cprops.Normal_Boiling_Point, cprops.Critical_Temperature, cprops.Critical_Pressure, cprops.Acentric_Factor, cprops.Molar_Weight) / cprops.Molar_Weight / 1000000.0), 0.5); cprops.Chao_Seader_Liquid_Molar_Volume = 1 / DWSIM.Thermodynamics.PropertyPackages.Auxiliary.PROPS.liq_dens_rackett(cprops.Normal_Boiling_Point, cprops.Critical_Temperature, cprops.Critical_Pressure, cprops.Acentric_Factor, cprops.Molar_Weight) * cprops.Molar_Weight / 1000 * 1000000.0; methods = null; cprops.ID = 30000 + i + 1; i += 1; } //Adjust Acentric Factors and Rackett parameters to fit NBP and Density DensityFitting dfit = new DensityFitting(); PRVSFitting prvsfit = new PRVSFitting(); SRKVSFitting srkvsfit = new SRKVSFitting(); NBPFitting nbpfit = new NBPFitting(); MaterialStream tms = new MaterialStream("", ""); PropertyPackage pp = default(PropertyPackage); double fzra = 0; double fw = 0; double fprvs = 0; double fsrkvs = 0; if (flowsheet.PropertyPackages.Count > 0) { pp = (DWSIM.Thermodynamics.PropertyPackages.PropertyPackage)flowsheet.PropertyPackages.Values.First(); } else { pp = new PengRobinsonPropertyPackage(); } foreach (var c in ccol.Values) { tms.Phases[0].Compounds.Add(c.Name, c); } bool recalcVc = false; i = 0; foreach (var c in ccol.Values) { var _with4 = nbpfit; _with4._pp = pp; _with4._ms = tms; _with4._idx = i; try { fw = _with4.MinimizeError(); } catch (Exception ex) { flowsheet.ShowMessage("Error fitting Acentric Factor for compound '" + c.Name + "': " + ex.Message, IFlowsheet.MessageType.GeneralError); } var _with5 = c.ConstantProperties; c.ConstantProperties.Acentric_Factor *= fw; c.ConstantProperties.Z_Rackett = DWSIM.Thermodynamics.PropertyPackages.Auxiliary.PROPS.Zc1(c.ConstantProperties.Acentric_Factor); if (_with5.Z_Rackett < 0) { _with5.Z_Rackett = 0.2; recalcVc = true; } _with5.Critical_Compressibility = DWSIM.Thermodynamics.PropertyPackages.Auxiliary.PROPS.Zc1(_with5.Acentric_Factor); _with5.Critical_Volume = DWSIM.Thermodynamics.PropertyPackages.Auxiliary.PROPS.Vc(_with5.Critical_Temperature, _with5.Critical_Pressure, _with5.Acentric_Factor, _with5.Critical_Compressibility); var _with6 = dfit; _with6._comp = c; try { fzra = _with6.MinimizeError(); } catch (Exception ex) { flowsheet.ShowMessage("Error fitting Rackett Parameter for compound '" + c.Name + "': " + ex.Message, IFlowsheet.MessageType.GeneralError); } var _with7 = c.ConstantProperties; _with7.Z_Rackett *= fzra; if (_with7.Critical_Compressibility < 0 | recalcVc) { _with7.Critical_Compressibility = _with7.Z_Rackett; _with7.Critical_Volume = DWSIM.Thermodynamics.PropertyPackages.Auxiliary.PROPS.Vc(_with7.Critical_Temperature, _with7.Critical_Pressure, _with7.Acentric_Factor, _with7.Critical_Compressibility); } c.ConstantProperties.PR_Volume_Translation_Coefficient = 1; prvsfit._comp = c; fprvs = prvsfit.MinimizeError(); var _with8 = c.ConstantProperties; if (Math.Abs(fprvs) < 99.0) { _with8.PR_Volume_Translation_Coefficient *= fprvs; } else { _with8.PR_Volume_Translation_Coefficient = 0.0; } c.ConstantProperties.SRK_Volume_Translation_Coefficient = 1; srkvsfit._comp = c; fsrkvs = srkvsfit.MinimizeError(); var _with9 = c.ConstantProperties; if (Math.Abs(fsrkvs) < 99.0) { _with9.SRK_Volume_Translation_Coefficient *= fsrkvs; } else { _with9.SRK_Volume_Translation_Coefficient = 0.0; } recalcVc = false; i += 1; } pp = null; dfit = null; nbpfit = null; tms = null; return(ccol); }
string WriteStreamReport(MaterialStream stream) { StringBuilder sb = new StringBuilder(); sb.AppendLine("Material Stream: " + stream.Name); sb.AppendLine(); sb.AppendLine(stream.Vfmolar.WriteReport()); sb.AppendLine(stream.Mixed.Temperature.WriteReport()); sb.AppendLine(stream.Mixed.Pressure.WriteReport()); sb.AppendLine(stream.Mixed.SpecificEnthalpy.WriteReport()); sb.AppendLine(stream.Mixed.TotalEnthalpy.WriteReport()); //sb.AppendLine(stream.Mixed.TotalMolarflow.WriteReport()); //sb.AppendLine(stream.Mixed.TotalMassflow.WriteReport()); sb.AppendLine(stream.Mixed.TotalVolumeflow.WriteReport()); sb.AppendLine(String.Format("{0,-25} = {1, 12}", "Phase", stream.State)); sb.AppendLine(""); sb.AppendLine("Mixed"); sb.Append(String.Format("{0,-12}", "Component")); sb.Append(String.Format("{0,15}", "Mole Flow")); sb.Append(String.Format("{0,15}", "Mole Fraction")); sb.Append(String.Format("{0,15}", "Mass Flow")); sb.AppendLine(String.Format("{0,15}", "Mass Fraction")); sb.Append(String.Format("{0,-12}", "")); sb.Append(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MolarFlow].Symbol)); sb.Append(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MolarFraction].Symbol)); sb.Append(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MassFlow].Symbol)); sb.AppendLine(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MassFraction].Symbol)); for (int i = 0; i < stream.Mixed.ComponentMassflow.Count; i++) { if (stream.Mixed.ComponentMolarflow[i].ValueInOutputUnit < 1e-10) { continue; } sb.Append(String.Format(" {0,-10}", stream.System.Components[i].ID)); sb.Append(String.Format("{0,15}", stream.Mixed.ComponentMolarflow[i].ValueInOutputUnit.ToString("0.0000"))); sb.Append(String.Format("{0,15}", stream.Mixed.ComponentMolarFraction[i].ValueInOutputUnit.ToString("0.0000"))); sb.Append(String.Format("{0,15}", stream.Mixed.ComponentMassflow[i].ValueInOutputUnit.ToString("0.0000"))); sb.AppendLine(String.Format("{0,15}", stream.Mixed.ComponentMassFraction[i].ValueInOutputUnit.ToString("0.0000"))); } sb.Append(String.Format(" {0,-10}", "Sum")); sb.Append(String.Format("{0,15}", stream.Mixed.TotalMolarflow.ValueInOutputUnit.ToString("0.0000"))); sb.Append(String.Format("{0,15}", "")); sb.AppendLine(String.Format("{0,15}", stream.Mixed.TotalMassflow.ValueInOutputUnit.ToString("0.0000"))); if (stream.Vapor.TotalMolarflow.ValueInSI > 1e-6) { sb.AppendLine(""); sb.AppendLine("Vapor"); sb.Append(String.Format("{0,-12}", "Component")); sb.Append(String.Format("{0,15}", "Mole Flow")); sb.Append(String.Format("{0,15}", "Mole Fraction")); sb.Append(String.Format("{0,15}", "Mass Flow")); sb.AppendLine(String.Format("{0,15}", "Mass Fraction")); sb.Append(String.Format("{0,-12}", "")); sb.Append(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MolarFlow].Symbol)); sb.Append(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MolarFraction].Symbol)); sb.Append(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MassFlow].Symbol)); sb.AppendLine(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MassFraction].Symbol)); for (int i = 0; i < stream.Mixed.ComponentMassflow.Count; i++) { if (stream.Vapor.ComponentMolarflow[i].ValueInOutputUnit < 1e-10) { continue; } sb.Append(String.Format(" {0,-10}", stream.System.Components[i].ID)); sb.Append(String.Format("{0,15}", stream.Vapor.ComponentMolarflow[i].ValueInOutputUnit.ToString("0.0000"))); sb.Append(String.Format("{0,15}", stream.Vapor.ComponentMolarFraction[i].ValueInOutputUnit.ToString("0.0000"))); sb.Append(String.Format("{0,15}", stream.Vapor.ComponentMassflow[i].ValueInOutputUnit.ToString("0.0000"))); sb.AppendLine(String.Format("{0,15}", stream.Vapor.ComponentMassFraction[i].ValueInOutputUnit.ToString("0.0000"))); } sb.Append(String.Format(" {0,-10}", "Sum")); sb.Append(String.Format("{0,15}", stream.Vapor.TotalMolarflow.ValueInOutputUnit.ToString("0.0000"))); sb.Append(String.Format("{0,15}", "")); sb.AppendLine(String.Format("{0,15}", stream.Vapor.TotalMassflow.ValueInOutputUnit.ToString("0.0000"))); } if (stream.Liquid.TotalMolarflow.ValueInSI > 1e-6) { sb.AppendLine(""); sb.AppendLine("Liquid"); sb.Append(String.Format("{0,-12}", "Component")); sb.Append(String.Format("{0,15}", "Mole Flow")); sb.Append(String.Format("{0,15}", "Mole Fraction")); sb.Append(String.Format("{0,15}", "Mass Flow")); sb.AppendLine(String.Format("{0,15}", "Mass Fraction")); sb.Append(String.Format("{0,-12}", "")); sb.Append(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MolarFlow].Symbol)); sb.Append(String.Format("{0,15}", "%")); sb.Append(String.Format("{0,15}", stream.System.VariableFactory.Output.UnitDictionary[OpenFMSL.Core.UnitsOfMeasure.PhysicalDimension.MassFlow].Symbol)); sb.AppendLine(String.Format("{0,15}", "w-%")); for (int i = 0; i < stream.Liquid.ComponentMassflow.Count; i++) { if (stream.Liquid.ComponentMolarflow[i].ValueInOutputUnit < 1e-10) { continue; } sb.Append(String.Format(" {0,-10}", stream.System.Components[i].ID)); sb.Append(String.Format("{0,15}", stream.Liquid.ComponentMolarflow[i].ValueInOutputUnit.ToString("0.0000"))); sb.Append(String.Format("{0,15}", stream.Liquid.ComponentMolarFraction[i].ValueInOutputUnit.ToString("0.0000"))); sb.Append(String.Format("{0,15}", stream.Liquid.ComponentMassflow[i].ValueInOutputUnit.ToString("0.0000"))); sb.AppendLine(String.Format("{0,15}", stream.Liquid.ComponentMassFraction[i].ValueInOutputUnit.ToString("0.0000"))); } sb.Append(String.Format(" {0,-10}", "Sum")); sb.Append(String.Format("{0,15}", stream.Liquid.TotalMolarflow.ValueInOutputUnit.ToString("0.0000"))); sb.Append(String.Format("{0,15}", "")); sb.AppendLine(String.Format("{0,15}", stream.Liquid.TotalMassflow.ValueInOutputUnit.ToString("0.0000"))); } return(sb.ToString()); }
public override ProcessUnit Initialize() { int NC = System.Components.Count; var In = FindMaterialPort("In"); var Vap = FindMaterialPort("VOut"); var Liq = FindMaterialPort("LOut"); var VIN = FindMaterialPort("VIn"); var LIN = FindMaterialPort("LIn"); var flash = new FlashRoutines(new Numerics.Solvers.Newton()); var flashStream = new MaterialStream("FLASH", System); flashStream.CopyFrom(In.Streams[0]); for (int i = 0; i < NC; i++) { flashStream.Mixed.ComponentMolarflow[i].ValueInSI += LIN.Streams[0].Mixed.ComponentMolarflow[i].ValueInSI + VIN.Streams[0].Mixed.ComponentMolarflow[i].ValueInSI; } if (p.IsFixed) { flashStream.Specify("p", p.ValueInSI); } else if (dp.IsFixed) { flashStream.Specify("p", In.Streams[0].Mixed.Pressure.ValueInSI - dp.ValueInSI); } flashStream.Specify("T", In.Streams[0].Mixed.Temperature.ValueInSI); flash.CalculateTP(flashStream); var eval = new Evaluator(); for (int i = 0; i < NC; i++) { Vap.Streams[0].Mixed.ComponentMolarflow[i].ValueInSI = (flashStream.Vapor.ComponentMolarflow[i]).Eval(eval); Liq.Streams[0].Mixed.ComponentMolarflow[i].ValueInSI = (flashStream.Liquid.ComponentMolarflow[i]).Eval(eval); } if (T.IsFixed) { Vap.Streams[0].Mixed.Temperature.ValueInSI = T.ValueInSI; Liq.Streams[0].Mixed.Temperature.ValueInSI = T.ValueInSI; } else { Vap.Streams[0].Mixed.Temperature.ValueInSI = flashStream.Mixed.Temperature.ValueInSI; Liq.Streams[0].Mixed.Temperature.ValueInSI = flashStream.Mixed.Temperature.ValueInSI; T.ValueInSI = flashStream.Mixed.Temperature.ValueInSI; } if (p.IsFixed) { Vap.Streams[0].Mixed.Pressure.ValueInSI = p.ValueInSI; Liq.Streams[0].Mixed.Pressure.ValueInSI = p.ValueInSI; } else { Vap.Streams[0].Mixed.Pressure.ValueInSI = flashStream.Mixed.Pressure.ValueInSI; Liq.Streams[0].Mixed.Pressure.ValueInSI = flashStream.Mixed.Pressure.ValueInSI; p.ValueInSI = flashStream.Mixed.Pressure.ValueInSI; } if (!Q.IsFixed) { Q.ValueInSI = -(In.Streams[0].Mixed.SpecificEnthalpy * In.Streams[0].Mixed.TotalMolarflow - Liq.Streams[0].Mixed.SpecificEnthalpy * Liq.Streams[0].Mixed.TotalMolarflow - Vap.Streams[0].Mixed.SpecificEnthalpy * Vap.Streams[0].Mixed.TotalMolarflow).Eval(eval); } Vap.Streams[0].GetVariable("VF").SetValue(1); Liq.Streams[0].GetVariable("VF").SetValue(0); flash.CalculateTP(Vap.Streams[0]); flash.CalculateTP(Liq.Streams[0]); Vap.Streams[0].State = PhaseState.DewPoint; Liq.Streams[0].State = PhaseState.BubblePoint; return(this); }
void Init() { Padding = new Padding(10); mw0 = 80.0f; sg0 = 0.70f; nbp0 = 333.0f; t1 = 38 + 273.15; t2 = 98.9 + 273.15; assayname = "OIL"; v1 = 0; v2 = 0; var su = flowsheet.FlowsheetOptions.SelectedUnitSystem; var nf = flowsheet.FlowsheetOptions.NumberFormat; s.CreateAndAddLabelRow(this, "Assay Identification"); s.CreateAndAddStringEditorRow(this, "Assay Name", assayname, (arg3, arg2) => { assayname = arg3.Text; }); s.CreateAndAddDescriptionRow(this, "Enter the name of the assay. It will be used to identify the Material Stream on the flowsheet and the associated compounds as well."); s.CreateAndAddLabelRow(this, "Property Methods"); s.CreateAndAddDescriptionRow(this, "Select the methods to calculate compound properties."); s.CreateAndAddDropDownRow(this, "Molecular Weight", new List <string>() { "Winn (1956)", "Riazi (1986)", "Lee-Kesler (1974)" }, 0, (arg3, arg2) => { MWcorr = arg3.SelectedValue.ToString(); }); s.CreateAndAddDropDownRow(this, "Critical Temperature", new List <string>() { "Riazi-Daubert (1985)", "Riazi (2005)", "Lee-Kesler (1976)", "Farah (2006)" }, 0, (arg3, arg2) => { Tccorr = arg3.SelectedValue.ToString(); }); s.CreateAndAddDropDownRow(this, "Critical Pressure", new List <string>() { "Riazi-Daubert (1985)", "Lee-Kesler (1976)", "Farah (2006)" }, 0, (arg3, arg2) => { Pccorr = arg3.SelectedValue.ToString(); }); s.CreateAndAddDropDownRow(this, "Acentric Factor", new List <string>() { "Lee-Kesler (1976)", "Korsten (2000)" }, 0, (arg3, arg2) => { AFcorr = arg3.SelectedValue.ToString(); }); s.CreateAndAddCheckBoxRow(this, "Adjust Acentric Factors to match Normal Boiling Temperatures", adjustAf, (arg1, arg2) => { adjustAf = arg1.Checked.GetValueOrDefault(); }, null); s.CreateAndAddCheckBoxRow(this, "Adjust Rackett Parameters to match Specific Gravities", adjustZR, (arg1, arg2) => { adjustZR = arg1.Checked.GetValueOrDefault(); }, null); s.CreateAndAddLabelRow(this, "Assay Properties"); s.CreateAndAddDescriptionRow(this, "Define at least one of the following three properties in order to calculate a property distribution."); s.CreateAndAddTextBoxRow(this, nf, "Molar Weight", mw.GetValueOrDefault(), (arg3, arg2) => { if (s.IsValidDouble(arg3.Text)) { mw = Double.Parse(arg3.Text); } }); s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available."); s.CreateAndAddTextBoxRow(this, nf, "Specific Gravity", sg.GetValueOrDefault(), (arg3, arg2) => { if (s.IsValidDouble(arg3.Text)) { sg = Double.Parse(arg3.Text); } }); s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available."); s.CreateAndAddTextBoxRow(this, nf, "Average NBP (" + su.temperature + ")", cv.ConvertFromSI(su.temperature, nbp.GetValueOrDefault()), (arg3, arg2) => { if (s.IsValidDouble(arg3.Text)) { nbp = cv.ConvertToSI(su.temperature, Double.Parse(arg3.Text)); } }); s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available."); s.CreateAndAddLabelRow(this, "Initial Values for Property Distribution"); s.CreateAndAddTextBoxRow(this, nf, "Molar Weight", mw0, (arg3, arg2) => { if (s.IsValidDouble(arg3.Text)) { mw0 = Double.Parse(arg3.Text); } }); s.CreateAndAddDescriptionRow(this, "This defines the Molar Weight of the lightest compound in the assay."); s.CreateAndAddTextBoxRow(this, nf, "Specific Gravity", sg0, (arg3, arg2) => { if (s.IsValidDouble(arg3.Text)) { sg0 = Double.Parse(arg3.Text); } }); s.CreateAndAddDescriptionRow(this, "This defines the Specific Gravity of the lightest compound in the assay."); s.CreateAndAddTextBoxRow(this, nf, "Normal Boiling Point (" + su.temperature + ")", cv.ConvertFromSI(su.temperature, nbp0), (arg3, arg2) => { if (s.IsValidDouble(arg3.Text)) { nbp0 = cv.ConvertToSI(su.temperature, Double.Parse(arg3.Text)); } }); s.CreateAndAddDescriptionRow(this, "This defines the Normal Boiling Point of the lightest compound in the assay."); s.CreateAndAddLabelRow(this, "Pseudo Compounds"); s.CreateAndAddTextBoxRow(this, "N0", "Number of Compounds", ncomps, (arg3, arg2) => { if (s.IsValidDouble(arg3.Text)) { ncomps = int.Parse(arg3.Text); } }); s.CreateAndAddDescriptionRow(this, "Specify the number of compounds to be generated that, together, will represent the assay. The generated compounds will be added to the simulation and a Material Stream will be created with distribution-defined amounts of these compounds."); s.CreateAndAddButtonRow(this, "Characterize Assay and Create Compounds", null, (arg3, arg2) => { var dialog = ProgressDialog.Show(this, "Petroleum C7+ Characterization", "Generating compounds, please wait...", false); var comps = new Dictionary <string, ICompound>(); Task.Factory.StartNew(() => { comps = new GenerateCompounds().GenerateCompounds(assayname, ncomps, Tccorr, Pccorr, AFcorr, MWcorr, adjustAf, adjustZR, mw, sg, nbp, v1, v2, t1, t2, mw0, sg0, nbp0); }).ContinueWith((t) => { Application.Instance.Invoke(() => { dialog.Close(); }); if (t.Exception == null) { var assay = new DWSIM.SharedClasses.Utilities.PetroleumCharacterization.Assay.Assay(mw.GetValueOrDefault(), sg.GetValueOrDefault(), nbp.GetValueOrDefault(), t1, t2, v1, v2); var ms2 = new MaterialStream("", ""); ms2.SetFlowsheet(flowsheet); if (flowsheet.PropertyPackages.Count > 0) { ms2.SetPropertyPackage(flowsheet.PropertyPackages.Values.First()); } else { ms2.SetPropertyPackage(new Thermodynamics.PropertyPackages.PengRobinsonPropertyPackage()); } foreach (var subst in comps.Values) { ms2.Phases[0].Compounds.Add(subst.Name, subst); ms2.Phases[1].Compounds.Add(subst.Name, new Compound(subst.Name, "") { ConstantProperties = subst.ConstantProperties }); ms2.Phases[2].Compounds.Add(subst.Name, new Compound(subst.Name, "") { ConstantProperties = subst.ConstantProperties }); ms2.Phases[3].Compounds.Add(subst.Name, new Compound(subst.Name, "") { ConstantProperties = subst.ConstantProperties }); ms2.Phases[4].Compounds.Add(subst.Name, new Compound(subst.Name, "") { ConstantProperties = subst.ConstantProperties }); ms2.Phases[5].Compounds.Add(subst.Name, new Compound(subst.Name, "") { ConstantProperties = subst.ConstantProperties }); ms2.Phases[6].Compounds.Add(subst.Name, new Compound(subst.Name, "") { ConstantProperties = subst.ConstantProperties }); ms2.Phases[7].Compounds.Add(subst.Name, new Compound(subst.Name, "") { ConstantProperties = subst.ConstantProperties }); } var qc = new Thermodynamics.QualityCheck(assay, ms2); qc.DoQualityCheck(); Application.Instance.Invoke(() => { qc.DisplayForm((c) => { Application.Instance.Invoke(() => { var form = s.GetDefaultEditorForm("Compound Properties: " + c.Name, 800, 600, new CompoundViewer((Flowsheet)flowsheet, c), false); form.Show(); }); }, () => { foreach (var comp in comps.Values) { if (!flowsheet.AvailableCompounds.ContainsKey(comp.Name)) { flowsheet.AvailableCompounds.Add(comp.Name, comp.ConstantProperties); } flowsheet.SelectedCompounds.Add(comp.Name, flowsheet.AvailableCompounds[comp.Name]); foreach (MaterialStream obj in flowsheet.SimulationObjects.Values.Where((x) => x.GraphicObject.ObjectType == ObjectType.MaterialStream)) { foreach (var phase in obj.Phases.Values) { phase.Compounds.Add(comp.Name, new Thermodynamics.BaseClasses.Compound(comp.Name, "")); phase.Compounds[comp.Name].ConstantProperties = flowsheet.SelectedCompounds[comp.Name]; } } } var ms = (MaterialStream)flowsheet.AddObject(ObjectType.MaterialStream, 100, 100, assayname); double wtotal = comps.Values.Select((x) => x.MoleFraction.GetValueOrDefault() * x.ConstantProperties.Molar_Weight).Sum(); foreach (var c in ms.Phases[0].Compounds.Values) { c.MassFraction = 0.0f; c.MoleFraction = 0.0f; } foreach (var c in comps.Values) { c.MassFraction = c.MoleFraction.GetValueOrDefault() * c.ConstantProperties.Molar_Weight / wtotal; ms.Phases[0].Compounds[c.Name].MassFraction = c.MassFraction.GetValueOrDefault(); ms.Phases[0].Compounds[c.Name].MoleFraction = c.MoleFraction.GetValueOrDefault(); } Application.Instance.Invoke(() => { flowsheet.UpdateInterface(); flowsheet.ShowMessage("Material Stream '" + assayname + "' added successfully. " + ncomps.ToString() + " compounds created.", IFlowsheet.MessageType.Information); if (MessageBox.Show("Do you want to export the created compounds to a XML database?", "Petroleum C7+ Characterization", MessageBoxButtons.YesNo, MessageBoxType.Question, MessageBoxDefaultButton.Yes) == DialogResult.Yes) { try { var compstoexport = comps.Values.Select((x) => x.ConstantProperties).ToArray(); var savedialog = new SaveFileDialog(); savedialog.Title = "Save Compounds to XML Database"; savedialog.Filters.Add(new FileFilter("XML File", new[] { ".xml" })); savedialog.CurrentFilterIndex = 0; if (savedialog.ShowDialog(this) == DialogResult.Ok) { try { if (!File.Exists(savedialog.FileName)) { File.WriteAllText(savedialog.FileName, ""); Thermodynamics.Databases.UserDB.CreateNew(savedialog.FileName, "compounds"); } Thermodynamics.Databases.UserDB.AddCompounds(compstoexport, savedialog.FileName, true); flowsheet.ShowMessage("Compounds successfully saved to XML file.", IFlowsheet.MessageType.Information); } catch (Exception ex) { flowsheet.ShowMessage("Error saving compound to JSON file: " + ex.ToString(), IFlowsheet.MessageType.GeneralError); } } } catch (Exception ex) { flowsheet.ShowMessage("Error saving data: " + ex.ToString(), IFlowsheet.MessageType.GeneralError); } } }); }); }); } else { Application.Instance.Invoke(() => { flowsheet.ShowMessage("Error saving data: " + t.Exception.GetBaseException().Message, IFlowsheet.MessageType.GeneralError); }); } }); }); }
public bool CalculateZP(MaterialStream stream) { PrecalculateZP(stream); return(true); }
void Init() { Padding = new Padding(10); var su = flowsheet.FlowsheetOptions.SelectedUnitSystem; var nf = flowsheet.FlowsheetOptions.NumberFormat; var complist = flowsheet.SelectedCompounds.Values.Select((x2) => x2.Name).ToList(); complist.Insert(0, ""); this.CreateAndAddLabelRow("Setup"); this.CreateAndAddDescriptionRow("The Binary Envelope utility calculates Temperature and Pressure VLE/VLLE envelopes for binary mixtures."); var spinnerComp1 = this.CreateAndAddDropDownRow("Compound 1", complist, 0, null); var spinnerComp2 = this.CreateAndAddDropDownRow("Compound 2", complist, 0, null); var spinnerPE = this.CreateAndAddDropDownRow("Envelope Type", Shared.StringArrays.binaryenvelopetype().ToList(), 0, null); var tval = this.CreateAndAddTextBoxRow(nf, "Temperature (" + su.temperature + ")", cv.ConvertFromSI(su.temperature, 298.15f), null); var pval = this.CreateAndAddTextBoxRow(nf, "Pressure (" + su.pressure + ")", cv.ConvertFromSI(su.pressure, 101325.0f), null); var pplist = flowsheet.PropertyPackages.Values.Select((x2) => x2.Tag).ToList(); pplist.Insert(0, ""); var spinnerpp = this.CreateAndAddDropDownRow("Property Package", pplist, 0, null); var button = this.CreateAndAddButtonRow("Build Envelope", null, null); var tabcontainer = new TabControl() { Height = 400 }; var chart = new Eto.OxyPlot.Plot { BackgroundColor = Colors.White }; var txtResults = new TextArea() { ReadOnly = true, Font = Fonts.Monospace(GlobalSettings.Settings.ResultsReportFontSize) }; tabcontainer.Pages.Add(new TabPage(new TableRow(txtResults)) { Text = "Data" }); tabcontainer.Pages.Add(new TabPage(new TableRow(chart)) { Text = "Chart" }); this.CreateAndAddLabelRow("Results"); this.CreateAndAddControlRow(tabcontainer); button.Click += (sender, e) => { if (spinnerPE.SelectedIndex >= 0 && spinnerComp1.SelectedIndex > 0 && spinnerComp2.SelectedIndex > 0 && spinnerpp.SelectedIndex > 0) { var comp1 = flowsheet.SelectedCompounds[complist[spinnerComp1.SelectedIndex]]; var comp2 = flowsheet.SelectedCompounds[complist[spinnerComp2.SelectedIndex]]; var ms = new MaterialStream("", ""); ms.SetFlowsheet(flowsheet); ms.PropertyPackage = (PropertyPackage)flowsheet.PropertyPackages.Values.Where(x => x.Tag == spinnerpp.SelectedValue.ToString()).First(); ms.SetFlowsheet(flowsheet); foreach (var phase in ms.Phases.Values) { phase.Compounds.Add(comp1.Name, new DWSIM.Thermodynamics.BaseClasses.Compound(comp1.Name, "")); phase.Compounds[comp1.Name].ConstantProperties = comp1; phase.Compounds.Add(comp2.Name, new DWSIM.Thermodynamics.BaseClasses.Compound(comp2.Name, "")); phase.Compounds[comp2.Name].ConstantProperties = comp2; } double val; if (Double.TryParse(tval.Text, out val)) { ms.Phases[0].Properties.temperature = cv.ConvertToSI(su.temperature, Double.Parse(tval.Text)); } if (Double.TryParse(pval.Text, out val)) { ms.Phases[0].Properties.pressure = cv.ConvertToSI(su.pressure, Double.Parse(pval.Text)); } var calc = new DWSIM.Thermodynamics.ShortcutUtilities.Calculation(ms); switch (spinnerPE.SelectedIndex) { case 0: calc.CalcType = Thermodynamics.ShortcutUtilities.CalculationType.BinaryEnvelopePxy; break; case 1: calc.CalcType = Thermodynamics.ShortcutUtilities.CalculationType.BinaryEnvelopeTxy; break; } DWSIM.Thermodynamics.ShortcutUtilities.CalculationResults results = null; Task.Factory.StartNew(() => { Application.Instance.Invoke(() => txtResults.Text = "Please wait..."); results = calc.Calculate(); }).ContinueWith((t) => { Application.Instance.Invoke(() => { if (results.ExceptionResult == null) { if (results.PlotModels.Count > 0) { chart.Model = (OxyPlot.PlotModel)results.PlotModels[0]; chart.Invalidate(); txtResults.Text = results.TextOutput; } else { chart.Model = null; txtResults.Text = "Invalid result"; } } else { txtResults.Text = results.ExceptionResult.Message; } }); }); } }; }
void RedrawBinaryAnalysisCharts() { var chart = new ChartModel(); chart.Title = SelectedBinaryAnalysis.ToString() + " [" + BinaryComponent1.ID + " /" + BinaryComponent2.ID + "]"; chart.XAxisTitle = "Molar Composition " + BinaryComponent1.ID + " [mol/mol]"; chart.XMin = 0; chart.XMax = 1; chart.AutoScaleY = true; int steps = 31; List <double> y1Values = new List <double>(); List <double> y2Values = new List <double>(); List <double> x1Values = new List <double>(); List <double> x2Values = new List <double>(); var eval = new Evaluator(); var stream = new MaterialStream("S1", CurrentSystem); foreach (var comp in CurrentSystem.Components) { if (comp != BinaryComponent1 && comp != BinaryComponent2) { stream.Specify("n[" + comp.ID + "]", 0.0); } } var solver = new Newton(); var flashAlgo = new FlashRoutines(solver); switch (SelectedBinaryAnalysis) { case BinaryAnalysisType.PXY: { chart.YAxisTitle = "Pressure [mbar]"; chart.Title += " at " + TemperatureForPX + " °C"; chart.LegendPosition = LegendPosition.TopLeft; stream.Specify("T", TemperatureForPX, METRIC.C); stream.Specify("p", 1000, METRIC.mbar); stream.Specify("n[" + BinaryComponent1.ID + "]", 0.0); stream.Specify("n[" + BinaryComponent2.ID + "]", 1.0); flashAlgo.CalculateTP(stream); stream.Unspecify("p"); stream.Specify("VF", 0); var equationSystem = GetEquationSystem(stream); for (int i = 0; i < steps; i++) { var x1 = (double)i / (double)(steps - 1); var x2 = 1.0 - x1; stream.Specify("n[" + BinaryComponent1.ID + "]", x1); stream.Specify("n[" + BinaryComponent2.ID + "]", x2); solver.Solve(equationSystem); eval.Reset(); x1Values.Add(x1); y1Values.Add(stream.GetVariable("p").ValueInSI / 100.0); } stream.Specify("VF", 1); for (int i = 0; i < steps; i++) { var x1 = (double)i / (double)(steps - 1); var x2 = 1.0 - x1; stream.Specify("n[" + BinaryComponent1.ID + "]", x1); stream.Specify("n[" + BinaryComponent2.ID + "]", x2); solver.Solve(equationSystem); eval.Reset(); x2Values.Add(x1); y2Values.Add(stream.GetVariable("p").ValueInSI / 100.0); } } break; case BinaryAnalysisType.TXY: { chart.YAxisTitle = "Temperature [°C]"; chart.Title += " at " + PressureForTX + " mbar"; chart.LegendPosition = LegendPosition.TopRight; stream.Specify("T", 25, METRIC.C); stream.Specify("p", PressureForTX, METRIC.mbar); stream.Specify("n[" + BinaryComponent1.ID + "]", 0.0); stream.Specify("n[" + BinaryComponent2.ID + "]", 1.0); flashAlgo.CalculateTP(stream); stream.Unspecify("T"); stream.Specify("VF", 0); var equationSystem = GetEquationSystem(stream); for (int i = 0; i < steps; i++) { var x1 = (double)i / (double)(steps - 1); var x2 = 1.0 - x1; stream.Specify("VF", 0); stream.Specify("n[" + BinaryComponent1.ID + "]", x1); stream.Specify("n[" + BinaryComponent2.ID + "]", x2); solver.Solve(equationSystem); eval.Reset(); x1Values.Add(x1); y1Values.Add(stream.GetVariable("T").ValueInSI - 273.15); stream.Specify("VF", 1.0); solver.Solve(equationSystem); eval.Reset(); x2Values.Add(x1); y2Values.Add(stream.GetVariable("T").ValueInSI - 273.150); } } break; case BinaryAnalysisType.XY: { chart.YAxisTitle = "Molar Composition Vapor [mol/mol]"; chart.Title += " at " + PressureForTX + " mbar"; chart.LegendPosition = LegendPosition.TopLeft; stream.Specify("T", 25, METRIC.C); stream.Specify("p", PressureForTX, METRIC.mbar); stream.Specify("n[" + BinaryComponent1.ID + "]", 0.0); stream.Specify("n[" + BinaryComponent2.ID + "]", 1.0); flashAlgo.CalculateTP(stream); stream.Specify("VF", 0); stream.Unspecify("T"); var equationSystem = GetEquationSystem(stream); for (int i = 0; i < steps; i++) { var x1 = (double)i / (double)(steps - 1); var x2 = 1.0 - x1; stream.Specify("n[" + BinaryComponent1.ID + "]", x1); stream.Specify("n[" + BinaryComponent2.ID + "]", x2); solver.Solve(equationSystem); eval.Reset(); x1Values.Add(x1); y1Values.Add(stream.GetVariable("xV[" + BinaryComponent1.ID + "]").ValueInSI); x2Values.Add(x2); y2Values.Add(stream.GetVariable("xV[" + BinaryComponent2.ID + "]").ValueInSI); } } break; } var ySeries1 = new SeriesModel(BinaryComponent1.ID, SeriesType.Line, x1Values, y1Values, "Red"); var ySeries2 = new SeriesModel(BinaryComponent2.ID, SeriesType.Line, x2Values, y2Values, "Blue"); chart.Series.Add(ySeries1); chart.Series.Add(ySeries2); BinaryAnalysisChart = _chartFactory.Create(chart); }
void Init() { pp = new DWSIM.Thermodynamics.PropertyPackages.RaoultPropertyPackage(false); MatStream = new MaterialStream("", "", flowsheet, pp); //add compound to the dummy material stream foreach (var phase in MatStream.Phases.Values) { phase.Compounds.Add(compound.Name, new Compound(compound.Name, "")); phase.Compounds[compound.Name].ConstantProperties = compound; } MatStream.EqualizeOverallComposition(); pp.CurrentMaterialStream = MatStream; var container1 = new DynamicLayout { Padding = new Padding(10), Tag = "Constant" }; AddProperties(container1); var container2 = new DynamicLayout { Padding = new Padding(10), Tag = "Molecular" }; AddMolecularProperties(container2); SetupGraphicalData(); var su = flowsheet.FlowsheetOptions.SelectedUnitSystem; Pages.Add(new TabPage { Content = new Scrollable { Content = container1 }, Text = (string)container1.Tag }); Pages.Add(new TabPage { Content = container2, Text = (string)container2.Tag }); if (!compound.IsSalt && !compound.IsIon && !compound.IsBlackOil) { var tabl = new TabControl(); tabl.Pages.Add(new TabPage { Text = "Heat Capacity", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxLiqCp.ToArray(), vyLiqCp.ToArray(), "Heat Capacity", "", "Temperature" + " (" + su.temperature + ")", "Heat Capacity" + " (" + su.heatCapacityCp + ")") } }); tabl.Pages.Add(new TabPage { Text = "Vapor Pressure", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxPvap.ToArray(), vyPvap.ToArray(), "Vapor Pressure", "", "Temperature" + " (" + su.temperature + ")", "Vapor Pressure" + " (" + su.vaporPressure + ")") } }); tabl.Pages.Add(new TabPage { Text = "Heat of Vaporization", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxDHvap.ToArray(), vyDHvap.ToArray(), "Heat of Vaporization", "", "Temperature" + " (" + su.temperature + ")", "Heat of Vaporization" + " (" + su.enthalpy + ")") } }); tabl.Pages.Add(new TabPage { Text = "Density", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxLD.ToArray(), vyLD.ToArray(), "Density", "", "Temperature", "Density" + " (" + su.density + ")") } }); tabl.Pages.Add(new TabPage { Text = "Viscosity", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxVisc.ToArray(), vyVisc.ToArray(), "Viscosity", "", "Temperature" + " (" + su.temperature + ")", "Viscosity" + " (" + su.viscosity + ")") } }); tabl.Pages.Add(new TabPage { Text = "Thermal Conductivity", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxLiqThCond.ToArray(), vyLiqThCond.ToArray(), "Thermal Conductivity", "", "Temperature", "Thermal Conductivity" + " (" + su.thermalConductivity + ")") } }); tabl.Pages.Add(new TabPage { Text = "Surface Tension", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxSurfTens.ToArray(), vySurfTens.ToArray(), "Surface Tension", "", "Temperature" + " (" + su.temperature + ")", "Surface Tension" + " (" + su.surfaceTension + ")") } }); var tabv = new TabControl(); tabv.Pages.Add(new TabPage { Text = "Ideal Gas Heat Capacity", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxCp.ToArray(), vyCp.ToArray(), "Ideal Gas Heat Capacity", "", "Temperature" + " (" + su.temperature + ")", "Ideal Gas Heat Capacity" + " (" + su.heatCapacityCp + ")") } }); tabv.Pages.Add(new TabPage { Text = "Viscosity", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxVapVisc.ToArray(), vyVapVisc.ToArray(), "Viscosity", "", "Temperature" + " (" + su.temperature + ")", "Viscosity" + " (" + su.viscosity + ")") } }); tabv.Pages.Add(new TabPage { Text = "Thermal Conductivity", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxVapThCond.ToArray(), vyVapThCond.ToArray(), "Thermal Conductivity", "", "Temperature" + " (" + su.temperature + ")", "Thermal Conductivity" + " (" + su.thermalConductivity + ")") } }); var tabs = new TabControl(); tabs.Pages.Add(new TabPage { Text = "Heat Capacity", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxSCP.ToArray(), vySCP.ToArray(), "Heat Capacity", "", "Temperature" + " (" + su.temperature + ")", "Heat Capacity" + " (" + su.heatCapacityCp + ")") } }); tabs.Pages.Add(new TabPage { Text = "Density", Content = new Eto.OxyPlot.Plot { Model = c.CreatePlotModel(vxSD.ToArray(), vySD.ToArray(), "Density", "", "Temperature" + " (" + su.temperature + ")", "Density" + " (" + su.density + ")") } }); Pages.Add(new TabPage { Content = tabl, Text = "Liquid" }); Pages.Add(new TabPage { Content = tabv, Text = "Vapor" }); Pages.Add(new TabPage { Content = tabs, Text = "Solid" }); } }
void Init() { Spacing = new Size(5, 5); DynamicLayout p1; TableLayout p2; p1 = UI.Shared.Common.GetDefaultContainer(); p2 = new TableLayout() { Spacing = new Size(5, 5), Padding = new Padding(15) }; Rows.Add(new TableRow(p1, p2)); p1.Width = 420; var l1 = p1.CreateAndAddLabelRow("Envelope Setup"); var tabcontainer = new TabControl(); Eto.OxyPlot.Plot chart = null; var su = flowsheet.FlowsheetOptions.SelectedUnitSystem; var nf = flowsheet.FlowsheetOptions.NumberFormat; var complist = flowsheet.SelectedCompounds.Values.Select((x2) => x2.Name).ToList(); complist.Insert(0, ""); p1.CreateAndAddDescriptionRow("The Binary Envelope utility calculates Temperature and Pressure VLE/VLLE envelopes for binary mixtures."); var spinnerComp1 = p1.CreateAndAddDropDownRow("Compound 1", complist, 0, null); var spinnerComp2 = p1.CreateAndAddDropDownRow("Compound 2", complist, 0, null); var spinnerPE = p1.CreateAndAddDropDownRow("Envelope Type", Shared.StringArrays.binaryenvelopetype().ToList(), 1, null); var tval = p1.CreateAndAddTextBoxRow(nf, "Temperature (" + su.temperature + ")", cv.ConvertFromSI(su.temperature, 298.15f), null); var pval = p1.CreateAndAddTextBoxRow(nf, "Pressure (" + su.pressure + ")", cv.ConvertFromSI(su.pressure, 101325.0f), null); bool vle = true, lle = false, sle = false, critical = false, areas = false; p1.CreateAndAddLabelRow("Display Options"); p1.CreateAndAddCheckBoxRow("VLE", vle, (arg1a, arg2a) => { vle = arg1a.Checked.GetValueOrDefault(); }); p1.CreateAndAddDescriptionRow("VLE calculation works on all diagram types."); p1.CreateAndAddCheckBoxRow("LLE", lle, (arg1a, arg2a) => { lle = arg1a.Checked.GetValueOrDefault(); }); p1.CreateAndAddDescriptionRow("LLE calculation works on T-x/y and P-x/y diagrams if the selected Property Package is associated with a Flash Algorithm which supports Liquid-Liquid equilibria."); p1.CreateAndAddCheckBoxRow("SLE", sle, (arg1a, arg2a) => { sle = arg1a.Checked.GetValueOrDefault(); }); p1.CreateAndAddDescriptionRow("SLE calculation works on T-x/y diagrams only."); p1.CreateAndAddCheckBoxRow("Critical Line", critical, (arg1a, arg2a) => { critical = arg1a.Checked.GetValueOrDefault(); }); p1.CreateAndAddDescriptionRow("Critical Line calculation works on T-x/y diagrams only."); p1.CreateAndAddCheckBoxRow("Highlight Regions", areas, (arg1a, arg2a) => { areas = arg1a.Checked.GetValueOrDefault(); }); p1.CreateAndAddDescriptionRow("Highlights the different phase regions in the envelope."); var pplist = flowsheet.PropertyPackages.Values.Select((x2) => x2.Tag).ToList(); pplist.Insert(0, ""); var spinnerpp = p1.CreateAndAddDropDownRow("Property Package", pplist, 0, null); var button = p1.CreateAndAddButtonRow("Build Envelope", null, null); chart = new Eto.OxyPlot.Plot { BackgroundColor = Colors.White }; var txtResults = new TextArea() { ReadOnly = true, Font = Fonts.Monospace(GlobalSettings.Settings.ResultsReportFontSize) }; tabcontainer.Pages.Add(new TabPage(new TableRow(chart)) { Text = "Chart" }); tabcontainer.Pages.Add(new TabPage(new TableRow(txtResults)) { Text = "Data" }); p2.CreateAndAddLabelRow("Results"); p2.CreateAndAddControlRow(tabcontainer); button.Click += (sender, e) => { if (spinnerPE.SelectedIndex >= 0 && spinnerComp1.SelectedIndex > 0 && spinnerComp2.SelectedIndex > 0 && spinnerpp.SelectedIndex > 0) { var comp1 = flowsheet.SelectedCompounds[complist[spinnerComp1.SelectedIndex]]; var comp2 = flowsheet.SelectedCompounds[complist[spinnerComp2.SelectedIndex]]; var ms = new MaterialStream("", ""); ms.SetFlowsheet(flowsheet); ms.PropertyPackage = (PropertyPackage)flowsheet.PropertyPackages.Values.Where(x => x.Tag == spinnerpp.SelectedValue.ToString()).First(); ms.SetFlowsheet(flowsheet); foreach (var phase in ms.Phases.Values) { phase.Compounds.Add(comp1.Name, new DWSIM.Thermodynamics.BaseClasses.Compound(comp1.Name, "")); phase.Compounds[comp1.Name].ConstantProperties = comp1; phase.Compounds.Add(comp2.Name, new DWSIM.Thermodynamics.BaseClasses.Compound(comp2.Name, "")); phase.Compounds[comp2.Name].ConstantProperties = comp2; } double val; if (Double.TryParse(tval.Text, out val)) { ms.Phases[0].Properties.temperature = cv.ConvertToSI(su.temperature, Double.Parse(tval.Text)); } if (Double.TryParse(pval.Text, out val)) { ms.Phases[0].Properties.pressure = cv.ConvertToSI(su.pressure, Double.Parse(pval.Text)); } var calc = new DWSIM.Thermodynamics.ShortcutUtilities.Calculation(ms); calc.DisplayEnvelopeAreas = areas; calc.BinaryEnvelopeOptions = new object[] { "", 0, 0, vle, lle, sle, critical, false }; switch (spinnerPE.SelectedIndex) { case 0: calc.CalcType = Thermodynamics.ShortcutUtilities.CalculationType.BinaryEnvelopePxy; break; case 1: calc.CalcType = Thermodynamics.ShortcutUtilities.CalculationType.BinaryEnvelopeTxy; break; } DWSIM.Thermodynamics.ShortcutUtilities.CalculationResults results = null; var token = new System.Threading.CancellationTokenSource(); var pg = ProgressDialog.ShowWithAbort(this, "Please Wait", "Calculating Envelope Lines...", false, "Abort/Cancel", (s, e1) => { token.Cancel(); }); Task.Factory.StartNew(() => { Application.Instance.Invoke(() => { txtResults.Text = "Please wait..."; }); results = calc.Calculate(); }, token.Token).ContinueWith((t) => { Application.Instance.Invoke(() => { pg.Close(); pg = null; if (results.ExceptionResult == null) { if (results.PlotModels.Count > 0) { chart.Model = (OxyPlot.PlotModel)results.PlotModels[0]; chart.Model.Padding = new OxyPlot.OxyThickness(5, 5, 20, 5); chart.Invalidate(); txtResults.Text = results.TextOutput; } else { chart.Model = null; txtResults.Text = "Invalid result"; } } else { txtResults.Text = results.ExceptionResult.Message; } }); }); } }; }
private void FlashCurrentStage(FlashRoutines flash, MaterialStream stageStream, Port <MaterialStream> VIn, Port <MaterialStream> LIn, int i) { stageStream.Mixed.Temperature.ValueInSI = _trays[i].T.ValueInSI; stageStream.Mixed.Pressure.ValueInSI = _trays[i].p.ValueInSI; var enthsum = 0.0; if (i > 0) { enthsum += _trays[i - 1].L.ValueInSI * _trays[i - 1].HL.ValueInSI; } else { enthsum += LIn.Streams[0].Mixed.TotalMolarflow.ValueInSI * LIn.Streams[0].Mixed.SpecificEnthalpy.ValueInSI; } if (i < NumberOfTrays - 1) { enthsum += _trays[i + 1].V.ValueInSI * _trays[i + 1].HV.ValueInSI; } else { enthsum += VIn.Streams[0].Mixed.TotalMolarflow.ValueInSI * VIn.Streams[0].Mixed.SpecificEnthalpy.ValueInSI; } enthsum += _trays[i].F.ValueInSI * _trays[i].HF.ValueInSI; for (int j = 0; j < System.Components.Count; j++) { var flowsum = 0.0; if (i > 0) { flowsum += _trays[i - 1].L.ValueInSI * _trays[i - 1].x[j].ValueInSI; } else { flowsum += LIn.Streams[0].Mixed.ComponentMolarflow[j].ValueInSI; } flowsum += _trays[i].F.ValueInSI * _trays[i].z[j].ValueInSI; if (i < NumberOfTrays - 1) { flowsum += _trays[i].V.ValueInSI * _trays[i].y[j].ValueInSI; } else { flowsum += VIn.Streams[0].Mixed.ComponentMolarflow[j].ValueInSI; } stageStream.Mixed.ComponentMolarflow[j].ValueInSI = flowsum; } //stageStream.Mixed. = enthsum ; //stageStream.Vfmolar.ValueInSI = 0.5; //flash.CalculateZP(stageStream); flash.CalculatePQ(stageStream, enthsum); _trays[i].V.ValueInSI = stageStream.Vapor.TotalMolarflow.ValueInSI; _trays[i].L.ValueInSI = stageStream.Liquid.TotalMolarflow.ValueInSI; for (int j = 0; j < System.Components.Count; j++) { _trays[i].y[j].ValueInSI = stageStream.Vapor.ComponentMolarFraction[j].ValueInSI; _trays[i].x[j].ValueInSI = stageStream.Liquid.ComponentMolarFraction[j].ValueInSI; } }
public Equation GetDefiningEquation(MaterialStream stream) { return(GetFactor(stream).IsEqualTo(GetDrivingForce(stream))); }
public MaterialStreamEditor(ISimulationObject selectedobject, DynamicLayout layout) { MatStream = (MaterialStream)selectedobject; container = layout; Initialize(); }
void InitRectifaction() { int NC = System.Components.Count; var In = FindMaterialPort("Feeds"); var VIn = FindMaterialPort("VIn"); var LIn = FindMaterialPort("LIn"); var VOut = FindMaterialPort("VOut"); var LOut = FindMaterialPort("LOut"); var Sidestreams = FindMaterialPort("Sidestreams"); var TTop = LIn.Streams[0].Mixed.Temperature.ValueInSI; var TBot = VIn.Streams[0].Mixed.Temperature.ValueInSI; var flash1 = new FlashRoutines(new Numerics.Solvers.Newton()); var feedcopy = new MaterialStream("FC", In.Streams[0].System); feedcopy.CopyFrom(In.Streams[0]); feedcopy.Vfmolar.ValueInSI = 0.01; flash1.CalculateZP(feedcopy); TTop = feedcopy.Mixed.Temperature.ValueInSI; feedcopy.Vfmolar.ValueInSI = 0.99; flash1.CalculateZP(feedcopy); TBot = feedcopy.Mixed.Temperature.ValueInSI; foreach (var feed in _feeds) { _trays[feed.Stage - 1].HF.ValueInSI = feed.Stream.Mixed.SpecificEnthalpy.ValueInSI; _trays[feed.Stage - 1].F.ValueInSI = feed.Stream.Mixed.TotalMolarflow.ValueInSI; _trays[feed.Stage - 1].HF.IsConstant = false; _trays[feed.Stage - 1].F.IsConstant = false; for (var comp = 0; comp < NC; comp++) { _trays[feed.Stage - 1].z[comp].ValueInSI = feed.Stream.Mixed.ComponentMolarFraction[comp].ValueInSI; _trays[feed.Stage - 1].z[comp].IsConstant = false; } } for (int i = 0; i < NumberOfTrays; i++) { _trays[i].T.ValueInSI = TTop + (TBot - TTop) / (double)(NumberOfTrays - 1) * i; _trays[i].TV.ValueInSI = TTop + (TBot - TTop) / (double)(NumberOfTrays - 1) * i; if (i == 0) { _trays[i].L.ValueInSI = In.Streams[0].Mixed.TotalMolarflow.ValueInSI * 0.5;// + LIn.Streams[0].Mixed.TotalMolarflow.ValueInSI; } else { _trays[i].L.ValueInSI = _trays[i - 1].L.ValueInSI + _trays[i].F.ValueInSI; } _trays[i].V.ValueInSI = In.Streams[0].Mixed.TotalMolarflow.ValueInSI;// + VIn.Streams[0].Mixed.TotalMolarflow.ValueInSI; for (int j = 0; j < System.Components.Count; j++) { _trays[i].x[j].ValueInSI = _feeds[0].Stream.Mixed.ComponentMolarFraction[j].ValueInSI; _trays[i].y[j].ValueInSI = _feeds[0].Stream.Mixed.ComponentMolarFraction[j].ValueInSI; _trays[i].yeq[j].ValueInSI = _feeds[0].Stream.Mixed.ComponentMolarFraction[j].ValueInSI; } } for (int i = NumberOfTrays - 1; i >= 0; i--) { if (i < NumberOfTrays - 1) { _trays[i].p.ValueInSI = _trays[i + 1].p.ValueInSI - _trays[i + 1].DP.ValueInSI; } else { _trays[i].p.ValueInSI = VIn.Streams[0].Mixed.Pressure.ValueInSI; } } InitOutlets(); }