コード例 #1
0
        private string CheckPointInRange(PointF pt)
        {
            bool   retValue = true;
            string retMsg   = null;

            if (pt.X < xVar.Min || pt.X > xVar.Max || pt.Y < yVar.Min || pt.Y > yVar.Max)
            {
                retValue = false;
            }
            else
            {
                double             p                  = pressure.Value;
                double             temperature        = (double)pt.X;
                double             humidity           = (double)pt.Y;
                HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();
                double             dewPoint           = humidGasCalculator.GetDewPointFromDryBulbAndRelativeHumidity(temperature, 1.0);
                double             humiditySat        = humidGasCalculator.GetHumidityFromDewPointAndPressure(dewPoint, p);
                if (humidity > humiditySat)
                {
                    retValue = false;
                }
            }
            if (retValue == false)
            {
                retMsg = "Specified state is out of range. It is reverted back to the original state";
            }

            return(retMsg);
        }
コード例 #2
0
        internal override double GetGasCp(double temperature)
        {
            double mcDryBase = moistureContentDryBase.Value;
            //double cpDryBase = GetHumidGasCalculator().GetHumidHeat(mcDryBase, temperature);
            double cpDryBase = HumidGasCalculator.GetHumidHeat(mcDryBase, temperature);

            return(cpDryBase / (1.0 + mcDryBase));
        }
コード例 #3
0
        internal override double GetGasDensity(double temperature, double pressure)
        {
            double mcDryBase = moistureContentDryBase.Value;
            //double humidVolumeValue = GetHumidGasCalculator().GetHumidVolume(temperature, mcDryBase, pressure);
            double humidVolumeValue = HumidGasCalculator.GetHumidVolume(temperature, mcDryBase, pressure);

            return((1.0 + mcDryBase) / humidVolumeValue);
        }
コード例 #4
0
        private CurveFamilyF GenerateAdiabaticSaturationFamily()
        {
            double             dewPoint;
            double             ysat;
            double             wetBulb;
            double             temperature;
            double             ih;
            double             tsat;
            double             maxTemp;
            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();
            double             p           = (double)pressure.Value;
            double             cg          = humidGasCalculator.GetSpecificHeatOfDryGas();
            double             cv          = humidGasCalculator.GetSpecificHeatOfVapor();
            double             r0          = humidGasCalculator.GetEvaporationHeat(273.15);
            double             dewPoint1   = humidGasCalculator.GetDewPointFromDryBulbAndRelativeHumidity(xVar.Max, 1.0);
            double             dewPoint2   = humidGasCalculator.GetDewPointFromHumidityAndPressure(yVar.Max, p);
            double             dewPointMin = Math.Min(dewPoint1, dewPoint2);
            int numOfCurves = (int)((dewPointMin - xVar.Min) / 5.0) + 1;

            CurveF[] curves = new CurveF[numOfCurves];
            double   y;

            for (int i = 0; i < numOfCurves; i++)
            {
                tsat     = xVar.Min + i * 5.0;
                dewPoint = humidGasCalculator.GetDewPointFromDryBulbAndRelativeHumidity(tsat, 1.0);
                ysat     = humidGasCalculator.GetHumidityFromDewPointAndPressure(dewPoint, p);
                wetBulb  = humidGasCalculator.GetWetBulbFromDryBulbHumidityAndPressure(tsat, ysat, p);
                PointF[] dataPoints = new PointF[11];
                maxTemp = humidGasCalculator.GetDryBulbFromWetBulbHumidityAndPressure(wetBulb, 0.0, p);
                if (maxTemp > xVar.Max)
                {
                    maxTemp = xVar.Max;
                }
                if (ysat > yVar.Max)
                {
                    tsat = humidGasCalculator.GetDryBulbFromWetBulbHumidityAndPressure(wetBulb, yVar.Max, p);
                }
                ih = (cg + cv * ysat) * (tsat - 273.15) + r0 * ysat;
                for (int j = 0; j <= 10; j++)
                {
                    temperature = tsat + (maxTemp - tsat) / 10.0 * j;
                    //iso-enthalpy line
                    y             = (ih - cg * (temperature - 273.15)) / (r0 + cv * (temperature - 273.15));
                    dataPoints[j] = new PointF((float)temperature, (float)y);
                }
                curves[i] = new CurveF(StringConstants.GetTypeName(StringConstants.ADIABATIC_SATURATION), (float)tsat, dataPoints);
            }

            CurveFamilyF curveFamily = new CurveFamilyF(StringConstants.GetTypeName(StringConstants.ADIABATIC_SATURATION), PhysicalQuantity.Temperature, curves);

            return(curveFamily);
        }
コード例 #5
0
        private CurveFamilyF GenerateRelativeHumidityFamily()
        {
            double dewPoint;
            double humidity;
            double temperature;
            double maxTemp;

            CurveF[]           curves = new CurveF[16];
            double             relativeHumidity;
            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();

            for (int i = 0; i < 16; i++)
            {
                //from 0.0% to 10%--interval 2%
                if (i < 5)
                {
                    relativeHumidity = (i + 1) * 0.02;
                }
                //from 10 to 50%--interval 5%
                else if (i < 9)
                {
                    relativeHumidity = 0.1 + (i - 4) * 0.05;
                }
                //from 30 to 100%--interval 10%
                else
                {
                    relativeHumidity = 0.3 + (i - 8) * 0.1;
                }

                dewPoint = humidGasCalculator.GetDewPointFromHumidityAndPressure(yVar.Max, pressure.Value);
                maxTemp  = humidGasCalculator.GetDryBulbFromDewPointAndRelativeHumidity(dewPoint, relativeHumidity);
                if (maxTemp > xVar.Max)
                {
                    maxTemp = xVar.Max;
                }
                PointF[] dataPoints = new PointF[101];
                for (int j = 0; j <= 100; j++)
                {
                    temperature   = xVar.Min + j * (maxTemp - xVar.Min) / 100;
                    dewPoint      = humidGasCalculator.GetDewPointFromDryBulbAndRelativeHumidity(temperature, relativeHumidity);
                    humidity      = humidGasCalculator.GetHumidityFromDewPointAndPressure(dewPoint, (double)pressure.Value);
                    dataPoints[j] = new PointF((float)temperature, (float)humidity);
                }
                curves[i] = new CurveF(StringConstants.GetTypeName(StringConstants.RELATIVE_HUMIDITY), (float)relativeHumidity, dataPoints);
            }

            CurveFamilyF curveFamily = new CurveFamilyF(StringConstants.GetTypeName(StringConstants.RELATIVE_HUMIDITY), PhysicalQuantity.Fraction, curves);

            return(curveFamily);
        }
コード例 #6
0
        private CurveF GenerateSpecificVolumeDryAirCurve()
        {
            double temperature;
            double specificVolumeDryAir;

            PointF[]           dataPoints         = new PointF[10];
            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();

            for (int i = 0; i < 10; i++)
            {
                temperature          = (xVar.Max - xVar.Min) / 10.0 * i;
                specificVolumeDryAir = humidGasCalculator.GetHumidVolume(temperature, 0.0, (double)pressure.Value);
                dataPoints[i]        = new PointF((float)temperature, (float)specificVolumeDryAir);
            }
            return(new CurveF(StringConstants.GetTypeName(StringConstants.SPECIFIC_VOLUME_DRY_AIR), 0.1f, dataPoints));
        }
コード例 #7
0
        private CurveF GenerateEvaporationHeatCurve()
        {
            double temperature;
            double evapHeat;

            PointF[]           dataPoints         = new PointF[10];
            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();

            for (int i = 0; i < 10; i++)
            {
                temperature   = (xVar.Max - xVar.Min) / 10.0 * i;
                evapHeat      = humidGasCalculator.GetEvaporationHeat(temperature);
                dataPoints[i] = new PointF((float)temperature, (float)evapHeat);
            }
            return(new CurveF(StringConstants.GetTypeName(StringConstants.EVAPORATION_HEAT), 0.1f, dataPoints));
        }
コード例 #8
0
        private CurveF GenerateHumidHeatCurve()
        {
            double humidity;
            double humidHeat;

            PointF[]           dataPoints         = new PointF[10];
            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();

            for (int i = 0; i < 10; i++)
            {
                humidity      = yVar.Min + (yVar.Max - yVar.Min) / 10.0 * i;
                humidHeat     = humidGasCalculator.GetHumidHeat(humidity);
                dataPoints[i] = new PointF((float)humidity, (float)humidHeat);
            }
            return(new CurveF(StringConstants.GetTypeName(StringConstants.HUMID_HEAT), 273.15f, dataPoints));
        }
コード例 #9
0
        private CurveF GenerateSaturationVolumeCurve()
        {
            double             temperature;
            double             dewPoint;
            double             humidity;
            double             saturationVolume;
            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();

            PointF[] dataPoints = new PointF[10];
            for (int i = 0; i < 10; i++)
            {
                temperature      = (xVar.Max - xVar.Min) / 10.0 * i;
                dewPoint         = humidGasCalculator.GetDewPointFromDryBulbAndRelativeHumidity(temperature, 1.0);
                humidity         = humidGasCalculator.GetHumidityFromDewPointAndPressure(dewPoint, (double)pressure.Value);
                saturationVolume = humidGasCalculator.GetHumidVolume(temperature, humidity, (double)pressure.Value);
                dataPoints[i]    = new PointF((float)temperature, (float)saturationVolume);
            }
            return(new CurveF(StringConstants.GetTypeName(StringConstants.SATURATION_VOLUME), 0.1f, dataPoints));
        }
コード例 #10
0
        protected override ErrorMessage CheckSpecifiedValueRange(ProcessVarDouble pv, double aValue)
        {
            ErrorMessage retValue = base.CheckSpecifiedValueRange(pv, aValue);

            if (retValue != null)
            {
                return(retValue);
            }

            //if (pv.VarTypeName == StringConstants.GetTypeName(StringConstants.DRY_BULB_TEMPERATURE)) {
            if (pv == temperature)
            {
                if (aValue != Constants.NO_VALUE && wetBulbTemperature.HasValue && aValue < wetBulbTemperature.Value)
                {
                    retValue = new ErrorMessage(ErrorType.SimpleGeneric, StringConstants.INAPPROPRIATE_SPECIFIED_VALUE, pv.VarTypeName + " can not be less than " + StringConstants.GetTypeName(StringConstants.WET_BULB_TEMPERATURE));
                }
                else if (aValue != Constants.NO_VALUE && dewPoint.HasValue && aValue < dewPoint.Value)
                {
                    retValue = new ErrorMessage(ErrorType.SimpleGeneric, StringConstants.INAPPROPRIATE_SPECIFIED_VALUE, pv.VarTypeName + " can not be less than " + StringConstants.GetTypeName(StringConstants.DEW_POINT));
                }
            }
            //else if (pv.VarTypeName == StringConstants.GetTypeName(StringConstants.WET_BULB_TEMPERATURE))
            else if (pv == wetBulbTemperature)
            {
                if (aValue != Constants.NO_VALUE && temperature.HasValue && aValue > temperature.Value)
                {
                    retValue = new ErrorMessage(ErrorType.SimpleGeneric, StringConstants.INAPPROPRIATE_SPECIFIED_VALUE, pv.VarTypeName + " can not be greater than " + StringConstants.GetTypeName(StringConstants.DRY_BULB_TEMPERATURE));
                }
                else if (aValue != Constants.NO_VALUE && dewPoint.HasValue && aValue < dewPoint.Value)
                {
                    retValue = new ErrorMessage(ErrorType.SimpleGeneric, StringConstants.INAPPROPRIATE_SPECIFIED_VALUE, pv.VarTypeName + " can not be less than than " + StringConstants.GetTypeName(StringConstants.DEW_POINT));
                }
            }
            //else if (pv.VarTypeName == StringConstants.GetTypeName(StringConstants.DEW_POINT))
            else if (pv == dewPoint)
            {
                if (aValue != Constants.NO_VALUE && temperature.HasValue && aValue > temperature.Value)
                {
                    retValue = new ErrorMessage(ErrorType.SimpleGeneric, StringConstants.INAPPROPRIATE_SPECIFIED_VALUE, pv.VarTypeName + " can not be greater than " + StringConstants.GetTypeName(StringConstants.DRY_BULB_TEMPERATURE));
                }
                else if (aValue != Constants.NO_VALUE && wetBulbTemperature.HasValue && aValue > wetBulbTemperature.Value)
                {
                    retValue = new ErrorMessage(ErrorType.SimpleGeneric, StringConstants.INAPPROPRIATE_SPECIFIED_VALUE, pv.VarTypeName + " can not be greater than " + StringConstants.GetTypeName(StringConstants.WET_BULB_TEMPERATURE));
                }
            }
            //else if (pv.VarTypeName == StringConstants.GetTypeName(StringConstants.HUMIDITY))
            else if (pv == Humidity)
            {
                if (aValue != Constants.NO_VALUE && aValue < 0)
                {
                    retValue = CreateLessThanZeroErrorMessage(pv);
                }
                else if (aValue != Constants.NO_VALUE && pressure.HasValue)
                {
                    double maxHumidity = 1000.0;

                    HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();
                    if (temperature.HasValue)
                    {
                        maxHumidity = humidGasCalculator.GetHumidityFromDewPointAndPressure(temperature.Value, pressure.Value);
                    }
                    else if (wetBulbTemperature.HasValue)
                    {
                        maxHumidity = humidGasCalculator.GetHumidityFromDewPointAndPressure(wetBulbTemperature.Value, pressure.Value);
                    }
                    else if (dewPoint.HasValue)
                    {
                        maxHumidity = humidGasCalculator.GetHumidityFromDewPointAndPressure(dewPoint.Value, pressure.Value);
                    }

                    if (aValue > maxHumidity)
                    {
                        aValue   = maxHumidity;
                        retValue = new ErrorMessage(ErrorType.SimpleGeneric, StringConstants.INAPPROPRIATE_SPECIFIED_VALUE, "The maximum humidity under current conditions is " + aValue.ToString());
                    }
                }
            }
            //else if (pv.VarTypeName == StringConstants.GetTypeName(StringConstants.RELATIVE_HUMIDITY))
            else if (pv == relativeHumidity)
            {
                if (aValue != Constants.NO_VALUE && (aValue < 0 || aValue > 1.0))
                {
                    retValue = CreateOutOfRangeZeroToOneErrorMessage(pv);
                }
            }

            return(retValue);
        }
