Class WellSystem

All Implemented Interfaces:
Serializable, Runnable, ProcessEquipmentInterface, SimulationInterface, NamedInterface

public class WellSystem extends ProcessEquipmentBaseClass
WellSystem class - Integrated well model combining IPR (Inflow Performance Relationship) and VLP (Vertical Lift Performance) for complete well modeling.

This class represents a complete producing well system including:

  • Reservoir inflow (IPR) via WellFlow
  • Wellbore hydraulics (VLP) via TubingPerformance
  • Optional production choke
  • Operating point calculation (IPR-VLP intersection)
  • Lift curve generation for reservoir simulator coupling
  • Multi-layer/commingled production support

Architecture Overview

┌─────────────┐    ┌──────────┐    ┌─────────────────┐    ┌───────┐    ┌────────┐
│  Reservoir  │───►│ WellFlow │───►│TubingPerformance│───►│ Choke │───►│ Output │
│   (IPR)     │    │  (IPR)   │    │     (VLP)       │    │(opt.) │    │ Stream │
└─────────────┘    └──────────┘    └─────────────────┘    └───────┘    └────────┘
      Pr              Pwf                                    WHP         Outlet

Usage Example 1 - Basic Well Setup

// Create reservoir fluid at reservoir conditions
SystemInterface resFluid = new SystemSrkEos(373.15, 250.0);
resFluid.addComponent("methane", 85.0);
resFluid.addComponent("ethane", 5.0);
resFluid.addComponent("propane", 3.0);
resFluid.addComponent("n-heptane", 7.0);
resFluid.setMixingRule("classic");
resFluid.setMultiPhaseCheck(true);

// Create reservoir stream
Stream reservoirStream = new Stream("reservoir", resFluid);
reservoirStream.setFlowRate(5000, "Sm3/day");
reservoirStream.run();

// Create integrated well system
WellSystem well = new WellSystem("Producer-1");
well.setReservoirStream(reservoirStream);

// Configure IPR (Vogel model)
well.setIPRModel(WellSystem.IPRModel.VOGEL);
well.setVogelParameters(8000, 180, 250); // qMax at AOF, test Pwf, Pr

// Configure VLP (tubing)
well.setTubingLength(2500, "m");
well.setTubingDiameter(4.0, "in");
well.setPressureDropCorrelation(TubingPerformance.PressureDropCorrelation.BEGGS_BRILL);

// Set wellhead pressure and solve for operating point
well.setWellheadPressure(50.0, "bara");
well.run();

// Get results
double opRate = well.getOperatingFlowRate("Sm3/day");
double bhp = well.getBottomHolePressure("bara");
double whp = well.getWellheadPressure("bara");

Usage Example 2 - Lift Curve Generation for Reservoir Simulator

// Setup well as above, then generate lift curves
double[] whPressures = {30, 40, 50, 60, 70}; // bara
double[] waterCuts = {0.0, 0.2, 0.4, 0.6, 0.8};

// Generate lift curve table
LiftCurveTable liftTable = well.generateLiftCurves(whPressures, waterCuts);

// Export for Eclipse/OPM/tNavigator
liftTable.exportToEclipseVFP("producer1_vfp.inc");

Usage Example 3 - Multi-Layer Commingled Well

WellSystem multilayerWell = new WellSystem("Commingled-1");

// Add multiple reservoir layers
multilayerWell.addLayer("Layer-1", layer1Stream, 0.6, 220, 0.0005); // kh fraction, Pi, PI
multilayerWell.addLayer("Layer-2", layer2Stream, 0.3, 200, 0.0003);
multilayerWell.addLayer("Layer-3", layer3Stream, 0.1, 180, 0.0002);

// Configure common tubing
multilayerWell.setTubingLength(3000, "m");
multilayerWell.setTubingDiameter(5.5, "in");

// Solve for commingled production
multilayerWell.setWellheadPressure(45.0, "bara");
multilayerWell.run();

// Get individual layer contributions
double[] layerRates = multilayerWell.getLayerFlowRates("Sm3/day");

Integration with SimpleReservoir

// Create reservoir
SimpleReservoir reservoir = new SimpleReservoir("Field Reservoir");
reservoir.setReservoirFluid(resFluid, gasVolume, oilVolume, waterVolume);

// Add producer as WellSystem
StreamInterface prodStream = reservoir.addOilProducer("PROD-1");

