Skip to content

LBPM Tutorial, Step 7. Morphological Initial Conditions for 2 phase Flow

JamesEMcClure edited this page Oct 22, 2019 · 10 revisions

It is often useful to generate initial conditions for a 2-phase flow simulation based on a morphological approach. In particular, morphological tools can be used to provide a physical reasonable initial condition in cases where direct experimental observations are not available. These initial configurations are compatible with any of the 2-phase simulation protocols used by lbpm_color_simulator. These initialization approaches alter the fluid labels within the input files, writing a new file with the new morphologically assigned labels.

Note: when Restart = true fluid labels assigned from the 8-bit image data will not be used by lbpm_color_simulator. Restart functionality is intended to initialize the system by matching the previous simulation state as closely as possible

There are currently three morphological pre-processors in LBPM

  • lbpm_morphdrain_pp -- initialize fluid configuration based on morphological drainage
  • lbpm_morphopen_pp -- initialize fluid configuration based on morphological opening
  • lbpm_morph_pp -- initialize fluid configuration based on morphological opening applied to the largest connected component

In this part of the tutorial we are focused on lbpm_morphdrain_pp because it is the least controversial. Although it is not perfect, the morphological drainage operation does a good job of approximating configurations observed along primary drainage processes performed under water-wet conditions. A limitation is that fluid trapped in the corners will not stop the morphological operation from eroding it. This should not discourage you too much -- morphological tools are very practical and can save you a lot of time! It is also a good thing to be skeptical.

Since the morphological operation works on the input domain, associated parameters are added to the Domain section of the input file. Here we will set a target saturation Sw = 0.20, which will run the morphological drainage operation until the fluid labeled as 2 occupies 20% of the pore space or less.

Domain {
   Filename = "mask_water_flooded_water_and_oil.raw"
   ReadType = "16bit"  // data type
   N = 601, 594, 1311  // size of original image
   nproc = 2, 2, 2     // process grid
   n = 300, 297, 300   // sub-domain size
   voxel_length = 7.0  // voxel length (in microns)
   ReadValues = 0, 1, 2  // labels within the original image
   WriteValues = 0, 2, 1 // associated labels to be used by LBPM
   InletLayers = 0, 0, 10 // specify 10 layers along the z-inlet
   checkerSize = 10       // size of the checker to use
   BC = 0
   Sw =	0.20              // target saturation for morphological tools
}

Once this has been set, we launch lbpm_morphdrain_pp in the same way as other parallel tools


Successful output looks like the following:

mpirun -np 8 lbpm_morphdrain_pp input.db
Performing morphological opening with target saturation 0.200000 
voxel length = 7.000000 micron 
Initialized solid phase -- Converting to Signed Distance function 
Volume fraction for morphological opening: 0.142584 
Maximum pore size: 21.430119 
     0.997950      20.358613
     0.996309      19.340682
     0.995439      18.373648
     0.994426      17.454966
     0.993985      16.582218
     0.993769      15.753107
     0.993551      14.965451
     0.993357      14.217179
     0.993080      13.506320
     0.992923      12.831004
     0.992754      12.189454
     0.992341      11.579981
     0.992188      11.000982
     0.992018      10.450933
     0.991844      9.928386
     0.991711      9.431967
     0.991529      8.960369
     0.991334      8.512350
     0.991026      8.086733
     0.990832      7.682396
     0.990713      7.298276
     0.990619      6.933362
     0.990438      6.586694
     0.989717      6.257360
     0.989577      5.944492
     0.989378      5.647267
     0.989227      5.364904
     0.989119      5.096658
     0.988801      4.841826
     0.988063      4.599734
     0.987605      4.369748
     0.987392      4.151260
     0.987122      3.943697
     0.985650      3.746512
     0.985142      3.559187
     0.984524      3.381227
     0.983794      3.212166
     0.982667      3.051558
     0.982667      2.898980
     0.971337      2.754031
     0.925678      2.616329
     0.891404      2.485513
     0.891021      2.361237
     0.889632      2.243175
     0.889632      2.131017
     0.814257      2.024466
     0.811459      1.923242
     0.810163      1.827080
     0.465590      1.735726
     0.465589      1.648940
     0.465589      1.566493
     0.326068      1.488168
     0.325049      1.413760
     0.325048      1.343072
     0.325048      1.275918
     0.325048      1.212122
     0.325048      1.151516
     0.184125      1.093940
Final void fraction =0.184125
Final critical radius=1.093940
Writing ID file 

Note that lbpm_morphdrain_pp prints both the saturation and sphere radius. The underlying algorithm works by initializing the sphere radius for the opening based on the largest pore size in the system. The largest pore is determined from a distance map generated within the tool. The sphere radius is then decreased until the part of the porespace covered by the largest connected component generated by a morphological opening operation on the porespace. The conceptual idea is described by Hilpert et al Hilpert et al. The algorithm decreases the sphere radius until the saturation is reduced below the target value.

The new labels will be written to the file mask_water_flooded_water_and_oil.raw.morphdrain.raw and also to the local sub-domain files ID.xxxxx. Note that re-labeled values assigned based on ReadValues and WriteValues will be assigned within the new image file. To initialize a simulation from the new image that includes the morphological labels, the Domain section of the input database should be updated accordingly.

Domain {
   Filename = "mask_water_flooded_water_and_oil.raw.morphdrain.raw"
   ReadType = "16bit"  // data type
   N = 601, 594, 1311  // size of original image
   nproc = 2, 2, 2     // process grid
   n = 300, 297, 300   // sub-domain size
   voxel_length = 7.0  // voxel length (in microns)
   ReadValues = 0, 1, 2  // labels within the original image
   WriteValues = 0, 1, 2 // associated labels to be used by LBPM
   InletLayers = 0, 0, 10 // specify 10 layers along the z-inlet
   checkerSize = 10       // size of the checker to use
   BC = 0
   Sw =	0.20              // target saturation for morphological tools
}

The morphological drainage curve produced by lbpm_morphdrain_pp is useful in it's own right. This information can be used to better understand the structure of the pore-space without needing to run an expensive simulation. For convenience the list of saturation and radius is logged to the file morphdrain.csv. We can easily plot the associated curve in python.

  1. Load the required modules to ingest the CSV file
import pandas as pd
import numpy as np
from matplotlib import pyplot
  1. Read the file
M=pd.read_csv("morphdrain.csv",sep=" ")
  1. Plot the data
pyplot.figure()
pyplot.plot(M['sw'],M['radius'])
pyplot.xlabel('sw')
pyplot.ylabel('radius')
pyplot.show()

You should see a plot as depicted below

We can also plot the curvature

pc=1/M['radius']
pyplot.figure()
pyplot.plot(M['sw'],pc)
pyplot.xlabel('sw')
pyplot.ylabel('pc')
pyplot.legend()
pyplot.show()

This morphological data can be produced very quickly and provides a lot of useful information. We can see that a typical pore throat is only about 2--4 voxels across. Based on this we might explore ways to increase the resolution. We could also use the curvature data to inform boundary conditions, or otherwise inform a simulation plan. Carefully planning a simulation will almost always save time and energy.

Proceed to next step in tutorial.

Clone this wiki locally