コード例 #11
0
        private void Solve()
        {
            //Mass Transfer--material particles transfer from gas stream to liquid stream
            //Mass Transfer--moisture transfers from liquid stream to gas stream
            //by an adiabaitc saturation process if ScrubberType is General.
            DryingMaterialStream dmsInlet  = liquidInlet as DryingMaterialStream;
            DryingMaterialStream dmsOutlet = liquidOutlet as DryingMaterialStream;

            DryingGasStream dgsInlet  = gasInlet as DryingGasStream;
            DryingGasStream dgsOutlet = gasOutlet as DryingGasStream;

            //gas stream goes through an adiabatic saturation process
            double tg1 = dgsInlet.Temperature.Value;
            double y1  = dgsInlet.Humidity.Value;
            double tw1 = dgsInlet.WetBulbTemperature.Value;
            double td1 = dgsInlet.DewPoint.Value;
            double fy1 = dgsInlet.RelativeHumidity.Value;

            double tg2 = dgsOutlet.Temperature.Value;
            double y2  = dgsOutlet.Humidity.Value;
            double tw2 = dgsOutlet.WetBulbTemperature.Value;
            double td2 = dgsOutlet.DewPoint.Value;
            double fy2 = dgsOutlet.RelativeHumidity.Value;

            double ih = 0;
            double p1 = dgsInlet.Pressure.Value;
            double p2 = dgsOutlet.Pressure.Value;

            if (p1 == Constants.NO_VALUE || p2 == Constants.NO_VALUE)
            {
                return;
            }
            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();

            if (tg1 != Constants.NO_VALUE && y1 != Constants.NO_VALUE)
            {
                ih = humidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(tg1, y1, p1);
                if (tg2 != Constants.NO_VALUE)
                {
                    y2 = humidGasCalculator.GetHumidityFromHumidEnthalpyTemperatureAndPressure(ih, tg2, p2);
                    if (y2 <= 0.0)
                    {
                        y2 = 1.0e-6;
                    }
                    Calculate(dgsOutlet.MoistureContentDryBase, y2);
                    solveState = SolveState.Solved;
                }
                else if (y2 != Constants.NO_VALUE)
                {
                    tg2 = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(ih, y2, p2);
                    Calculate(dgsOutlet.Temperature, tg2);
                    solveState = SolveState.Solved;
                }
                else if (td2 != Constants.NO_VALUE)
                {
                    y2  = humidGasCalculator.GetHumidityFromDewPointAndPressure(td2, p2);
                    tg2 = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(ih, y2, p2);
                    Calculate(dgsOutlet.Temperature, tg2);
                    solveState = SolveState.Solved;
                }
                else if (fy2 != Constants.NO_VALUE)
                {
                    double fy_temp    = 0;
                    double delta      = 10.0;
                    double totalDelta = delta;
                    tg2 = tg1 - delta;
                    bool negativeLastTime = false;

                    int counter = 0;
                    do
                    {
                        counter++;
                        y2      = humidGasCalculator.GetHumidityFromHumidEnthalpyTemperatureAndPressure(ih, tg2, p2);
                        fy_temp = humidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(tg2, y2, p2);
                        if (fy2 > fy_temp)
                        {
                            if (negativeLastTime)
                            {
                                delta /= 2.0; //testing finds delta/2.0 is almost optimal
                            }
                            totalDelta      += delta;
                            negativeLastTime = false;
                        }
                        else if (fy2 < fy_temp)
                        {
                            delta           /= 2.0; //testing finds delta/2.0 is almost optimal
                            totalDelta      -= delta;
                            negativeLastTime = true;
                        }
                        tg2 = tg1 - totalDelta;
                    } while (Math.Abs(fy2 - fy_temp) > 1.0e-6 && counter <= 200);

                    if (counter < 200)
                    {
                        Calculate(dgsOutlet.Temperature, tg2);
                        solveState = SolveState.Solved;
                    }
                }

                if (solveState == SolveState.Solved)
                {
                    double fy = humidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(tg2, y2, p2);
                    if (fy > 1.0)
                    {
                        solveState = SolveState.NotSolved;
                        string msg = "Specified gas inlet state makes the relative humidity of the outlet greater than 1.0.";
                        throw new InappropriateSpecifiedValueException(msg);
                    }
                }
            }
            else if (tg2 != Constants.NO_VALUE && y2 != Constants.NO_VALUE)
            {
                ih = humidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(tg2, y2, p2);
                if (tg1 != Constants.NO_VALUE)
                {
                    y1 = humidGasCalculator.GetHumidityFromHumidEnthalpyTemperatureAndPressure(ih, tg1, p1);
                    Calculate(dgsInlet.MoistureContentDryBase, y1);
                    solveState = SolveState.Solved;
                }
                else if (y1 != Constants.NO_VALUE)
                {
                    tg1 = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(ih, y1, p1);
                    Calculate(dgsInlet.Temperature, tg1);
                    solveState = SolveState.Solved;
                }
                else if (td1 != Constants.NO_VALUE)
                {
                    y1  = humidGasCalculator.GetHumidityFromDewPointAndPressure(td1, p1);
                    tg1 = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(ih, y1, p1);
                    Calculate(dgsInlet.Temperature, tg1);
                    solveState = SolveState.Solved;
                }
                else if (fy1 != Constants.NO_VALUE)
                {
                    double fy_temp    = 0;
                    double delta      = 10.0;
                    double totalDelta = delta;
                    tg1 = tg2 + delta;
                    bool negativeLastTime = false;

                    int counter = 0;
                    do
                    {
                        counter++;
                        y1      = humidGasCalculator.GetHumidityFromHumidEnthalpyTemperatureAndPressure(ih, tg1, p1);
                        fy_temp = humidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(tg1, y1, p1);
                        if (fy1 < fy_temp)
                        {
                            if (negativeLastTime)
                            {
                                delta /= 2.0; //testing finds delta/2.0 is almost optimal
                            }
                            totalDelta      += delta;
                            negativeLastTime = false;
                        }
                        else if (fy1 > fy_temp)
                        {
                            delta           /= 2.0; //testing finds delta/2.0 is almost optimal
                            totalDelta      -= delta;
                            negativeLastTime = true;
                        }
                        tg1 = tg2 + totalDelta;
                    } while (Math.Abs(fy1 - fy_temp) > 1.0e-6 && counter <= 200);

                    if (counter < 200)
                    {
                        Calculate(dgsInlet.Temperature, tg1);
                        solveState = SolveState.Solved;
                    }
                }
            }
            //end of adiabatic saturation process calculatioin


            //have to recalculate the streams so that the following balance calcualtion
            //can have all the latest balance calculated values taken into account
            //PostSolve(false);
            UpdateStreamsIfNecessary();

            balanceModel.DoBalanceCalculation();

            double inletDustMassFlowRate      = Constants.NO_VALUE;
            double outletDustMassFlowRate     = Constants.NO_VALUE;
            double inletDustMoistureFraction  = 0.0;
            double outletDustMoistureFraction = 0.0;

            DryingGasComponents dgc;

            if (InletParticleLoading.HasValue && gasInlet.VolumeFlowRate.HasValue)
            {
                inletDustMassFlowRate = InletParticleLoading.Value * gasInlet.VolumeFlowRate.Value;
                dgc = dgsInlet.GasComponents;
                if (dgc.SolidPhase != null)
                {
                    SolidPhase        sp = dgc.SolidPhase;
                    MaterialComponent mc = sp[1];
                    inletDustMoistureFraction = mc.GetMassFractionValue();
                }
            }

            if (OutletParticleLoading.HasValue && gasOutlet.VolumeFlowRate.HasValue)
            {
                outletDustMassFlowRate = OutletParticleLoading.Value * gasOutlet.VolumeFlowRate.Value;
                dgc = dgsOutlet.GasComponents;
                if (dgc.SolidPhase != null)
                {
                    SolidPhase        sp = dgc.SolidPhase;
                    MaterialComponent mc = sp[1];
                    inletDustMoistureFraction = mc.GetMassFractionValue();
                }
            }

            double inletMoistureFlowRate  = Constants.NO_VALUE;
            double outletMoistureFlowRate = Constants.NO_VALUE;

            if (dgsInlet.MassFlowRateDryBase.HasValue && dgsInlet.MoistureContentDryBase.HasValue)
            {
                inletMoistureFlowRate = dgsInlet.MassFlowRateDryBase.Value * dgsInlet.MoistureContentDryBase.Value;
            }

            if (dgsOutlet.MassFlowRateDryBase.HasValue && dgsOutlet.MoistureContentDryBase.HasValue)
            {
                outletMoistureFlowRate = dgsOutlet.MassFlowRateDryBase.Value * dgsOutlet.MoistureContentDryBase.Value;
            }

            double materialFromGas = 0.0;

            if (inletDustMassFlowRate != Constants.NO_VALUE && outletDustMassFlowRate != Constants.NO_VALUE &&
                inletMoistureFlowRate != Constants.NO_VALUE && outletMoistureFlowRate != Constants.NO_VALUE)
            {
                double moistureToGas = outletMoistureFlowRate - inletMoistureFlowRate;
                materialFromGas = inletDustMassFlowRate - outletDustMassFlowRate;
                double moistureOfMaterialFromGas = inletDustMassFlowRate * inletDustMoistureFraction - outletDustMassFlowRate * outletDustMoistureFraction;

                if (dmsInlet.MassFlowRate.HasValue)
                {
                    double outletMassFlowRate = dmsInlet.MassFlowRate.Value + materialFromGas - moistureToGas;
                    Calculate(dmsOutlet.MassFlowRate, outletMassFlowRate);

                    if (dmsInlet.MoistureContentWetBase.HasValue)
                    {
                        double inletMaterialMoistureFlowRate  = dmsInlet.MassFlowRate.Value * dmsInlet.MoistureContentWetBase.Value;
                        double outletMaterialMoistureFlowRate = inletMaterialMoistureFlowRate - moistureToGas + moistureOfMaterialFromGas;
                        double outletMoistureContentWetBase   = outletMaterialMoistureFlowRate / outletMassFlowRate;
                        Calculate(dmsOutlet.MoistureContentWetBase, outletMoistureContentWetBase);
                        solveState = SolveState.Solved;
                    }
                    else if (dmsOutlet.MoistureContentWetBase.HasValue)
                    {
                        double outletMaterialMoistureFlowRate = dmsOutlet.MassFlowRate.Value * dmsInlet.MoistureContentWetBase.Value;
                        double inletMaterialMoistureFlowRate  = outletMaterialMoistureFlowRate + moistureToGas - moistureOfMaterialFromGas;
                        double inletMoistureContentWetBase    = inletMaterialMoistureFlowRate / dmsInlet.MassFlowRate.Value;
                        Calculate(dmsInlet.MoistureContentWetBase, inletMoistureContentWetBase);
                        solveState = SolveState.Solved;
                    }
                }
                else if (dmsOutlet.MassFlowRate.HasValue)
                {
                    double inletMassFlowRate = dmsOutlet.MassFlowRate.Value - materialFromGas + moistureToGas;
                    Calculate(dmsInlet.MassFlowRate, inletMassFlowRate);

                    if (dmsInlet.MoistureContentWetBase.HasValue)
                    {
                        double inletMaterialMoistureFlowRate  = dmsInlet.MassFlowRate.Value * dmsInlet.MoistureContentWetBase.Value;
                        double outletMaterialMoistureFlowRate = inletMaterialMoistureFlowRate - moistureToGas + moistureOfMaterialFromGas;
                        double outletMoistureContentWetBase   = outletMaterialMoistureFlowRate / dmsOutlet.MassFlowRate.Value;
                        Calculate(dmsOutlet.MoistureContentWetBase, outletMoistureContentWetBase);
                        solveState = SolveState.Solved;
                    }
                    else if (dmsOutlet.MoistureContentWetBase.HasValue)
                    {
                        double outletMaterialMoistureFlowRate = dmsOutlet.MassFlowRate.Value * dmsInlet.MoistureContentWetBase.Value;
                        double inletMaterialMoistureFlowRate  = outletMaterialMoistureFlowRate + moistureToGas - moistureOfMaterialFromGas;
                        double inletMoistureContentWetBase    = inletMaterialMoistureFlowRate / inletMassFlowRate;
                        Calculate(dmsInlet.MoistureContentWetBase, inletMoistureContentWetBase);
                        solveState = SolveState.Solved;
                    }
                }
                else if (dmsOutlet.MassConcentration.HasValue)
                {
                    double cValue            = dmsOutlet.MassConcentration.Value;
                    double inletMassFlowRate = (materialFromGas * (1 - cValue) + moistureToGas * cValue) / cValue;
                    Calculate(dmsInlet.MassFlowRate, inletMassFlowRate);
                    double outletMassFlowRate = inletMassFlowRate + materialFromGas - moistureToGas;
                    Calculate(dmsOutlet.MassFlowRate, outletMassFlowRate);
                    solveState = SolveState.Solved;
                }
            }

            MoistureProperties moistureProperties        = (this.unitOpSystem as EvaporationAndDryingSystem).GetMoistureProperties(((DryingMaterialStream)liquidInlet).MaterialComponents.Moisture.Substance);
            double             enthalpyOfMaterialFromGas = 0.0;

            if (dmsOutlet.GetCpOfAbsoluteDryMaterial() != Constants.NO_VALUE && inletDustMoistureFraction != Constants.NO_VALUE && gasInlet.Temperature.HasValue)
            {
                double tempValue = gasInlet.Temperature.Value;
                double liquidCp  = moistureProperties.GetSpecificHeatOfLiquid(tempValue);
                double specificHeatOfSolidPhase = (1.0 - inletDustMoistureFraction) * dmsOutlet.GetCpOfAbsoluteDryMaterial() + inletDustMoistureFraction * liquidCp;
                enthalpyOfMaterialFromGas = materialFromGas * specificHeatOfSolidPhase * (tempValue - 273.15);
            }

            if (gasInlet.SpecificEnthalpy.HasValue && gasInlet.MassFlowRate.HasValue &&
                gasOutlet.SpecificEnthalpy.HasValue && gasOutlet.MassFlowRate.HasValue)
            {
                double gasEnthalpyLoss = gasInlet.SpecificEnthalpy.Value * gasInlet.MassFlowRate.Value -
                                         gasOutlet.SpecificEnthalpy.Value * gasOutlet.MassFlowRate.Value;

                if (liquidInlet.SpecificEnthalpy.HasValue && liquidInlet.MassFlowRate.HasValue &&
                    liquidOutlet.MassFlowRate.HasValue)
                {
                    double totalLiquidOutletEnthalpy    = gasEnthalpyLoss + enthalpyOfMaterialFromGas + liquidInlet.SpecificEnthalpy.Value * liquidInlet.MassFlowRate.Value;
                    double specificLiquidOutletEnthalpy = totalLiquidOutletEnthalpy / liquidOutlet.MassFlowRate.Value;
                    Calculate(liquidOutlet.SpecificEnthalpy, specificLiquidOutletEnthalpy);
                }
                //else if (gasInlet.SpecificEnthalpy.HasValue && gasInlet.MassFlowRate.HasValue &&
                //               gasOutlet.SpecificEnthalpy.HasValue && gasOutlet.MassFlowRate.HasValue &&
                //               liquidOutlet.SpecificEnthalpy.HasValue && liquidOutlet.MassFlowRate.HasValue &&
                //               liquidInlet.MassFlowRate.HasValue) {
                //   double totalLiquidInletEnthalpy = liquidOutlet.SpecificEnthalpy.Value * liquidOutlet.MassFlowRate.Value - gasEnthalpyLoss - enthalpyOfMaterialFromGas;
                //   double specificLiquidInletEnthalpy = totalLiquidInletEnthalpy / liquidInlet.MassFlowRate.Value;
                //   Calculate(liquidInlet.SpecificEnthalpy, specificLiquidInletEnthalpy);
                //}
            }
            else if (liquidInlet.SpecificEnthalpy.HasValue && liquidInlet.MassFlowRate.HasValue &&
                     liquidOutlet.SpecificEnthalpy.HasValue && liquidOutlet.MassFlowRate.HasValue)
            {
                double liquidEnthalpyLoss = liquidInlet.SpecificEnthalpy.Value * liquidInlet.MassFlowRate.Value -
                                            liquidOutlet.SpecificEnthalpy.Value * liquidOutlet.MassFlowRate.Value;

                if (gasInlet.SpecificEnthalpy.HasValue && gasInlet.MassFlowRate.HasValue &&
                    gasOutlet.MassFlowRate.HasValue)
                {
                    double totalGasOutletEnthalpy    = liquidEnthalpyLoss + gasInlet.SpecificEnthalpy.Value * gasInlet.MassFlowRate.Value + enthalpyOfMaterialFromGas;
                    double specificGasOutletEnthalpy = totalGasOutletEnthalpy / gasOutlet.MassFlowRate.Value;
                    Calculate(gasOutlet.SpecificEnthalpy, specificGasOutletEnthalpy);
                }
                //else if (gasOutlet.SpecificEnthalpy.HasValue && gasOutlet.MassFlowRate.HasValue &&
                //               gasInlet.MassFlowRate.HasValue) {
                //   double totalGasInletEnthalpy = gasOutlet.SpecificEnthalpy.Value * gasOutlet.MassFlowRate.Value - liquidEnthalpyLoss;
                //   double specificGasInletEnthalpy = totalGasInletEnthalpy / gasInlet.MassFlowRate.Value;
                //   Calculate(gasInlet.SpecificEnthalpy, specificGasInletEnthalpy);
                //}
            }

            if (liquidToGasVolumeRatio.HasValue && gasInlet.VolumeFlowRate.HasValue)
            {
                //double recirculationVolumeFlow = liquidToGasVolumeRatio.Value * gasInlet.VolumeFlowRate.Value;
                //Calculate(liquidRecirculationVolumeFlowRate, recirculationVolumeFlow);
                //if (liquidOutlet.Density.HasValue) {
                //   double recirculationMassFlow = recirculationVolumeFlow / liquidOutlet.Density.Value;
                //   Calculate(liquidRecirculationMassFlowRate, recirculationMassFlow);
                //}
            }
        }
