PINN / Variant_5 BaseFlow /dataset.py
inaniloquentee's picture
Upload folder using huggingface_hub
7fa74f9 verified
Raw
History Blame Contribute Delete
5.25 kB
import torch
import numpy as np
from torch.utils.data import Dataset
from scipy.interpolate import griddata
from scipy.linalg import qr
class CFDReconstructionDataset(Dataset):
def __init__(self, unsteady_path, mean_path, sensor_count=65, target_grid=(128, 256), dt=0.01):
super().__init__()
print("[Dataset] Initializing v3.0 (Sparse Mode: 5 returns)...")
self.sensor_count = sensor_count
self.H, self.W = target_grid
self.dt = dt
try:
raw_unsteady = np.load(unsteady_path).astype(np.float32)
raw_mean = np.load(mean_path).astype(np.float32)
except Exception as e:
print(f"Error loading data: {e}")
raise
mean_cols = raw_mean.shape[1] if raw_mean.ndim > 1 else 1
coords_mean = raw_mean[:, :2]
x_min, y_min = coords_mean.min(axis=0)
x_max, y_max = coords_mean.max(axis=0)
self.box_len = [x_max - x_min, y_max - y_min, 1.0]
grid_x = np.linspace(x_min, x_max, self.W)
grid_y = np.linspace(y_min, y_max, self.H)
self.grid_X, self.grid_Y = np.meshgrid(grid_x, grid_y)
self.grid_coords = torch.stack([torch.tensor(self.grid_X), torch.tensor(self.grid_Y)], dim=-1).float()
self.grid_coords_norm = self.grid_coords.clone()
self.grid_coords_norm[..., 0] = 2 * (self.grid_coords[..., 0] - x_min) / (x_max - x_min) - 1
self.grid_coords_norm[..., 1] = 2 * (self.grid_coords[..., 1] - y_min) / (y_max - y_min) - 1
if mean_cols >= 6: mean_vals = raw_mean[:, 3:6]
elif mean_cols == 5: mean_vals = raw_mean[:, 2:5]
else: mean_vals = raw_mean[:, -3:]
self.mean_data = griddata(coords_mean, mean_vals, (self.grid_X, self.grid_Y), method='linear', fill_value=0)
self.mean_data = torch.from_numpy(self.mean_data).permute(2, 0, 1).float()
unsteady_cols = raw_unsteady.shape[-1] if raw_unsteady.ndim > 1 else raw_mean.shape[-1]
points_per_frame = raw_mean.shape[0]
total_elements = raw_unsteady.size
frame_size = points_per_frame * unsteady_cols
num_frames = total_elements // frame_size
raw_unsteady = raw_unsteady.flatten()[:num_frames * frame_size]
raw_unsteady = raw_unsteady.reshape(num_frames, points_per_frame, unsteady_cols)
process_frames = min(num_frames, 200)
data_list = []
for i in range(process_frames):
frame_data = raw_unsteady[i]
if unsteady_cols >= 6: values = frame_data[:, 3:6]
elif unsteady_cols == 5: values = frame_data[:, 2:5]
else: values = frame_data[:, :3]
coords = frame_data[:, :2] if unsteady_cols >= 5 else coords_mean
grid_val = griddata(coords, values, (self.grid_X, self.grid_Y), method='linear', fill_value=0)
data_list.append(grid_val)
self.data = np.stack(data_list, axis=0)
self.data = torch.from_numpy(self.data).permute(0, 3, 1, 2).float()
self.stats = {}
self.max_vals = torch.amax(self.data, dim=(0, 2, 3), keepdim=True)
self.min_vals = torch.amin(self.data, dim=(0, 2, 3), keepdim=True)
self.stats['max'] = self.max_vals
self.stats['min'] = self.min_vals
self.stats['dt'] = self.dt
self.stats['box_len'] = self.box_len
denom = self.max_vals - self.min_vals
denom[denom < 1e-8] = 1.0
self.data = 2 * (self.data - self.min_vals) / denom - 1
self.mean_data = 2 * (self.mean_data - self.min_vals.squeeze(0)) / denom.squeeze(0) - 1
print(f"[Dataset] Selecting {sensor_count} sensors (QR Pivot)...")
self.sensor_indices = self.compute_qr_sensors(self.data, self.mean_data, sensor_count)
def compute_qr_sensors(self, data, mean, num_sensors):
T, C, H, W = data.shape
fluctuations = (data[:, 0, :, :] - mean[0, :, :]).reshape(T, -1).numpy().T
k = min(T, num_sensors + 10)
U, _, _ = np.linalg.svd(fluctuations, full_matrices=False)
Psi = U[:, :k]
_, _, P = qr(Psi.T, pivoting=True)
best_indices_flat = P[:num_sensors]
sensor_locs = []
for idx in best_indices_flat:
y = idx // W
x = idx % W
sensor_locs.append((y, x))
return sensor_locs
def denormalize(self, tensor):
return (tensor + 1) / 2 * (self.stats['max'].to(tensor.device) - self.stats['min'].to(tensor.device)) + self.stats['min'].to(tensor.device)
def __len__(self):
return max(0, self.data.shape[0] - 1)
def __getitem__(self, idx):
if idx >= self.data.shape[0] - 1: idx = self.data.shape[0] - 2
target_t = self.data[idx]
target_next = self.data[idx + 1]
vals_t, coords_t = [], []
for y, x in self.sensor_indices:
vals_t.append(target_t[:, y, x])
coords_t.append(self.grid_coords_norm[y, x])
vals_next = []
for y, x in self.sensor_indices:
vals_next.append(target_next[:, y, x])
return (torch.stack(vals_t), torch.stack(coords_t), self.grid_coords_norm,
torch.stack(vals_next), self.mean_data)