Skip to the content.

Field Development Economics Module

The NeqSim field development economics module provides comprehensive tools for economic analysis of oil and gas field developments. This includes cash flow modeling, tax calculations for multiple jurisdictions, production forecasting, and uncertainty analysis.

Table of Contents

Overview

The economics module is located in neqsim.process.fielddevelopment.economics and provides:

Class Purpose
CashFlowEngine Full-lifecycle cash flow projections with NPV, IRR, payback
TaxModel Interface for country-specific tax calculations
GenericTaxModel Parameter-driven tax model for any fiscal regime
TaxModelRegistry Database of 16+ country tax parameters
FiscalParameters Data class for fiscal regime configuration
ProductionProfileGenerator Arps decline curve production forecasts
SensitivityAnalyzer Monte Carlo and tornado chart analysis
NorwegianTaxModel Legacy Norwegian petroleum tax model

Tax Models

Country-Independent Tax Framework

The module supports any country’s fiscal regime through the TaxModel interface:

// Get tax model for any registered country
TaxModel norwayModel = TaxModelRegistry.createModel("NO");
TaxModel brazilModel = TaxModelRegistry.createModel("BR-PSA");
TaxModel ukModel = TaxModelRegistry.createModel("UK");

// Calculate tax for a year
TaxModel.TaxResult result = model.calculateTax(
    500.0,    // gross revenue (MUSD)
    100.0,    // OPEX (MUSD)
    80.0,     // depreciation (MUSD)
    44.0      // uplift (MUSD)
);

System.out.println("Total tax: " + result.getTotalTax());
System.out.println("After-tax income: " + result.getAfterTaxIncome());
System.out.println("Effective rate: " + result.getEffectiveTaxRate() * 100 + "%");

Registered Countries

The following countries are available in TaxModelRegistry:

Code Country Fiscal System Marginal Rate
NO Norway Concessionary 78% (22% corp + 56% resource)
UK United Kingdom Concessionary 40% (30% corp + 10% resource)
US-GOM Gulf of Mexico Concessionary + Royalty 21% + 18.75% royalty
BR Brazil (Concession) Concessionary + Royalty 34% + 10% royalty
BR-PSA Brazil Pre-Salt Production Sharing 34% + profit share
BR-DW Brazil Deep Water Special Participation 34% + special tax
AO Angola PSC 30% + 60% profit share
NG Nigeria PSC 30% + 51% profit share
AU Australia PRRT 70% (30% corp + 40% PRRT)
MY Malaysia PSC 24% + 70% profit share
ID Indonesia Cost Recovery PSC 35%
AE UAE Concessionary 55%
CA-AB Canada - Alberta Concessionary + Royalty 27%
GY Guyana PSC 25%
EG Egypt PSC 40.5%
KZ Kazakhstan Concessionary 37.5%

Custom Tax Parameters

Create custom fiscal regimes using FiscalParameters.Builder:

FiscalParameters custom = FiscalParameters.builder("MY-CUSTOM")
    .countryName("Malaysia Custom Block")
    .fiscalSystemType(FiscalSystemType.PSC)
    .corporateTaxRate(0.24)
    .costRecoveryLimit(0.70)
    .profitSharing(0.65, 0.35)  // 65% government, 35% contractor
    .depreciation(DepreciationMethod.DECLINING_BALANCE, 5)
    .build();

TaxModel customModel = new GenericTaxModel(custom);
TaxModelRegistry.register(custom);  // Optional: add to registry

Fiscal Parameters JSON Database

Parameters are loaded from data/fiscal/fiscal_parameters.json. To add new countries:

{
  "countryCode": "XX",
  "countryName": "New Country",
  "description": "Description of fiscal regime",
  "fiscalSystemType": "CONCESSIONARY",
  "corporateTaxRate": 0.25,
  "resourceTaxRate": 0.10,
  "royaltyRate": 0.05,
  "depreciationMethod": "STRAIGHT_LINE",
  "depreciationYears": 6
}

Cash Flow Engine

Basic Usage

// Create engine for a specific country
CashFlowEngine engine = new CashFlowEngine("BR");  // Brazil

// Set project parameters
engine.setCapex(800, 2025);           // 800 MUSD in 2025
engine.addCapex(200, 2026);           // Additional 200 MUSD in 2026
engine.setOpexPercentOfCapex(0.04);   // 4% of CAPEX per year

// Set commodity prices
engine.setOilPrice(75.0);             // USD/bbl
engine.setGasPrice(0.25);             // USD/Sm3
engine.setGasTariff(0.02);            // USD/Sm3 transport

