Skip to the content.

Evaporation and Dissolution in Pipelines: A Practical Tutorial

Overview

This tutorial provides practical guidance for modeling complete evaporation of liquids into gas and dissolution of gas into liquids using NeqSim’s non-equilibrium two-phase pipe flow model.

Related Documentation:

Common Industrial Applications:


1. Physical Background

1.1 Evaporation (Liquid → Gas)

Evaporation occurs when liquid molecules escape into the gas phase. The driving force is:

\[\Delta y_i = y_i^{interface} - y_i^{bulk,gas}\]

Conditions favoring evaporation:

Rate equation: \(N_i = k_G \cdot c_{t,G} \cdot (y_i^{int} - y_i^{bulk})\)

1.2 Dissolution (Gas → Liquid)

Dissolution occurs when gas molecules transfer into the liquid phase. The driving force is:

\[\Delta x_i = x_i^{interface} - x_i^{bulk,liquid}\]

Conditions favoring dissolution:

Rate equation: \(N_i = k_L \cdot c_{t,L} \cdot (x_i^{int} - x_i^{bulk})\)

1.3 Mass Transfer Modes

NeqSim provides three mass transfer modes to handle different scenarios:

Mode Direction Use Case
BIDIRECTIONAL Both ways General two-phase flow
EVAPORATION_ONLY Liquid → Gas Drying, flash evaporation
DISSOLUTION_ONLY Gas → Liquid Gas injection, absorption

Why use directional modes?

When one phase is nearly depleted (e.g., last liquid droplets evaporating), numerical instabilities can occur if the solver tries to condense material back. Directional modes prevent this by enforcing one-way transfer.


2. Complete Liquid Evaporation

Completion-distance calculations: use the dedicated finite-rate pipeline liquid evaporation model. Hydrodynamic liquid holdup is not a remaining-liquid inventory and must not be used to calculate percent evaporated or a completion distance. The older two-fluid example below is retained only to illustrate general non-equilibrium pipe setup.

2.1 Scenario: Water Droplets in Dry Gas

Physical situation: Small water droplets carried in a hot, dry methane gas stream. The droplets evaporate as they travel through the pipeline.

Key parameters:

2.2 Java Implementation

import neqsim.fluidmechanics.flowsystem.twophaseflowsystem.twophasepipeflowsystem.TwoPhasePipeFlowSystem;
import neqsim.fluidmechanics.flowsolver.twophaseflowsolver.twophasepipeflowsolver.TwoPhaseFixedStaggeredGridSolver.MassTransferMode;
import neqsim.thermo.system.SystemInterface;
import neqsim.thermo.system.SystemSrkEos;
import neqsim.thermodynamicoperations.ThermodynamicOperations;

public class WaterEvaporationExample {
    public static void main(String[] args) {
        // Step 1: Create two-phase fluid
        // Low pressure + high temperature = strong evaporation driving force
        SystemInterface fluid = new SystemSrkEos(350.0, 5.0);  // 77°C, 5 bar
        
        // Add gas phase (phase 0) - large excess of dry methane
        fluid.addComponent("methane", 500.0, "kg/hr", 0);
        
        // Add liquid phase (phase 1) - small amount of water droplets
        fluid.addComponent("water", 2.0, "kg/hr", 1);
        
        fluid.createDatabase(true);
        fluid.setMixingRule(2);  // Classic mixing rule
        
        // Flash to establish phases
        ThermodynamicOperations ops = new ThermodynamicOperations(fluid);
        ops.TPflash();
        
        // Step 2: Create pipe flow system
        double pipeLength = 50.0;    // meters
        double pipeDiameter = 0.05;  // 50 mm
        int numberOfNodes = 100;
        
        TwoPhasePipeFlowSystem pipe = new TwoPhasePipeFlowSystem();
        pipe.setInletThermoSystem(fluid);
        pipe.setNumberOfLegs(1);
        pipe.setNumberOfNodesInLeg(numberOfNodes);
        pipe.setLegPositions(new double[] {0, pipeLength});
        pipe.setEquipmentGeometry(pipeDiameter, pipeLength);
        pipe.setOuterHeatTransferCoefficient(15.0);  // W/m²K
        pipe.setSurroundingTemperature(350.0);       // Isothermal
        
        // Step 3: Initialize and configure
        pipe.createSystem();
        pipe.init();
        
        // Enable non-equilibrium mass transfer
        pipe.enableNonEquilibriumMassTransfer();
        
        // IMPORTANT: Use EVAPORATION_ONLY mode to prevent numerical issues
        // when liquid phase becomes depleted
        pipe.setMassTransferMode(MassTransferMode.EVAPORATION_ONLY);
        
        // Step 4: Solve
        pipe.solveSteadyState(2);  // 2 outer iterations
        
        // Step 5: Extract results
        double[] liquidHoldup = pipe.getLiquidHoldupProfile();
        double[] temperature = pipe.getTemperatureProfile();
        double[] pressure = pipe.getPressureProfile();
        int numNodes = pipe.getTotalNumberOfNodes();
        
        // Print evaporation profile
        System.out.println("=== Water Evaporation Profile ===");
        System.out.println("Position [m]   Liquid Holdup   Gas Fraction   T [K]");
        System.out.println("--------------------------------------------------");
        
        for (int i = 0; i < numNodes; i += numNodes/10) {
            double position = i * pipeLength / (numNodes - 1);
            System.out.printf("%8.1f      %.6f        %.6f       %.1f%n",
                position, liquidHoldup[i], 1.0 - liquidHoldup[i], temperature[i]);
        }
        
        // Holdup is a hydrodynamic result. Do not infer evaporated inventory from it.
        // Use PipelineEvaporationStudy when the required output is completion distance.
    }
}

