/// <summary> /// Функция моделирования работы обводненной скважины с погружным насосом, возвращает дебит газа (тыс.м3/сут) /// </summary> /// <param name="eps">Точность с которой будет расчитываться забойное давление (безразмерная)</param> /// <param name="dynamicH">Динамический уровень пластовой жидкости, отсчитывается от входа в насос (м)</param> /// <param name="bottomHolePressure">Забойное давление (МПа)</param> /// <param name="waterRate">Расход жидкости (м3/сут)</param> /// <param name="nglRate">Дебит газового конденсата (т/сут)</param> /// <returns>Дебит газа в стандартных условиях (тыс.куб.м/сут)</returns> public double ModelingPump(double eps, double dynamicH, out double bottomHolePressure, out double waterRate, out double nglRate) { //Скважина делится на 3 части: //topPartWell - часть затрубного пространства, выше динамического уровня //bottomPartWell - часть затрубного пространства, ниже динамического уровня //innerPartWell - НКТ double topPartLength = Tubing.Length - dynamicH; double dynamicHTemperature = BottomholeTemperature + (WellheadTemperature - BottomholeTemperature) * (dynamicH / Tubing.Length); AnnularTubing = new Tubing(Tubing); AnnularTubing.TubingDiameter = Tubing.CalcEquivalentAnnularDiameter(); //Для затрубного пространства свободного от жидкости создаем эквивалент сухой скважины DryWell topPartWell = new DryWell(this); topPartWell.Tubing = AnnularTubing; topPartWell.BottomholePressure = dynamicHTemperature; double Ph; //давление в точке динамического уровня double gasQ = topPartWell.Modeling(eps, out Ph, out nglRate); bottomHolePressure = Ph + WaterFluid.CalcColumnPressure(dynamicH); //Давление для притока воды берется как давление на середине динамического уровня double waterPress = Ph + WaterFluid.CalcColumnPressure(dynamicH / 2); waterRate = Layer.CalcWaterRate(bottomHolePressure); return(gasQ); }
/// <summary> /// Конструктор копирования DryWell /// </summary> /// <param name="dryWell"></param> public DryWell(DryWell dryWell) { Layer = dryWell.Layer; GasFluid = dryWell.GasFluid; Tubing = new Tubing(dryWell.Tubing); WellheadPressure = dryWell.WellheadPressure; WellheadTemperature = dryWell.WellheadTemperature; BottomholeTemperature = dryWell.BottomholeTemperature; NglFluid = dryWell.NglFluid; }
/// <summary> /// Функция высчитывания забойного давления остановленной скважины по затрубному давлению (МПа) /// </summary> public double CalcStaticBottomholePressureByAnnularTubing(double annularWellheadPressure) { AnnularTubing = new Tubing(Tubing); AnnularTubing.TubingDiameter = Tubing.CalcEquivalentAnnularDiameter(); DryWell well = new DryWell(this); well.Tubing = AnnularTubing; well.WellheadPressure = annularWellheadPressure; GasFlow gasFlow = new GasFlow(GasFluid, 0, annularWellheadPressure, WellheadTemperature); double Pb = well.Tubing.CalcStaticBottomholePressure(gasFlow, BottomholeTemperature); return(Pb); }
/// <summary> /// Функция высчитывания затрубного давления на устье остановленной скважины по забойному давлению (МПа) /// </summary> public double CalcStaticAnnularTubingByBottomholePressure(double bottomholePressure) { AnnularTubing = new Tubing(Tubing); AnnularTubing.TubingDiameter = Tubing.CalcEquivalentAnnularDiameter(); DryWell well = new DryWell(this); well.Tubing = AnnularTubing; well.WellheadPressure = 0; well.BottomholePressure = bottomholePressure; GasFlow gasFlow = new GasFlow(GasFluid, 0, bottomholePressure, BottomholeTemperature, true); double annularWellheadPressure = well.Tubing.CalcStaticWellheadPressure(gasFlow, WellheadTemperature); return(annularWellheadPressure); }
/// <summary> /// Функция получения точек кривых притока P2 и оттока P1 по затрубному пространству для узлового анализа /// обводненной скважины (с откачкой насосом) /// </summary> /// <param name="dynamicH">Динамический уровень пластовой жидкости, отсчитывается от входа в насос (м)</param> /// <param name="num">Число точек</param> /// <param name="P1">Массив значений забойного давления для точек кривой оттока с забоя (МПа)</param> /// <param name="P2">Массив значений забойного давления для точек кривой притока из пласта к забою (МПа)</param> /// <param name="gasDischarge">Массив значений дебита газа (тыс.куб.м/сут)</param> /// <param name="waterDischarge">Массив значений дебит воды (м3/сут)</param> public void GetPointsAnnularTubingNodeAnalize(double dynamicH, int num, out double[] P1, out double[] P2, out double[] gasDischarge, out double[] waterDischarge) { double topPartLength = Tubing.Length - dynamicH; double dynamicHTemperature = BottomholeTemperature + (WellheadTemperature - BottomholeTemperature) * (dynamicH / Tubing.Length); P1 = new double[num]; P2 = new double[num]; gasDischarge = new double[num]; waterDischarge = new double[num]; double maxQ = Layer.CalcMaxGasRate(); double step = maxQ / num; double gasQ = 0; //создается новый Tubing чтобы не перезаписывать SegmentFlows Tubing annularTubing = new Tubing(AnnularTubing); //Для затрубного пространства свободного от жидкости создаем эквивалент сухой скважины DryWell topPartWell = new DryWell(this); topPartWell.Tubing = annularTubing; topPartWell.BottomholePressure = dynamicHTemperature; for (int i = 0; i < num; i++) { gasDischarge[i] = gasQ; GasFlow gasFlow = new GasFlow(GasFluid, gasQ, WellheadPressure, WellheadTemperature); P2[i] = topPartWell.Layer.CalcBottomholePressure(gasQ); P1[i] = topPartWell.Tubing.CalcBottomholePressure(gasFlow, dynamicHTemperature); //Давление для притока воды берется как давление на середине динамического уровня double waterPres = P2[i] + WaterFluid.CalcColumnPressure(dynamicH / 2); waterDischarge[i] = Layer.CalcWaterRate(waterPres); gasQ += step; } }