// Add production profile
engine.addAnnualProduction(2027, 0, 5.0e6, 0);   // 5 MSm3 gas
engine.addAnnualProduction(2028, 0, 10.0e6, 0);  // 10 MSm3 gas
// ... more years

// Calculate
CashFlowResult result = engine.calculate(0.08);  // 8% discount rate

// Results
System.out.println("NPV: " + result.getNpv() + " MUSD");
System.out.println("IRR: " + result.getIrr() * 100 + "%");
System.out.println("Payback: " + result.getPaybackYears() + " years");
System.out.println(result.toMarkdownTable());

Switching Tax Models

CashFlowEngine engine = new CashFlowEngine();

// Use any registered country
engine.setTaxModel("UK");           // By country code
engine.setTaxModel("BR-PSA");       // Brazil Pre-Salt

// Or use custom model
TaxModel custom = new GenericTaxModel(customParams);
engine.setTaxModel(custom);

// Check current model
System.out.println("Country: " + engine.getCountryName());
System.out.println("Marginal rate: " + engine.getTaxModel().getTotalMarginalTaxRate() * 100 + "%");

Breakeven Analysis

double breakevenOil = engine.calculateBreakevenOilPrice(0.08);
double breakevenGas = engine.calculateBreakevenGasPrice(0.08);

System.out.println("Breakeven oil price: " + breakevenOil + " USD/bbl");
System.out.println("Breakeven gas price: " + breakevenGas + " USD/Sm3");

Production Profile Generator

Generate decline curve forecasts using Arps equations:

Exponential Decline

ProductionProfileGenerator generator = new ProductionProfileGenerator();

// Gas well with 15% annual decline
Map<Integer, Double> gasProfile = generator.generateExponentialDecline(
    10.0e6,    // Initial rate: 10 MSm3/d
    0.15,      // 15% annual decline
    2026,      // Start year
    20,        // 20 years maximum
    0.5e6      // Economic limit: 0.5 MSm3/d
);

Hyperbolic Decline

// Oil well with b-factor = 0.5
Map<Integer, Double> oilProfile = generator.generateHyperbolicDecline(
    15000,     // Initial rate: 15,000 bbl/d
    0.20,      // 20% initial decline
    0.5,       // b-factor (0 < b < 1)
    2026,      // Start year
    25,        // 25 years
    100        // Economic limit: 100 bbl/d
);

Full Profile with Ramp-up

// Realistic profile: 2-year ramp, 3-year plateau, exponential decline
Map<Integer, Double> profile = generator.generateFullProfile(
    20000,                        // Peak rate: 20,000 bbl/d
    2,                            // 2 years ramp-up
    3,                            // 3 years plateau
    0.12,                         // 12% decline rate
    DeclineType.EXPONENTIAL,
    2026,                         // Start year
    25                            // Total years
);

// Get summary
System.out.println(ProductionProfileGenerator.getProfileSummary(profile));

Combining Profiles

// Multiple wells or phases
Map<Integer, Double> phase1 = generator.generateExponentialDecline(...);
Map<Integer, Double> phase2 = ProductionProfileGenerator.shiftProfile(
    generator.generateExponentialDecline(...), 
    3  // Start 3 years later
);

Map<Integer, Double> combined = ProductionProfileGenerator.combineProfiles(phase1, phase2);

Sensitivity Analysis

Tornado Analysis

SensitivityAnalyzer analyzer = new SensitivityAnalyzer(engine, 0.08);

// Vary each parameter by ±20%
TornadoResult tornado = analyzer.tornadoAnalysis(0.20);

// Output as markdown table
System.out.println(tornado.toMarkdownTable());

// Get most sensitive parameter
TornadoItem mostSensitive = tornado.getMostSensitiveParameter();
System.out.println("Most sensitive: " + mostSensitive.getParameterName());
System.out.println("NPV swing: " + mostSensitive.getSwing() + " MUSD");

Monte Carlo Simulation

SensitivityAnalyzer analyzer = new SensitivityAnalyzer(engine, 0.08);

// Set parameter distributions
analyzer.setOilPriceDistribution(60.0, 90.0);   // Uniform: $60-90/bbl
analyzer.setGasPriceDistribution(0.20, 0.35);   // Uniform: $0.20-0.35/Sm3
analyzer.setCapexDistribution(700, 900);        // Uniform: 700-900 MUSD
analyzer.setOpexFactorDistribution(0.8, 1.2);   // ±20% OPEX

// Set seed for reproducibility
analyzer.setRandomSeed(42);