コード例 #12
0
        public override void Execute(bool propagate)
        {
            //if dew point is known
            //HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();
            if (dewPoint.HasValue)
            {
                if (relativeHumidity.HasValue && !temperature.IsSpecifiedAndHasValue)
                {
                    Calculate(temperature, HumidGasCalculator.GetDryBulbFromDewPointAndRelativeHumidity(dewPoint.Value, relativeHumidity.Value));
                }
                else if (pressure.HasValue)
                {
                    if (dewPoint.Value <= 1.0e-10 && !moistureContentDryBase.IsSpecifiedAndHasValue)
                    {
                        Calculate(moistureContentDryBase, 0);
                    }
                    else if (!moistureContentDryBase.IsSpecifiedAndHasValue)
                    {
                        Calculate(moistureContentDryBase, HumidGasCalculator.GetHumidityFromDewPointAndPressure(dewPoint.Value, pressure.Value));
                    }
                }
                //Pressure should always be known. So it should not be calculated
                else if (moistureContentDryBase.HasValue)
                {
                    //Calculate(pressure, humidGasCalculator.GetPressureFromDewPointAndHumidity(dewPoint.Value, humidity.Value));
                }
            }

            //if humidity is known
            if (moistureContentDryBase.HasValue)
            {
                if (pressure.HasValue && !dewPoint.IsSpecifiedAndHasValue)
                {
                    Calculate(dewPoint, HumidGasCalculator.GetDewPointFromHumidityAndPressure(moistureContentDryBase.Value, pressure.Value));
                }

                //to prevent repeated calculation of the same variable
                //if (relativeHumidity.HasValue && dewPoint.HasValue && !temperature.IsSpecifiedAndHasValue) {
                if (relativeHumidity.HasValue && dewPoint.HasValue && !temperature.HasValue)
                {
                    Calculate(temperature, HumidGasCalculator.GetDryBulbFromDewPointAndRelativeHumidity(dewPoint.Value, relativeHumidity.Value));
                }

                //to prevent repeated calculation of the same variable
                //if (wetBulbTemperature.HasValue && pressure.HasValue && !temperature.IsSpecifiedAndHasValue) {
                if (wetBulbTemperature.HasValue && pressure.HasValue && !temperature.HasValue)
                {
                    Calculate(temperature, HumidGasCalculator.GetDryBulbFromWetBulbHumidityAndPressure(wetBulbTemperature.Value, moistureContentDryBase.Value, pressure.Value));
                }
            }

            //to prevent repeated calculation of the same variable
            //if (wetBulbTemperature.HasValue && relativeHumidity.HasValue && pressure.HasValue
            //   && !temperature.IsSpecifiedAndHasValue) {
            if (wetBulbTemperature.HasValue && relativeHumidity.HasValue && pressure.HasValue &&
                !temperature.HasValue)
            {
                Calculate(temperature, HumidGasCalculator.GetDryBulbFromWetBulbRelativeHumidityAndPressure(wetBulbTemperature.Value, relativeHumidity.Value, pressure.Value));
            }

            double humidEnthalpyValue;
            double mcDryBase = moistureContentDryBase.Value;

            if (specificEnthalpy.HasValue && moistureContentDryBase.HasValue && !specificEnthalpyDryBase.HasValue)
            {
                Calculate(specificEnthalpyDryBase, specificEnthalpy.Value * (1.0 + mcDryBase));
            }

            //if (specificEnthalpyDryBase.HasValue && pressure.HasValue && !temperature.IsSpecifiedAndHasValue) {
            if (specificEnthalpyDryBase.HasValue && pressure.HasValue && !temperature.HasValue)
            {
                if (moistureContentDryBase.HasValue)
                {
                    Calculate(temperature, HumidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(specificEnthalpyDryBase.Value, moistureContentDryBase.Value, pressure.Value));
                }
                else if (relativeHumidity.HasValue)
                {
                    Calculate(temperature, HumidGasCalculator.GetDryBulbFromHumidEnthalpyRelativeHumidityAndPressure(specificEnthalpyDryBase.Value, relativeHumidity.Value, pressure.Value));
                }
                else if (dewPoint.HasValue)
                {
                    Calculate(temperature, HumidGasCalculator.GetDryBulbFromHumidEnthalpyDewPointAndPressure(specificEnthalpyDryBase.Value, relativeHumidity.Value, pressure.Value));
                }
                else if (wetBulbTemperature.HasValue)
                {
                    Calculate(temperature, HumidGasCalculator.GetDryBulbFromHumidEnthalpyWetBulbAndPressure(specificEnthalpyDryBase.Value, wetBulbTemperature.Value, pressure.Value));
                }
            }

            //if temperature is first known
            if (temperature.HasValue)
            {
                if (dewPoint.HasValue || relativeHumidity.HasValue)
                {
                    if (dewPoint.HasValue && !relativeHumidity.IsSpecifiedAndHasValue)
                    {
                        Calculate(relativeHumidity, HumidGasCalculator.GetRelativeHumidityFromDryBulbAndDewPoint(temperature.Value, dewPoint.Value));
                    }
                    else if (relativeHumidity.HasValue && !dewPoint.IsSpecifiedAndHasValue)
                    {
                        Calculate(dewPoint, HumidGasCalculator.GetDewPointFromDryBulbAndRelativeHumidity(temperature.Value, relativeHumidity.Value));
                    }

                    if (pressure.HasValue)
                    {
                        if (!moistureContentDryBase.IsSpecifiedAndHasValue)
                        {
                            Calculate(moistureContentDryBase, HumidGasCalculator.GetHumidityFromDewPointAndPressure(dewPoint.Value, pressure.Value));
                        }
                        if (!wetBulbTemperature.IsSpecifiedAndHasValue)
                        {
                            Calculate(wetBulbTemperature, HumidGasCalculator.GetWetBulbFromDryBulbHumidityAndPressure(temperature.Value, moistureContentDryBase.Value, pressure.Value));
                            //double satTemp = humidGasCalculator.GetSatTempFromDryBulbHumidityAndPressure(temperature.Value, moistureContentDryBase.Value, pressure.Value);
                        }
                    }
                    else if (moistureContentDryBase.HasValue)
                    {
                        if (!pressure.IsSpecifiedAndHasValue)
                        {
                            Calculate(pressure, HumidGasCalculator.GetPressureFromDewPointAndHumidity(dewPoint.Value, moistureContentDryBase.Value));
                        }
                        if (!wetBulbTemperature.IsSpecifiedAndHasValue)
                        {
                            Calculate(wetBulbTemperature, HumidGasCalculator.GetWetBulbFromDryBulbHumidityAndPressure(temperature.Value, moistureContentDryBase.Value, pressure.Value));
                            //double satTemp = humidGasCalculator.GetSatTempFromDryBulbHumidityAndPressure(temperature.Value, moistureContentDryBase.Value, pressure.Value);
                        }
                    }
                }
                else if (wetBulbTemperature.HasValue && pressure.HasValue)
                {
                    if (!moistureContentDryBase.IsSpecifiedAndHasValue)
                    {
                        Calculate(moistureContentDryBase, HumidGasCalculator.GetHumidityFromDryBulbWetBulbAndPressure(temperature.Value, wetBulbTemperature.Value, pressure.Value));
                    }
                    if (!relativeHumidity.IsSpecifiedAndHasValue)
                    {
                        Calculate(relativeHumidity, HumidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(temperature.Value, moistureContentDryBase.Value, pressure.Value));
                    }
                    if (!dewPoint.IsSpecifiedAndHasValue)
                    {
                        Calculate(dewPoint, HumidGasCalculator.GetDewPointFromDryBulbAndRelativeHumidity(temperature.Value, relativeHumidity.Value));
                    }
                }

                else if (moistureContentDryBase.HasValue && pressure.HasValue)
                {
                    if (!wetBulbTemperature.IsSpecifiedAndHasValue)
                    {
                        Calculate(wetBulbTemperature, HumidGasCalculator.GetWetBulbFromDryBulbHumidityAndPressure(temperature.Value, moistureContentDryBase.Value, pressure.Value));
                        //double satTemp = humidGasCalculator.GetSatTempFromDryBulbHumidityAndPressure(temperature.Value, moistureContentDryBase.Value, pressure.Value);
                    }

                    if (!relativeHumidity.IsSpecifiedAndHasValue)
                    {
                        Calculate(relativeHumidity, HumidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(temperature.Value, moistureContentDryBase.Value, pressure.Value));
                    }
                    if (!dewPoint.IsSpecifiedAndHasValue)
                    {
                        Calculate(dewPoint, HumidGasCalculator.GetDewPointFromDryBulbAndRelativeHumidity(temperature.Value, relativeHumidity.Value));
                    }
                }

                else if (wetBulbTemperature.HasValue && moistureContentDryBase.HasValue)
                {
                    //if (!pressure.IsSpecifiedAndHasValue) {
                    //   Calculate(pressure, humidGasCalculator.GetPressureFromDryBulbWetBulbAndHumidity(temperature.Value, wetBulbTemperature.Value, moistureContentDryBase.Value));
                    //}
                    if (!dewPoint.IsSpecifiedAndHasValue)
                    {
                        Calculate(dewPoint, HumidGasCalculator.GetDewPointFromHumidityAndPressure(temperature.Value, pressure.Value));
                    }
                    if (!relativeHumidity.IsSpecifiedAndHasValue)
                    {
                        Calculate(relativeHumidity, HumidGasCalculator.GetRelativeHumidityFromDryBulbAndDewPoint(temperature.Value, dewPoint.Value));
                    }
                }
            }

            mcDryBase = moistureContentDryBase.Value;
            if (moistureContentDryBase.HasValue && temperature.HasValue)
            {
                double cpDryBase = HumidGasCalculator.GetHumidHeat(moistureContentDryBase.Value, temperature.Value);
                Calculate(specificHeatDryBase, cpDryBase);
                Calculate(specificHeat, cpDryBase / (1.0 + mcDryBase));
                if (pressure.HasValue)
                {
                    double humidVolumeValue = HumidGasCalculator.GetHumidVolume(temperature.Value, moistureContentDryBase.Value, pressure.Value);
                    Calculate(humidVolume, humidVolumeValue);
                    humidEnthalpyValue = HumidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(temperature.Value, moistureContentDryBase.Value, pressure.Value);
                    Calculate(specificEnthalpyDryBase, humidEnthalpyValue);
                    Calculate(specificEnthalpy, humidEnthalpyValue / (1.0 + mcDryBase));
                    Calculate(density, (1.0 + mcDryBase) / humidVolumeValue);
                }
            }

            CalculateFlow();

            //if (temperature.HasValue && pressure.HasValue && massFlowRate.HasValue &&
            //   volumeFlowRate.HasValue && massFlowRateDryBase.HasValue && wetBulbTemperature.HasValue &&
            //   dewPoint.HasValue && moistureContentDryBase.HasValue && relativeHumidity.HasValue &&
            //   density.HasValue && specificEnthalpy.HasValue && specificHeatDryBase.HasValue) {
            //   solveState = SolveState.Solved;
            //}

            bool hasUnsolvedVar = false;

            foreach (ProcessVarDouble pv in varList)
            {
                if (!pv.HasValue)
                {
                    hasUnsolvedVar = true;
                    break;
                }
            }
            if (!hasUnsolvedVar)
            {
                solveState = SolveState.Solved;
            }
            //else
            //{
            //   foreach (ProcessVarDouble pv in varList)
            //   {
            //      if (!pv.IsSpecified && pv.HasValue)
            //      {
            //         solveState = SolveState.PartiallySolved;
            //         break;
            //      }
            //   }
            //}

            if (HasSolvedAlready)
            {
                DryingGasComponents dgc = (DryingGasComponents)materialComponents;
                //we cannot do a calculate operation since these variables are not in the
                //varList and they cannot be erased after they are initially calculated
                dgc.DryMedium.SetMassFractionValue(1.0 / (1.0 + Humidity.Value));
                dgc.Moisture.SetMassFractionValue(Humidity.Value / (1.0 + Humidity.Value));
                dgc.ComponentsFractionsChanged();
            }
            AdjustVarsStates();
            OnSolveComplete();
        }
コード例 #13
0
        protected override ErrorMessage CheckSpecifiedValueRange(ProcessVarDouble pv, double aValue)
        {
            ErrorMessage retValue = base.CheckSpecifiedValueRange(pv, aValue);

            if (retValue != null)
            {
                return(retValue);
            }

            string valueString = aValue.ToString();

            if (pv == temperature)
            {
                if (wetBulbTemperature.IsSpecifiedAndHasValue && aValue < wetBulbTemperature.Value)
                {
                    retValue = CreateSimpleGenericInappropriateSpecifiedValueErrorMessage("Specified " + pv.VarTypeName + " value is less than " + wetBulbTemperature.VarTypeName + " and therefore cannot be committed.");
                }
                else if (dewPoint.IsSpecifiedAndHasValue && aValue < dewPoint.Value)
                {
                    retValue = CreateSimpleGenericInappropriateSpecifiedValueErrorMessage("Specified " + pv.VarTypeName + " value is less than " + dewPoint.VarTypeName + " and therefore cannot be committed.");
                }
            }
            else if (pv == wetBulbTemperature)
            {
                if (temperature.IsSpecifiedAndHasValue && aValue > temperature.Value)
                {
                    retValue = CreateSimpleGenericInappropriateSpecifiedValueErrorMessage("Specified " + pv.VarTypeName + " value is greater than " + temperature.VarTypeName + " and therefore cannot be committed.");
                }
                else if (dewPoint.IsSpecifiedAndHasValue && aValue < dewPoint.Value)
                {
                    retValue = CreateSimpleGenericInappropriateSpecifiedValueErrorMessage("Specified " + pv.VarTypeName + " value is less than than " + dewPoint.VarTypeName + " and therefore cannot be committed.");
                }
            }
            else if (pv == dewPoint)
            {
                if (temperature.IsSpecifiedAndHasValue && aValue > temperature.Value)
                {
                    retValue = CreateSimpleGenericInappropriateSpecifiedValueErrorMessage("Specified " + pv.VarTypeName + " value is greater than " + temperature.VarTypeName + " and therefore cannot be committed.");
                }
                else if (wetBulbTemperature.IsSpecifiedAndHasValue && aValue > wetBulbTemperature.Value)
                {
                    retValue = CreateSimpleGenericInappropriateSpecifiedValueErrorMessage("Specified " + pv.VarTypeName + " value is greater than " + wetBulbTemperature.VarTypeName + " and therefore cannot be committed.");
                }
            }
            else if (pv == Humidity)
            {
                if (aValue < 0)
                {
                    retValue = CreateLessThanZeroErrorMessage(pv);
                }
                else if (pressure.HasValue)
                {
                    double maxHumidity = 1000.0;

                    //HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();
                    if (temperature.HasValue)
                    {
                        maxHumidity = HumidGasCalculator.GetHumidityFromDewPointAndPressure(temperature.Value, pressure.Value);
                    }
                    else if (wetBulbTemperature.HasValue)
                    {
                        maxHumidity = HumidGasCalculator.GetHumidityFromDewPointAndPressure(wetBulbTemperature.Value, pressure.Value);
                    }
                    else if (dewPoint.HasValue)
                    {
                        maxHumidity = HumidGasCalculator.GetHumidityFromDewPointAndPressure(dewPoint.Value, pressure.Value);
                    }

                    if (aValue > maxHumidity)
                    {
                        aValue   = maxHumidity;
                        retValue = CreateSimpleGenericInappropriateSpecifiedValueErrorMessage("The maximum " + pv.VarTypeName + " value under current conditions is " + aValue.ToString() + ".\n Specified value " + valueString + " is greater than the maximum and therefore cannot be committed.");
                    }
                }
            }
            else if (pv == relativeHumidity)
            {
                if (aValue < 0 || aValue > 1.0)
                {
                    retValue = CreateOutOfRangeZeroToOneErrorMessage(pv);
                }
            }

            if (retValue == null)
            {
                retValue = CheckSpecifiedValueInContextOfOwner(pv, aValue);
            }

            return(retValue);
        }
