ccitonline.com

CCIT – Cara Cerdas Ingat Tuhan

| AIDAI5 | DAI5 eBook Free Download | CFDSOF | VisualFOAM | PT CCIT Group Indonesia | 8N8 |

PINN : 1 D Steady Heat Conduction

A Physics-Informed Neural Network (PINN) implemented in Python using PyTorch to solve a 1D steady-state heat conduction problem. I’ll also include a simple GUI using tkinter to input parameters and display the results.

Algorithm for PINN 1D Steady Heat Conduction

  1. Initialization:
    • Define a neural network NN(x;ฮธ) with input x and trainable parameters ฮธ
    • Set boundary conditions: T(x=0) = T0 โ€‹, T(x=1)=T1โ€‹.
    • Choose hyperparameters: learning rate (e.g., 0.001), number of epochs (e.g., 1000), number of collocation points (e.g., 100).
  2. Discretize Domain:
    • Generate N collocation points xi in the domain [0,1] [0, 1] [0,1] (e.g., using torch.linspace).
  3. Training Loop (for each epoch):
    • Step 3.1: Forward pass
      • Compute predicted temperature T(xi)=NN(xi;ฮธ) for all xi
    • Step 3.2: Compute derivatives
      • Calculate dTdxโ€‹ using automatic differentiation.
      • Calculate d2Tdx2โ€‹ by differentiating dTdxโ€‹.

import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import ttk

Define the PINN neural network

class PINN(nn.Module):
def init(self):
super(PINN, self).init()
self.net = nn.Sequential(
nn.Linear(1, 20),
nn.Tanh(),
nn.Linear(20, 20),
nn.Tanh(),
nn.Linear(20, 1)
)

def forward(self, x):
    return self.net(x)

Function to compute the loss

def compute_loss(model, x, T0, T1):
x = x.requires_grad_(True)
T = model(x)

# Compute derivatives
dT_dx = torch.autograd.grad(T, x, grad_outputs=torch.ones_like(T), create_graph=True)[0]
d2T_dx2 = torch.autograd.grad(dT_dx, x, grad_outputs=torch.ones_like(dT_dx), create_graph=True)[0]

# Physics loss (d^2T/dx^2 = 0)
physics_loss = torch.mean(d2T_dx2**2)

# Boundary conditions
T_left = model(torch.tensor([[0.0]]))
T_right = model(torch.tensor([[1.0]]))
bc_loss = (T_left - T0)**2 + (T_right - T1)**2

return physics_loss + bc_loss

Training function

def train_pinn(T0, T1, epochs=1000):
model = PINN()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
x = torch.linspace(0, 1, 100).reshape(-1, 1)

for epoch in range(epochs):
    optimizer.zero_grad()
    loss = compute_loss(model, x, T0, T1)
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f"Epoch {epoch}, Loss: {loss.item():.6f}")

return model

Function to plot results

def plot_results(model, T0, T1):
x = torch.linspace(0, 1, 100).reshape(-1, 1)
with torch.no_grad():
T_pred = model(x).numpy()
x = x.numpy()
T_analytical = T0 + (T1 – T0) * x

plt.figure(figsize=(8, 6))
plt.plot(x, T_pred, label="PINN Solution")
plt.plot(x, T_analytical, '--', label="Analytical Solution")
plt.xlabel("x")
plt.ylabel("Temperature")
plt.title("1D Steady-State Heat Conduction")
plt.legend()
plt.grid(True)
plt.show()

GUI Application

class PINNApp:
def init(self, root):
self.root = root
self.root.title(“PINN 1D Heat Conduction Solver”)

    # Labels and Entries
    ttk.Label(root, text="T0 (Left Boundary, ยฐC):").grid(row=0, column=0, padx=5, pady=5)
    self.T0_entry = ttk.Entry(root)
    self.T0_entry.grid(row=0, column=1, padx=5, pady=5)
    self.T0_entry.insert(0, "100")

    ttk.Label(root, text="T1 (Right Boundary, ยฐC):").grid(row=1, column=0, padx=5, pady=5)
    self.T1_entry = ttk.Entry(root)
    self.T1_entry.grid(row=1, column=1, padx=5, pady=5)
    self.T1_entry.insert(0, "0")

    ttk.Label(root, text="Epochs:").grid(row=2, column=0, padx=5, pady=5)
    self.epochs_entry = ttk.Entry(root)
    self.epochs_entry.grid(row=2, column=1, padx=5, pady=5)
    self.epochs_entry.insert(0, "1000")

    # Solve Button
    self.solve_button = ttk.Button(root, text="Solve & Plot", command=self.solve)
    self.solve_button.grid(row=3, column=0, columnspan=2, pady=10)

def solve(self):
    try:
        T0 = float(self.T0_entry.get())
        T1 = float(self.T1_entry.get())
        epochs = int(self.epochs_entry.get())

        model = train_pinn(T0, T1, epochs)
        plot_results(model, T0, T1)
    except ValueError:
        tk.messagebox.showerror("Error", "Please enter valid numerical values.")

Run the GUI

if name == “main“:
root = tk.Tk()
app = PINNApp(root)
root.mainloop()