FPINNs / scripts /data_utils.py
OneScience's picture
Upload folder using huggingface_hub
371b59f verified
Raw
History Blame Contribute Delete
2.67 kB
from __future__ import annotations
from collections.abc import Mapping
from pathlib import Path
import numpy as np
import scipy.io
import torch
def load_allen_cahn(path: Path) -> dict[str, np.ndarray | tuple[int, int]]:
if not path.is_file():
raise FileNotFoundError(f"Allen-Cahn data not found: {path}")
data = scipy.io.loadmat(path)
missing = {"tt", "x", "uu"}.difference(data)
if missing:
raise ValueError(f"Allen-Cahn data is missing fields: {sorted(missing)}")
time_axis = np.asarray(data["tt"], dtype=np.float64).reshape(-1)
space_axis = np.asarray(data["x"], dtype=np.float64).reshape(-1)
raw_solution = np.real(np.asarray(data["uu"]))
expected_shape = (space_axis.size, time_axis.size)
if raw_solution.shape != expected_shape:
raise ValueError(
f"uu shape must be {expected_shape} in [x,t] order, got {raw_solution.shape}"
)
exact_grid = raw_solution.T
mesh_x, mesh_t = np.meshgrid(space_axis, time_axis, indexing="xy")
coordinates = np.column_stack((mesh_x.ravel(), mesh_t.ravel()))
exact = exact_grid.reshape(-1, 1)
return {
"time": time_axis,
"space": space_axis,
"coordinates": coordinates,
"exact": exact,
"grid_shape": exact_grid.shape,
}
def sample_training_data(
dataset: Mapping,
n_train: int,
seed: int,
device: torch.device,
dtype: torch.dtype,
) -> tuple[torch.Tensor, torch.Tensor]:
coordinates = np.asarray(dataset["coordinates"])
exact = np.asarray(dataset["exact"])
if n_train <= 0 or n_train > coordinates.shape[0]:
raise ValueError(
f"n_train must be between 1 and {coordinates.shape[0]}, got {n_train}"
)
generator = np.random.default_rng(seed)
indices = generator.choice(coordinates.shape[0], n_train, replace=False)
return (
torch.as_tensor(coordinates[indices], dtype=dtype, device=device),
torch.as_tensor(exact[indices], dtype=dtype, device=device),
)
def batched_predict(
model: torch.nn.Module,
coordinates: np.ndarray,
batch_size: int,
device: torch.device,
dtype: torch.dtype,
) -> np.ndarray:
if batch_size <= 0:
raise ValueError("evaluation batch size must be positive")
predictions = []
model.eval()
with torch.no_grad():
for start in range(0, coordinates.shape[0], batch_size):
batch = torch.as_tensor(
coordinates[start : start + batch_size], dtype=dtype, device=device
)
predictions.append(model.predict_u(batch).cpu().numpy())
return np.concatenate(predictions, axis=0)