コード例 #14
0
        private void Solve()
        {
            ProcessStreamBase inletStream;
            double            totalFlow = 0.0;
            //double totalFlowDryBase = 0.0;
            double temp;
            int    numOfUnknownFlow = 0;
            //int numOfUnknownFlowDryBase = 0;
            int unknownFlowIndex = -1;
            //int unknownFlowDryBaseIndex = -1;

            DryingStream dryingStream;
            DryingStream dsInlet;
            DryingStream dsOutlet = null;

            if (outlet is DryingStream)
            {
                dsOutlet = outlet as DryingStream;
            }

            int knownIndex = -1;
            int numOfKnown = 0;
            ProcessStreamBase stream;

            /*for (int i = 0; i < InOutletStreams.Count; i++) {
             * stream = InOutletStreams[i] as ProcessStreamBase;
             * if (stream.Pressure.HasValue) {
             *    knownIndex = i;
             *    numOfKnown++;
             * }
             * }
             *
             * if (numOfKnown == 1) {
             * stream = InOutletStreams[knownIndex] as ProcessStreamBase;
             * temp = stream.Pressure.Value;
             * for (int i = 0; i < InOutletStreams.Count; i++) {
             *    stream = InOutletStreams[i] as ProcessStreamBase;
             *    if (i != knownIndex) {
             *       Calculate(stream.Pressure, temp);
             *       stream.Execute(false);
             *    }
             * }
             * }*/

            numOfKnown = 0;
            DryingMaterialStream matStream;

            if (outlet is DryingMaterialStream)
            {
                for (int i = 0; i < InOutletStreams.Count; i++)
                {
                    matStream = InOutletStreams[i] as DryingMaterialStream;
                    if (matStream.SpecificHeatAbsDry.HasValue)
                    {
                        knownIndex = i;
                        numOfKnown++;
                    }
                }

                if (numOfKnown == 1)
                {
                    matStream = InOutletStreams[knownIndex] as DryingMaterialStream;
                    temp      = matStream.SpecificHeatAbsDry.Value;
                    for (int i = 0; i < InOutletStreams.Count; i++)
                    {
                        matStream = InOutletStreams[i] as DryingMaterialStream;
                        if (i != knownIndex)
                        {
                            Calculate(matStream.SpecificHeatAbsDry, temp);
                            matStream.Execute(false);
                        }
                    }
                }
            }


            //flow balance
            for (int i = 0; i < inletStreams.Count; i++)
            {
                inletStream = inletStreams[i] as ProcessStreamBase;
                if (inletStream.MassFlowRate.HasValue)
                {
                    totalFlow += inletStream.MassFlowRate.Value;
                }
                else
                {
                    unknownFlowIndex = i;
                    numOfUnknownFlow++;
                }
            }

            if (numOfUnknownFlow == 1 && outlet.MassFlowRate.HasValue)
            {
                inletStream = inletStreams[unknownFlowIndex] as ProcessStreamBase;
                //if (outlet.MassFlowRate.Value > totalFlow && inletStream.MassFlowRate.IsSpecifiedAndHasNoValue)
                if (outlet.MassFlowRate.Value > totalFlow && !inletStream.MassFlowRate.HasValue)
                {
                    Calculate(inletStream.MassFlowRate, (outlet.MassFlowRate.Value - totalFlow));
                }
            }
            else if (numOfUnknownFlow == 0)
            {
                Calculate(outlet.MassFlowRate, totalFlow);
            }

            double inletTotal        = 0.0;
            int    numOfUnknownInlet = 0;
            int    unknownInletIndex = -1;

            //moisture content balance
            if (outlet is DryingStream)
            {
                double mcDryBase;
                double mcWetBase;
                for (int i = 0; i < inletStreams.Count; i++)
                {
                    dsInlet   = inletStreams[i] as DryingStream;
                    mcWetBase = Constants.NO_VALUE;
                    if (dsInlet.MoistureContentWetBase.HasValue)
                    {
                        mcWetBase = dsInlet.MoistureContentWetBase.Value;
                    }
                    else if (dsInlet.MoistureContentDryBase.HasValue)
                    {
                        mcDryBase = dsInlet.MoistureContentDryBase.Value;
                        mcWetBase = mcDryBase / (1.0 + mcDryBase);
                    }
                    if (dsInlet.MassFlowRate.HasValue && mcWetBase != Constants.NO_VALUE)
                    {
                        //inletTotal += dsInlet.MassFlowRate.Value * mcDryBase/(1.0 + mcDryBase);
                        inletTotal += dsInlet.MassFlowRate.Value * mcWetBase;
                    }
                    else
                    {
                        unknownInletIndex = i;
                        numOfUnknownInlet++;
                    }
                }

                mcDryBase = dsOutlet.MoistureContentDryBase.Value;
                if (numOfUnknownInlet == 1 &&
                    dsOutlet.MassFlowRate.HasValue && mcDryBase != Constants.NO_VALUE)
                {
                    dsInlet = inletStreams[unknownInletIndex] as DryingStream;
                    double outletMoisture = dsOutlet.MassFlowRate.Value * mcDryBase / (1.0 + mcDryBase);
                    if (outletMoisture > inletTotal)
                    {
                        //if (dsInlet.MassFlowRate.HasValue && dsInlet.MoistureContentWetBase.IsSpecifiedAndHasNoValue) {
                        if (dsInlet.MassFlowRate.HasValue && !dsInlet.MoistureContentWetBase.HasValue)
                        {
                            mcWetBase = (outletMoisture - inletTotal) / dsInlet.MassFlowRate.Value;
                            Calculate(dsInlet.MoistureContentWetBase, mcWetBase);
                        }
                        //else if (dsInlet.MassFlowRate.HasValue && dsInlet.MoistureContentDryBase.IsSpecifiedAndHasNoValue) {
                        else if (dsInlet.MassFlowRate.HasValue && !dsInlet.MoistureContentDryBase.HasValue)
                        {
                            mcWetBase = (outletMoisture - inletTotal) / dsInlet.MassFlowRate.Value;
                            Calculate(dsInlet.MoistureContentDryBase, mcWetBase / (1.0 - mcWetBase));
                        }
                        //else if (dsInlet.MassFlowRateDryBase.HasValue && dsInlet.MoistureContentDryBase.IsSpecifiedAndHasNoValue) {
                        else if (dsInlet.MassFlowRateDryBase.HasValue && !dsInlet.MoistureContentDryBase.HasValue)
                        {
                            mcDryBase = (outletMoisture - inletTotal) / dsInlet.MassFlowRateDryBase.Value;
                            Calculate(dsInlet.MoistureContentDryBase, mcDryBase);
                        }
                        //else if (dsInlet.MoistureContentDryBase.HasValue && dsInlet.MassFlowRateDryBase.IsSpecifiedAndHasNoValue) {
                        else if (dsInlet.MoistureContentDryBase.HasValue && !dsInlet.MassFlowRateDryBase.HasValue)
                        {
                            double massFlowDryBase = (outletMoisture - inletTotal) / dsInlet.MoistureContentDryBase.Value;
                            Calculate(dsInlet.MassFlowRateDryBase, massFlowDryBase);
                        }
                        //else if (dsInlet.MoistureContentDryBase.HasValue && dsInlet.MassFlowRate.IsSpecifiedAndHasNoValue) {
                        else if (dsInlet.MoistureContentDryBase.HasValue && !dsInlet.MassFlowRate.HasValue)
                        {
                            mcDryBase = dsInlet.MoistureContentDryBase.Value;
                            double massFlow = (outletMoisture - inletTotal) / mcDryBase * (1.0 + mcDryBase);
                            Calculate(dsInlet.MassFlowRate, massFlow);
                        }
                    }
                }
                else if (numOfUnknownInlet == 0)
                {
                    //if (dsOutlet.MassFlowRate.HasValue && dsOutlet.MoistureContentWetBase.IsSpecifiedAndHasNoValue) {
                    if (dsOutlet.MassFlowRate.HasValue && !dsOutlet.MoistureContentWetBase.HasValue)
                    {
                        mcWetBase = inletTotal / dsOutlet.MassFlowRate.Value;
                        Calculate(dsOutlet.MoistureContentWetBase, mcWetBase);
                    }
                    //else if (dsOutlet.MassFlowRate.HasValue && dsOutlet.MoistureContentDryBase.IsSpecifiedAndHasNoValue) {
                    else if (dsOutlet.MassFlowRate.HasValue && !dsOutlet.MoistureContentDryBase.HasValue)
                    {
                        mcWetBase = inletTotal / dsOutlet.MassFlowRate.Value;
                        Calculate(dsOutlet.MoistureContentDryBase, mcWetBase / (1.0 - mcWetBase));
                    }
                    //else if (dsOutlet.MassFlowRateDryBase.HasValue && dsOutlet.MoistureContentDryBase.IsSpecifiedAndHasNoValue) {
                    else if (dsOutlet.MassFlowRateDryBase.HasValue && !dsOutlet.MoistureContentDryBase.HasValue)
                    {
                        mcDryBase = inletTotal / dsOutlet.MassFlowRateDryBase.Value;
                        Calculate(dsOutlet.MoistureContentDryBase, mcDryBase);
                    }
                    //else if (dsOutlet.MoistureContentDryBase.HasValue && dsOutlet.MassFlowRateDryBase.IsSpecifiedAndHasNoValue) {
                    else if (dsOutlet.MoistureContentDryBase.HasValue && !dsOutlet.MassFlowRateDryBase.HasValue)
                    {
                        double massFlowDryBase = inletTotal / dsOutlet.MoistureContentDryBase.Value;
                        Calculate(dsOutlet.MassFlowRateDryBase, massFlowDryBase);
                    }
                    //else if (dsOutlet.MoistureContentDryBase.HasValue && dsOutlet.MassFlowRate.IsSpecifiedAndHasNoValue) {
                    else if (dsOutlet.MoistureContentDryBase.HasValue && !dsOutlet.MassFlowRate.HasValue)
                    {
                        mcDryBase = dsOutlet.MoistureContentDryBase.Value;
                        double massFlow = inletTotal / mcDryBase * (1.0 + mcDryBase);
                        Calculate(dsOutlet.MassFlowRate, massFlow);
                    }
                }
            }

            inletTotal        = 0.0;
            numOfUnknownInlet = 0;
            unknownInletIndex = -1;
            double inletTotalDryBase        = 0.0;
            int    numOfUnknownInletDryBase = 0;
            int    unknownInletIndexDryBase = -1;

            //double cpDryBase;
            //double cpWetBase;

            for (int i = 0; i < inletStreams.Count; i++)
            {
                inletStream = inletStreams[i] as ProcessStreamBase;
                if (inletStream.MassFlowRate.HasValue && inletStream.SpecificEnthalpy.HasValue)
                {
                    inletTotal += inletStream.MassFlowRate.Value * inletStream.SpecificEnthalpy.Value;
                }
                else
                {
                    unknownInletIndex = i;
                    numOfUnknownInlet++;
                }

                if (outlet is DryingStream)
                {
                    dsInlet = inletStream as DryingStream;
                    if (dsInlet.MassFlowRateDryBase.HasValue && dsInlet.SpecificEnthalpyDryBase.HasValue)
                    {
                        inletTotalDryBase += dsInlet.MassFlowRateDryBase.Value * dsInlet.SpecificEnthalpyDryBase.Value;
                    }
                    else
                    {
                        unknownInletIndexDryBase = i;
                        numOfUnknownInletDryBase++;
                    }
                }
            }

            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();

            if (numOfUnknownInletDryBase == 1 &&
                (dsOutlet.MassFlowRate.HasValue && dsOutlet.SpecificEnthalpy.HasValue))
            {
                dsInlet = inletStreams[unknownInletIndexDryBase] as DryingStream;
                //cpDryBase = dsInlet.SpecificHeatDryBase.Value;
                //if (cpDryBase == Constants.NO_VALUE && dsInlet is DryingGasStream && dsInlet.MoistureContentDryBase.HasValue) {
                //   cpDryBase = humidGasCalculator.GetHumidHeat(dsInlet.MoistureContentDryBase.Value);
                //}
                double outletEnergy = dsOutlet.MassFlowRate.Value * dsOutlet.SpecificEnthalpy.Value;

                if (outletEnergy > inletTotalDryBase)
                {
                    if (dsInlet.MassFlowRate.HasValue && !dsInlet.SpecificEnthalpy.HasValue)
                    {
                        temp = (outletEnergy - inletTotalDryBase) / dsInlet.MassFlowRate.Value;
                        Calculate(dsInlet.SpecificEnthalpy, temp);
                    }
                    else if (dsInlet.MassFlowRateDryBase.HasValue && !dsInlet.SpecificEnthalpyDryBase.HasValue)
                    {
                        temp = (outletEnergy - inletTotalDryBase) / dsInlet.MassFlowRateDryBase.Value;
                        Calculate(dsInlet.SpecificEnthalpyDryBase, temp);
                    }
                    else if (dsInlet.SpecificEnthalpy.HasValue && !dsInlet.MassFlowRate.HasValue)
                    {
                        temp = (outletEnergy - inletTotalDryBase) / dsInlet.SpecificEnthalpy.Value;
                        Calculate(dsInlet.MassFlowRate, temp);
                    }
                    else if (dsInlet.SpecificEnthalpyDryBase.HasValue && !dsInlet.MassFlowRateDryBase.HasValue)
                    {
                        temp = (outletEnergy - inletTotalDryBase) / dsInlet.SpecificEnthalpyDryBase.Value;
                        Calculate(dsInlet.MassFlowRateDryBase, temp);
                    }
                }
            }
            else if (numOfUnknownInletDryBase == 0)
            {
                dsOutlet.Execute(false);
                if (dsOutlet.MassFlowRate.HasValue && !dsOutlet.SpecificEnthalpy.HasValue)
                {
                    temp = inletTotalDryBase / dsOutlet.MassFlowRate.Value;
                    Calculate(dsOutlet.SpecificEnthalpy, temp);
                }
                if (dsOutlet.MassFlowRateDryBase.HasValue && !dsOutlet.SpecificEnthalpyDryBase.HasValue)
                {
                    temp = inletTotalDryBase / dsOutlet.MassFlowRateDryBase.Value;
                    Calculate(dsOutlet.SpecificEnthalpyDryBase, temp);
                }
                else if (dsOutlet.SpecificEnthalpy.HasValue && !dsOutlet.MassFlowRate.HasValue)
                {
                    temp = inletTotalDryBase / dsOutlet.SpecificEnthalpy.Value;
                    Calculate(dsOutlet.MassFlowRate, temp);
                }
                else if (dsOutlet.SpecificEnthalpyDryBase.HasValue && !dsOutlet.MassFlowRateDryBase.HasValue)
                {
                    temp = inletTotalDryBase / dsOutlet.SpecificEnthalpyDryBase.Value;
                    Calculate(dsOutlet.MassFlowRateDryBase, temp);
                }
            }
            else if (numOfUnknownInlet == 1 && outlet.MassFlowRate.HasValue && outlet.SpecificEnthalpy.HasValue &&
                     outlet.SpecificHeat.HasValue)
            {
                inletStream = inletStreams[unknownInletIndex] as ProcessStreamBase;
                double outletEnergy = outlet.MassFlowRate.Value * outlet.Temperature.Value * outlet.SpecificHeat.Value;
                if (outletEnergy > inletTotal)
                {
                    if (inletStream.MassFlowRate.HasValue && !inletStream.SpecificEnthalpy.HasValue)
                    {
                        temp = (outletEnergy - inletTotal) / inletStream.MassFlowRate.Value;
                        Calculate(inletStream.SpecificEnthalpy, temp);
                    }
                    else if (inletStream.SpecificEnthalpy.HasValue && !inletStream.MassFlowRate.HasValue)
                    {
                        temp = (outletEnergy - inletTotal) / inletStream.SpecificEnthalpy.Value;
                        Calculate(inletStream.MassFlowRate, temp);
                    }
                }
            }
            else if (numOfUnknownInlet == 0)
            {
                if (outlet.MassFlowRate.HasValue && !outlet.SpecificEnthalpy.HasValue)
                {
                    temp = inletTotal / outlet.MassFlowRate.Value;
                    Calculate(outlet.SpecificEnthalpy, temp);
                }
                else if (outlet.SpecificEnthalpy.HasValue && !outlet.MassFlowRate.HasValue)
                {
                    temp = inletTotal / outlet.SpecificEnthalpy.Value;
                    Calculate(outlet.MassFlowRate, temp);
                }
            }

            int numOfKnownMassFlow        = 0;
            int numOfKnownPressure        = 0;
            int numOfKnownTemperature     = 0;
            int numOfKnownMoistureContent = 0;
            int numOfStrms = InOutletStreams.Count;

            for (int i = 0; i < numOfStrms; i++)
            {
                stream = InOutletStreams[i] as ProcessStreamBase;
                if (stream.MassFlowRate.HasValue)
                {
                    numOfKnownMassFlow++;
                }
                if (stream.Pressure.HasValue)
                {
                    numOfKnownPressure++;
                }
                if (stream.SpecificEnthalpy.HasValue)
                {
                    numOfKnownTemperature++;
                }
                if (outlet is DryingStream)
                {
                    dryingStream = stream as DryingStream;
                    if (dryingStream.MoistureContentDryBase.HasValue || dryingStream.MoistureContentWetBase.HasValue)
                    {
                        numOfKnownMoistureContent++;
                    }
                }
            }

            if (numOfKnownMassFlow == numOfStrms && numOfKnownTemperature == numOfStrms)
            {
                if (outlet is ProcessStream && numOfKnownPressure == numOfStrms)
                {
                    solveState = SolveState.Solved;
                }
                else if (outlet is DryingGasStream && numOfKnownPressure == numOfStrms && numOfKnownMoistureContent == numOfStrms)
                {
                    solveState = SolveState.Solved;
                }
                else if (outlet is DryingMaterialStream && numOfKnownMoistureContent == numOfStrms)
                {
                    solveState = SolveState.Solved;
                }
            }
        }