2.3 Interpreting Results

No fixed completion distance is asserted for this illustrative two-fluid setup. A defensible result requires explicit droplet or film area, component inventory tracking, coupled heat transfer, numerical refinement, and validation of the thermodynamic and transport inputs. PipelineEvaporationStudy supplies those completion-distance-specific elements.

2.4 Key Observations

  1. Inventory, not holdup: component flow inventories determine percent evaporated; holdup is a hydraulic state

  2. Temperature effect: At constant temperature (isothermal case), evaporation is driven purely by concentration difference

  3. Pressure effect: Lower pressure = higher evaporation rate (more driving force)

  4. Flow pattern: Droplet/mist flow has high interfacial area, accelerating evaporation


3. Complete Gas Dissolution

3.1 Scenario: Methane Bubbles in Oil

Physical situation: Small methane gas bubbles rising through undersaturated n-decane oil. The gas dissolves as it flows through the pipeline.

Key parameters:

3.2 Java Implementation

Important: hydrodynamic gas fraction or liquid holdup is not an injected-gas inventory. It cannot be used to calculate percent dissolved or a dissolution completion distance. The general two-fluid example below is useful when pressure drop and holdup are required, but use PipelineDissolutionStudy for a conservative tracked-inventory completion distance, bubble slip, and a defined incomplete result when gas remains.

import neqsim.fluidmechanics.flowsystem.twophaseflowsystem.twophasepipeflowsystem.TwoPhasePipeFlowSystem;
import neqsim.fluidmechanics.flowsolver.twophaseflowsolver.twophasepipeflowsolver.TwoPhaseFixedStaggeredGridSolver.MassTransferMode;
import neqsim.thermo.system.SystemInterface;
import neqsim.thermo.system.SystemSrkEos;
import neqsim.thermodynamicoperations.ThermodynamicOperations;

public class GasDissolutionExample {
    public static void main(String[] args) {
        // Step 1: Create two-phase fluid
        // High pressure = high gas solubility in oil
        SystemInterface fluid = new SystemSrkEos(305.0, 120.0);  // 32°C, 120 bar
        
        // Add gas phase (phase 0) - small amount of methane bubbles
        fluid.addComponent("methane", 5.0, "kg/hr", 0);
        
        // Add liquid phase (phase 1) - large excess of n-decane (undersaturated)
        fluid.addComponent("nC10", 1200.0, "kg/hr", 1);
        
        fluid.createDatabase(true);
        fluid.setMixingRule("classic");
        
        // Flash to establish phases
        ThermodynamicOperations ops = new ThermodynamicOperations(fluid);
        ops.TPflash();
        
        // Verify we have two phases
        System.out.println("Number of phases: " + fluid.getNumberOfPhases());
        System.out.println("Inlet gas fraction: " + (1.0 - fluid.getBeta(1)));
        
        // Step 2: Create pipe flow system
        double pipeLength = 100.0;   // meters
        double pipeDiameter = 0.05;  // 50 mm
        int numberOfNodes = 100;
        
        TwoPhasePipeFlowSystem pipe = new TwoPhasePipeFlowSystem();
        pipe.setInletThermoSystem(fluid);
        pipe.setNumberOfLegs(1);
        pipe.setNumberOfNodesInLeg(numberOfNodes);
        pipe.setLegPositions(new double[] {0, pipeLength});
        pipe.setEquipmentGeometry(pipeDiameter, pipeLength);
        
        // Horizontal pipe (no gravity effect on pressure)
        pipe.setElevations(new double[] {0, 0});
        
        // Step 3: Initialize and configure
        pipe.createSystem();
        pipe.init();
        
        // Enable non-equilibrium mass transfer
        pipe.enableNonEquilibriumMassTransfer();
        
        // IMPORTANT: Use DISSOLUTION_ONLY mode when gas phase may deplete
        pipe.setMassTransferMode(MassTransferMode.DISSOLUTION_ONLY);
        
        // Step 4: Solve
        pipe.solveSteadyState(2);
        
        // Step 5: Extract results
        double[] liquidHoldup = pipe.getLiquidHoldupProfile();
        double[] pressure = pipe.getPressureProfile();
        int numNodes = pipe.getTotalNumberOfNodes();
        
        // Print dissolution profile
        System.out.println("\n=== Methane Dissolution Profile ===");
        System.out.println("Position [m]   Gas Fraction   Liquid Holdup   P [bar]");
        System.out.println("----------------------------------------------------");
        
        for (int i = 0; i < numNodes; i += numNodes/10) {
            double position = i * pipeLength / (numNodes - 1);
            double gasFraction = 1.0 - liquidHoldup[i];
            System.out.printf("%8.1f      %.6f       %.6f        %.2f%n",
                position, gasFraction, liquidHoldup[i], pressure[i]);
        }
        
        // Get mass transfer rate
        double massTransferRate = pipe.getTotalMassTransferRate(0);  // methane (component 0)
        System.out.printf("Methane mass transfer rate: %.4f mol/s%n", massTransferRate);
        System.out.println("(Positive = dissolution into liquid)");

        // Do not infer dissolved inventory or completion distance from liquidHoldup.
        // Use PipelineDissolutionStudy for that calculation.
    }
}

