Asphaltene Method Comparison
Overview
NeqSim provides two complementary approaches for asphaltene stability analysis:
- De Boer Screening: Fast, empirical correlation for initial assessment
- CPA Thermodynamic Modeling: Rigorous EOS-based onset calculations
This document explains when to use each method and how to compare their results.
Method Summary
| Aspect | De Boer | CPA |
|---|---|---|
| Speed | Milliseconds | Seconds to minutes |
| Input Required | P_res, P_bub, ρ | Full composition + properties |
| Output | Risk category | Onset P, T, amounts |
| Accuracy | Conservative screening | Predictive (if tuned) |
| Composition Effects | No | Yes |
| Temperature Effects | No | Yes |
| Injection Effects | No | Yes |
Decision Framework
When to Use De Boer Only
✅ Early field screening with limited data
✅ Quick portfolio risk ranking
✅ Conservative go/no-go decisions
✅ Baseline risk communication
When to Use CPA Only
✅ Detailed well/facility design
✅ Operating envelope definition
✅ Gas injection impact assessment
✅ Inhibitor effectiveness evaluation
When to Use Both
✅ Field development planning (screen then analyze)
✅ Validating thermodynamic model predictions
✅ Communicating risk to non-technical stakeholders
✅ Comprehensive flow assurance studies
Using AsphalteneMethodComparison
Basic Comparison
import neqsim.pvtsimulation.flowassurance.AsphalteneMethodComparison;
import neqsim.thermo.system.SystemSrkCPAstatoil;
// Create CPA fluid
SystemSrkCPAstatoil fluid = new SystemSrkCPAstatoil(373.15, 350.0);
fluid.addComponent("methane", 0.40);
fluid.addComponent("n-heptane", 0.50);
fluid.addComponent("asphaltene", 0.10);
fluid.setMixingRule("classic");
fluid.init(0);
fluid.init(1);
// Create comparison
AsphalteneMethodComparison comparison = new AsphalteneMethodComparison(fluid);
comparison.setReservoirPressure(350.0);
comparison.setBubblePointPressure(150.0);
comparison.setInSituDensity(720.0);
// Run comparison
String report = comparison.runComparison();
System.out.println(report);
Sample Output
=================================================
ASPHALTENE STABILITY: METHOD COMPARISON REPORT
=================================================
FLUID INFORMATION
-----------------
Temperature: 100.0 °C
Pressure: 350.0 bar
Number of Components: 3
DE BOER SCREENING RESULTS
-------------------------
Undersaturation: 200.0 bar
In-situ Density: 720.0 kg/m³
Risk Level: MODERATE_PROBLEM
Risk Index: 0.55
CPA THERMODYNAMIC RESULTS
-------------------------
Asphaltene Onset Pressure: 185.0 bar
Above Bubble Point: Yes
Precipitation Expected: Yes
Onset Margin: 35.0 bar above bubble point
COMPARISON SUMMARY
------------------
De Boer Risk: MODERATE
CPA Prediction: Precipitation at 185 bar
Agreement: CONSISTENT
Both methods indicate asphaltene precipitation
risk during normal production.
RECOMMENDATIONS
---------------
1. Consider asphaltene inhibitor injection
2. Design for periodic wellbore cleanout
3. Monitor production for pressure decline
4. Validate with laboratory AOP test
Quick Summary
For rapid assessment:
String summary = comparison.getQuickSummary();
System.out.println(summary);
Output:
De Boer: MODERATE_PROBLEM | CPA Onset: 185 bar | Agreement: CONSISTENT
Interpretation Guidelines
Consistent Results
| De Boer | CPA | Interpretation |
|---|---|---|
| NO_PROBLEM | No onset found | Low risk, minimal mitigation |
| SLIGHT_PROBLEM | Onset near P_bub | Monitor during late life |
| MODERATE_PROBLEM | Onset > P_bub | Active mitigation needed |
| SEVERE_PROBLEM | Onset » P_bub | Significant risk, design for it |
Inconsistent Results
| De Boer | CPA | Possible Causes |
|---|---|---|
| HIGH | No onset | De Boer conservative; unusual composition |
| LOW | Onset found | Light oil with high asphaltene; check composition |
When results disagree:
- Review input data quality
- Check CPA model tuning
- Consider laboratory validation
- Use more conservative result for design
Example Workflows
Workflow 1: Field Development Screening
// Step 1: De Boer screening of all fluids
List<String> needsDetailedAnalysis = new ArrayList<>();
for (FluidSample sample : allSamples) {
DeBoerAsphalteneScreening screening = new DeBoerAsphalteneScreening(
sample.getReservoirPressure(),
sample.getBubblePoint(),
sample.getInSituDensity()
);
String risk = screening.evaluateRisk();
if (!risk.equals("NO_PROBLEM")) {
needsDetailedAnalysis.add(sample.getName());
}
}
// Step 2: CPA analysis only for flagged samples
for (String sampleName : needsDetailedAnalysis) {
// Create detailed CPA model
SystemSrkCPAstatoil fluid = createCPAFluid(sampleName);
AsphalteneStabilityAnalyzer analyzer =
new AsphalteneStabilityAnalyzer(fluid);
double onsetP = analyzer.calculateOnsetPressure();
System.out.printf("Sample %s: Onset at %.1f bar%n",
sampleName, onsetP);
}
Workflow 2: Operating Envelope Definition
// Use CPA to define safe operating window
AsphalteneStabilityAnalyzer analyzer = new AsphalteneStabilityAnalyzer(fluid);
// Generate precipitation boundary
double[][] envelope = analyzer.generatePrecipitationEnvelope(
280.0, 420.0, 10.0 // Temperature range [K]
);
// Define operating envelope with safety margin
double safetyMargin = 20.0; // bar below onset
System.out.println("Safe Operating Envelope:");
System.out.println("T [°C], Max P [bar]");
for (int i = 0; i < envelope[0].length; i++) {
double T_C = envelope[0][i] - 273.15;
double maxSafeP = envelope[1][i] - safetyMargin;
System.out.printf("%.0f, %.1f%n", T_C, maxSafeP);
}
Workflow 3: Blending Compatibility
// Base fluid
SystemSrkCPAstatoil baseFluid = createFluid("FieldA");
// Blend fluid
SystemSrkCPAstatoil blendFluid = createFluid("FieldB");
// Test blend ratios
double[] blendRatios = {0.0, 0.25, 0.50, 0.75, 1.0};
System.out.println("Blend Compatibility Study");
System.out.println("-------------------------");
for (double ratio : blendRatios) {
SystemSrkCPAstatoil mixed = blendFluids(baseFluid, blendFluid, ratio);
AsphalteneStabilityAnalyzer analyzer =
new AsphalteneStabilityAnalyzer(mixed);
double onsetP = analyzer.calculateOnsetPressure();
String deBoer = analyzer.deBoerScreening();
System.out.printf("%.0f%% Field B: Onset = %.1f bar, De Boer = %s%n",
ratio * 100, onsetP, deBoer);
}
Model Validation
Laboratory Data Requirements
For CPA model tuning:
| Test | Purpose | Priority |
|---|---|---|
| AOP Test | Onset pressure at reservoir T | Required |
| HPM Analysis | Onset detection and quantification | Recommended |
| SARA Analysis | Composition for characterization | Required |
| Titration | Onset with n-heptane at ambient | Optional |
| Density | For De Boer screening | Required |
Automated Parameter Tuning
NeqSim provides the AsphalteneOnsetFitting class for automated CPA parameter tuning:
import neqsim.pvtsimulation.util.parameterfitting.AsphalteneOnsetFitting;
// Create fitter with your fluid system
AsphalteneOnsetFitting fitter = new AsphalteneOnsetFitting(fluid);
// Add experimental AOP data from lab tests
fitter.addOnsetPointCelsius(80.0, 350.0); // 80°C, 350 bar
fitter.addOnsetPointCelsius(100.0, 320.0); // 100°C, 320 bar
fitter.addOnsetPointCelsius(120.0, 280.0); // 120°C, 280 bar
// Set initial parameter guesses based on oil type
// Light oils: epsilon/R=3000, kappa=0.01
// Heavy oils: epsilon/R=4000, kappa=0.003
fitter.setInitialGuess(3500.0, 0.005);
// Run Levenberg-Marquardt optimization
boolean success = fitter.solve();
if (success) {
// Get fitted parameters
double epsilonR = fitter.getFittedAssociationEnergy();
double kappa = fitter.getFittedAssociationVolume();
System.out.printf("Fitted ε/R: %.1f K%n", epsilonR);
System.out.printf("Fitted κ: %.4f%n", kappa);
// Predict onset at new temperature
double predictedAOP = fitter.calculateOnsetPressure(393.15); // 120°C
System.out.printf("Predicted AOP at 120°C: %.1f bar%n", predictedAOP);
}
Manual Tuning Process
For manual iteration without the automated fitter:
// Experimental AOP
double measuredAOP = 195.0; // bar at 100°C
// Initial CPA prediction
AsphalteneStabilityAnalyzer analyzer =
new AsphalteneStabilityAnalyzer(fluid);
double predictedAOP = analyzer.calculateOnsetPressure();
// Calculate error
double error = predictedAOP - measuredAOP;
System.out.printf("Initial error: %.1f bar%n", error);
// Adjust asphaltene parameters to match
// Options: molecular weight, critical properties, kij values
// Iterate until error < tolerance
Performance Comparison
Calculation Times (Typical)
| Operation | Time | Notes |
|---|---|---|
| De Boer screening | < 1 ms | Single correlation evaluation |
| De Boer batch (1000 samples) | < 100 ms | Highly parallelizable |
| CPA single flash | 10-100 ms | Depends on composition |
| CPA onset pressure | 1-5 s | Multiple flashes + bisection |
| CPA full envelope | 10-60 s | Many onset calculations |
| Parameter fitting (3 points) | 10-60 s | Depends on convergence |
| Full comparison report | 2-10 s | Both methods + formatting |
When Speed Matters
// For real-time monitoring: Use De Boer only
if (isRealTimeMonitoring) {
DeBoerAsphalteneScreening screening =
new DeBoerAsphalteneScreening(pRes, pBub, density);
return screening.calculateRiskIndex();
}
// For batch screening: Use De Boer first
if (numberOfSamples > 100) {
// Screen with De Boer
List<Sample> flagged = deBoerScreen(samples);
// CPA only on flagged samples
for (Sample s : flagged) {
runCPAAnalysis(s);
}
}
Best Practices
Do’s
✅ Start with De Boer for initial assessment
✅ Validate CPA with experimental data before design
✅ Use both for comprehensive studies
✅ Document assumptions in both methods
✅ Apply safety margins to predicted onset
Don’ts
❌ Don’t use CPA without tuning for critical decisions
❌ Don’t ignore De Boer warnings even if CPA looks safe
❌ Don’t over-interpret small onset pressure differences
❌ Don’t extrapolate beyond validated conditions
Example: Complete Comparison
import neqsim.pvtsimulation.flowassurance.*;
import neqsim.thermo.system.SystemSrkCPAstatoil;
public class AsphalteneStudy {
public static void main(String[] args) {
// Create realistic oil composition
SystemSrkCPAstatoil fluid = new SystemSrkCPAstatoil(373.15, 350.0);
// Light ends
fluid.addComponent("nitrogen", 0.01);
fluid.addComponent("CO2", 0.02);
fluid.addComponent("methane", 0.35);
fluid.addComponent("ethane", 0.08);
fluid.addComponent("propane", 0.05);
// Intermediates
fluid.addComponent("n-butane", 0.03);
fluid.addComponent("n-pentane", 0.03);
fluid.addComponent("n-hexane", 0.05);
fluid.addComponent("n-heptane", 0.15);
fluid.addComponent("n-decane", 0.10);
// Heavy ends
fluid.addComponent("n-C15", 0.08);
fluid.addComponent("asphaltene", 0.05);
fluid.setMixingRule("classic");
fluid.init(0);
fluid.init(1);
// Reservoir conditions
double pRes = 350.0; // bar
double pBub = 150.0; // bar
double density = 720.0; // kg/m³
// Run full comparison
AsphalteneMethodComparison comparison =
new AsphalteneMethodComparison(fluid);
comparison.setReservoirPressure(pRes);
comparison.setBubblePointPressure(pBub);
comparison.setInSituDensity(density);
// Generate reports
System.out.println(comparison.runComparison());
System.out.println("\n" + StringUtils.repeat("=", 50));
System.out.println("QUICK REFERENCE");
System.out.println(StringUtils.repeat("=", 50));
System.out.println(comparison.getQuickSummary());
}
}