コード例 #15
0
        private void Solve()
        {
            SubstanceCatalog catalog       = SubstanceCatalog.GetInstance();
            Substance        carbon        = catalog.GetSubstance("carbon");
            Substance        hydrogen      = catalog.GetSubstance("hydrogen");
            Substance        oxygen        = catalog.GetSubstance("oxygen");
            Substance        sulfur        = catalog.GetSubstance("sulfur");
            Substance        air           = catalog.GetSubstance("air");
            Substance        carbonDioxide = catalog.GetSubstance("carbon dioxide");
            Substance        sulfurDioxide = catalog.GetSubstance("sulfur dioxide");
            Substance        water         = catalog.GetSubstance("water");
            Substance        nitrogen      = catalog.GetSubstance("nitrogen");
            Substance        argon         = catalog.GetSubstance("argon");
            //Substance ash = SubstanceCatalog.GetInstance().GetSubstance("ash");

            double totalEenthalpyOfReactantInFuelInlet = 0;
            double moleFractionCarbon   = 0;
            double moleFractionHydrogen = 0;
            double moleFractionSulfur   = 0;
            double moleFractionOxygen   = 0;
            //double massAsh = 0;
            double             moleFractionCarbonDioxide = 0;
            double             moleFractionNitrogen      = 0;
            MaterialComponents components = fuelInlet.Components;
            MaterialComponent  component;
            Substance          mySubstance;
            double             myMassFraction;

            if (fuelInlet is GenericFuelStream)
            {
                for (int i = 0; i < components.Count; i++)
                {
                    component      = components[i];
                    mySubstance    = component.Substance;
                    myMassFraction = component.MassFraction.Value;
                    if (mySubstance == carbon)
                    {
                        moleFractionCarbon = myMassFraction / carbon.MolarWeight;
                    }
                    else if (mySubstance == hydrogen)
                    {
                        moleFractionHydrogen = 0.5 * myMassFraction / hydrogen.MolarWeight;
                    }
                    else if (mySubstance == oxygen)
                    {
                        moleFractionOxygen = myMassFraction / oxygen.MolarWeight;
                    }
                    else if (mySubstance == sulfur)
                    {
                        moleFractionSulfur = myMassFraction / sulfur.MolarWeight;
                    }
                    //else if (component.Substance == ash) {
                    //   massAsh = myMassFraction;
                    //}
                }
            }
            else if (fuelInlet is DetailedFuelStream)
            {
                totalEenthalpyOfReactantInFuelInlet = 0;
                moleFractionCarbon   = 0;
                moleFractionHydrogen = 0;
                moleFractionOxygen   = 0;
                moleFractionSulfur   = 0;
                SubstanceFormula formula;
                string[]         elements;
                int    elementCount;
                double t = fuelInlet.Temperature.Value;
                for (int i = 0; i < components.Count; i++)
                {
                    component      = components[i];
                    mySubstance    = component.Substance;
                    myMassFraction = component.MassFraction.Value;

                    if (mySubstance == carbonDioxide)
                    {
                        moleFractionCarbonDioxide = myMassFraction / carbonDioxide.MolarWeight;
                    }
                    else if (mySubstance == nitrogen)
                    {
                        moleFractionNitrogen = myMassFraction / nitrogen.MolarWeight;
                    }
                    else
                    {
                        totalEenthalpyOfReactantInFuelInlet += myMassFraction * ThermalPropCalculator.Instance.CalculateEnthalpyOfFormation(t, mySubstance);
                        formula  = mySubstance.Formula;
                        elements = formula.Elements;
                        foreach (string element in elements)
                        {
                            elementCount = formula.GetElementCount(element);
                            if (element == "C")
                            {
                                moleFractionCarbon += elementCount * myMassFraction / carbon.MolarWeight;
                            }
                            else if (element == "H")
                            {
                                moleFractionHydrogen += elementCount * 0.25 * myMassFraction / hydrogen.MolarWeight;
                            }
                            else if (element == "O")
                            {
                                moleFractionOxygen = elementCount * 0.5 * myMassFraction / oxygen.MolarWeight;
                            }
                            else if (element == "S")
                            {
                                moleFractionSulfur += elementCount * myMassFraction / sulfur.MolarWeight;
                            }
                        }
                    }
                }
            }

            double fuelMassFlowRate                   = fuelInlet.MassFlowRate.Value;
            double moleFractionOxygenNeeded           = moleFractionCarbon + moleFractionHydrogen + moleFractionSulfur - moleFractionOxygen;
            double totalExactOxygenMassNeeded         = fuelMassFlowRate * moleFractionOxygenNeeded * oxygen.MolarWeight;
            double totalOxygenMoleNeeded              = fuelMassFlowRate * moleFractionOxygenNeeded * (1.0 + excessAir.Value);
            double totalDryAirMassNeeded              = totalOxygenMoleNeeded * air.MolarWeight / 0.21;
            double totalMoistureMassCarriedByInletAir = totalDryAirMassNeeded * airInlet.Humidity.Value;
            double totalAirMassNeeded                 = totalDryAirMassNeeded + totalMoistureMassCarriedByInletAir;

            Calculate(airInlet.MassFlowRate, totalAirMassNeeded);

            double totalMoitureGeneratedByReaction = fuelMassFlowRate * moleFractionHydrogen * water.MolarWeight;
            double totalMoistureInFlueGas          = totalMoitureGeneratedByReaction + totalMoistureMassCarriedByInletAir;

            double totalDryFlueGas       = totalDryAirMassNeeded + fuelMassFlowRate - totalMoitureGeneratedByReaction;
            double totalFlueGasGenerated = totalDryFlueGas + totalMoistureInFlueGas;

            Calculate(flueGasOutlet.MassFlowRate, totalFlueGasGenerated);

            double flueGasMoistureContentDryBase = totalMoistureInFlueGas / totalDryFlueGas;

            Calculate(flueGasOutlet.Humidity, flueGasMoistureContentDryBase);

            ArrayList componentList             = new ArrayList();
            double    massFractionCarbonDioxide = fuelMassFlowRate * (moleFractionCarbon + moleFractionCarbonDioxide) * carbonDioxide.MolarWeight / totalDryFlueGas;

            componentList.Add(new MaterialComponent(carbonDioxide, massFractionCarbonDioxide));

            double massFractionNitrogen = (totalDryAirMassNeeded * 0.78 + fuelMassFlowRate * moleFractionNitrogen) / totalDryFlueGas;

            componentList.Add(new MaterialComponent(nitrogen, massFractionNitrogen));

            double massFractionSulfurDioxide = fuelMassFlowRate * moleFractionSulfur * sulfurDioxide.MolarWeight / totalDryFlueGas;

            componentList.Add(new MaterialComponent(sulfurDioxide, massFractionSulfurDioxide));

            double massFractionOxygen = fuelMassFlowRate * moleFractionOxygenNeeded * excessAir.Value * oxygen.MolarWeight / totalDryFlueGas;

            componentList.Add(new MaterialComponent(oxygen, massFractionOxygen));

            double massFractionArgon = totalDryAirMassNeeded * 0.01 / totalDryFlueGas;

            componentList.Add(new MaterialComponent(argon, massFractionArgon));

            CompositeSubstance flueGas = new CompositeSubstance("Flue Gas", componentList);

            MaterialComponents flueGasComponents = new MaterialComponents();

            flueGasComponents.Add(new MaterialComponent(flueGas, 1 / (1 + flueGasMoistureContentDryBase)));
            flueGasComponents.Add(new MaterialComponent(water, flueGasMoistureContentDryBase / (1 + flueGasMoistureContentDryBase)));

            flueGasOutlet.Components = flueGasComponents;

            double fuelInletEnthalpy  = fuelMassFlowRate * fuelInlet.SpecificEnthalpy.Value;
            double airInletEnthalpy   = totalAirMassNeeded * airInlet.SpecificEnthalpy.Value;
            double totalHeatGenerated = Constants.NO_VALUE;

            if (fuelInlet is GenericFuelStream)
            {
                GenericFuelStream gfs = fuelInlet as GenericFuelStream;
                if (gfs.HeatValue.HasValue)
                {
                    //total heat genrate eaquls to heat value of the fuel times fuelMassFlowRate
                    totalHeatGenerated = gfs.HeatValue.Value * fuelMassFlowRate;
                    double totalFlueGasSpecificEnthalpy = (fuelInletEnthalpy + airInletEnthalpy + totalHeatGenerated) / totalFlueGasGenerated;
                    Calculate(flueGasOutlet.SpecificEnthalpy, totalFlueGasSpecificEnthalpy);
                }
            }
            else if (fuelInlet is DetailedFuelStream)
            {
                HumidGasCalculator    humidGasCalculator = new HumidGasCalculator(flueGas, water);
                ThermalPropCalculator propCalculator     = ThermalPropCalculator.Instance;

                double totalEenthalpyOfProductCarbonDioxide;
                double totalEenthalpyOfProductWater;
                double totalEenthalpyOfProductSulfer;
                double totalEenthalpyOfProduct;
                double totalFlueGasSpecificEnthalpy;

                double t = fuelInlet.Temperature.Value;;
                totalEenthalpyOfReactantInFuelInlet *= fuelMassFlowRate;
                double totalEnthalpyOfReactantOxygen = totalExactOxygenMassNeeded * propCalculator.CalculateEnthalpyOfFormation(t, oxygen);
                double totalEenthalpyOfReactants     = totalEenthalpyOfReactantInFuelInlet + totalEnthalpyOfReactantOxygen;

                double p       = flueGasOutlet.Pressure.Value;
                double tNew    = t;
                int    counter = 0;
                do
                {
                    counter++;
                    t = tNew;
                    totalEenthalpyOfProductCarbonDioxide = fuelMassFlowRate * moleFractionCarbon * propCalculator.CalculateEnthalpyOfFormation(t, carbonDioxide);
                    totalEenthalpyOfProductWater         = fuelMassFlowRate * moleFractionHydrogen * propCalculator.CalculateEnthalpyOfFormation(t, water);
                    totalEenthalpyOfProductSulfer        = fuelMassFlowRate * moleFractionSulfur * propCalculator.CalculateEnthalpyOfFormation(t, sulfurDioxide);
                    totalEenthalpyOfProduct      = totalEenthalpyOfProductCarbonDioxide + totalEenthalpyOfProductWater + totalEenthalpyOfProductSulfer;
                    totalHeatGenerated           = totalEenthalpyOfProduct - totalEenthalpyOfReactants;
                    totalFlueGasSpecificEnthalpy = (fuelInletEnthalpy + airInletEnthalpy + totalHeatGenerated) / totalFlueGasGenerated;

                    tNew = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(totalFlueGasSpecificEnthalpy, flueGasMoistureContentDryBase, p);
                } while (Math.Abs(tNew - t) < 1.0e-6 && counter < 100);

                if (counter == 100)
                {
                }

                Calculate(flueGasOutlet.Temperature, tNew);
            }
        }
