Class TransientWellModel
- All Implemented Interfaces:
Serializable
This class models transient pressure behavior in production and injection wells, including:
- Pressure Buildup: Shut-in pressure recovery analysis
- Pressure Drawdown: Flowing pressure decline during production
- Superposition: Effect of multiple rate changes
- Radius of Investigation: Time-dependent drainage area
- Boundary Effects: Transition from infinite-acting to boundary-dominated
Mathematical Basis
The line-source solution for radial flow in an infinite-acting reservoir:
ΔP = (q·μ)/(4πkh) × Ei(-r²/(4·η·t))
where η = k/(φ·μ·ct) is the hydraulic diffusivity. For the wellbore (r=rw), using the logarithmic approximation:
P_wf = P_i - (q·μ)/(4πkh) × [ln(4·η·t/r_w²) - γ + 2S]
Superposition Principle
For multiple rate changes at times t₁, t₂, ... tₙ with rates q₁, q₂, ... qₙ:
ΔP(t) = Σ (qᵢ - qᵢ₋₁) × P_D(t - tᵢ)
This allows modeling complex production histories including shut-ins and rate changes.
Usage Example - Drawdown Analysis
TransientWellModel well = new TransientWellModel();
well.setReservoirPressure(250.0, "bara");
well.setPermeability(100.0, "mD");
well.setFormationThickness(30.0, "m");
well.setPorosity(0.20);
well.setTotalCompressibility(1.5e-4, "1/bar");
well.setFluidViscosity(0.5, "cP");
well.setWellboreRadius(0.1, "m");
well.setSkinFactor(2.0);
// Calculate flowing pressure after 10 hours at 1000 Sm3/day
DrawdownResult result = well.calculateDrawdown(1000.0, 10.0);
System.out.println("Pwf after 10 hours: " + result.flowingPressure + " bara");
Usage Example - Buildup Analysis (Horner Method)
// Well flowed at 1500 Sm3/day for 100 hours before shut-in
well.addRateChange(0.0, 1500.0); // Start production
well.addRateChange(100.0, 0.0); // Shut-in
BuildupResult buildup = well.calculateBuildup(24.0); // After 24 hrs shut-in
System.out.println("Pws: " + buildup.shutInPressure + " bara");
System.out.println("Permeability from slope: " + buildup.permeabilityFromSlope + " mD");
System.out.println("Skin from intercept: " + buildup.skinFromIntercept);
- Version:
- 1.0
- Author:
- ESOL
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumBoundary type for late-time effects.static classResult of buildup calculation.static classResult of drawdown calculation.static classTransient pressure profile point.static classRate change event for superposition.static enumWell type. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate TransientWellModel.BoundaryTypeprivate doubleprivate doubleprivate static final doubleprivate doubleprivate doubleprivate doubleprivate doubleprivate doubleprivate doubleprivate doubleprivate static final doubleprivate doubleprivate List<TransientWellModel.RateChange> private doubleprivate static final longprivate doubleprivate doubleprivate doubleprivate doubleprivate doubleprivate TransientWellModel.WellType -
Constructor Summary
ConstructorsConstructorDescriptionCreates a new transient well model with default parameters. -
Method Summary
Modifier and TypeMethodDescriptionaddRateChange(double timeHours, double rate) Adds a rate change to the history.calculateBuildup(double shutInTimeHours) Calculates buildup pressure after shut-in.calculateDrawdown(double rate, double timeHours) Calculates drawdown pressure at a given time.private doublecalculatePressureDrop(double rate, double timeSec) Calculates pressure drop using line-source solution.doublecalculatePressureWithSuperposition(double timeHours) Calculates pressure at a given time using superposition of all rate changes.private doublecalculateRadiusOfInvestigation(double timeSec) Calculates radius of investigation.Clears the rate history.private doubledimensionlessTime(double timeSec) Calculates dimensionless time.private doubleexponentialIntegral(double x) Exponential integral function Ei(-x).double[]generateLogTimePoints(double startHours, double endHours, int numPoints) Generates logarithmically spaced time points for analysis.generatePressureProfile(double[] timePointsHours) Generates a transient pressure profile.doubleGets the hydraulic diffusivity.doubleGets the initial reservoir pressure.private doublegetRateAtTime(double timeHours) Gets rate at a given time from rate history.Gets the rate history.doubleGets the transmissibility.Sets boundary type.setDrainageRadius(double radius, String unit) Sets drainage radius.setFluidViscosity(double viscosity, String unit) Sets fluid viscosity.setFormationThickness(double thickness, String unit) Sets formation thickness.setFormationVolumeFactor(double bFactor) Sets formation volume factor.setPermeability(double permeability, String unit) Sets formation permeability.setPorosity(double porosity) Sets porosity.setReservoirPressure(double pressure, String unit) Sets reservoir initial pressure.setSkinFactor(double skin) Sets skin factor.setTotalCompressibility(double compressibility, String unit) Sets total compressibility.setWellboreRadius(double radius, String unit) Sets wellbore radius.Sets well type.private voidUpdates derived properties from input parameters.
-
Field Details
-
serialVersionUID
private static final long serialVersionUID- See Also:
-
EULER_GAMMA
private static final double EULER_GAMMA- See Also:
-
PI
private static final double PI- See Also:
-
wellType
-
boundaryType
-
initialPressure
private double initialPressure -
currentPressure
private double currentPressure -
permeability
private double permeability -
formationThickness
private double formationThickness -
porosity
private double porosity -
totalCompressibility
private double totalCompressibility -
drainageRadius
private double drainageRadius -
reservoirTemperature
private double reservoirTemperature -
wellboreRadius
private double wellboreRadius -
skinFactor
private double skinFactor -
wellboreStorage
private double wellboreStorage -
fluidViscosity
private double fluidViscosity -
fluidDensity
private double fluidDensity -
formationVolumeFactor
private double formationVolumeFactor -
rateHistory
-
hydraulicDiffusivity
private double hydraulicDiffusivity -
transmissibility
private double transmissibility
-
-
Constructor Details
-
TransientWellModel
public TransientWellModel()Creates a new transient well model with default parameters.
-
-
Method Details
-
updateDerivedProperties
private void updateDerivedProperties()Updates derived properties from input parameters. -
calculateDrawdown
Calculates drawdown pressure at a given time.- Parameters:
rate- production rate (Sm³/day)timeHours- time since start of production (hours)- Returns:
- drawdown result
-
calculateBuildup
Calculates buildup pressure after shut-in.- Parameters:
shutInTimeHours- time since shut-in (hours)- Returns:
- buildup result
-
calculatePressureWithSuperposition
public double calculatePressureWithSuperposition(double timeHours) Calculates pressure at a given time using superposition of all rate changes.- Parameters:
timeHours- time (hours)- Returns:
- pressure (bara)
-
generatePressureProfile
Generates a transient pressure profile.- Parameters:
timePointsHours- array of time points (hours)- Returns:
- list of pressure points
-
generateLogTimePoints
public double[] generateLogTimePoints(double startHours, double endHours, int numPoints) Generates logarithmically spaced time points for analysis.- Parameters:
startHours- start time (hours)endHours- end time (hours)numPoints- number of points- Returns:
- array of time points
-
calculatePressureDrop
private double calculatePressureDrop(double rate, double timeSec) Calculates pressure drop using line-source solution.Uses the dimensionless pressure function with logarithmic approximation for late time:
p_D = 0.5 × [ln(t_D) + 0.80907 + 2S]for t_D greater than 25Or the exponential integral for early time:
p_D = -0.5 × Ei(-1/(4t_D)) + Sfor t_D ≤ 25The dimensional pressure drop is then:
ΔP = q_res / (2πT) × p_Dwhere T = kh/μ is the transmissibility.
- Parameters:
rate- rate (Sm³/day)timeSec- time (seconds)- Returns:
- pressure drop (bar)
-
dimensionlessTime
private double dimensionlessTime(double timeSec) Calculates dimensionless time.Dimensionless time is defined as:
t_D = η·t / r_w² = (k·t) / (φ·μ·c_t·r_w²)where η is the hydraulic diffusivity. This parameter controls the rate of pressure propagation through the reservoir.
- Parameters:
timeSec- time (seconds)- Returns:
- dimensionless time t_D (dimensionless)
-
calculateRadiusOfInvestigation
private double calculateRadiusOfInvestigation(double timeSec) Calculates radius of investigation.The radius of investigation represents how far the pressure transient has propagated:
r_inv = √(4·η·t)This is based on the distance at which the pressure disturbance is approximately 1% of the wellbore value. When r_inv approaches the drainage radius, the well transitions from infinite-acting to boundary-dominated flow.
- Parameters:
timeSec- time (seconds)- Returns:
- radius of investigation (m)
-
exponentialIntegral
private double exponentialIntegral(double x) Exponential integral function Ei(-x).The exponential integral is defined as:
Ei(x) = ∫_{-∞}^{x} (e^t / t) dtFor negative arguments (transient flow), this is computed using:
- Small |x| (less than 1): Series expansion:
Ei(-x) = -γ - ln(x) + x - x²/(2·2!) + x³/(3·3!) - ... - Large |x| (≥ 1): Asymptotic expansion: Ei(-x) ≈ -(e^(-x)/x) × [1 - 1/x + 2!/x² - ...]
where γ = 0.5772... is the Euler-Mascheroni constant.
- Parameters:
x- argument (should be negative for transient flow)- Returns:
- Ei(x) value
- Small |x| (less than 1): Series expansion:
-
getRateAtTime
private double getRateAtTime(double timeHours) Gets rate at a given time from rate history.- Parameters:
timeHours- time (hours)- Returns:
- rate (Sm³/day)
-
addRateChange
Adds a rate change to the history.- Parameters:
timeHours- time of change (hours)rate- rate after change (Sm³/day)- Returns:
- this for chaining
-
clearRateHistory
-
setReservoirPressure
Sets reservoir initial pressure.- Parameters:
pressure- pressureunit- unit (bara, psia)- Returns:
- this for chaining
-
setPermeability
Sets formation permeability.- Parameters:
permeability- permeabilityunit- unit (mD, D)- Returns:
- this for chaining
-
setFormationThickness
Sets formation thickness.- Parameters:
thickness- thicknessunit- unit (m, ft)- Returns:
- this for chaining
-
setPorosity
Sets porosity.- Parameters:
porosity- porosity (fraction 0-1)- Returns:
- this for chaining
-
setTotalCompressibility
Sets total compressibility.- Parameters:
compressibility- compressibilityunit- unit (1/bar, 1/psi)- Returns:
- this for chaining
-
setFluidViscosity
Sets fluid viscosity.- Parameters:
viscosity- viscosityunit- unit (cP, mPa.s)- Returns:
- this for chaining
-
setWellboreRadius
Sets wellbore radius.- Parameters:
radius- radiusunit- unit (m, ft, in)- Returns:
- this for chaining
-
setSkinFactor
Sets skin factor.- Parameters:
skin- skin factor (dimensionless)- Returns:
- this for chaining
-
setFormationVolumeFactor
Sets formation volume factor.- Parameters:
bFactor- B (reservoir volume / surface volume)- Returns:
- this for chaining
-
setDrainageRadius
Sets drainage radius.- Parameters:
radius- radiusunit- unit (m, ft)- Returns:
- this for chaining
-
setWellType
Sets well type.- Parameters:
type- well type- Returns:
- this for chaining
-
setBoundaryType
Sets boundary type.- Parameters:
type- boundary type- Returns:
- this for chaining
-
getHydraulicDiffusivity
public double getHydraulicDiffusivity()Gets the hydraulic diffusivity.- Returns:
- diffusivity (m²/s)
-
getTransmissibility
public double getTransmissibility()Gets the transmissibility.- Returns:
- transmissibility (m³/(bar·s))
-
getRateHistory
Gets the rate history.- Returns:
- list of rate changes
-
getInitialPressure
public double getInitialPressure()Gets the initial reservoir pressure.- Returns:
- pressure (bara)
-