// Run simulation
MonteCarloResult mc = analyzer.monteCarloAnalysis(10000);

// Results
System.out.println("NPV P10: " + mc.getNpvP10() + " MUSD");
System.out.println("NPV P50: " + mc.getNpvP50() + " MUSD");
System.out.println("NPV P90: " + mc.getNpvP90() + " MUSD");
System.out.println("P(NPV > 0): " + mc.getProbabilityPositiveNpv() * 100 + "%");

Scenario Analysis

ScenarioResult scenarios = analyzer.scenarioAnalysis(
    55.0,   // Low oil price
    95.0,   // High oil price
    0.18,   // Low gas price
    0.35,   // High gas price
    0.20    // 20% CAPEX contingency for low case
);

System.out.println(scenarios);

Regional Cost Factors

Adjust NCS-baseline costs for different regions:

Using Regional Factors

// Create estimator for specific region
EconomicsEstimator estimator = new EconomicsEstimator("BR");

// Or set region after construction
EconomicsEstimator estimator = new EconomicsEstimator();
estimator.setRegion("US-GOM");

// Get estimate (automatically adjusted)
EconomicsReport report = estimator.estimate(concept, facility);
System.out.println("Region: " + estimator.getRegionName());
System.out.println("CAPEX: " + report.getTotalCapexMUSD() + " MUSD");

Available Regions

// List all regions
System.out.println(RegionalCostFactors.getSummaryTable());

// Get specific region factors
RegionalCostFactors brazil = RegionalCostFactors.forRegion("BR");
System.out.println("Brazil CAPEX factor: " + brazil.getCapexFactor());
System.out.println("Brazil well factor: " + brazil.getWellCostFactor());
Code Region CAPEX OPEX Wells
NO Norwegian Continental Shelf 1.00 1.00 1.00
UK UK Continental Shelf 0.95 0.90 0.90
US-GOM Gulf of Mexico 0.85 0.80 0.75
US-PERMIAN Permian Basin 0.60 0.55 0.50
BR Brazil Offshore 1.10 1.05 1.15
BR-PS Brazil Pre-Salt 1.20 1.10 1.25
MY Malaysia 0.70 0.65 0.70
AU Australia Offshore 1.15 1.10 1.10

Custom Regions

RegionalCostFactors custom = new RegionalCostFactors(
    "CUSTOM",           // Code
    "Custom Region",    // Name
    0.90,              // CAPEX factor
    0.85,              // OPEX factor
    0.95,              // Well cost factor
    0.80,              // Labor factor
    "Custom notes"
);

RegionalCostFactors.register(custom);

Integration Examples

Complete Field Economics Workflow

// 1. Define production profile
ProductionProfileGenerator gen = new ProductionProfileGenerator();
Map<Integer, Double> gasProfile = gen.generateFullProfile(
    15.0e6,                       // 15 MSm3/d peak
    1,                            // 1 year ramp
    4,                            // 4 years plateau
    0.10,                         // 10% decline
    DeclineType.EXPONENTIAL,
    2027,                         // Start
    20                            // Total years
);

// 2. Configure cash flow engine
CashFlowEngine engine = new CashFlowEngine("NO");
engine.setCapex(1200, 2025);
engine.setCapex(400, 2026);
engine.setOilPrice(75.0);
engine.setGasPrice(0.28);
engine.setProductionProfile(null, gasProfile, null);

// 3. Calculate base case
CashFlowResult result = engine.calculate(0.08);
System.out.println(result.getSummary());

// 4. Sensitivity analysis
SensitivityAnalyzer analyzer = new SensitivityAnalyzer(engine, 0.08);
analyzer.setGasPriceDistribution(0.20, 0.40);
analyzer.setCapexDistribution(1400, 1800);
MonteCarloResult mc = analyzer.monteCarloAnalysis(5000);
System.out.println(mc);

// 5. Compare regions
for (String region : Arrays.asList("NO", "UK", "BR", "AU")) {
    engine.setTaxModel(region);
    double npv = engine.calculateNPV(0.08);
    System.out.printf("%s: NPV = %.1f MUSD%n", region, npv);
}

Screening Multiple Concepts

List<FieldConcept> concepts = loadConcepts();
EconomicsEstimator estimator = new EconomicsEstimator("US-GOM");

for (FieldConcept concept : concepts) {
    EconomicsReport report = estimator.quickEstimate(concept);
    System.out.printf("%s: CAPEX=%.0f MUSD, $/boe=%.1f%n",
        concept.getName(),
        report.getTotalCapexMUSD(),
        report.getCapexPerBoeUSD());
}

See Also

References