コード例 #16
0
        private void Solve()
        {
            double p   = pressure.Value;
            double tg1 = inputStream.Temperature.Value;
            double y1  = inputStream.Humidity.Value;
            double tw1 = inputStream.WetBulbTemperature.Value;
            double td1 = inputStream.DewPoint.Value;
            double fy1 = inputStream.RelativeHumidity.Value;

            double tg2 = outputStream.Temperature.Value;
            double y2  = outputStream.Humidity.Value;
            double tw2 = outputStream.WetBulbTemperature.Value;
            double td2 = outputStream.DewPoint.Value;
            double fy2 = outputStream.RelativeHumidity.Value;

            double ih = 0;

            if (inputStream.Pressure.Value != p)
            {
                Calculate(inputStream.Pressure, p);
            }
            if (outputStream.Pressure.Value != p)
            {
                Calculate(outputStream.Pressure, p);
            }

            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();

            if (tg1 != Constants.NO_VALUE && y1 != Constants.NO_VALUE)
            {
                //wetBulb = humidGasCalculator.GetWetBulbFromDryBulbHumidityAndPressure(tg1, y1, p);
                ih = humidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(tg1, y1, p);
                if (tg2 != Constants.NO_VALUE)
                {
                    y2 = humidGasCalculator.GetHumidityFromHumidEnthalpyTemperatureAndPressure(ih, tg2, p);
                    if (y2 <= 0.0)
                    {
                        y2 = 1.0e-6;
                    }

                    Calculate(outputStream.MoistureContentDryBase, y2);
                    solveState = SolveState.Solved;
                }
                else if (y2 != Constants.NO_VALUE)
                {
                    tg2 = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(ih, y2, p);
                    Calculate(outputStream.Temperature, tg2);
                    solveState = SolveState.Solved;
                }
                else if (td2 != Constants.NO_VALUE)
                {
                    y2  = humidGasCalculator.GetHumidityFromDewPointAndPressure(td2, p);
                    tg2 = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(ih, y2, p);
                    Calculate(outputStream.Temperature, tg2);
                    solveState = SolveState.Solved;
                }
                else if (fy2 != Constants.NO_VALUE)
                {
                    double fy_temp    = 0;
                    double delta      = 10.0;
                    double totalDelta = delta;
                    tg2 = tg1 - delta;
                    bool negativeLastTime = false;

                    int counter = 0;
                    do
                    {
                        counter++;
                        y2      = humidGasCalculator.GetHumidityFromHumidEnthalpyTemperatureAndPressure(ih, tg2, p);
                        fy_temp = humidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(tg2, y2, p);
                        if (fy2 > fy_temp)
                        {
                            if (negativeLastTime)
                            {
                                delta /= 2.0; //testing finds delta/2.0 is almost optimal
                            }
                            totalDelta      += delta;
                            negativeLastTime = false;
                        }
                        else if (fy2 < fy_temp)
                        {
                            delta           /= 2.0; //testing finds delta/2.0 is almost optimal
                            totalDelta      -= delta;
                            negativeLastTime = true;
                        }
                        tg2 = tg1 - totalDelta;
                    } while (Math.Abs(fy2 - fy_temp) > 1.0e-6 && counter <= 200);

                    if (counter < 200)
                    {
                        Calculate(outputStream.Temperature, tg2);
                        solveState = SolveState.Solved;
                    }
                }

                double fy = humidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(tg2, y2, p);
                if (fy > 1.0)
                {
                    solveState = SolveState.NotSolved;
                    string msg = "Specified input state makes the relative humidity of the output greater than 1.0.";
                    throw new InappropriateSpecifiedValueException(msg);
                }
            }
            else if (tg2 != Constants.NO_VALUE && y2 != Constants.NO_VALUE)
            {
                ih = humidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(tg2, y2, p);
                if (tg1 != Constants.NO_VALUE)
                {
                    y1 = humidGasCalculator.GetHumidityFromHumidEnthalpyTemperatureAndPressure(ih, tg1, p);
                    Calculate(inputStream.MoistureContentDryBase, y1);
                    solveState = SolveState.Solved;
                }
                else if (y1 != Constants.NO_VALUE)
                {
                    tg1 = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(ih, y1, p);
                    Calculate(inputStream.Temperature, tg1);
                    solveState = SolveState.Solved;
                }
                else if (td1 != Constants.NO_VALUE)
                {
                    y1  = humidGasCalculator.GetHumidityFromDewPointAndPressure(td1, p);
                    tg1 = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(ih, y1, p);
                    Calculate(inputStream.Temperature, tg1);
                    solveState = SolveState.Solved;
                }
                else if (fy1 != Constants.NO_VALUE)
                {
                    double fy_temp    = 0;
                    double delta      = 10.0;
                    double totalDelta = delta;
                    tg1 = tg2 + delta;
                    bool negativeLastTime = false;

                    int counter = 0;
                    do
                    {
                        counter++;
                        y1      = humidGasCalculator.GetHumidityFromHumidEnthalpyTemperatureAndPressure(ih, tg1, p);
                        fy_temp = humidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(tg1, y1, p);
                        if (fy1 < fy_temp)
                        {
                            if (negativeLastTime)
                            {
                                delta /= 2.0; //testing finds delta/2.0 is almost optimal
                            }
                            totalDelta      += delta;
                            negativeLastTime = false;
                        }
                        else if (fy1 > fy_temp)
                        {
                            delta           /= 2.0; //testing finds delta/2.0 is almost optimal
                            totalDelta      -= delta;
                            negativeLastTime = true;
                        }
                        tg1 = tg2 + totalDelta;
                    } while (Math.Abs(fy1 - fy_temp) > 1.0e-6 && counter <= 200);

                    if (counter < 200)
                    {
                        Calculate(inputStream.Temperature, tg1);
                        solveState = SolveState.Solved;
                    }
                }
            }
        }
コード例 #17
0
        public ErrorMessage SetState(DryingGasStream gasStream, PointF pt)
        {
            double p           = pressure.Value;
            double temperature = (double)pt.X;
            double humidity    = (double)pt.Y;
            double wetBulb;
            double dewPoint;
            double relativeHumidity;

            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();
            Hashtable          varAndValueTable   = new Hashtable();

            if (gasStream.Temperature.IsSpecified)
            {
                if (gasStream.Humidity.IsSpecified)
                {
                    varAndValueTable.Add(gasStream.MoistureContentDryBase, humidity);
                }
                else if (gasStream.WetBulbTemperature.IsSpecified)
                {
                    wetBulb = humidGasCalculator.GetWetBulbFromDryBulbHumidityAndPressure(temperature, humidity, p);
                    varAndValueTable.Add(gasStream.WetBulbTemperature, wetBulb);
                }
                else if (gasStream.DewPoint.IsSpecified)
                {
                    dewPoint = humidGasCalculator.GetDewPointFromHumidityAndPressure(humidity, p);
                    varAndValueTable.Add(gasStream.DewPoint, dewPoint);
                }
                else if (gasStream.RelativeHumidity.IsSpecified)
                {
                    relativeHumidity = humidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(temperature, humidity, p);
                    varAndValueTable.Add(gasStream.RelativeHumidity, relativeHumidity);
                }
                varAndValueTable.Add(gasStream.Temperature, temperature);
            }
            else if (gasStream.WetBulbTemperature.IsSpecified)
            {
                if (outputStream.DewPoint.IsSpecified)
                {
                    dewPoint = humidGasCalculator.GetDewPointFromHumidityAndPressure(humidity, p);
                    varAndValueTable.Add(gasStream.DewPoint, dewPoint);
                }
                else if (gasStream.RelativeHumidity.IsSpecified)
                {
                    relativeHumidity = humidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(temperature, humidity, p);
                    varAndValueTable.Add(currentStream.RelativeHumidity, relativeHumidity);
                }
                wetBulb = humidGasCalculator.GetWetBulbFromDryBulbHumidityAndPressure(temperature, humidity, p);
                varAndValueTable.Add(gasStream.WetBulbTemperature, wetBulb);
            }
            else if (gasStream.DewPoint.IsSpecified)
            {
                if (gasStream.RelativeHumidity.IsSpecified)
                {
                    relativeHumidity = humidGasCalculator.GetRelativeHumidityFromDryBulbHumidityAndPressure(temperature, humidity, pressure.Value);
                    varAndValueTable.Add(outputStream.RelativeHumidity, relativeHumidity);
                }
                dewPoint = humidGasCalculator.GetDewPointFromHumidityAndPressure(humidity, pressure.Value);
                varAndValueTable.Add(gasStream.DewPoint, dewPoint);
            }

            return(gasStream.Specify(varAndValueTable));
        }
