Skip to content

LBPM Tutorial, Step 10. Steady state simulations from a sequence of images

JamesEMcClure edited this page Oct 22, 2019 · 3 revisions

Just as steady-state flow simulations are used to measure permeability, steady-state simulations are very useful to measure effective permeability. In a steady-state simulation full periodic boundary conditions are applied, which ensures that the fluid saturation will remain nearly fixed. LBPM currently supports several protocols to support these computations. The most flexible of these is the "image sequence" protocol, for which a sequence of 8-bit binary images is provided, and lbpm_color_simulator will perform a steady-state simulation for each. The images can be from any source. For this case, we will assume that a previous simulation (e.g. the water-flooding simulation from Step 9) has produced a sequence of three images, which are the 8-bit binary files id_t100000.raw, id_t200000.raw and id_3100000.raw. We modify the input file from Step 9 as follows:

  1. Modify the Domain section of the database:
  • specify stead-state boundary conditions: BC = 0
  1. Modify the Color section of the database:
  • specify that we want to provide a sequence of images: protocol = "image sequence"
  • specify the image sequence as a list: image_sequence = "id_t100000.raw", "id_t200000.raw", "id_3100000.raw"
  • specify a target capillary number: capillary_number = 1.0e-4
  • specify an initial force: F = 0, 0, 1.0e-5
  1. Modify the Analysis section of the database
  • specify the minimum timesteps per image: min_steady_timesteps = 50000
  • specify the maximum timesteps per image: max_steady_timesteps = 100000
  • specify the tolerable relative fluctuation in the total flow rate: tolerance = 0.01
  • specify the interval to compare the flow rate: morph_interval = 50000

Note that capillary_number is a target value. The first image in the sequence will be driven to steady-state using the initial force. The capillary number will be measured from the steady state field, and the force will then be linearly re-scaled to attempt to better match the target capillary number.

The resulting input file should look like the following

Domain {
   Filename = "mask_water_flooded_water_and_oil.raw.morphdrain.raw"  
   ReadType = "8bit"  // data type
   nproc = 2, 2, 2     // process grid
   n = 300, 297, 300   // sub-domain size
   N = 600, 594, 600  // size of original image
   voxel_length = 7.0  // voxel length (in microns)
   ReadValues = -1, 0, 1, 2  // labels within the original image
   WriteValues = -1, 0, 1, 2 // associated labels to be used by LBPM
   BC = 4                // boundary condition type (0 for flux)
   Sw = 0.18
}
Color {
    tauA = 0.7;             // relaxation time for fluid A (labeled as "1")       
    tauB = 0.7;             // relaxation time for fluid B (labeled as "2") 
    rhoA   = 1.0;           // density for fluid A (in lattice units)
    rhoB   = 1.0;           // density for fluid B (in lattice units)
    alpha = 1e-3;           // controls the surface tension
    beta  = 0.95;           // controls the interface width 
    F = 0, 0, 5.0e-6             // controls the external force
    Restart = false         // initialize simulation from restart file?
    timestepMax = 1000000    // maximum number of timesteps to perform before exit
    ComponentLabels = 0, -1     // number of immobile component labels in the input image
    ComponentAffinity = -1.0, -0.9  // wetting condition for each immobile component
    protocol = "image sequence"
    image_sequence = "id_t100000.raw", "id_t200000.raw", "id_3100000.raw"
    capillary_number = 1.0e-4       // target capillary number
}
Analysis {
    morph_interval = 50000          // check steady-state at this interval
    min_steady_timesteps = 50000    // minimum number of timesteps for each image
    max_steady_timesteps = 100000   // maximum number of timesteps for each image
    tolerance = 0.01                // error tolerance (based on relative change in flow rate)
    analysis_interval = 1000         // Frequency to perform analysis
    visualization_interval = 100000  // Frequency to write visualization data
    restart_interval = 1000000       // Frequency to write restart data
    restart_file = "Restart"         // Filename to use for restart file (will append rank)
    N_threads    = 4                 // Number of threads to use for analysis
    load_balance = "independent"     // Load balance method to use: "none", "default", "independent"
}
Visualization {
}

Once steady-state criteria has been met, the following information is written to the file relperm.csv

  • timesteps - the number of timesteps needed to reach steady state
  • sat.water - the saturation of water
  • eff.perm.oil - the effective permeability of oil
  • eff.perm.water - the effective permeability of water
  • eff.perm.oil.connected - contribution to effective permeability of oil due to connected flow
  • eff.perm.water.connected- contribution to effective permeability of water due to connected flow
  • cap.pressure - difference between the fluid pressures
  • cap.pressure.connected - difference between the connected fluid pressures
  • pressure.drop - viscous pressure drop based on external force
  • Ca - actual capillary number
  • M - viscosity ratio

Plotting data follows the same procedure as for other CSV data written by LBPM, e.g.

import pandas as pd
import numpy as np
from matplotlib import pyplot
D=pd.read_csv("relperm.csv",sep=" ")
pyplot.figure()
pyplot.plot(D['sat.water'],D['eff.perm.oil'])
pyplot.plot(D['sat.water'],D['eff.perm.water'])
pyplot.xlabel('water saturation')
pyplot.ylabel('effective permeability')
pyplot.show()

Since the number of timesteps that will be required to reach steady state will depend on the flow domain, capillary_number, tolerance, and morph_interval, and other physical parameters for the simulation, it is a good idea to visualize the simulation data to verify based on the time history that the data seems to have reached a steady state.

T=pd.read_csv("timelog.csv",sep=" ")
pyplot.figure()
pyplot.plot(T['krn'])
pyplot.plot(T['krw'])
pyplot.xlabel('time')
pyplot.ylabel('effective permeability')
pyplot.show()

Proceed to next step in tutorial