/// <summary> /// Вычисление давления в самом низу сегмента (можно сказать "забой" сегмента) НКТ по барометрической формуле. /// Гриценко стр. 117, 113, 140 (для обводненной скважины). /// </summary> /// <param name="gasFlow">Газовый поток сегмента трубы</param> /// <param name="liquidFlow">Жидкостной поток сегмента трубы</param> /// <param name="btmTemperature">Температура внизу сегмента (К)</param> /// <returns>Давление на забое НКТ (МПа)</returns> public double CalcBottomPressure(GasFlow gasFlow, LiquidFlow liquidFlow, double btmTemperature) { double mixtureQ = Tubing.CalcMixtureRate(gasFlow, liquidFlow); double Ptop = gasFlow.TopPressure; gasFlow.BottomParametersDefinition(Ptop, btmTemperature); double orientirS0 = CalcS0Coeff(gasFlow, liquidFlow); double orientirTeta = CalcTetaCoeff(gasFlow, liquidFlow, orientirS0); double orientirP = Math.Sqrt(Ptop * Ptop * Math.Exp(2 * orientirS0) + orientirTeta * mixtureQ * mixtureQ); gasFlow.BottomParametersDefinition(orientirP, btmTemperature); double Pbtm = 0; for (int i = 0; i < 3; i++) { double s0 = CalcS0Coeff(gasFlow, liquidFlow); double Teta = CalcTetaCoeff(gasFlow, liquidFlow, s0); Pbtm = Math.Sqrt(Ptop * Ptop * Math.Exp(2 * s0) + Teta * mixtureQ * mixtureQ); gasFlow.BottomParametersDefinition(Pbtm, btmTemperature); } return(gasFlow.BottomPressure); }
/// <summary> /// Вычисление расхода смеси (тыс.м3/сут) /// при стандартных условиях T=293K P=0,101325МПа /// </summary> /// <param name="gasFlow">Газовый поток</param> /// <param name="liquidFlow">Жидкостной поток</param> /// <returns></returns> public static double CalcMixtureRate(GasFlow gasFlow, LiquidFlow liquidFlow) { double gasQ = gasFlow.RateAtStandardConditions; //Расход жидкости (тыс.куб.м/сут) double liquidQ = liquidFlow.Rate * 0.001; return(gasQ + liquidQ); }
/// <summary> /// Вычисление коэффициента s0 для обводнённой скважины /// Гриценко стр. 140 /// </summary> /// <param name="gasFlow">Поток</param> /// <returns>Значение коэффициента s0</returns> private double CalcS0Coeff(GasFlow gasFlow, LiquidFlow liquidFlow) { double rho = gasFlow.RelativeDensity; double L = Depth; double Z = gasFlow.SupercompressibilityFactor; double T = gasFlow.AvgTemperature; double gasContentParametr = Tubing.CalcGasContentParameter(gasFlow, liquidFlow.Rate, liquidFlow.Density); double s0 = 0.03415 * gasContentParametr * rho * L / (Z * T); return(s0); }
private void FlowOutward(IWorld world, LiquidFlow target, IMultiplayerServer server) { // For each block we can flow into, generate an item entity if appropriate var provider = world.BlockRepository.GetBlockProvider(world.GetBlockID(target.TargetBlock)); provider.GenerateDropEntity(new BlockDescriptor { Coordinates = target.TargetBlock, ID = provider.ID }, world, server); // And overwrite the block with a new fluid block. world.SetBlockID(target.TargetBlock, FlowingID); world.SetMetadata(target.TargetBlock, target.Level); server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(SecondsBetweenUpdates), s => AutomataUpdate(s, world, target.TargetBlock)); }
/// <summary> /// Вычисление Тета коэффициента (обводненнная скважина) /// Гриценко стр. 141 /// </summary> /// <param name="gasFlow">Поток протекающий по трубе</param> /// <param name="pipe">Труба</param> /// <returns>Значение Тета коэффициента</returns> public double CalcTetaCoeff(GasFlow gasFlow, LiquidFlow liquidFlow, double s0Coeff = 0) { double Z = gasFlow.SupercompressibilityFactor; double T = gasFlow.AvgTemperature; double D = Diameter; double s0 = s0Coeff; if (s0Coeff == 0) { s0 = CalcS0Coeff(gasFlow, liquidFlow); } double lambda = CalcHydraulicResistance(gasFlow); double gasContentParametr = Tubing.CalcGasContentParameter(gasFlow, liquidFlow.Rate, liquidFlow.Density); double Teta = 0.01413 * Math.Pow(10, -10) * Z * Z * T * T * (Math.Exp(2 * s0) - 1) * lambda / (gasContentParametr * Math.Pow(D, 5)); return(Teta); }
private void FlowOutward(IWorld world, LiquidFlow target, IMultiplayerServer server) { // For each block we can flow into, generate an item entity if appropriate var provider = world.BlockRepository.GetBlockProvider(world.GetBlockID(target.TargetBlock)); provider.GenerateDropEntity(new BlockDescriptor { Coordinates = target.TargetBlock, ID = provider.ID }, world, server, ItemStack.EmptyStack); // And overwrite the block with a new fluid block. world.SetBlockID(target.TargetBlock, FlowingID); world.SetMetadata(target.TargetBlock, target.Level); var chunk = world.FindChunk(target.TargetBlock); server.Scheduler.ScheduleEvent("fluid", chunk, TimeSpan.FromSeconds(SecondsBetweenUpdates), s => AutomataUpdate(s, world, target.TargetBlock)); if (FlowingID == LavaBlock.BlockID) { (BlockRepository.GetBlockProvider(FireBlock.BlockID) as FireBlock).ScheduleUpdate( server, world, world.GetBlockData(target.TargetBlock)); } }
/// <summary> /// Вычисление забойного давления НКТ в обводненной скважине по барометрической формуле (МПа) /// Гриценко стр. 113, 117, 140 /// </summary> /// <param name="topFlow">Поток, получаемый на устье</param> /// <param name="liquidFlow">Жидкостной поток</param> /// <param name="bottomholeTemperature">Забойная температура (К)</param> /// <returns></returns> public double CalcBottomholePressure(GasFlow topFlow, LiquidFlow liquidFlow, double bottomholeTemperature) { SegmentFlows.Clear(); double length = Length / NumberOfSegments; double depth = length; double dT = (bottomholeTemperature - topFlow.TopTemperature) / NumberOfSegments; WaterPipe pipe = new WaterPipe(PipeDiameter, length, depth, PipeRoughness); GasFlow gasFlow = topFlow; for (int i = 0; i < NumberOfSegments; i++) { double btmTemp = gasFlow.TopTemperature + dT; pipe.CalcBottomPressure(gasFlow, liquidFlow, btmTemp); SegmentFlows.Add(gasFlow); gasFlow = gasFlow.GenerateBottomFlow(); } return(SegmentFlows.Last().BottomPressure); }