コード例 #18
0
        private void Solve()
        {
            double totalFlow = 0.0;
            double temp;
            int    numOfUnknownFlow = 0;
            int    unknownFlowIndex = -1;

            DryingStream dryingStream;
            DryingStream dsInlet;
            DryingStream dsOutlet = null;

            if (outlet is DryingStream)
            {
                dsOutlet = outlet as DryingStream;
            }

            ////flow balance
            //for (int i = 0; i < inletStreams.Count; i++) {
            //   inletStream = inletStreams[i] as ProcessStreamBase;
            //   if (inletStream.MassFlowRate.HasValue) {
            //      totalFlow += inletStream.MassFlowRate.Value;
            //   }
            //   else {
            //      unknownFlowIndex = i;
            //      numOfUnknownFlow++;
            //   }
            //}

            //if (numOfUnknownFlow == 1 && outlet.MassFlowRate.HasValue) {
            //   inletStream = inletStreams[unknownFlowIndex] as ProcessStreamBase;
            //   //if (outlet.MassFlowRate.Value > totalFlow && inletStream.MassFlowRate.IsSpecifiedAndHasNoValue)
            //   if (outlet.MassFlowRate.Value > totalFlow && !inletStream.MassFlowRate.HasValue) {
            //      Calculate(inletStream.MassFlowRate, (outlet.MassFlowRate.Value - totalFlow));
            //   }
            //}
            //else if (numOfUnknownFlow == 0) {
            //   Calculate(outlet.MassFlowRate, totalFlow);
            //}

            //double inletTotal = 0.0;
            //int numOfUnknownInlet = 0;
            //int unknownInletIndex = -1;
            //moisture content balance
            //if (outlet is DryingStream) {
            //   double mcDryBase;
            //   double mcWetBase;
            //   for (int i = 0; i < inletStreams.Count; i++) {
            //      dsInlet = inletStreams[i] as DryingStream;
            //      mcWetBase = Constants.NO_VALUE;
            //      if (dsInlet.MoistureContentWetBase.HasValue) {
            //         mcWetBase = dsInlet.MoistureContentWetBase.Value;
            //      }
            //      else if (dsInlet.MoistureContentDryBase.HasValue) {
            //         mcDryBase = dsInlet.MoistureContentDryBase.Value;
            //         mcWetBase = mcDryBase/(1.0 + mcDryBase);
            //      }
            //      if (dsInlet.MassFlowRate.HasValue && mcWetBase != Constants.NO_VALUE) {
            //         //inletTotal += dsInlet.MassFlowRate.Value * mcDryBase/(1.0 + mcDryBase);
            //         inletTotal += dsInlet.MassFlowRate.Value * mcWetBase;
            //      }
            //      else {
            //         unknownInletIndex = i;
            //         numOfUnknownInlet++;
            //      }
            //   }

            //   mcDryBase = dsOutlet.MoistureContentDryBase.Value;
            //   if (numOfUnknownInlet == 1 && dsOutlet.MassFlowRate.HasValue && mcDryBase != Constants.NO_VALUE) {
            //      dsInlet = inletStreams[unknownInletIndex] as DryingStream;
            //      double outletMoisture = dsOutlet.MassFlowRate.Value * mcDryBase/(1.0 + mcDryBase);

            //      if (outletMoisture > inletTotal) {
            //         //if (dsInlet.MassFlowRate.HasValue && dsInlet.MoistureContentWetBase.IsSpecifiedAndHasNoValue) {
            //         if (dsInlet.MassFlowRate.HasValue && !dsInlet.MoistureContentWetBase.HasValue) {
            //            mcWetBase = (outletMoisture - inletTotal)/dsInlet.MassFlowRate.Value;
            //            Calculate(dsInlet.MoistureContentWetBase, mcWetBase);
            //         }
            //         //else if (dsInlet.MassFlowRate.HasValue && dsInlet.MoistureContentDryBase.IsSpecifiedAndHasNoValue) {
            //         else if (dsInlet.MassFlowRate.HasValue && !dsInlet.MoistureContentDryBase.HasValue) {
            //            mcWetBase = (outletMoisture - inletTotal)/dsInlet.MassFlowRate.Value;
            //            Calculate(dsInlet.MoistureContentDryBase, mcWetBase/(1.0 - mcWetBase));
            //         }
            //         //else if (dsInlet.MassFlowRateDryBase.HasValue && dsInlet.MoistureContentDryBase.IsSpecifiedAndHasNoValue) {
            //         else if (dsInlet.MassFlowRateDryBase.HasValue && !dsInlet.MoistureContentDryBase.HasValue) {
            //            mcDryBase = (outletMoisture - inletTotal)/dsInlet.MassFlowRateDryBase.Value;
            //            Calculate(dsInlet.MoistureContentDryBase, mcDryBase);
            //         }
            //         //else if (dsInlet.MoistureContentDryBase.HasValue && dsInlet.MassFlowRateDryBase.IsSpecifiedAndHasNoValue) {
            //         else if (dsInlet.MoistureContentDryBase.HasValue && !dsInlet.MassFlowRateDryBase.HasValue) {
            //            double massFlowDryBase = (outletMoisture - inletTotal)/dsInlet.MoistureContentDryBase.Value;
            //            Calculate(dsInlet.MassFlowRateDryBase, massFlowDryBase);
            //         }
            //         //else if (dsInlet.MoistureContentDryBase.HasValue && dsInlet.MassFlowRate.IsSpecifiedAndHasNoValue) {
            //         else if (dsInlet.MoistureContentDryBase.HasValue && !dsInlet.MassFlowRate.HasValue) {
            //            mcDryBase = dsInlet.MoistureContentDryBase.Value;
            //            double massFlow = (outletMoisture - inletTotal)/mcDryBase * (1.0 + mcDryBase);
            //            Calculate(dsInlet.MassFlowRate, massFlow);
            //         }
            //      }
            //   }
            //   else if (numOfUnknownInlet == 0) {
            //      //if (dsOutlet.MassFlowRate.HasValue && dsOutlet.MoistureContentWetBase.IsSpecifiedAndHasNoValue) {
            //      if (dsOutlet.MassFlowRate.HasValue && !dsOutlet.MoistureContentWetBase.HasValue) {
            //         mcWetBase = inletTotal/dsOutlet.MassFlowRate.Value;
            //         Calculate(dsOutlet.MoistureContentWetBase, mcWetBase);
            //      }
            //      //else if (dsOutlet.MassFlowRate.HasValue && dsOutlet.MoistureContentDryBase.IsSpecifiedAndHasNoValue) {
            //      else if (dsOutlet.MassFlowRate.HasValue && !dsOutlet.MoistureContentDryBase.HasValue) {
            //         mcWetBase = inletTotal/dsOutlet.MassFlowRate.Value;
            //         Calculate(dsOutlet.MoistureContentDryBase, mcWetBase/(1.0 - mcWetBase));
            //      }
            //      //else if (dsOutlet.MassFlowRateDryBase.HasValue && dsOutlet.MoistureContentDryBase.IsSpecifiedAndHasNoValue) {
            //      else if (dsOutlet.MassFlowRateDryBase.HasValue && !dsOutlet.MoistureContentDryBase.HasValue) {
            //         mcDryBase = inletTotal/dsOutlet.MassFlowRateDryBase.Value;
            //         Calculate(dsOutlet.MoistureContentDryBase, mcDryBase);
            //      }
            //      //else if (dsOutlet.MoistureContentDryBase.HasValue && dsOutlet.MassFlowRateDryBase.IsSpecifiedAndHasNoValue) {
            //      else if (dsOutlet.MoistureContentDryBase.HasValue && !dsOutlet.MassFlowRateDryBase.HasValue) {
            //         double massFlowDryBase = inletTotal/dsOutlet.MoistureContentDryBase.Value;
            //         Calculate(dsOutlet.MassFlowRateDryBase, massFlowDryBase);
            //      }
            //      //else if (dsOutlet.MoistureContentDryBase.HasValue && dsOutlet.MassFlowRate.IsSpecifiedAndHasNoValue) {
            //      else if (dsOutlet.MoistureContentDryBase.HasValue && !dsOutlet.MassFlowRate.HasValue) {
            //         mcDryBase = dsOutlet.MoistureContentDryBase.Value;
            //         double massFlow = inletTotal/mcDryBase * (1.0 + mcDryBase);
            //         Calculate(dsOutlet.MassFlowRate, massFlow);
            //      }
            //   }
            //}

            double inletTotal        = 0.0;
            int    numOfUnknownInlet = 0;
            int    unknownInletIndex = -1;

            if (outlet is DryingGasStream)
            {
                DryingGasStream dgsInlet;
                for (int i = 0; i < inletStreams.Count; i++)
                {
                    dgsInlet = inletStreams[i] as DryingGasStream;
                    if (dgsInlet.MassFlowRateDryBase.HasValue)
                    {
                        totalFlow += dgsInlet.MassFlowRateDryBase.Value;
                    }
                    else
                    {
                        unknownFlowIndex = i;
                        numOfUnknownFlow++;
                    }
                }

                if (numOfUnknownFlow == 1 && dsOutlet.MassFlowRateDryBase.HasValue)
                {
                    dsInlet = inletStreams[unknownFlowIndex] as DryingGasStream;
                    if (dsOutlet.MassFlowRateDryBase.Value > totalFlow && !dsInlet.MassFlowRateDryBase.HasValue)
                    {
                        Calculate(dsInlet.MassFlowRateDryBase, (dsOutlet.MassFlowRateDryBase.Value - totalFlow));
                    }
                }
                else if (numOfUnknownFlow == 0)
                {
                    Calculate(dsOutlet.MassFlowRateDryBase, totalFlow);
                }

                for (int i = 0; i < inletStreams.Count; i++)
                {
                    dgsInlet = inletStreams[i] as DryingGasStream;
                    if (dgsInlet.MoistureContentDryBase.HasValue && dgsInlet.MassFlowRateDryBase.HasValue)
                    {
                        inletTotal += dgsInlet.MassFlowRateDryBase.Value * dgsInlet.MoistureContentDryBase.Value;
                    }
                    else
                    {
                        unknownInletIndex = i;
                        numOfUnknownInlet++;
                    }
                }

                if (numOfUnknownInlet == 1 && dsOutlet.MassFlowRateDryBase.HasValue && dsOutlet.MoistureContentDryBase.HasValue)
                {
                    dgsInlet = inletStreams[unknownInletIndex] as DryingGasStream;
                    double outletMoisture = dsOutlet.MassFlowRateDryBase.Value * dsOutlet.MoistureContentDryBase.Value;

                    if (outletMoisture > inletTotal)
                    {
                        if (dgsInlet.MassFlowRateDryBase.HasValue && !dgsInlet.MoistureContentDryBase.HasValue)
                        {
                            double mcDryBase = (outletMoisture - inletTotal) / dgsInlet.MassFlowRateDryBase.Value;
                            Calculate(dgsInlet.MoistureContentDryBase, mcDryBase);
                        }
                        else if (dgsInlet.MoistureContentDryBase.HasValue && !dgsInlet.MassFlowRateDryBase.HasValue)
                        {
                            double massFlowDryBase = (outletMoisture - inletTotal) / dgsInlet.MoistureContentDryBase.Value;
                            Calculate(dgsInlet.MassFlowRateDryBase, massFlowDryBase);
                        }
                    }
                    else
                    {
                        throw new CalculationFailedException(this.name + "Total mositure content from inlets is greater than that of the outlet");
                    }
                }
                else if (numOfUnknownInlet == 0)
                {
                    if (dsOutlet.MassFlowRateDryBase.HasValue && !dsOutlet.MoistureContentDryBase.HasValue)
                    {
                        double mcDryBase = inletTotal / dsOutlet.MassFlowRateDryBase.Value;
                        Calculate(dsOutlet.MoistureContentDryBase, mcDryBase);
                    }
                    else if (dsOutlet.MoistureContentDryBase.HasValue && !dsOutlet.MassFlowRateDryBase.HasValue)
                    {
                        double massFlowDryBase = inletTotal / dsOutlet.MoistureContentDryBase.Value;
                        Calculate(dsOutlet.MassFlowRateDryBase, massFlowDryBase);
                    }
                }
            }
            else if (outlet is DryingMaterialStream)
            {
                DryingMaterialStream dmsInlet;
                for (int i = 0; i < inletStreams.Count; i++)
                {
                    dmsInlet = inletStreams[i] as DryingMaterialStream;
                    if (dmsInlet.MassFlowRate.HasValue)
                    {
                        totalFlow += dmsInlet.MassFlowRate.Value;
                    }
                    else
                    {
                        unknownFlowIndex = i;
                        numOfUnknownFlow++;
                    }
                }

                if (numOfUnknownFlow == 1 && outlet.MassFlowRate.HasValue)
                {
                    dmsInlet = inletStreams[unknownFlowIndex] as DryingMaterialStream;
                    if (outlet.MassFlowRate.Value > totalFlow && !dmsInlet.MassFlowRate.HasValue)
                    {
                        Calculate(dmsInlet.MassFlowRate, (outlet.MassFlowRate.Value - totalFlow));
                    }
                }
                else if (numOfUnknownFlow == 0)
                {
                    Calculate(outlet.MassFlowRate, totalFlow);
                }
                for (int i = 0; i < inletStreams.Count; i++)
                {
                    dmsInlet = inletStreams[i] as DryingMaterialStream;
                    if (dmsInlet.MassFlowRate.HasValue && dmsInlet.MoistureContentWetBase.HasValue)
                    {
                        inletTotal += dmsInlet.MassFlowRate.Value * dmsInlet.MoistureContentWetBase.Value;
                    }
                    else
                    {
                        unknownInletIndex = i;
                        numOfUnknownInlet++;
                    }
                }

                if (numOfUnknownInlet == 1 && dsOutlet.MassFlowRate.HasValue && dsOutlet.MoistureContentWetBase.HasValue)
                {
                    dmsInlet = inletStreams[unknownInletIndex] as DryingMaterialStream;
                    double outletMoisture = dsOutlet.MassFlowRate.Value * dsOutlet.MoistureContentWetBase.Value;

                    if (outletMoisture > inletTotal)
                    {
                        if (dmsInlet.MassFlowRate.HasValue && !dmsInlet.MoistureContentWetBase.HasValue)
                        {
                            double mcWetBase = (outletMoisture - inletTotal) / dmsInlet.MassFlowRate.Value;
                            Calculate(dmsInlet.MoistureContentWetBase, mcWetBase);
                        }
                        else if (dmsInlet.MoistureContentWetBase.HasValue && !dmsInlet.MassFlowRate.HasValue)
                        {
                            double massFlow = (outletMoisture - inletTotal) / dmsInlet.MoistureContentWetBase.Value;
                            Calculate(dmsInlet.MassFlowRate, massFlow);
                        }
                    }
                    else
                    {
                        throw new CalculationFailedException(this.name + "Total mositure content from inlets is greater than that of the outlet");
                    }
                }
                else if (numOfUnknownInlet == 0)
                {
                    if (dsOutlet.MassFlowRate.HasValue && !dsOutlet.MoistureContentWetBase.HasValue)
                    {
                        double mcWetBase = inletTotal / dsOutlet.MassFlowRate.Value;
                        Calculate(dsOutlet.MoistureContentWetBase, mcWetBase);
                    }
                    else if (dsOutlet.MoistureContentWetBase.HasValue && !dsOutlet.MassFlowRate.HasValue)
                    {
                        double massFlow = inletTotal / dsOutlet.MoistureContentWetBase.Value;
                        Calculate(dsOutlet.MassFlowRate, massFlow);
                    }
                }
            }

            //have to recalculate the streams so that the following balance calcualtion
            //can have all the latest balance calculated values taken into account
            UpdateStreamsIfNecessary();

            inletTotal        = 0.0;
            numOfUnknownInlet = 0;
            unknownInletIndex = -1;
            double inletTotalDryBase        = 0.0;
            int    numOfUnknownInletDryBase = 0;
            int    unknownInletIndexDryBase = -1;

            ProcessStreamBase inletStream;

            for (int i = 0; i < inletStreams.Count; i++)
            {
                inletStream = inletStreams[i] as ProcessStreamBase;
                if (inletStream.MassFlowRate.HasValue && inletStream.SpecificEnthalpy.HasValue)
                {
                    inletTotal += inletStream.MassFlowRate.Value * inletStream.SpecificEnthalpy.Value;
                }
                else
                {
                    unknownInletIndex = i;
                    numOfUnknownInlet++;
                }

                if (outlet is DryingStream)
                {
                    dsInlet = inletStream as DryingStream;
                    if (dsInlet.MassFlowRateDryBase.HasValue && dsInlet.SpecificEnthalpyDryBase.HasValue)
                    {
                        inletTotalDryBase += dsInlet.MassFlowRateDryBase.Value * dsInlet.SpecificEnthalpyDryBase.Value;
                    }
                    else
                    {
                        unknownInletIndexDryBase = i;
                        numOfUnknownInletDryBase++;
                    }
                }
            }

            HumidGasCalculator humidGasCalculator = GetHumidGasCalculator();

            if (numOfUnknownInletDryBase == 1 &&
                (dsOutlet.MassFlowRate.HasValue && dsOutlet.SpecificEnthalpy.HasValue))
            {
                dsInlet = inletStreams[unknownInletIndexDryBase] as DryingStream;
                double outletEnergy = dsOutlet.MassFlowRate.Value * dsOutlet.SpecificEnthalpy.Value;

                if (outletEnergy > inletTotalDryBase)
                {
                    if (dsInlet.MassFlowRate.HasValue && !dsInlet.SpecificEnthalpy.HasValue)
                    {
                        temp = (outletEnergy - inletTotalDryBase) / dsInlet.MassFlowRate.Value;
                        Calculate(dsInlet.SpecificEnthalpy, temp);
                    }
                    else if (dsInlet.MassFlowRateDryBase.HasValue && !dsInlet.SpecificEnthalpyDryBase.HasValue)
                    {
                        temp = (outletEnergy - inletTotalDryBase) / dsInlet.MassFlowRateDryBase.Value;
                        Calculate(dsInlet.SpecificEnthalpyDryBase, temp);
                    }
                    else if (dsInlet.SpecificEnthalpy.HasValue && !dsInlet.MassFlowRate.HasValue)
                    {
                        temp = (outletEnergy - inletTotalDryBase) / dsInlet.SpecificEnthalpy.Value;
                        Calculate(dsInlet.MassFlowRate, temp);
                    }
                    else if (dsInlet.SpecificEnthalpyDryBase.HasValue && !dsInlet.MassFlowRateDryBase.HasValue)
                    {
                        temp = (outletEnergy - inletTotalDryBase) / dsInlet.SpecificEnthalpyDryBase.Value;
                        Calculate(dsInlet.MassFlowRateDryBase, temp);
                    }
                }
            }
            else if (numOfUnknownInletDryBase == 0)
            {
                if (dsOutlet.MassFlowRate.HasValue && !dsOutlet.SpecificEnthalpy.HasValue)
                {
                    temp = inletTotalDryBase / dsOutlet.MassFlowRate.Value;
                    Calculate(dsOutlet.SpecificEnthalpy, temp);
                }
                if (dsOutlet.MassFlowRateDryBase.HasValue && !dsOutlet.SpecificEnthalpyDryBase.HasValue)
                {
                    temp = inletTotalDryBase / dsOutlet.MassFlowRateDryBase.Value;
                    Calculate(dsOutlet.SpecificEnthalpyDryBase, temp);
                }
                else if (dsOutlet.SpecificEnthalpy.HasValue && !dsOutlet.MassFlowRate.HasValue)
                {
                    temp = inletTotalDryBase / dsOutlet.SpecificEnthalpy.Value;
                    Calculate(dsOutlet.MassFlowRate, temp);
                }
                else if (dsOutlet.SpecificEnthalpyDryBase.HasValue && !dsOutlet.MassFlowRateDryBase.HasValue)
                {
                    temp = inletTotalDryBase / dsOutlet.SpecificEnthalpyDryBase.Value;
                    Calculate(dsOutlet.MassFlowRateDryBase, temp);
                }
            }
            else if (numOfUnknownInlet == 1 && outlet.MassFlowRate.HasValue && outlet.SpecificEnthalpy.HasValue &&
                     outlet.SpecificHeat.HasValue)
            {
                inletStream = inletStreams[unknownInletIndex] as ProcessStreamBase;
                double outletEnergy = outlet.MassFlowRate.Value * outlet.Temperature.Value * outlet.SpecificHeat.Value;
                if (outletEnergy > inletTotal)
                {
                    if (inletStream.MassFlowRate.HasValue && !inletStream.SpecificEnthalpy.HasValue)
                    {
                        temp = (outletEnergy - inletTotal) / inletStream.MassFlowRate.Value;
                        Calculate(inletStream.SpecificEnthalpy, temp);
                    }
                    else if (inletStream.SpecificEnthalpy.HasValue && !inletStream.MassFlowRate.HasValue)
                    {
                        temp = (outletEnergy - inletTotal) / inletStream.SpecificEnthalpy.Value;
                        Calculate(inletStream.MassFlowRate, temp);
                    }
                }
            }
            else if (numOfUnknownInlet == 0)
            {
                if (outlet.MassFlowRate.HasValue && !outlet.SpecificEnthalpy.HasValue)
                {
                    temp = inletTotal / outlet.MassFlowRate.Value;
                    Calculate(outlet.SpecificEnthalpy, temp);
                }
                else if (outlet.SpecificEnthalpy.HasValue && !outlet.MassFlowRate.HasValue)
                {
                    temp = inletTotal / outlet.SpecificEnthalpy.Value;
                    Calculate(outlet.MassFlowRate, temp);
                }
            }

            ProcessStreamBase stream;
            int numOfKnownMassFlow        = 0;
            int numOfKnownPressure        = 0;
            int numOfKnownTemperature     = 0;
            int numOfKnownMoistureContent = 0;
            int numOfStrms = InOutletStreams.Count;

            for (int i = 0; i < numOfStrms; i++)
            {
                stream = InOutletStreams[i] as ProcessStreamBase;
                if (stream.MassFlowRate.HasValue)
                {
                    numOfKnownMassFlow++;
                }
                if (stream.Pressure.HasValue)
                {
                    numOfKnownPressure++;
                }
                if (stream.SpecificEnthalpy.HasValue)
                {
                    numOfKnownTemperature++;
                }
                if (outlet is DryingStream)
                {
                    dryingStream = stream as DryingStream;
                    if (dryingStream.MoistureContentDryBase.HasValue || dryingStream.MoistureContentWetBase.HasValue)
                    {
                        numOfKnownMoistureContent++;
                    }
                }
            }

            if (numOfKnownMassFlow == numOfStrms && numOfKnownTemperature == numOfStrms)
            {
                if (outlet is ProcessStream && numOfKnownPressure == numOfStrms)
                {
                    solveState = SolveState.Solved;
                }
                else if (outlet is DryingGasStream && numOfKnownPressure == numOfStrms && numOfKnownMoistureContent == numOfStrms)
                {
                    solveState = SolveState.Solved;
                }
                else if (outlet is DryingMaterialStream && numOfKnownMoistureContent == numOfStrms)
                {
                    solveState = SolveState.Solved;
                }
            }

            if (solveState == SolveState.Solved && outlet is DryingGasStream)
            {
                double     totalSolidPhaseMass = 0.0;
                SolidPhase solidPhase          = null;
                SolidPhase lastSolidPhase      = null;
                foreach (DryingGasStream gasStream in inletStreams)
                {
                    solidPhase = gasStream.GasComponents.SolidPhase;
                    if (solidPhase != null)
                    {
                        totalSolidPhaseMass += solidPhase.MassFraction * gasStream.MassFlowRate.Value;
                        lastSolidPhase       = solidPhase;
                    }
                }

                if (lastSolidPhase != null)
                {
                    double          outletSolidPhaseMassFraction = totalSolidPhaseMass / outlet.MassFlowRate.Value;
                    DryingGasStream dgsOutlet        = outlet as DryingGasStream;
                    SolidPhase      outletSolidPhase = dgsOutlet.GasComponents.SolidPhase;
                    if (outletSolidPhase != null)
                    {
                        outletSolidPhase.MassFraction = outletSolidPhaseMassFraction;
                    }
                    else
                    {
                        outletSolidPhase = lastSolidPhase.Clone();
                        outletSolidPhase.MassFraction      = outletSolidPhase.MassFraction;
                        dgsOutlet.GasComponents.SolidPhase = outletSolidPhase;
                    }
                }
            }
        }
