PDENNEval / scripts /common.py
OneScience's picture
Upload folder using huggingface_hub
ede74c0 verified
Raw
History Blame Contribute Delete
2.96 kB
from __future__ import annotations
import json
import random
import sys
from pathlib import Path
from typing import Any
import numpy as np
import torch
import yaml
PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
def load_config(config_path: str | Path | None = None) -> dict[str, Any]:
path = Path(config_path) if config_path else PROJECT_ROOT / "conf" / "config.yaml"
if not path.is_absolute():
path = PROJECT_ROOT / path
with path.open("r", encoding="utf-8") as f:
return yaml.safe_load(f)
def project_path(path: str | Path) -> Path:
path = Path(path)
return path if path.is_absolute() else PROJECT_ROOT / path
def seed_everything(seed: int) -> None:
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed_all(seed)
def select_device(value: str = "auto") -> torch.device:
if value == "auto":
return torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
return torch.device(value)
def ensure_parent(path: Path) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
def ensure_runtime_dirs(cfg: dict[str, Any]) -> None:
for key in ("fake_data", "prediction", "metrics", "loss", "figure"):
ensure_parent(project_path(cfg["paths"][key]))
ensure_parent(project_path(cfg["training"]["checkpoint"]))
def build_model(cfg: dict[str, Any]) -> torch.nn.Module:
from model import PINNsformer1D
model_cfg = cfg["model"]
return PINNsformer1D(
d_out=int(model_cfg["d_out"]),
d_hidden=int(model_cfg["d_hidden"]),
d_model=int(model_cfg["d_model"]),
N=int(model_cfg["num_layers"]),
heads=int(model_cfg["heads"]),
)
def initial_condition(x: np.ndarray | torch.Tensor, cfg: dict[str, Any]):
initial = cfg["equation"]["initial"]
center = initial["center"]
sigma = initial["sigma"]
if isinstance(x, torch.Tensor):
return torch.exp(-((x - center) ** 2) / (2 * sigma**2))
return np.exp(-((x - center) ** 2) / (2 * sigma**2))
def exact_reaction_solution(
x: np.ndarray | torch.Tensor,
t: np.ndarray | torch.Tensor,
cfg: dict[str, Any],
):
h = initial_condition(x, cfg)
rate = cfg["equation"]["reaction_rate"]
if isinstance(h, torch.Tensor):
exp_term = torch.exp(rate * t)
else:
exp_term = np.exp(rate * t)
return h * exp_term / (h * exp_term + 1 - h)
def relative_errors(pred: np.ndarray, target: np.ndarray) -> dict[str, float]:
return {
"relative_l1": float(np.sum(np.abs(target - pred)) / np.sum(np.abs(target))),
"relative_l2": float(np.sqrt(np.sum((target - pred) ** 2) / np.sum(target**2))),
}
def write_json(path: Path, payload: dict[str, Any]) -> None:
ensure_parent(path)
path.write_text(json.dumps(payload, indent=2), encoding="utf-8")