3.3 Result interpretation

The two-fluid result reports hydraulic state and local transfer rates. It does not by itself establish what fraction of the initially injected gas remains. For PipelineDissolutionStudy, inspect isCompleteDissolution() and getCompleteDissolutionDistance(). When completion is not reached, the distance is NaN, the profile extends to the configured pipe outlet, and getRemainingTrackedPhaseFraction() reports the remaining injected-gas mass fraction.

3.4 Key Observations

  1. High pressure is critical: At 120 bar, methane has high solubility in n-decane. At 10 bar, dissolution would be much slower.

  2. Approach to saturation: The dissolution rate slows as the liquid approaches saturation; complete dissolution may be thermodynamically impossible for the specified liquid inventory and local conditions.

  3. Bubble flow provides large area: Small bubbles have high surface area per volume, accelerating mass transfer

  4. Sign convention: Positive mass transfer rate = transfer TO liquid phase. Completion is nevertheless based on the tracked injected-gas inventory, not on the sign of a total flux or on holdup.


4. Bidirectional Mass Transfer

4.1 When to Use Bidirectional Mode

Use BIDIRECTIONAL mode when:

4.2 Example: Multicomponent Oil/Gas Flow

// Multicomponent system with both light and heavy components
SystemInterface fluid = new SystemSrkEos(320.0, 80.0);

// Gas phase
fluid.addComponent("methane", 100.0, "kg/hr", 0);
fluid.addComponent("ethane", 20.0, "kg/hr", 0);

// Liquid phase  
fluid.addComponent("nC6", 200.0, "kg/hr", 1);
fluid.addComponent("nC10", 300.0, "kg/hr", 1);

// In this case:
// - Light components (methane, ethane) may dissolve into oil
// - Heavy components (nC6, nC10) may evaporate into gas
// Both directions are physically reasonable

pipe.setMassTransferMode(MassTransferMode.BIDIRECTIONAL);

5. Mode Selection Guide

Decision Flowchart

Start
  │
  ├── Is one phase nearly depleted (< 5% volume)?
  │     │
  │     ├── YES: Is it the liquid phase?
  │     │    │
  │     │    ├── YES → Use EVAPORATION_ONLY
  │     │    │         (prevents spurious condensation)
  │     │    │
  │     │    └── NO → Use DISSOLUTION_ONLY
  │     │              (prevents spurious evaporation)
  │     │
  │     └── NO: Is transfer predominantly one direction?
  │          │
  │          ├── YES: Light component evaporating?
  │          │    │
  │          │    ├── YES → Use EVAPORATION_ONLY
  │          │    │
  │          │    └── NO → Use DISSOLUTION_ONLY
  │          │
  │          └── NO → Use BIDIRECTIONAL
  │
  └── End

Quick Reference Table

