ccitonline.com

CCIT – Cara Cerdas Ingat Tuhan

| AI-DAI5 | CFDSOF | VisualFOAM | 8N8 | DAI5 eBook Free Download |

Pemodelan Aliran Fluida pada Lid-Driven Cavity dengan Physics-Informed Neural Networks_Raditya Danishara

Pendahuluan

Proyek ini mengembangkan model kecerdasan buatan berbasis Physics-Informed Neural Networks (PINN) untuk memprediksi perilaku aliran fluida dalam konfigurasi lid-driven cavity. Alih-alih mengandalkan sepenuhnya pada persamaan Navier-Stokes dalam solver konvensional, pendekatan ini bermaksud melatih jaringan neural untuk memahami pola distribusi kecepatan dan tekanan dengan tetap mempertahankan kesesuaian fisika yang mendasarinya.

Kami memulai dengan melakukan simulasi menggunakan software CFDSOF untuk menghasilkan data referensi yang kemudian digunakan untuk melatih model AI kami.

Spesifikasi Aliran dan Geometri

Karakteristik aliran yang dimodelkan meliputi:

  • Sifat aliran: Incompressible, steady-state, turbulent, dan isothermal
  • Geometri: Cavity 2D dengan dimensi 0.1m ร— 0.1m
  • Bilangan Reynolds: 517.2 (termasuk kategori aliran turbulent)

Kondisi batas yang diterapkan:

  • Dinding atas bergerak dengan kecepatan konstan 0.1 m/s ke arah kanan
  • Dinding bagian lain (kiri, kanan, dan bawah) bersifat no-slip (tidak bergerak)

Parameter fluida yang digunakan:

  • Densitas: 1293 kg/mยณ
  • Viskositas: 2.5 ร— 10โปโต kg/mยทs

Metodologi

Metode penelitian dilaksanakan dalam beberapa tahap:

  1. Simulasi CFD Menggunakan software CFDSOF, kami menjalankan simulasi untuk mendapatkan data referensi, meliputi:
    • Kontur dan vektor kecepatan (komponen U dan V)
    • Magnitud kecepatan
    • Pola streamline
    • Viskositas turbulen efektif
    • Tekanan statik
  2. Ekstraksi Data Data numerik diperoleh melalui menu “lihat alfa” dan “pilih variabel” untuk mendapatkan nilai-nilai yang diperlukan sebagai dasar pelatihan model AI.
  3. Pengembangan Model PINN Model Physics-Informed Neural Network diimplementasikan dengan Python dan TensorFlow dengan arsitektur:
    • Input: koordinat posisi (x, y)
    • Output: komponen kecepatan u dan v, serta tekanan p
    • Struktur jaringan: 2 hidden layers dengan 32 neuron per layer
    • Fungsi aktivasi: tanh
    • Optimizer: Adam dengan learning rate 0.001
  4. Fungsi Loss Model dioptimalkan berdasarkan kombinasi dua jenis loss:
    • Physics Loss: Didasarkan pada persamaan kontinuitas dan momentum Navier-Stokes
    • Data Loss: Selisih kuadrat antara prediksi model dan data simulasi CFD
  5. Pelatihan Model Model dilatih selama 1000 epoch menggunakan 10.000 titik domain yang dibangkitkan secara acak dalam geometri cavity.

Hasil Simulasi CFD

Simulasi menghasilkan beragam visualisasi dan dataset, termasuk:

  • Data distribusi densitas, turbulensi, dan viskositas efektif
  • Profil tekanan statik di seluruh domain
  • Pola kecepatan pada arah U (horizontal) dan V (vertikal)
  • Magnitud kecepatan yang menggambarkan intensitas aliran
  • Pola streamline yang menunjukkan jalur partikel fluida

Visualisasi ini memberikan gambaran komprehensif tentang karakteristik aliran dalam cavity dan menjadi dasar untuk validasi model PINN.

Implementasi Kode

Kode Python untuk model PINN mengimplementasikan arsitektur neural network yang telah dijelaskan. Beberapa komponen utama dalam implementasi meliputi:

  • Kelas LidDrivenCavityPINN yang mencakup definisi model, fungsi prediksi, dan logika pelatihan
  • Fungsi untuk membangkitkan mesh cavity dan memvisualisasikan hasil
  • Penerapan kondisi batas, terutama untuk dinding atas yang bergerak
  • Pemrosesan data CFD sebagai referensi pelatihan
  • Visualisasi hasil simulasi PINN dibandingkan dengan data CFD

Analisis Hasil

Berdasarkan visualisasi hasil dan data yang diperoleh, dapat disimpulkan bahwa:

  1. Model PINN menunjukkan kemampuan memprediksi pola aliran dalam cavity setelah dilatih dengan data CFD.
  2. Pola sirkulasi utama dan vorteks sekunder yang karakteristik untuk kasus lid-driven cavity berhasil direproduksi.
  3. Distribusi kecepatan horizontal (u) menunjukkan nilai maksimum di dekat dinding atas yang bergerak dan nilai negatif di bagian tengah-bawah cavity, konsisten dengan ekspektasi teoritis.
  4. Distribusi kecepatan vertikal (v) menunjukkan pola yang sesuai dengan sirkulasi aliran dalam cavity tertutup.
  5. Gradien tekanan terbentuk sebagai respons terhadap gerakan dinding dan geometri tertutup.

Kesimpulan

Pendekatan hybrid CFD-AI yang dikembangkan dalam proyek ini menunjukkan potensi yang menjanjikan dalam memodelkan aliran fluida kompleks. Beberapa poin utama dari proyek ini:

  1. Integrasi Metode Numerik dan AI: Pendekatan ini berhasil menggabungkan kekuatan simulasi CFD tradisional dengan kemampuan pembelajaran mesin dari PINN.
  2. Efisiensi Komputasional: Setelah dilatih, model PINN dapat memprediksi karakteristik aliran tanpa perlu menyelesaikan persamaan Navier-Stokes secara eksplisit, yang berpotensi meningkatkan efisiensi untuk analisis aliran fluida.
  3. Batasan Implementasi: Implementasi kode saat ini masih memiliki beberapa keterbatasan, termasuk inkonsistensi dalam fungsi pelatihan dan penyederhanaan fungsi loss yang kurang merepresentasikan physics-informed loss yang ideal.
  4. Validasi Visual: Visualisasi hasil menjadi metode utama validasi kualitas prediksi model, memungkinkan evaluasi kualitatif terhadap kemampuan model dalam merepresentasikan karakteristik aliran.
  5. Potensi Pengembangan: Model ini dapat dikembangkan lebih lanjut dengan:
    • Meningkatkan kompleksitas arsitektur neural network
    • Mengoptimalkan hyperparameter pelatihan
    • Menerapkan strategi sampling yang lebih efisien
    • Mengimplementasikan formulasi physics loss yang lebih komprehensif

Secara keseluruhan, proyek ini membuktikan bahwa PINN dapat menjadi alternatif atau pendekatan komplementer yang berharga untuk simulasi CFD tradisional, meskipun masih memerlukan pengembangan dan validasi lebih lanjut untuk aplikasi praktis yang lebih kompleks.


DATA INPUT

Da


  • 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


Leave a Reply

Your email address will not be published. Required fields are marked *