Class GasLiftOptimizer
- All Implemented Interfaces:
Serializable
This class optimizes the allocation of limited lift gas across multiple wells to maximize total field production. It considers:
- Well performance curves: Oil rate vs. injection gas rate for each well
- Gas availability: Total available lift gas constraint
- Compression constraints: Maximum compression power
- Well constraints: Minimum/maximum injection rates per well
- Economic factors: Value of incremental oil vs. cost of compression
Optimization Methods
The optimizer supports multiple solution methods:
- Equal slope: Allocate gas so marginal production increase is equal for all wells
- Proportional: Allocate gas proportional to well potential
- Sequential: Fill wells in order of highest marginal response
- Gradient-based: Iterative optimization using derivatives
Mathematical Basis
For optimal gas allocation, the marginal production increase should be equal across all wells:
∂Qoil₁/∂Qgas₁ = ∂Qoil₂/∂Qgas₂ = ... = ∂Qoilₙ/∂Qgasₙ
Subject to the total gas constraint:
ΣQgasᵢ ≤ Qgas_available
Usage Example
GasLiftOptimizer optimizer = new GasLiftOptimizer();
// Add wells with their performance curves
optimizer.addWell("Well-1", performanceCurve1, 50000.0); // Max 50 MSm³/d injection
optimizer.addWell("Well-2", performanceCurve2, 40000.0);
optimizer.addWell("Well-3", performanceCurve3, 60000.0);
// Set total available gas
optimizer.setAvailableGas(100000.0, "Sm3/d");
// Set compression constraints
optimizer.setMaxCompressionPower(5000.0); // kW
optimizer.setCompressionEfficiency(0.75);
// Optimize
AllocationResult result = optimizer.optimize();
System.out.println("Total oil production: " + result.totalOilRate + " Sm³/d");
for (WellAllocation alloc : result.allocations) {
System.out.println(
alloc.wellName + ": " + alloc.gasRate + " Sm³/d gas → " + alloc.oilRate + " Sm³/d oil");
}
- Version:
- 1.0
- Author:
- ESOL
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classComplete optimization result.static enumOptimization method.static classWell performance curve representation.static classAllocation result for a single well.static classWell data for optimization. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate doubleprivate doubleprivate doubleprivate doubleprivate doubleprivate intprivate static final longprivate doubleprivate doubleprivate List<GasLiftOptimizer.WellData> -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionAdds a well with simplified curve parameters.addWell(String name, GasLiftOptimizer.PerformanceCurve curve, double maxGasRate) Adds a well with its performance curve.private doublecalculateCompressionPower(double gasRate) Calculates compression power for a given gas rate.private doubleCalculates maximum gas rate limited by compression power.private doublefindGasRateForSlope(GasLiftOptimizer.WellData well, double targetSlope) Finds gas rate that gives target marginal response using binary search.private GasLiftOptimizer.WellDatafindWellByName(String name) Finds well data by name.private intGets count of enabled wells.intGets number of wells.optimize()Runs the optimization.optimizeEqualSlope(double totalGas) Optimizes using equal slope (marginal response) method.optimizeGradient(double totalGas) Optimizes using gradient descent.optimizeProportional(double totalGas) Optimizes using proportional allocation.optimizeSequential(double totalGas) Optimizes using sequential filling (greedy algorithm).setAvailableGas(double gas, String unit) Sets the available lift gas.setCompressionEfficiency(double efficiency) Sets compression efficiency.setCompressionPressures(double suction, double discharge) Sets compression pressures.setMaxCompressionPower(double maxPower) Sets compression constraints.Sets the optimization method.setWellEnabled(String wellName, boolean enabled) Sets a well's enabled status.setWellPriority(String wellName, double priority) Sets a well's priority.
-
Field Details
-
serialVersionUID
private static final long serialVersionUID- See Also:
-
wells
-
availableGas
private double availableGas -
maxCompressionPower
private double maxCompressionPower -
compressionEfficiency
private double compressionEfficiency -
suctionPressure
private double suctionPressure -
dischargePressure
private double dischargePressure -
gasSpecificGravity
private double gasSpecificGravity -
method
-
tolerance
private double tolerance -
maxIterations
private int maxIterations
-
-
Constructor Details
-
GasLiftOptimizer
public GasLiftOptimizer()Creates a new gas lift optimizer.
-
-
Method Details
-
addWell
public GasLiftOptimizer addWell(String name, GasLiftOptimizer.PerformanceCurve curve, double maxGasRate) Adds a well with its performance curve.- Parameters:
name- well namecurve- gas lift performance curvemaxGasRate- maximum gas injection rate (Sm³/d)- Returns:
- this for chaining
-
addWell
public GasLiftOptimizer addWell(String name, double naturalRate, double maxRate, double optimalGas, double maxGasRate) Adds a well with simplified curve parameters.- Parameters:
name- well namenaturalRate- natural flow rate (Sm³/d)maxRate- maximum rate with gas lift (Sm³/d)optimalGas- optimal gas injection (Sm³/d)maxGasRate- maximum allowed gas rate (Sm³/d)- Returns:
- this for chaining
-
setAvailableGas
Sets the available lift gas.- Parameters:
gas- available gasunit- unit (Sm3/d, MSm3/d)- Returns:
- this for chaining
-
setMaxCompressionPower
Sets compression constraints.- Parameters:
maxPower- maximum compression power (kW)- Returns:
- this for chaining
-
setCompressionEfficiency
Sets compression efficiency.- Parameters:
efficiency- isentropic efficiency (0-1)- Returns:
- this for chaining
-
setCompressionPressures
Sets compression pressures.- Parameters:
suction- suction pressure (bara)discharge- discharge pressure (bara)- Returns:
- this for chaining
-
setOptimizationMethod
Sets the optimization method.- Parameters:
method- optimization method- Returns:
- this for chaining
-
setWellEnabled
Sets a well's enabled status.- Parameters:
wellName- well nameenabled- true to include in optimization- Returns:
- this for chaining
-
setWellPriority
Sets a well's priority.- Parameters:
wellName- well namepriority- priority (higher = more gas)- Returns:
- this for chaining
-
optimize
Runs the optimization.- Returns:
- allocation result
-
optimizeEqualSlope
Optimizes using equal slope (marginal response) method.This method implements the optimal gas allocation strategy based on economic theory. At the optimum, the marginal production response should be equal for all wells:
∂Q_oil,1/∂Q_gas,1 = ∂Q_oil,2/∂Q_gas,2 = ... = λwhere λ is the common marginal response (Lagrange multiplier). The algorithm uses binary search to find λ such that the total gas allocation equals the available gas.
Algorithm:
- Bracket the common marginal response λ between [0, max_slope]
- Binary search: for each λ, find gas allocation per well where slope = λ
- If total allocation is greater than available, increase λ (less gas per well)
- If total allocation is less than available, decrease λ (more gas per well)
- Converge when |total - available| / available is less than tolerance
- Parameters:
totalGas- total available gas (Sm³/d)- Returns:
- allocation result with optimal distribution
-
findWellByName
Finds well data by name.- Parameters:
name- well name to find- Returns:
- well data or null if not found
-
findGasRateForSlope
Finds gas rate that gives target marginal response using binary search.For a given performance curve, finds the gas rate Q_gas where:
∂Q_oil/∂Q_gas = targetSlopeUses the diminishing returns property: higher gas rates yield lower marginal response.
- Parameters:
well- well data with performance curvetargetSlope- target marginal response (Sm³ oil / Sm³ gas)- Returns:
- gas rate that achieves target slope (Sm³/d)
-
optimizeProportional
Optimizes using proportional allocation.Allocates gas proportionally to each well's production potential:
Q_gas,i = Q_gas_total × (potential_i / Σ potential_j)where potential_i = (Q_oil_max,i - Q_oil_natural,i) × priority_i
This is a simple heuristic that does not account for varying marginal responses but is fast and intuitive.
- Parameters:
totalGas- total available gas (Sm³/d)- Returns:
- allocation result
-
optimizeSequential
Optimizes using sequential filling (greedy algorithm).Incrementally allocates gas to the well with the highest marginal response:
- Start with minimum gas allocation for each well
- Compute marginal response for all wells
- Add increment to well with highest response
- Repeat until gas is exhausted or no beneficial allocation remains
This greedy approach converges to the optimal solution as the increment size approaches zero. Uses 1% increments for reasonable accuracy.
- Parameters:
totalGas- total available gas (Sm³/d)- Returns:
- allocation result
-
optimizeGradient
Optimizes using gradient descent.Iteratively adjusts allocations to equalize marginal responses:
Q_gas,i(k+1) = Q_gas,i(k) + α × (∂Q_oil,i/∂Q_gas,i - avg_slope)where α is the step size. After each iteration, allocations are renormalized to satisfy the total gas constraint. The step size decreases with iterations for convergence stability.
- Parameters:
totalGas- total available gas (Sm³/d)- Returns:
- allocation result
-
calculateMaxGasFromPower
private double calculateMaxGasFromPower()Calculates maximum gas rate limited by compression power.Inverts the compression power equation to find the maximum gas rate:
Q_max = W_max / [0.1 × ln(P2/P1) / η]where W_max is the maximum available compression power.
- Returns:
- maximum gas rate (Sm³/d) or Double.MAX_VALUE if unconstrained
-
calculateCompressionPower
private double calculateCompressionPower(double gasRate) Calculates compression power for a given gas rate.Uses simplified isothermal compression power formula:
W = 0.1 × Q × ln(P2/P1) / ηwhere:
- W = power (kW)
- Q = gas rate (Sm³/d)
- P2/P1 = compression ratio
- η = isentropic efficiency
- Parameters:
gasRate- gas rate (Sm³/d)- Returns:
- compression power (kW)
-
getEnabledWellCount
private int getEnabledWellCount()Gets count of enabled wells.- Returns:
- number of wells enabled for optimization
-
getWellCount
public int getWellCount()Gets number of wells.- Returns:
- well count
-