//Итеративный расчет содержания PO (общая функция) private (double, double[]) CalculateStrength(double waterContent, double acnContent, float densityFromMassFT, ref Density inputDensity, bool isIncrement) { //isDecrement = true - итерация в сторону увеличения; false - итерация в сторону уменьшения var newDens = isIncrement ? 0.0 : 10000.0; var POContent = 0.0; var percArray = new double[4] { waterContent, acnContent, 0.0, 0.0 }; //ACN, Water, P, PO inputDensity.PercArray = percArray; if (inputDensity == null) { return(-1.0, new double[] { -1.0, -1.0, -1.0, -1.0 }); } int i = 0; //Формирование условия выхода из цикла в зависимости от направления итерации bool GetExitCondition() { return(isIncrement ? newDens > densityFromMassFT * 10.0 : newDens < densityFromMassFT * 10.0); } while (true) { //newDens = inputDensity.CalculateDensity(); if (GetExitCondition() || i++ > 10000) { POContent = inputDensity.PercArray[3]; break; } inputDensity.PercArray[3] += 0.01; //PO inputDensity.PercArray[1] = (100.0 - inputDensity.PercArray[3] - inputDensity.PercArray[2]) * acnContent * 0.01; //ACN inputDensity.PercArray[0] = 100.0 - inputDensity.PercArray[1] - inputDensity.PercArray[2] - inputDensity.PercArray[3]; //Water newDens = inputDensity.CalculateDensity(); } return(Math.Min(100.0, POContent), inputDensity.PercArray); }
internal void CalculateMassOfPropylene() { double propyleneMass; if (!isInitPropyleneSuccess) { return; } //Проверка на наличие минимального расхода ACN и воды, а также, чтобы расход из P05 был выше, чем из D02 if ((singleTagCreator.AcnWaterMassFlow < 408.85 * densityCreator.DensityList.FirstOrDefault(d => d.TagName == "S11_A01_FC02_DENS").ValHmi * 0.0001) || singleTagCreator.averReactFlow < singleTagCreator.AcnWaterMassFlow / (densityCreator.DensityList.FirstOrDefault(d => d.TagName == "S11_A01_FC02_DENS").ValHmi * 0.0001) + 1) { propyleneMass = 0.0; } else { var waterMass = singleTagCreator.AcnWaterMassFlow * acnWaterDensity.PercArray[0] * 0.01; var acnMass = singleTagCreator.AcnWaterMassFlow * acnWaterDensity.PercArray[1] * 0.01; //Инициализурем расчитываемую плотность стартовыми значениями (без пропилена - только вода и ACN tempDensity.PercArray[0] = acnWaterDensity.PercArray[0]; tempDensity.PercArray[1] = acnWaterDensity.PercArray[1]; tempDensity.PercArray[2] = 0.0; var dens = tempDensity.CalculateDensity(); var massAverReactFlowSave = singleTagCreator.averReactFlow * dens * 0.0001; var massAverReactFlow = 0.0; var diff = 0.0; //Подставляем для расчета плотности температуру после P05 tempDensity.Temperature = acnWaterPropyleneTemperature; var i = 0; do { //Рассчитываем массовый расход реакционной смеси и % компонентов в ней if (massAverReactFlowSave != 0) { tempDensity.PercArray[0] = Math.Max(0.0, Math.Min(100.0, waterMass * 100.0 / massAverReactFlowSave)); tempDensity.PercArray[1] = Math.Max(0.0, Math.Min(100.0, acnMass * 100.0 / massAverReactFlowSave)); tempDensity.PercArray[2] = Math.Max(0.0, 100.0 - tempDensity.PercArray[1] - tempDensity.PercArray[0]); } //Считаем плотность с новым содержанием компонентов dens = tempDensity.CalculateDensity(); if (dens != -1) { massAverReactFlow = singleTagCreator.averReactFlow * dens * 0.0001; propyleneMass = massAverReactFlow * tempDensity.PercArray[2] * 0.01; diff = Math.Abs(massAverReactFlowSave - massAverReactFlow); massAverReactFlowSave = massAverReactFlow; i++; } else { return; } }while (diff > 1.0 || i < 10); } singleTagCreator.PropyleneMass = (short)(propyleneMass * 10.0); }