The code implements IT-PI, an information-theoretic, data-driven method to identify the most predictive dimensionless inputs for non-dimensional quantities.
Dimensional analysis is one of the most fundamental tools for understanding physical systems. However, the construction of dimensionless variables, as guided by the Buckingham-$\pi$ theorem, is not uniquely determined. Here, we introduce IT-$\pi$, a model-free method that combines dimensionless learning with the principles of information theory. Grounded in the irreducible error theorem, IT-$\pi$ identifies dimensionless variables with the highest predictive power by measuring their shared information content.
- IT-PI identifies optimal dimensionless variables.
- IT-PI estimates optimal error bounds and its uncertainty based on discovered dimensionless variables.
- IT-PI distinguishes physical regimes.
- IT-PI discovers self-similar variables.
- IT-PI extracts characteristic scales.
Use the following command to install all required libraries:
pip install numpy scipy matplotlib pandas cma
Clone the repository, then import the module:
import IT_PI
Here is a quick start tutorial for using the module.
# import IT_PI is a module import IT_PI from scipy.special import erf import numpy as np from numpy.linalg import inv, matrix_rank from pprint import pprint def velocity_profile(y, nu, U, t): return U * (1 - erf(y / (2 * np.sqrt(nu * t)))) # Generate synthetic dataset y_vals = np.linspace(0, 1, 20) t_vals = np.linspace(5, 10, 20) U = np.random.uniform(0.5, 1.0, 5) nu = np.random.uniform(1e-3, 1e-2, 5) u_array = [] params = [] for u0, n0 in zip(U, nu): for y in y_vals: for t in t_vals: u_array.append(velocity_profile(y, n0, u0, t)) params.append([u0, y, t, n0]) u_array = np.array(u_array).reshape(-1, 1) params = np.array(params) # Define inputs and outputs Y = u_array / params[:, 0].reshape(-1, 1) # Output Pi_o = u/U X = params # Dimensional input list q variables = ['U', 'y', 't', '\\nu'] # Variable names D_in = np.matrix('1 1 0 2; -1 0 1 -1') # Dimension matrix num_input = 1 print("Rank of D_in:", matrix_rank(D_in)) print("D_in matrix:\n", D_in) num_basis = D_in.shape[1] - matrix_rank(D_in) basis_matrices = IT_PI.calc_basis(D_in, num_basis) print("Basis vectors:") pprint(basis_matrices) # Run IT_PI results = IT_PI.main( X, Y, basis_matrices, num_input=num_input, estimator="kraskov", estimator_params={"k": 5}, seed=42 ) # Display results coef_pi_list = results["input_coef"] variables = ['U','y', 't','\\nu']; #Define variable name optimal_pi_lab = IT_PI.create_labels(np.array(coef_pi_list).reshape(-1, len(variables)), variables) for j, label in enumerate(optimal_pi_lab): print(f'Optimal_pi_lab[{j}] = {label}') input_PI = results["input_PI"] output_PI = results["output_PI"] epsilon = results["irreducible_error"] uq = results["uncertainty"] IT_PI.plot_scatter(input_PI,output_PI) IT_PI.plot_error_bars(input_PI, epsilon,uq)
See the Jupyter notebooks in Examples directory for results presented in the paper. This includes:
Five validation cases:
- Rayleigh: Rayleigh problem
- Colebrook: Colebrook equation
- Malkus: Malkus waterwheel
- Benard: Rayleigh–Bénard convection
- Blasius: Blasius boundary layer
Five application cases:
- Velocity_transformation: Velocity scaling for compressible wall-bounded turbulence
- Wall_model: Wall fluxes in compressible turbulence over rough walls
- Dixit: Wall friction in turbulent flow over smooth surfaces under different mean pressure gradients
- Keyhole: Formation of a keyhole in a puddle of liquid metal melted by a laser
- MHD: Magnetohydrodynamics power generator