Scenario Phase Ratio Recommended Mode Reason
Water drying in gas 99% gas, 1% liquid EVAPORATION_ONLY Prevent condensation when liquid depletes
Gas injection into oil 5% gas, 95% liquid DISSOLUTION_ONLY Prevent evaporation when gas depletes
Wet gas pipeline 80% gas, 20% liquid BIDIRECTIONAL Both phases persist
Slug flow oil/gas ~50% each BIDIRECTIONAL Equilibrium between phases
Flash evaporation Liquid → Gas EVAPORATION_ONLY One-way process
High-P absorption Gas → Liquid DISSOLUTION_ONLY One-way process

6. Numerical Considerations

6.1 Grid Resolution

For accurate mass transfer calculations:

// Minimum 50 nodes for mass transfer problems
int nodes = 100;  // Recommended

// Higher resolution near phase depletion
// The solver automatically refines internally

Rule of thumb: Use at least 2 nodes per characteristic mass transfer length:

\[L_{MT} = \frac{u}{k \cdot a}\]

6.2 Convergence

// Start with fewer outer iterations
pipe.solveSteadyState(2);  // Usually sufficient

// For difficult cases (near-complete phase change)
pipe.solveSteadyState(5);  // More iterations

6.3 Common Issues and Solutions

Issue Symptom Solution
Negative holdup holdup < 0 warnings Use directional mode
Non-convergence Oscillating results Reduce time step, add iterations
Phase disappears Sudden jump to 0 or 1 Increase grid resolution
Wrong direction Evaporation when should dissolve Check thermodynamic setup

7. Validation Against Theory

7.1 Analytical Solution for Simple Case

For single-component evaporation into pure carrier gas, the analytical solution is:

\[\alpha_L(z) = \alpha_{L,0} \cdot \exp\left(-\frac{k_L \cdot a}{u_L} \cdot z\right)\]

Where:

7.2 Comparing NeqSim to Analytical

// After solving, compare:
double analyticalAlpha = alpha0 * Math.exp(-kL * a / uL * z);
double neqsimAlpha = liquidHoldup[i];

double error = Math.abs(analyticalAlpha - neqsimAlpha) / analyticalAlpha * 100;
System.out.printf("Position %.1f m: Error = %.2f%%", z, error);

Typical agreement: < 5% for simple cases, < 15% for multicomponent.


8. Advanced Topics

8.1 Temperature Effects on Mass Transfer

Evaporation absorbs latent heat, potentially cooling the system:

// Enable coupled heat transfer
pipe.enableNonEquilibriumHeatTransfer();

// Provide heat source to maintain evaporation rate
pipe.setOuterHeatTransferCoefficient(50.0);  // W/m²K
pipe.setSurroundingTemperature(400.0);       // Hot environment

8.2 High Flux Corrections

For rapid mass transfer (Ackermann correction):

// Enable finite flux correction (Stefan flow)
FlowNodeInterface node = pipe.getNode(i);
node.getFluidBoundary().setFiniteFluxCorrection(0, true);  // Gas
node.getFluidBoundary().setFiniteFluxCorrection(1, true);  // Liquid

8.3 Reactive Systems (CO₂ Absorption)

For systems with chemical reactions:

// Use CPA equation of state for polar/associating systems
SystemInterface fluid = new SystemSrkCPAstatoil(313.15, 30.0);
fluid.addComponent("CO2", 10.0, "kg/hr", 0);
fluid.addComponent("water", 1000.0, "kg/hr", 1);
fluid.addComponent("MDEA", 200.0, "kg/hr", 1);

// The enhancement factor for reaction is calculated automatically
// See mass_transfer.md for reaction kinetics details

9. Summary

Key Takeaways

  1. Choose the right mode: EVAPORATION_ONLY when liquid depletes, DISSOLUTION_ONLY when gas depletes, BIDIRECTIONAL otherwise

  2. High pressure favors dissolution, low pressure favors evaporation

  3. Temperature drives the equilibrium - higher T means more volatile components in gas phase

  4. Interfacial area is critical - flow pattern affects mass transfer rate significantly

  5. Use sufficient grid resolution - at least 50-100 nodes for mass transfer problems

  6. Validate your results - check mass balances and compare with analytical solutions when possible

Further Reading


References

  1. Solbraa, E. (2002). Equilibrium and Non-Equilibrium Thermodynamics of Natural Gas Processing. PhD Thesis, NTNU.

  2. Krishna, R. and Standart, G.L. (1976). “A multicomponent film model incorporating a general matrix method of solution to the Maxwell-Stefan equations.” AIChE Journal, 22(2), 383-389.

  3. Taylor, R. and Krishna, R. (1993). Multicomponent Mass Transfer. Wiley.

  4. Bird, R.B., Stewart, W.E., and Lightfoot, E.N. (2002). Transport Phenomena, 2nd Ed.


Document created for NeqSim Two-Phase Pipe Flow Mass Transfer Module