Example #1
0
 public RateBasedSection Ignore(params string[] components)
 {
     foreach (var compId in components)
     {
         var comp = System.Components.FirstOrDefault(c => c.ID == compId);
         if (comp != null)
         {
             IgnoredComponents.Add(comp);
         }
     }
     return(this);
 }
Example #2
0
        void ApplyIgnoredComponents()
        {
            int NT = (int)(NumberOfElements);

            for (int c = 0; c < System.Components.Count; c++)
            {
                if (IgnoredComponents.Contains(System.Components[c]))
                {
                    for (int i = 0; i < NT; i++)
                    {
                        _trays[i].x[c].FixValue(0);
                        _trays[i].y[c].FixValue(0);
                        _trays[i].yI[c].FixValue(0);
                        _trays[i].xI[c].FixValue(0);

                        _trays[i].x[c].IsConstant  = true;
                        _trays[i].y[c].IsConstant  = true;
                        _trays[i].yI[c].IsConstant = true;
                        _trays[i].xI[c].IsConstant = true;
                    }
                }
            }
        }
Example #3
0
        public override void FillEquationSystem(EquationSystem problem)
        {
            int NC   = System.Components.Count;
            var VIn  = FindMaterialPort("VIn").Streams[0];
            var LIn  = FindMaterialPort("LIn").Streams[0];
            var VOut = FindMaterialPort("VOut").Streams[0];
            var LOut = FindMaterialPort("LOut").Streams[0];

            var pscale = 1e4;
            var hscale = 1e6;
            var L0     = LIn.Mixed.TotalMolarflow;
            var x0     = LIn.Mixed.ComponentMolarFraction;
            var VNT    = VIn.Mixed.TotalMolarflow;
            var yNT    = VIn.Mixed.ComponentMolarFraction;

            ApplyIgnoredComponents();

            Action <Equation> EQ = (x) => AddEquationToEquationSystem(problem, x);

            for (var i = 0; i < NumberOfElements; i++)
            {
                var tray = _trays[i];

                //Calculate average properties on  stage, Divide molar weight by 1000 because unit is kg/kmol and not kg/mol as would be SI
                var TV        = tray.TV;
                var p         = tray.p;
                var rhoVMolar = System.EquationFactory.GetAverageVaporDensityExpression(System, TV, p, tray.y.ToList());
                var rhoV      = rhoVMolar * System.EquationFactory.GetAverageMolarWeightExpression(System, tray.y);
                var etaV      = System.EquationFactory.GetAverageVaporViscosityExpression(System, tray.y, TV, p);

                var A = Math.PI / 4 * Sym.Pow(tray.d, 2);
                //Hydraulics
                //Effective exchange area
                EQ(tray.aeff.IsEqualTo(tray.h * A * tray.aspez));
                //Superficial velocity
                EQ(tray.uV.IsEqualTo(tray.V / (rhoVMolar * A)));
                //Reynolds number
                tray.ReV.BindTo(rhoV * tray.uV * tray.dhyd / etaV);


                //Component (M)assbalance
                for (var comp = 0; comp < NC; comp++)
                {
                    if (!IgnoredComponents.Contains(System.Components[comp]))
                    {
                        if (i == 0)
                        {
                            EQ((tray.V * tray.y[comp] - _trays[i + 1].V * _trays[i + 1].y[comp] + tray.N[comp]).IsEqualTo(0));
                            EQ((tray.L * tray.x[comp] - L0 * x0[comp] - _trays[i].N[comp]).IsEqualTo(0));
                        }
                        else if (i == NumberOfElements - 1)
                        {
                            EQ((tray.V * tray.y[comp] - VNT * yNT[comp] + _trays[i].N[comp]).IsEqualTo(0));
                            EQ((tray.L * tray.x[comp] - _trays[i - 1].L * _trays[i - 1].x[comp] - tray.N[comp]).IsEqualTo(0));
                        }
                        else
                        {
                            EQ((tray.V * tray.y[comp] - _trays[i + 1].V * _trays[i + 1].y[comp] + tray.N[comp]).IsEqualTo(0));
                            EQ((tray.L * tray.x[comp] - _trays[i - 1].L * _trays[i - 1].x[comp] - tray.N[comp]).IsEqualTo(0));
                        }
                    }
                }

                //(E)quilibrium
                for (var comp = 0; comp < NC; comp++)
                {
                    System.EquationFactory.EquilibriumCoefficient(System, tray.K[comp], tray.TI, p, tray.xI.ToList(), tray.yI.ToList(), comp);
                    if (!IgnoredComponents.Contains(System.Components[comp]))
                    {
                        EQ((tray.yI[comp]).IsEqualTo(tray.K[comp] * tray.xI[comp]));
                    }
                }

                //(R)ate Equation - Intefacial Mass Transfer
                for (var comp = 0; comp < NC; comp++)
                {
                    if (!IgnoredComponents.Contains(System.Components[comp]))
                    {
                        if (NoContact)
                        {
                            EQ((_trays[i].N[comp]).IsEqualTo(0));
                            EQ((_trays[i].xI[comp]).IsEqualTo(tray.x[comp]));
                        }
                        else
                        {
                            if (!_massTransferResistanceOnLiquid)
                            {
                                EQ((_trays[i].xI[comp]).IsEqualTo(tray.x[comp]));
                            }
                            else
                            {
                                var x    = tray.x;
                                var xI   = tray.xI;
                                var n    = tray.N;
                                var ii   = comp;
                                var xiiq = 0.5 * Sym.Par(x[ii] + xI[ii]);
                                EQ((rhoVMolar * _trays[i].aeff * Sym.Par(tray.xI[ii] - tray.x[ii])).IsEqualTo(Sym.SumX(0, NC, comp, j => (0.5 * Sym.Par(x[j] + xI[j]) * n[ii] - xiiq * n[j]) / tray.BetaL[ii, j])));
                            }

                            if (!_massTransferResistanceOnVapor)
                            {
                                EQ((_trays[i].yI[comp]).IsEqualTo(tray.y[comp]));
                            }
                            else
                            {
                                //Simplified Stefan-Maxwell Equation for Film model
                                var y    = tray.y;
                                var yI   = tray.yI;
                                var n    = tray.N;
                                var ii   = comp;
                                var yiiq = 0.5 * Sym.Par(y[ii] + yI[ii]);
                                EQ((rhoVMolar * _trays[i].aeff * Sym.Par(tray.y[ii] - tray.yI[ii])).IsEqualTo(Sym.SumX(0, NC, comp, j => (0.5 * Sym.Par(y[j] + yI[j]) * n[ii] - yiiq * n[j]) / tray.BetaV[ii, j])));
                            }
                        }
                    }
                }
                //Heat Transfer coefficient calcluation
                if (!BetaVIsConstant)
                {
                    for (int k = 0; k < NC; k++)
                    {
                        for (int j = 0; j < NC; j++)
                        {
                            if (k != j)
                            {
                                var parameterSet = System.BinaryParameters.FirstOrDefault(ps => ps.Name == "DVIJ0");
                                if (parameterSet == null)
                                {
                                    throw new ArgumentNullException("No Diffusion coefficients defined");
                                }

                                //Estimate Diffusion coefficient at system temperature and pressure using the approach by Fuller, Schettler, Giddings
                                var DVij0 = parameterSet.Matrices["A"][k, j];
                                var DVij  = Sym.Pow(Sym.Par(TV / 273.15), 1.75) / (p / 1e5) * DVij0;

                                //Schmidt Number
                                var Scij = etaV / Sym.Par(rhoV * DVij);
                                //Sherwood Number
                                var Shij = SherwoodParameter[0] * Sym.Pow(tray.ReV, SherwoodParameter[1]) * Sym.Pow(Scij, SherwoodParameter[2]);
                                tray.BetaV[k, j].BindTo(Shij * DVij / tray.dhyd);
                            }
                            else
                            {
                                tray.BetaV[k, j].BindTo(0);
                            }
                        }
                    }
                }

                //(R)ate Equation - Interfacial Heat Transfer
                if (NoContact)
                {
                    EQ((tray.E).IsEqualTo(0));
                    EQ((tray.TI).IsEqualTo(0.5 * Sym.Par(tray.TL + tray.TV)));
                }
                else
                {
                    if (!_heatTransferResistanceOnLiquid)
                    {
                        EQ((tray.TI).IsEqualTo(tray.TL));
                    }
                    if (!_heatTransferResistanceOnVapor)
                    {
                        EQ((tray.TI).IsEqualTo(tray.TV));
                    }
                }

                //(S)ummation
                EQ(Sym.Sum(0, NC, (j) => Sym.Par(tray.x[j])).IsEqualTo(1));
                EQ(Sym.Sum(0, NC, (j) => Sym.Par(tray.y[j])).IsEqualTo(1));


                //Ent(H)alpy
                tray.HL.BindTo(Sym.Sum(0, NC, (idx) => tray.x[idx] * System.EquationFactory.GetLiquidEnthalpyExpression(System, idx, tray.TL)));
                tray.HV.BindTo(Sym.Sum(0, NC, (idx) => tray.y[idx] * System.EquationFactory.GetVaporEnthalpyExpression(System, idx, tray.TV)));


                if (i == 0)
                {
                    EQ((Sym.Par(_trays[i].V * _trays[i].HV - _trays[i + 1].V * _trays[i + 1].HV + _trays[i].E) / hscale).IsEqualTo(0));
                    EQ((Sym.Par(_trays[i].L * _trays[i].HL - L0 * LIn.Mixed.SpecificEnthalpy - _trays[i].E + tray.Q) / hscale).IsEqualTo(0));
                }
                else if (i == NumberOfElements - 1)
                {
                    EQ((Sym.Par(_trays[i].V * _trays[i].HV - VNT * VIn.Mixed.SpecificEnthalpy + _trays[i].E) / hscale).IsEqualTo(0));
                    EQ((Sym.Par(_trays[i].L * _trays[i].HL - _trays[i - 1].L * _trays[i - 1].HL - _trays[i].E + tray.Q) / hscale).IsEqualTo(0));
                }
                else
                {
                    EQ((Sym.Par(_trays[i].V * _trays[i].HV - _trays[i + 1].V * _trays[i + 1].HV + _trays[i].E) / hscale).IsEqualTo(0));
                    EQ((Sym.Par(_trays[i].L * _trays[i].HL - _trays[i - 1].L * _trays[i - 1].HL - _trays[i].E + tray.Q) / hscale).IsEqualTo(0));
                }

                //Pressure profile
                if (i == NumberOfElements - 1)
                {
                    EQ((tray.p / pscale).IsEqualTo((VIn.Mixed.Pressure - _trays[NumberOfElements - 1].DP) / pscale));
                }
                else
                {
                    EQ((tray.p / pscale).IsEqualTo(Sym.Par(_trays[i + 1].p - _trays[i].DP) / pscale));
                }
            }

            //Setting outlet stream conditions
            for (var comp = 0; comp < NC; comp++)
            {
                EQ(VOut.Mixed.ComponentMolarflow[comp].IsEqualTo(_trays[0].V * _trays[0].y[comp]));
                EQ(LOut.Mixed.ComponentMolarflow[comp].IsEqualTo(_trays[NumberOfElements - 1].L * _trays[NumberOfElements - 1].x[comp]));
            }

            EQ((VOut.Mixed.SpecificEnthalpy / 1e6).IsEqualTo(_trays[0].HV / 1e6));
            EQ(VOut.Mixed.Pressure.IsEqualTo(_trays[0].p));
            EQ(LOut.Mixed.Temperature.IsEqualTo(_trays[NumberOfElements - 1].TL));
            EQ(LOut.Mixed.Pressure.IsEqualTo(_trays[NumberOfElements - 1].p));


            base.FillEquationSystem(problem);
        }