WellSystem prodWell = new WellSystem("PROD-1 System");
prodWell.setReservoirStream(prodStream);
prodWell.setIPRModel(WellSystem.IPRModel.PRODUCTION_INDEX);
prodWell.setProductionIndex(0.0005, "Sm3/day/bar2");
prodWell.setTubingLength(2500, "m");
prodWell.setTubingDiameter(4.5, "in");
prodWell.setWellheadPressure(50.0, "bara");

// Add to process system
ProcessSystem process = new ProcessSystem();
process.add(reservoir);
process.add(prodWell);

// Run transient depletion
for (int year = 0; year < 10; year++) {
  reservoir.runTransient(365 * 24 * 3600); // 1 year
  prodWell.run();
  System.out.println("Year " + year + ": Rate=" + prodWell.getOperatingFlowRate("Sm3/day"));
}
Version:
1.0
Author:
Even Solbraa
See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      Serialization version UID.
      See Also:
    • logger

      private static final org.apache.logging.log4j.Logger logger
      Logger object for class.
    • wellFlowIPR

      private WellFlow wellFlowIPR
    • tubingVLP

      private TubingPerformance tubingVLP
    • productionChoke

      private ThrottlingValve productionChoke
    • reservoirStream

      private StreamInterface reservoirStream
    • outletStream

      private StreamInterface outletStream
    • inletStream

      private StreamInterface inletStream
    • layers

    • isMultiLayer

      private boolean isMultiLayer
    • iprModel

      private WellSystem.IPRModel iprModel
    • reservoirPressure

      private double reservoirPressure
    • productivityIndex

      private double productivityIndex
    • vogelQmax

      private double vogelQmax
    • fetkovichC

      private double fetkovichC
    • fetkovichN

      private double fetkovichN
    • backpressureA

      private double backpressureA
    • backpressureB

      private double backpressureB
    • targetWellheadPressure

      private double targetWellheadPressure
    • operatingFlowRate

      private double operatingFlowRate
    • operatingBHP

      private double operatingBHP
    • chokeOpening

      private double chokeOpening
    • tubingLength

      private double tubingLength
    • tubingDiameter

      private double tubingDiameter
    • tubingRoughness

      private double tubingRoughness
    • tubingInclination

      private double tubingInclination
    • pdCorrelation

    • tempModel

    • bhTemperature

      private double bhTemperature
    • whTemperature

      private double whTemperature
    • tolerance

      private double tolerance
    • maxIterations

      private int maxIterations
    • vlpSolverMode

      private WellSystem.VLPSolverMode vlpSolverMode
  • Constructor Details

    • WellSystem

      public WellSystem(String name)
      Constructor for WellSystem.
      Parameters:
      name - well name
    • WellSystem

      public WellSystem(String name, StreamInterface inletStream)
      Constructor for WellSystem with inlet stream.

      This constructor allows WellSystem to be created like other process equipment, making it compatible with ProcessSystem sequential building.

      Parameters:
      name - well name
      inletStream - reservoir/inlet stream
  • Method Details

    • setReservoirStream

      public void setReservoirStream(StreamInterface stream)
      Set the reservoir stream (inlet from reservoir).
      Parameters:
      stream - reservoir stream
    • setInletStream

      public void setInletStream(StreamInterface stream)
      Set the inlet stream (alias for setReservoirStream for ProcessSystem compatibility).

      This method allows WellSystem to be used in a ProcessSystem like other equipment.

      Parameters:
      stream - inlet stream from reservoir
    • getInletStream

      public StreamInterface getInletStream()
      Get the inlet stream.
      Returns:
      inlet stream (same as reservoir stream)
    • setIPRModel

      public void setIPRModel(WellSystem.IPRModel model)
      Set the IPR model type.
      Parameters:
      model - IPR model to use
    • setProductionIndex

      public void setProductionIndex(double pi, String unit)
      Set productivity index for PI model.
      Parameters:
      pi - productivity index
      unit - PI unit ("Sm3/day/bar2", "bbl/day/psi2", "Sm3/day/bar")
    • setVogelParameters

      public void setVogelParameters(double qTest, double pwfTest, double pRes)
      Set Vogel IPR parameters.
      Parameters:
      qTest - test flow rate (same unit as stream)
      pwfTest - test BHP (bara)
      pRes - reservoir pressure (bara)
    • setFetkovichParameters

      public void setFetkovichParameters(double c, double n, double pRes)
      Set Fetkovich IPR parameters.
      Parameters:
      c - Fetkovich C coefficient
      n - Fetkovich exponent (typically 0.5-1.0)
      pRes - reservoir pressure (bara)
    • setBackpressureParameters

      public void setBackpressureParameters(double a, double b, double pRes)
      Set backpressure equation parameters with non-Darcy term.

      Equation: Pr² - Pwf² = a·q + b·q² where b captures turbulence.

      Parameters:
      a - Darcy coefficient
      b - non-Darcy coefficient
      pRes - reservoir pressure (bara)
    • setTubingLength

      public void setTubingLength(double length, String unit)
      Set tubing length (measured depth).
      Parameters:
      length - tubing length
      unit - length unit ("m", "ft")
    • setTubingDiameter

      public void setTubingDiameter(double diameter, String unit)
      Set tubing inner diameter.
      Parameters:
      diameter - inner diameter
      unit - diameter unit ("m", "in", "mm")
    • setTubingRoughness

      public void setTubingRoughness(double roughness)
      Set tubing wall roughness.
      Parameters:
      roughness - wall roughness (m)
    • setInclination

      public void setInclination(double degrees)
      Set well inclination.
      Parameters:
      degrees - inclination from horizontal (90 = vertical)
    • setPressureDropCorrelation

      public void setPressureDropCorrelation(TubingPerformance.PressureDropCorrelation correlation)
      Set pressure-drop correlation for VLP.
      Parameters:
      correlation - pressure-drop correlation
    • setVLPSolverMode

      public void setVLPSolverMode(WellSystem.VLPSolverMode mode)
      Set the VLP solver mode.

      Available modes:

      Parameters:
      mode - VLP solver mode
    • getVLPSolverMode

      public WellSystem.VLPSolverMode getVLPSolverMode()
      Get the current VLP solver mode.
      Returns:
      VLP solver mode
    • setTemperatureModel

      public void setTemperatureModel(TubingPerformance.TemperatureModel model)
      Set temperature model for VLP.
      Parameters:
      model - temperature model
    • setBottomHoleTemperature

      public void setBottomHoleTemperature(double temperature, String unit)
      Set bottom-hole temperature.
      Parameters:
      temperature - temperature
      unit - temperature unit ("K", "C", "F")
    • setWellheadTemperature

      public void setWellheadTemperature(double temperature, String unit)
      Set wellhead temperature.
      Parameters:
      temperature - temperature
      unit - temperature unit ("K", "C", "F")
    • setWellheadPressure

      public void setWellheadPressure(double pressure, String unit)
      Set target wellhead pressure (back-pressure constraint).
      Parameters:
      pressure - wellhead pressure
      unit - pressure unit ("bara", "barg", "psia")
    • setChokeOpening

      public void setChokeOpening(double opening)
      Set choke opening (for choked wells).
      Parameters:
      opening - choke opening percentage (0-100)
    • addLayer

      public void addLayer(String name, StreamInterface stream, double khFraction, double reservoirPressure, double pi)
      Add a reservoir layer for commingled production.
      Parameters:
      name - layer name
      stream - stream from this layer
      khFraction - fraction of total kh
      reservoirPressure - initial reservoir pressure (bara)
      pi - productivity index
    • run

      public void run(UUID id)

      In this method all thermodynamic and unit operations will be calculated in a steady state calculation.

      Solves for the operating point where IPR and VLP intersect at the specified wellhead pressure constraint.

      Parameters:
      id - UUID
    • runSingleLayer

      private void runSingleLayer(UUID id)
      Run single-layer well (standard case).
      Parameters:
      id - calculation identifier UUID
    • estimateMaxFlowRate

      private double estimateMaxFlowRate()
      Estimate maximum flow rate based on IPR model (AOF - Absolute Open Flow).
      Returns:
      estimated maximum flow rate in Sm3/day
    • runMultiLayer

      private void runMultiLayer(UUID id)
      Run multi-layer commingled well.
      Parameters:
      id - calculation identifier UUID
    • calculateIPR_BHP

      private double calculateIPR_BHP(double flowRate)
      Calculate bottom-hole pressure from IPR at a given flow rate.
      Parameters:
      flowRate - flow rate in Sm3/day
      Returns:
      bottom-hole pressure in bara
    • calculateVLP_BHP

      private double calculateVLP_BHP(double flowRate)
      Calculate required bottom-hole pressure from VLP to achieve target WHP. Uses either simplified or full multiphase correlation based on vlpSolverMode.
      Parameters:
      flowRate - flow rate in Sm3/day
      Returns:
      bottom-hole pressure in bara
    • calculateVLP_BHP_Simplified

      private double calculateVLP_BHP_Simplified(double flowRate)
      Simplified VLP calculation using hydrostatic + friction. Fast but less accurate for complex multiphase flow.
      Parameters:
      flowRate - flow rate in Sm3/day
      Returns:
      calculated bottom-hole pressure in bara
    • calculateVLP_BHP_Full

      private double calculateVLP_BHP_Full(double flowRate)
      Full VLP calculation using TubingPerformance with selected multiphase correlation. More accurate but slower.
      Parameters:
      flowRate - flow rate in Sm3/day
      Returns:
      calculated bottom-hole pressure in bara
    • calculateVLP_BHP_DriftFlux

      private double calculateVLP_BHP_DriftFlux(double flowRate)
      Drift-flux VLP calculation.

      Uses a drift-flux model that accounts for slip between phases. More accurate than homogeneous models for gas-liquid flow in vertical/inclined pipes.

      The drift-flux model uses: v_g = C_0 * v_m + v_d where C_0 is the distribution parameter and v_d is the drift velocity.

      Parameters:
      flowRate - flow rate in Sm3/day
      Returns:
      calculated bottom-hole pressure in bara
    • calculateVLP_BHP_TwoFluid

      private double calculateVLP_BHP_TwoFluid(double flowRate)
      Two-fluid VLP calculation.

      Uses a simplified two-fluid model with separate momentum balances for each phase. This is the most accurate approach for complex flow patterns but also the slowest.

      Solves coupled gas and liquid momentum equations accounting for:

      • Interfacial friction between phases
      • Wall friction for each phase
      • Gravitational effects
      • Phase acceleration
      Parameters:
      flowRate - flow rate in Sm3/day
      Returns:
      calculated bottom-hole pressure in bara
    • estimateInitialFlowRate

      private double estimateInitialFlowRate()
      Estimate initial flow rate for iteration.
      Returns:
      estimated initial flow rate in Sm3/day
    • generateIPRCurve

      public double[][] generateIPRCurve(int pressurePoints)
      Generate IPR curve (Inflow Performance Relationship).
      Parameters:
      pressurePoints - number of pressure points
      Returns:
      2D array: [0]=flow rates (Sm3/day), [1]=bottom-hole pressures (bara)
    • calculateFlowFromIPR

      private double calculateFlowFromIPR(double bhp)
      Calculate flow rate from IPR at a given BHP.
      Parameters:
      bhp - bottom-hole pressure in bara
      Returns:
      calculated flow rate in Sm3/day
    • generateVLPCurve

      public double[][] generateVLPCurve(double[] flowRates)
      Generate VLP curve for a range of flow rates.
      Parameters:
      flowRates - array of flow rates (Sm3/day)
      Returns:
      2D array: [0]=flow rates, [1]=required BHP (bara)
    • getOperatingFlowRate

      public double getOperatingFlowRate(String unit)
      Get the calculated operating flow rate.
      Parameters:
      unit - flow rate unit
      Returns:
      operating flow rate
    • getBottomHolePressure

      public double getBottomHolePressure(String unit)
      Get the calculated bottom-hole pressure.
      Parameters:
      unit - pressure unit
      Returns:
      bottom-hole pressure
    • getWellheadPressure

      public double getWellheadPressure(String unit)
      Get the target wellhead pressure.
      Parameters:
      unit - pressure unit
      Returns:
      wellhead pressure
    • getReservoirPressure

      public double getReservoirPressure(String unit)
      Get reservoir pressure.
      Parameters:
      unit - pressure unit
      Returns:
      reservoir pressure
    • getOutletStream

      public StreamInterface getOutletStream()
      Get outlet stream.
      Returns:
      outlet stream at wellhead conditions
    • getLayerFlowRates

      public double[] getLayerFlowRates(String unit)
      Get flow rates from individual layers (for commingled wells).
      Parameters:
      unit - flow rate unit
      Returns:
      array of layer flow rates
    • getWellFlowIPR

      public WellFlow getWellFlowIPR()
      Get the internal WellFlow (IPR) component.
      Returns:
      WellFlow instance
    • getTubingVLP

      public TubingPerformance getTubingVLP()
      Get the internal TubingPerformance (VLP) component.
      Returns:
      TubingPerformance instance
    • getDrawdown

      public double getDrawdown(String unit)
      Get drawdown (reservoir pressure - BHP).
      Parameters:
      unit - pressure unit
      Returns:
      drawdown (always non-negative)
    • getEffectiveProductivityIndex

      public double getEffectiveProductivityIndex()
      Get productivity index from last calculation.
      Returns:
      effective PI (Sm3/day/bar²)