This project implements a Lattice Boltzmann (LB-WBS) scheme for simulating flows in heterogeneous porous media with pressure dependence.
The implementation is mainly based on the WBS scheme (Walsh–Burwinkle–Saar, 2009) 1, but the framework is modular and can also be extended to other approaches such as the GLB model by Zhu & Ma (2013) 2 for multi-scale porous media.
streamlit run Assist_WBS.py
: Streamlit interface to set up LB-WBS parameters and save them into a JSON file describing the porous medium.streamlit run Reader_JSON.py
: Streamlit interface to read and visualize the content of a JSON file.LB_WBS.py
: Implementation of the LB-WBS scheme.PorousMedia.py
: Generation of heterogeneous porous matrices (vein networks, blobs, circular shapes, layered and non-layered media, ...).extractJSON.py
: Reading and extracting parameters from.json
files.utils.py
: Utility functions (visualization, parameter handling, etc.).media_json/
: Directory containing.json
files describing porous layer properties.main.py
: Full example script illustrating how to use the LB-WBS scheme._JSON_impermeable/
: Scripts to generate JSON files describing impermeable properties.
Install the required dependencies (tested with Python 3.9):
pip install -r requirements.txt
Run the main script:
python main.py
This script will:
- Generate a porous matrix with multiple layers.
- Extract parameters from the
.json
files. - Build the LB-WBS model with pressure dependence.
- Run the simulation until convergence.
- Display the velocity magnitude field with
matplotlib
.
Two graphical interfaces are provided to make the project easier to use:
streamlit run Assist_WBS.py
This interface allows you to:
- Configure the physical parameters of the model and the LB-WBS scheme parameters.
- Save them into a JSON file describing the porous medium.
streamlit run Reader_JSON.py
This interface allows you to:
- Load an existing JSON file.
- Visualize its parameters and associated properties.
Below is a complete example of running the LB-WBS scheme in a heterogeneous porous medium.
import matplotlib.pyplot as plt
import numpy as np
import LB_WBS as LB
import extractJSON
import PorousMedia
import utils
# 📐 Domain size
NX, NY = 200, 200
# 🌊 Initial conditions
UX0, UY0 = 0, 0
# 📂 JSON files describing porous layers
root_file = 'media_json/'
path_json = [
'medium_test4.json',
'medium_test3.json',
'medium_test6.json',
'medium_test6.json'
]
path_json = [root_file + file_json for file_json in path_json]
number_of_layers = len(path_json)
# 🧱 Step 1: Generate heterogeneous porous medium
porous_media = PorousMedia.generate_layers(
height=NX, width=NX, num_layers=number_of_layers, seed=33
).T
# 📑 Extract parameters from JSON
multi_porous = extractJSON.multi_model(path_json, view_table=False)
value_gamma = [0] * number_of_layers # Non-linear term (set to 0 here)
# 🔍 Visualization
utils.show_porous_media_and_LB_paramters(porous_media, multi_porous, gamma_value=value_gamma) # <-- first output
# ⚙️ Pre-processing LB-WBS parameters
RHO_OUT = float(multi_porous[0]['adimensionne']['rho_out'])
RHO0 = RHO_OUT
RHO_IN = float(multi_porous[0]['adimensionne']['rho_in'])
LENGTH = float(multi_porous[0]['adimensionne']['L'])
DX = float(multi_porous[0]['adimensionne']['dx'])
DT = float(multi_porous[0]['adimensionne']['dt'])
CS = DX / DT / np.sqrt(3)
# Relaxation times, theta field and gamma field
XI, THETA_FIELD, GAMMA_FIELD = LB.relaxation_time_matrix(
NX=NX, NY=NY, DX=DX,
number_of_layers=number_of_layers,
multi_porous=multi_porous,
porous_media=porous_media,
gamma_value=value_gamma
)
# 🌀 LB-WBS Model
# Create the bridge between the porous media (porous matrix) and LB-WBS parameters
model = LB.PressureDependanceModel(
THETA_FIELD=THETA_FIELD,
GAMMA_FIELD=GAMMA_FIELD,
XI=XI,
NX=NX, NY=NY,
RHO_IN=RHO_IN,
RHO_OUT=RHO_OUT,
CS=CS,
)
# 🔄 Initialization
model.initilisation(RHO0=RHO0, UX0=UX0, UY0=UY0)
# 🚧 Boundary conditions
model.right_bc = 'No slip' # or 'Free slip'
model.left_bc = 'No slip' # or 'Free slip'
# Streaming model can be 'WBS' or 'ZM'
model.streaming_model = 'WBS'
# ▶️ Run simulation
model.maximum_of_iteration = 2000 # number of iterations
model.run()
# 📊 Post-processing: velocity magnitude
magnitude = np.sqrt(model.u**2 + model.v**2)
fig, ax = plt.subplots(1, 1, figsize=(6, 5))
im = ax.imshow(magnitude, extent=[0, LENGTH, 0, LENGTH],
cmap='jet', aspect='equal')
cbar = plt.colorbar(im, ax=ax)
cbar.set_label("Magnitude")
ax.set_xlabel("x")
ax.set_ylabel("y")
plt.show() # <-- second output
(after utils.show_porous_media_and_LB_paramters(...)
)
(after the final plt.show()
)
If you use this project in your research, please cite it as follows:
@misc{Coiffard2025LBMultiScale,
author = {Coiffard, Théo},
title = {LB-MultiScale: Multiscale Lattice Boltzmann Methods for Porous Media},
year = {2025},
howpublished = {\url{https://github.com/theocoiffard/LB-MultiScale}},
version = {0.1.0},
institution = {Laboratoire Mathématiques, Image et Applications (MIA), La Rochelle Université, France}
}
Footnotes
-
Walsh, S. D. C., Burwinkle, H., & Saar, M. O. (2009). A new partial-bounceback lattice-Boltzmann method for fluid flow through heterogeneous media. Comput. Geosci., 35, 1186–1193. ↩
-
Zhu, J., & Ma, J. (2013). An improved gray lattice Boltzmann model for simulating fluid flow in multi-scale porous media. Advances in Water Resources, 56, 61–76. https://doi.org/10.1016/j.advwatres.2013.03.001 ↩