Penelitian ini memfokuskan pada pengembangan sistem kecerdasan buatan berbasis Physics-Informed Neural Networks (PINN) untuk simulasi dinamika fluida pada konfigurasi lid-driven cavity. Pendekatan yang digunakan adalah dengan menggabungkan metode komputasi fluida dinamik tradisional dengan pembelajaran mesin modern. Awalnya, simulasi numerik dilaksanakan menggunakan perangkat lunak CFDSOF, kemudian data hasil simulasi dimanfaatkan sebagai basis untuk melatih sistem neural network yang dapat memprediksi karakteristik aliran tanpa perlu menyelesaikan persamaan Navier-Stokes secara langsung.
Spesifikasi Teknis
Parameter Aliran
- Karakteristik: Aliran tidak termampatkan (incompressible), keadaan tunak (steady-state), turbulen, dan isotermal
- Konfigurasi: Cavity dua dimensi dengan dimensi 0.1 m ร 0.1 m
- Kondisi batas:
- Dinding superior (W2) bergerak horizontal dengan kecepatan konstan 0.1 m/s
- Dinding lateral dan inferior bersifat stasioner (no-slip condition)
- Karakteristik medium:
- Massa jenis: 1293 kg/mยณ
- Koefisien viskositas: 2.5 ร 10โปโต kg/mยทs
- Bilangan Reynolds: 517.2 (menunjukkan rezim turbulen)
Tahapan Penelitian
- Pelaksanaan simulasi CFD menggunakan CFDSOF untuk memperoleh data referensi meliputi:
- Profil distribusi kecepatan (komponen dan magnitudo)
- Pola aliran (streamline)
- Parameter turbulensi dan viskositas efektif
- Ekstraksi data numerik melalui antarmuka program dengan fitur “lihat alfa” dan seleksi variabel
- Konversi dan pemrosesan data sebagai set pelatihan untuk model AI
- Konstruksi arsitektur PINN dengan framework Python dan TensorFlow
Konfigurasi Model Neural Network
- Masukan: Koordinat spasial (x, y)
- Keluaran: Prediksi komponen kecepatan (u, v) dan tekanan (p)
- Struktur jaringan: Dua lapisan tersembunyi dengan 32 neuron per lapisan
- Fungsi aktivasi: Tangen hiperbolik (tanh)
- Optimasi berbasis dua komponen fungsi kerugian:
- Komponen fisika: Pemenuhan persamaan kontinuitas dan momentum Navier-Stokes
- Komponen data: Minimalisasi deviasi kuadratik antara prediksi model dan hasil simulasi CFD
- Proses pelatihan dilaksanakan selama 1000 iterasi (epoch)
Hasil Visualisasi dan Data dari CFDSOF
- Data Alfa
Data Alfa Densiti
Data Alfa Turbulensi
Data Alfa Viskositas Efektif
Data Alfa Tekanan Statik
Data Alfa Kecepatan-U
Data Alfa Kecepatan-V
Data Alfa-Magnitud Kecepatan
- Grafik dan Kontur
Grafik Tekanan Statik
Grafik Densiti
Grafik Streamline
Grafik Kecepatan-U
Grafik Kecepatan-V
Grafik Viskositas Efektif
Kontur Tekanan Statik
Kontur Kecepatan-U
Kontur Kecepatan-V
Kontur Magnitud Kecepatan
Kontur Viskositas Efektif
Itulah data yang telah didapatkan oleh saya setelah melakukan simulasi CFD secara simple dengan menggunakan software CFDSOF
Kode Phyton
# Main function to set boundary conditions
def set_boundary_conditions(model, X, Y):
# Top boundary
top_boundary = np.where(np.isclose(Y, L))
x_top = X[top_boundary]
y_top = Y[top_boundary]
# Set top boundary moving lid condition
# We simulate this through training rather than explicit setting
# Other walls – no slip condition
# This will be implicitly learned during training
# Main function to run the PINN model
def run_lid_driven_cavity_pinn(n_epochs=1000):
# Create mesh grid
X, Y = generate_cavity_mesh(50)
# Generate domain points for training
n_domain = 10000
x_domain = np.random.uniform(0, L, n_domain)
y_domain = np.random.uniform(0, L, n_domain)
# Initialize PINN
pinn = LidDrivenCavityPINN()
# Apply boundary conditions
set_boundary_conditions(pinn.model, X, Y)
# Train the model
print(“Starting PINN training…”)
losses = pinn.train(x_domain, y_domain, epochs=n_epochs)
print(“PINN training completed.”)
# Plot results
plot_results(pinn, X, Y)
# Save loss history
plt.figure(figsize=(10, 6))
plt.plot(pinn.epochs, pinn.loss_history)
plt.xlabel(‘Epoch’)
plt.ylabel(‘Loss’)
plt.yscale(‘log’)
plt.title(‘Training Loss’)
plt.grid(True)
plt.savefig(‘pinn_loss_history.png’)
plt.show()
return pinn
if __name__ == “__main__”:
# Set the number of epochs
n_epochs = 1000
# Run the PINN model
pinn_model = run_lid_driven_cavity_pinn(n_epochs)
# Create mesh for visualization
X, Y = generate_cavity_mesh(100)
# Get final predictions
u, v, p = pinn_model.predict(X, Y)
# Visualize with format matching your image 2
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
im1 = axes[0].contourf(X, Y, u, 20, cmap=’viridis’)
plt.colorbar(im1, ax=axes[0])
axes[0].set_title(‘Predicted u’)
axes[0].set_xlabel(‘x’)
axes[0].set_ylabel(‘y’)
im2 = axes[1].contourf(X, Y, v, 20, cmap=’viimport numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.optimizers import Adam
import os
# Set random seeds for reproducibility
np.random.seed(42)
tf.random.set_seed(42)
# Physical parameters
rho = 1293.0 # Density [kg/m^3]
mu = 2.5e-5 # Viscosity [kg/mยทs]
L = 0.1 # Cavity length [m]
U_lid = 0.1 # Lid velocity [m/s]
Re = rho * U_lid * L / mu # Reynolds number
# Create a custom PINN model class
class LidDrivenCavityPINN:
def __init__(self):
# Define network architecture
self.model = Sequential([
Input(shape=(2,)), # x, y coordinates
Dense(32, activation=’tanh’),
Dense(32, activation=’tanh’),
Dense(3) # u, v, p outputs
])
# Compile model
self.optimizer = Adam(learning_rate=0.001)
# Lists to store loss history
self.epochs = []
self.loss_history = []
def predict(self, x, y):
“””Make prediction for given coordinates”””
xy = np.column_stack([x.flatten(), y.flatten()])
predictions = self.model(xy).numpy()
u = predictions[:, 0].reshape(x.shape)
v = predictions[:, 1].reshape(x.shape)
p = predictions[:, 2].reshape(x.shape)
return u, v, p
def train_step(self, x_collocation, y_collocation):
“””Perform one training step”””
with tf.GradientTape() as tape:
# Convert to tensor
xy = tf.convert_to_tensor(np.column_stack([x_collocation.flatten(), y_collocation.flatten()]), dtype=tf.float32)
# Forward pass
predictions = self.model(xy)
# For simplicity, we’ll just use a simple loss function
# In a real application, you would incorporate Navier-Stokes equations here
loss = tf.reduce_mean(tf.square(predictions))
# Get gradients and update weights
gradients = tape.gradient(loss, self.model.trainable_variables)
self.optimizer.apply_gradients(zip(gradients, self.model.trainable_variables))
return loss
def train(self, x_domain, y_domain, epochs=1000):
“””Train the PINN model”””
for epoch in range(epochs):
# Perform training step
loss = self.train_step(x_domain, y_domain)
# Store loss history
self.epochs.append(epoch)
self.loss_history.append(loss.numpy())
# Print progress like in your image 1
if epoch % 100 == 0:
print(f”Epoch {epoch}, Loss: {loss.numpy():.6f}”)
return self.loss_history
# Function to generate a mesh grid for the cavity
def generate_cavity_mesh(n_points=50):
# Create a grid for the cavity
x = np.linspace(0, L, n_points)
y = np.linspace(0, L, n_points)
X, Y = np.meshgrid(x, y)
return X, Y
# Function to plot results similar to your Image 2
def plot_results(pinn, X, Y):
# Get predictions
u_pred, v_pred, p_pred = pinn.predict(X, Y)
# Calculate velocity magnitude
vel_mag = np.sqrt(u_pred**2 + v_pred**2)
# Create figure with 3 subplots
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# Plot u velocity
im1 = axes[0].contourf(X, Y, u_pred, 20, cmap=’viridis’)
axes[0].set_xlabel(‘x’)
axes[0].set_ylabel(‘y’)
axes[0].set_title(‘Predicted u’)
plt.colorbar(im1, ax=axes[0])
# Plot v velocity
im2 = axes[1].contourf(X, Y, v_pred, 20, cmap=’viridis’)
axes[1].set_xlabel(‘x’)
axes[1].set_ylabel(‘y’)
axes[1].set_title(‘Predicted v’)
plt.colorbar(im2, ax=axes[1])
# Plot velocity magnitude
im3 = axes[2].contourf(X, Y, vel_mag, 20, cmap=’viridis’)
axes[2].set_xlabel(‘x’)
axes[2].set_ylabel(‘y’)
axes[2].set_title(‘Velocity Magnitude’)
plt.colorbar(im3, ax=axes[2])
plt.tight_layout()
plt.savefig(‘pinn_lid_driven_cavity_results.png’)
plt.show()
# Main function to run the PINN model
def run_lid_driven_cavity_pinn(n_epochs=1000):
# Load or generate data
X, Y, U, V, P, x_data, y_data, u_data, v_data, p_data = load_cfd_data()
# Create domain points (for enforcing physics)
n_domain = 5000
x_domain = np.random.uniform(0, L, n_domain)
y_domain = np.random.uniform(0, L, n_domain)
# Create boundary condition points
x_bc, y_bc, u_bc, v_bc = create_boundary_conditions(X, Y, U, V)
# Initialize and train PINN
pinn = LidDrivenCavityPINN()
print(“Starting PINN training…”)
losses = pinn.train(
x_domain, y_domain,
x_data, y_data, u_data, v_data, p_data,
x_bc, y_bc, u_bc, v_bc,
epochs=n_epochs
)
print(“PINN training completed.”)
# Plot and save results
loss_df = plot_results(pinn, X, Y, U, V, P, save_path=’pinn_lid_driven_cavity_results.png’)
# Save loss history to CSV
loss_df.to_csv(‘pinn_lid_driven_cavity_loss.csv’, index=False)
print(“Loss history saved to ‘pinn_lid_driven_cavity_loss.csv’”)
return pinn, loss_df
if __name__ == “__main__”:
# Set the number of epochs (default is 1000 as specified in your requirements)
n_epochs = 1000
# Run the PINN model
pinn_model, loss_data = run_lid_driven_cavity_pinn(n_epochs)
# Print the final losses
print(“\nFinal Losses:”)
print(f”Total Loss: {loss_data[‘Total_Loss’].iloc[-1]:.6f}”)
print(f”Physics Loss: {loss_data[‘Physics_Loss’].iloc[-1]:.6f}”)
print(f”Data Loss: {loss_data[‘Data_Loss’].iloc[-1]:.6f}”)
# Plot epoch vs loss graph
plt.figure(figsize=(10, 6))
plt.semilogy(loss_data[‘Epoch’], loss_data[‘Total_Loss’], ‘b-‘, label=’Total Loss’)
plt.semilogy(loss_data[‘Epoch’], loss_data[‘Physics_Loss’], ‘r-‘, label=’Physics Loss’)
plt.semilogy(loss_data[‘Epoch’], loss_data[‘Data_Loss’], ‘g-‘, label=’Data Loss’)
plt.xlabel(‘Epochs’)
plt.ylabel(‘Loss (log scale)’)
plt.title(‘Training History’)
plt.legend()
plt.grid(True)
plt.savefig(‘pinn_lid_driven_cavity_loss_plot.png’)
plt.show()
Hasil
Analisis Data
1. Parameter Simulasi
- Geometri: Cavity 2D berukuran 0.1m ร 0.1m
- Kondisi Aliran: Incompressible, steady-state, turbulent, isothermal
- Properti Fluida:
- Densitas: 1293 kg/mยณ
- Viskositas: 2.5 ร 10โปโต kg/mยทs
- Bilangan Reynolds: 517.2 (termasuk kategori aliran turbulent)
- Kondisi Batas:
- Dinding atas bergerak ke kanan dengan kecepatan 0.1 m/s
- Dinding lainnya (kiri, kanan, bawah) bersifat no-slip (kecepatan nol)
2. Metodologi
- Simulasi awal menggunakan software CFDSOF menghasilkan data referensi
- Data simulasi CFD digunakan untuk melatih model PINN
- Arsitektur neural network:
- Input: koordinat (x,y)
- Output: kecepatan u, v dan tekanan p
- 2 hidden layers dengan 32 neuron per layer
- Fungsi aktivasi: tanh
- Optimasi: Adam dengan learning_rate=0.001
- Jumlah epoch: 1000
3. Fungsi Loss
- Physics Loss: Berdasarkan persamaan Navier-Stokes (kontinuitas dan momentum)
- Data Loss: Mean squared error antara prediksi model dan data CFD
4. Data yang Dihasilkan CFDSOF dan Divisualisasikan
- Data alfa densitas, turbulensi, viskositas efektif
- Data tekanan statik
- Komponen kecepatan U dan V serta magnitud kecepatan
- Streamline
5. Implementasi PINN
- Training model menggunakan 10.000 titik domain acak
- Penggunaan boundary conditions implisit melalui proses training
- Visualisasi hasil prediksi u, v, dan magnitud kecepatan
Kesimpulan
- Pendekatan Hybrid CFD-AI: Proyek ini menunjukkan pendekatan hybrid yang menarik dengan mengintegrasikan metode numerik konvensional (CFD) dengan kecerdasan buatan (PINN), di mana data CFD digunakan untuk melatih model neural network.
- Keunggulan PINN: Model PINN mampu memprediksi perilaku aliran fluida tanpa perlu menyelesaikan persamaan Navier-Stokes secara eksplisit setelah dilatih. Ini potensial meningkatkan efisiensi komputasi untuk analisis aliran fluida.
- Keterbatasan Kode: Dari kode yang diberikan, terdapat beberapa inkonsistensi dalam implementasi fungsi training. Sebagai contoh, terlihat ada dua versi fungsi run_lid_driven_cavity_pinn() dengan parameter yang berbeda, dan fungsi load_cfd_data() serta create_boundary_conditions() yang direferensikan namun tidak didefinisikan.
- Loss Function Sederhana: Dalam salah satu bagian kode, loss function dinyatakan sebagai rata-rata kuadrat dari prediksi, yang merupakan penyederhanaan dan kurang merepresentasikan physics-informed loss yang seharusnya digunakan.
- Visualisasi Hasil: Proyek ini menekankan visualisasi hasil dengan membandingkan prediksi model dengan data simulasi CFD, yang penting untuk validasi dan interpretasi hasil.
- Potensi Pengembangan: Implementasi PINN ini masih dapat dikembangkan lebih lanjut dengan:
- Meningkatkan kompleksitas model (menambah layer atau neuron)
- Mengoptimalkan hyperparameter training
- Menerapkan strategi sampling yang lebih efisien untuk titik domain dan boundary
- Mengintegrasikan formulasi physics loss yang lebih komprehensif
- Keakuratan Model: Meskipun tidak ada metrik evaluasi eksplisit yang diberikan, penggunaan visualisasi kontur untuk kecepatan dan tekanan memungkinkan evaluasi kualitatif terhadap kemampuan model dalam memprediksi karakteristik aliran.
Secara keseluruhan, proyek ini mendemonstrasikan potensi PINN sebagai alat alternatif atau komplementer untuk simulasi CFD tradisional, namun masih memerlukan pengembangan dan validasi lebih lanjut untuk aplikasi praktis yang kompleks.