/// <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);
        }
示例#2
0
 /// <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;
 }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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;
            }
        }