ElBalor's picture
Upload folder using huggingface_hub
3e5dd83 verified
Raw History Blame Contribute Delete
2.84 kB
"""
AlienX (ISN) - 2D Release v2: GPU Darcy Flow Data Generator
============================================================
Pull-back rotation: fields are evaluated in reference coordinates, then the
gradients are pushed forward with the rotation matrix. The domain always
stays within [-1, 1]^2 - no diamond stretching at 45 degrees.
Analytical gradients (no finite differences) - the fix for the numerical
gradient artifacts that produced the 45-degree residual in v1.
Eric Yaka (Elbalor / The Digital Necromancer)
"""
import math
import torch
def generate_darcy_sample_gpu(resolution, device, angle_deg=0.0, seed=None):
"""
Generate a Darcy flow sample on the GPU with pull-back rotation.
Args:
resolution: grid size (nx = ny)
device: torch device
angle_deg: rotation angle of the permeability field, degrees
seed: optional RNG seed for reproducibility
Returns:
coords: [N, 2] grid coordinates in [-1, 1]^2
k: [N] permeability field
grad_k_mag: [N] magnitude of grad k (pushed forward)
grad_k_vec: [N, 2] gradient vector of k (pushed forward)
p: [N] pressure field (ground truth)
"""
if seed is not None:
torch.manual_seed(seed)
nx = ny = resolution
x = torch.linspace(-1, 1, nx, device=device)
y = torch.linspace(-1, 1, ny, device=device)
X, Y = torch.meshgrid(x, y, indexing='ij')
coords = torch.stack([X.flatten(), Y.flatten()], dim=-1)
theta = angle_deg * math.pi / 180.0
R_inv = torch.tensor([[math.cos(-theta), -math.sin(-theta)],
[math.sin(-theta), math.cos(-theta)]], device=device)
coords_ref = coords @ R_inv.T
X_r = coords_ref[:, 0].reshape(nx, ny)
Y_r = coords_ref[:, 1].reshape(nx, ny)
k = 1.0 + 0.3 * torch.sin(2*math.pi*X_r + 1.0) * torch.cos(3*math.pi*Y_r - 0.5)
k += 0.2 * torch.sin(4*math.pi*X_r*Y_r)
k = torch.clamp(k, 0.5, 2.0)
p = torch.sin(2*math.pi*X_r) * torch.cos(2*math.pi*Y_r) + \
0.5*torch.sin(5*math.pi*X_r + 1.3)*torch.cos(4*math.pi*Y_r - 0.7)
dk_dX = (0.3 * (2*math.pi) * torch.cos(2*math.pi*X_r + 1.0) * torch.cos(3*math.pi*Y_r - 0.5) +
0.2 * (4*math.pi*Y_r) * torch.cos(4*math.pi*X_r*Y_r))
dk_dY = (-0.3 * (3*math.pi) * torch.sin(2*math.pi*X_r + 1.0) * torch.sin(3*math.pi*Y_r - 0.5) +
0.2 * (4*math.pi*X_r) * torch.cos(4*math.pi*X_r*Y_r))
grad_ref = torch.stack([dk_dX.flatten(), dk_dY.flatten()], dim=-1)
R = torch.tensor([[math.cos(theta), -math.sin(theta)],
[math.sin(theta), math.cos(theta)]], device=device)
grad_k_vec = grad_ref @ R.T
grad_k_mag = torch.sqrt((grad_k_vec**2).sum(-1)).flatten()
return coords, k.flatten(), grad_k_mag, grad_k_vec, p.flatten()