Exemplo n.º 1
0
 Expression GetFactor(MaterialStream stream)
 {
     switch (Type)
     {
     case ReactionType.EQLA:
         Expression lnK = Coefficients[0];
         if (Coefficients.Count > 1)
         {
             lnK += Coefficients[1] / stream.Mixed.Temperature;
         }
         if (Coefficients.Count > 2)
         {
             lnK += Coefficients[2] * Sym.Ln(stream.Mixed.Temperature);
         }
         if (Coefficients.Count > 3)
         {
             lnK += Coefficients[3] * stream.Mixed.Temperature;
         }
         if (Coefficients.Count > 4)
         {
             lnK += Coefficients[4] * Sym.Pow(stream.Mixed.Temperature, 2.0);
         }
         if (Coefficients.Count > 5)
         {
             lnK += Coefficients[5] * Sym.Pow(stream.Mixed.Temperature, 3.0);
         }
         return(Sym.Exp(lnK));
     }
     return(1);
 }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 4
0
 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);
 }
Exemplo n.º 5
0
        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("");
        }
Exemplo n.º 6
0
 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);
 }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
 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);
 }
Exemplo n.º 9
0
        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);
            }
        }
Exemplo n.º 10
0
        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);
            }
        }
Exemplo n.º 11
0
        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);
            }
        }
Exemplo n.º 12
0
        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);
        }
Exemplo n.º 13
0
        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);
        }
Exemplo n.º 14
0
        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);
        }
Exemplo n.º 15
0
        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);
        }
Exemplo n.º 16
0
        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);
        }
Exemplo n.º 17
0
        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());
        }
Exemplo n.º 18
0
        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);
        }
Exemplo n.º 19
0
        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);
                        });
                    }
                });
            });
        }
Exemplo n.º 20
0
        public bool CalculateZP(MaterialStream stream)
        {
            PrecalculateZP(stream);

            return(true);
        }
Exemplo n.º 21
0
        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);
        }
Exemplo n.º 23
0
        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"
                });
            }
        }
Exemplo n.º 24
0
        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;
                            }
                        });
                    });
                }
            };
        }
Exemplo n.º 25
0
        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;
            }
        }
Exemplo n.º 26
0
 public Equation GetDefiningEquation(MaterialStream stream)
 {
     return(GetFactor(stream).IsEqualTo(GetDrivingForce(stream)));
 }
Exemplo n.º 27
0
 public MaterialStreamEditor(ISimulationObject selectedobject, DynamicLayout layout)
 {
     MatStream = (MaterialStream)selectedobject;
     container = layout;
     Initialize();
 }
Exemplo n.º 28
0
        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();
        }