コード例 #19
0
        private void Solve()
        {
            double totalEenthalpyOfReactantInFuelInlet = 0;
            double moleFractionCarbon   = 0;
            double moleFractionHydrogen = 0;
            double moleFractionSulfur   = 0;
            double moleFractionOxygen   = 0;
            //double massAsh = 0;
            double             moleFractionCarbonDioxide = 0;
            double             moleFractionNitrogen      = 0; //mole fraction of nitrogen in original gas fuel
            MaterialComponents components = fuelInlet.Components;

            if (fuelInlet is GenericFuelStream)
            {
                for (int i = 0; i < components.Count; i++)
                {
                    MaterialComponent component   = components[i];
                    Substance         mySubstance = component.Substance;
                    //myMassFraction = component.MassFraction.Value;
                    double myMoleFraction = component.MoleFraction.Value;
                    if (mySubstance == carbon)
                    {
                        moleFractionCarbon = myMoleFraction;
                    }
                    else if (mySubstance == hydrogen)
                    {
                        moleFractionHydrogen = myMoleFraction;
                    }
                    else if (mySubstance == oxygen)
                    {
                        moleFractionOxygen = myMoleFraction;
                    }
                    else if (mySubstance == sulfur)
                    {
                        moleFractionSulfur = myMoleFraction;
                    }
                    //else if (component.Substance == ash) {
                    //   massAsh = myMassFraction;
                    //}
                }
            }
            else if (fuelInlet is DetailedFuelStream)
            {
                totalEenthalpyOfReactantInFuelInlet = 0;
                moleFractionCarbon   = 0;
                moleFractionHydrogen = 0;
                moleFractionOxygen   = 0;
                moleFractionSulfur   = 0;
                double t = fuelInlet.Temperature.Value;
                for (int i = 0; i < components.Count; i++)
                {
                    MaterialComponent component      = components[i];
                    Substance         mySubstance    = component.Substance;
                    double            myMoleFraction = component.MoleFraction.Value;

                    if (mySubstance == carbonDioxide)
                    {
                        moleFractionCarbonDioxide = myMoleFraction;
                    }
                    else if (mySubstance == nitrogen)
                    {
                        moleFractionNitrogen = myMoleFraction;
                    }
                    else
                    {
                        totalEenthalpyOfReactantInFuelInlet += myMoleFraction * propCalculator.CalculateEnthalpyOfFormation(t, mySubstance);
                        SubstanceFormula formula  = mySubstance.Formula;
                        string[]         elements = formula.Elements;
                        foreach (string element in elements)
                        {
                            int elementCount = formula.GetElementCount(element);
                            if (element == "C")
                            {
                                moleFractionCarbon += elementCount * myMoleFraction;
                            }
                            else if (element == "H")
                            {
                                moleFractionHydrogen += elementCount * myMoleFraction;
                            }
                            else if (element == "O")
                            {
                                moleFractionOxygen += elementCount * myMoleFraction;
                            }
                            else if (element == "S")
                            {
                                moleFractionSulfur += elementCount * myMoleFraction;
                            }
                        }
                    }
                }
            }

            moleFractionHydrogen = 0.5 * moleFractionHydrogen; //convert from H to H2
            moleFractionOxygen   = 0.5 * moleFractionOxygen;   //convert from O to O2

            //multiply 0.5 for moleFractionHydrogen because 1 mole of H2 only needs 0.5 mole of O2
            double moleFractionOxygenNeeded = moleFractionCarbon + 0.5 * moleFractionHydrogen + moleFractionSulfur - moleFractionOxygen;
            double exactDryAirMassNeeded    = moleFractionOxygenNeeded / OXYGEN_MOLE_FRACTION_IN_AIR * air.MolarWeight;

            double excessAirValue                = excessAir.HasValue ? excessAir.Value / 100 : 0;
            double excessDryAirNeeded            = exactDryAirMassNeeded * excessAirValue;
            double dryAirMassNeeded              = exactDryAirMassNeeded + excessDryAirNeeded;
            double moistureMassCarriedByInletAir = dryAirMassNeeded * airInlet.Humidity.Value;
            double airMassNeeded = dryAirMassNeeded + moistureMassCarriedByInletAir;

            double moitureGeneratedByReaction = moleFractionHydrogen * water.MolarWeight; //since 1 mole of H2 generates 1 mole of water
            double totalMoistureInFlueGas     = moitureGeneratedByReaction + moistureMassCarriedByInletAir;

            double flueGasTotal = airMassNeeded + fuelInlet.Components.MolarWeight;
            double dryFlueGas   = flueGasTotal - totalMoistureInFlueGas;
            double flueGasMoistureContentDryBase = totalMoistureInFlueGas / dryFlueGas;

            CompositeSubstance  flueGas           = CreateDryFlueGasSubstance(moleFractionCarbon, moleFractionSulfur, moleFractionCarbonDioxide, moleFractionNitrogen, moleFractionOxygenNeeded, dryAirMassNeeded, dryFlueGas, excessAirValue);
            DryingGasComponents flueGasComponents = CreateDryingGasComponents(flueGasMoistureContentDryBase, flueGas);

            flueGasOutlet.GasComponents = flueGasComponents;

            double fuelMoleFlowRate = fuelInlet.MoleFlowRate.Value;

            if (excessAir.HasValue)
            {
                Calculate(flueGasOutlet.Humidity, flueGasMoistureContentDryBase);

                if (fuelInlet.MoleFlowRate.HasValue)
                {
                    Calculate(airInlet.MassFlowRateDryBase, dryAirMassNeeded * fuelMoleFlowRate);
                    Calculate(flueGasOutlet.MassFlowRate, flueGasTotal * fuelMoleFlowRate);
                }
                else if (flueGasOutlet.MassFlowRate.HasValue)
                {
                    fuelMoleFlowRate = flueGasOutlet.MassFlowRate.Value / flueGasTotal;
                    Calculate(fuelInlet.MoleFlowRate, fuelMoleFlowRate);
                    Calculate(airInlet.MassFlowRateDryBase, dryAirMassNeeded * fuelMoleFlowRate);
                }
            }

            double fuelInletEnthalpy  = fuelInlet.SpecificEnthalpy.Value;
            double airInletEnthalpy   = airMassNeeded * airInlet.SpecificEnthalpy.Value;
            double totalHeatGenerated = Constants.NO_VALUE;
            double heatLossValue      = 0;

            if (fuelInlet is GenericFuelStream)
            {
                //GenericFuelStream gfs = fuelInlet as GenericFuelStream;
                //if (gfs.HeatValue.HasValue) {
                //   //total heat genrate eaquls to heat value of the fuel times fuelMassFlowRate
                //   totalHeatGenerated = gfs.HeatValue.Value * fuelMoleFlowRate;

                //   heatLossValue = totalHeatGenerated * percentageHeatLoss.Value / 100;

                //   double totalFlueGasSpecificEnthalpy = (fuelInletEnthalpy + airInletEnthalpy + totalHeatGenerated - heatLossValue) / flueGasTotal;
                //   Calculate(flueGasOutlet.SpecificEnthalpy, totalFlueGasSpecificEnthalpy);
                //}
            }
            else if (fuelInlet is DetailedFuelStream)
            {
                HumidGasCalculator humidGasCalculator = new HumidGasCalculator(flueGas, water);

                //evaporation heat of 2 moles of water
                double evaporationHeat = 2.0 * water.MolarWeight * humidGasCalculator.GetEvaporationHeat(273.15);
                double p = flueGasOutlet.Pressure.Value;
                //double originalTemperature = airInlet.Temperature.Value;
                //double initialHumidEnthalpy = humidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(originalTemperature, flueGasMoistureContentDryBase, p);
                double initialHumidEnthalpy = airInlet.SpecificEnthalpyDryBase.Value;
                initialHumidEnthalpy = initialHumidEnthalpy * dryAirMassNeeded / dryFlueGas;
                double t = airInlet.Temperature.Value;
                double totalEnthalpyOfReactantOxygen = moleFractionOxygenNeeded * propCalculator.CalculateEnthalpyOfFormation(t, oxygen);
                double totalEenthalpyOfReactants     = totalEenthalpyOfReactantInFuelInlet + totalEnthalpyOfReactantOxygen;

                double tNew    = t;
                int    counter = 0;
                if (excessAir.HasValue && percentageHeatLoss.IsSpecifiedAndHasValue)
                {
                    do
                    {
                        counter++;
                        t = tNew;
                        double totalEenthalpyOfProduct = CalculateTotalEntalpyOfProduct(moleFractionCarbon, moleFractionHydrogen, moleFractionSulfur, t);
                        totalHeatGenerated = totalEenthalpyOfReactants - totalEenthalpyOfProduct + evaporationHeat;

                        heatLossValue = totalHeatGenerated * percentageHeatLoss.Value / 100;

                        double flueGasHumidEnthalpy = initialHumidEnthalpy + (totalHeatGenerated - heatLossValue) / dryFlueGas;
                        tNew = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(flueGasHumidEnthalpy, flueGasMoistureContentDryBase, p);
                    } while (Math.Abs(tNew - t) / tNew > 1.0e-8 && counter < 100);

                    if (counter == 100)
                    {
                        throw new CalculationFailedException("Calculation of flame temperature failed.");
                    }

                    Calculate(flueGasOutlet.Temperature, tNew);
                    totalHeatGenerated *= fuelMoleFlowRate;

                    Calculate(heatLoss, totalHeatGenerated * percentageHeatLoss.Value / 100);
                }
                else if (excessAir.HasValue && flueGasOutlet.Temperature.IsSpecifiedAndHasValue)
                {
                    double flueGasTemp             = flueGasOutlet.Temperature.Value;
                    double totalEenthalpyOfProduct = CalculateTotalEntalpyOfProduct(moleFractionCarbon, moleFractionHydrogen, moleFractionSulfur, flueGasTemp);
                    totalHeatGenerated = totalEenthalpyOfReactants - totalEenthalpyOfProduct + evaporationHeat;
                    heatLossValue      = totalHeatGenerated * percentageHeatLoss.Value / 100;
                    double flueGasHumidEnthalpy = initialHumidEnthalpy + (totalHeatGenerated - heatLossValue) / dryFlueGas;
                    tNew = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(flueGasHumidEnthalpy, flueGasMoistureContentDryBase, p);

                    if (tNew < flueGasTemp)
                    {
                        throw new CalculationFailedException("Specified flue gas temperature cannot be reached.");
                    }

                    counter = 0;
                    double humidEnthanlpy0 = humidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(flueGasTemp, flueGasMoistureContentDryBase, p);
                    do
                    {
                        counter++;
                        double humidEnthanlpy1 = humidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(tNew, flueGasMoistureContentDryBase, p);
                        heatLossValue       += dryFlueGas * (humidEnthanlpy1 - humidEnthanlpy0);
                        flueGasHumidEnthalpy = initialHumidEnthalpy + (totalHeatGenerated - heatLossValue) / dryFlueGas;
                        tNew = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(flueGasHumidEnthalpy, flueGasMoistureContentDryBase, p);
                    } while (Math.Abs(tNew - flueGasTemp) / flueGasTemp > 1.0e-8 && counter < 100);

                    if (counter == 100)
                    {
                        throw new CalculationFailedException("Calculation of flame temperature failed.");
                    }

                    totalHeatGenerated *= fuelMoleFlowRate;
                    heatLossValue      *= fuelMoleFlowRate;

                    Calculate(heatLoss, heatLossValue);
                    Calculate(percentageHeatLoss, heatLossValue / totalHeatGenerated * 100);
                }
                else if (flueGasOutlet.Temperature.IsSpecifiedAndHasValue && percentageHeatLoss.IsSpecifiedAndHasValue)
                {
                    double flueGasTemp             = flueGasOutlet.Temperature.Value;
                    double totalEenthalpyOfProduct = CalculateTotalEntalpyOfProduct(moleFractionCarbon, moleFractionHydrogen, moleFractionSulfur, flueGasTemp);
                    totalHeatGenerated = totalEenthalpyOfReactants - totalEenthalpyOfProduct + evaporationHeat;

                    heatLossValue = totalHeatGenerated * percentageHeatLoss.Value / 100;
                    double flueGasHumidEnthalpy = initialHumidEnthalpy + (totalHeatGenerated - heatLossValue) / dryFlueGas;
                    tNew = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(flueGasHumidEnthalpy, flueGasMoistureContentDryBase, p);

                    if (tNew < flueGasTemp)
                    {
                        throw new CalculationFailedException("Specified flue gas temperature cannot be reached.");
                    }

                    //double excessDryAirNeededOld;
                    do
                    {
                        counter++;
                        t = tNew;
                        //excessDryAirNeededOld = excessDryAirNeeded;
                        //initialHumidEnthalpy = humidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(originalTemperature, flueGasMoistureContentDryBase, p);
                        flueGasHumidEnthalpy = humidGasCalculator.GetHumidEnthalpyFromDryBulbHumidityAndPressure(flueGasTemp, flueGasMoistureContentDryBase, p);
                        dryFlueGas           = (totalHeatGenerated - heatLossValue) / (flueGasHumidEnthalpy - initialHumidEnthalpy);

                        flueGasTotal  = dryFlueGas + totalMoistureInFlueGas;
                        airMassNeeded = flueGasTotal - fuelInlet.Components.MolarWeight;

                        dryAirMassNeeded       = airMassNeeded / (1 + airInlet.Humidity.Value);
                        totalMoistureInFlueGas = moitureGeneratedByReaction + dryAirMassNeeded * airInlet.Humidity.Value;
                        excessDryAirNeeded     = dryAirMassNeeded - exactDryAirMassNeeded;
                        excessAirValue         = excessDryAirNeeded / exactDryAirMassNeeded;

                        flueGasMoistureContentDryBase = totalMoistureInFlueGas / dryFlueGas;

                        flueGas            = CreateDryFlueGasSubstance(moleFractionCarbon, moleFractionSulfur, moleFractionCarbonDioxide, moleFractionNitrogen, moleFractionOxygenNeeded, dryAirMassNeeded, dryFlueGas, excessAirValue);
                        humidGasCalculator = new HumidGasCalculator(flueGas, water);

                        tNew = humidGasCalculator.GetDryBulbFromHumidEnthalpyHumidityAndPressure(flueGasHumidEnthalpy, flueGasMoistureContentDryBase, p);
                    } while (Math.Abs(tNew - flueGasTemp) / flueGasTemp > 1.0e-8 && counter < 100);
                    //} while (Math.Abs(excessDryAirNeeded - excessDryAirNeededOld) > 1.0e-6 && counter < 100);

                    if (counter == 100)
                    {
                        throw new CalculationFailedException("Calculation of flame temperature failed.");
                    }

                    Calculate(flueGasOutlet.Humidity, flueGasMoistureContentDryBase);
                    Calculate(excessAir, excessAirValue * 100);
                    flueGasComponents           = CreateDryingGasComponents(flueGasMoistureContentDryBase, flueGas);
                    flueGasOutlet.GasComponents = flueGasComponents;

                    if (flueGasOutlet.MassFlowRate.IsSpecifiedAndHasValue)
                    {
                        fuelMoleFlowRate = flueGasOutlet.MassFlowRate.Value / flueGasTotal;
                        Calculate(fuelInlet.MoleFlowRate, fuelMoleFlowRate);
                    }
                    else
                    {
                        Calculate(flueGasOutlet.MassFlowRate, flueGasTotal * fuelMoleFlowRate);
                    }

                    Calculate(airInlet.MassFlowRateDryBase, dryAirMassNeeded * fuelMoleFlowRate);
                    Calculate(heatLoss, heatLossValue * fuelMoleFlowRate);

                    totalHeatGenerated *= fuelMoleFlowRate;
                }

                Calculate(totalHeatGeneration, totalHeatGenerated);
            }

            if (flueGasOutlet.Temperature.HasValue && totalHeatGeneration.HasValue)
            {
                solveState = SolveState.Solved;
                double oxygenMassFraction = moleFractionOxygenNeeded * excessAirValue * oxygen.MolarWeight / flueGasTotal;
                double oxygenMoleFraction = moleFractionOxygenNeeded * excessAirValue / (1 + airMassNeeded / air.MolarWeight);
                Calculate(oxygenMassFractionFlueGas, oxygenMassFraction);
                Calculate(oxygenMoleFractionFlueGas, oxygenMoleFraction);
            }
        }