BENO / scripts /fake_data.py
OneScience's picture
Upload folder using huggingface_hub
7087ec2 verified
Raw
History Blame Contribute Delete
4.21 kB
import math
import os
import sys
from pathlib import Path
import numpy as np
PROJECT_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(PROJECT_ROOT))
from onescience.utils.YParams import YParams
def set_default_data_env():
os.environ.setdefault("ONESCIENCE_BENO_DATA_DIR", str(PROJECT_ROOT / "data"))
def resolve_path(path_value):
path = Path(path_value)
return path if path.is_absolute() else PROJECT_ROOT / path
def load_config():
set_default_data_env()
cfg = YParams(str(PROJECT_ROOT / "conf" / "config.yaml"), "root")
cfg.datapipe.source.data_dir = str(resolve_path(cfg.datapipe.source.data_dir))
cfg.datapipe.source.cache_dir = str(resolve_path(cfg.datapipe.source.cache_dir))
cfg.fake_data.root_dir = str(resolve_path(cfg.fake_data.root_dir))
return cfg
def square_boundary(points, boundary_points):
bottom = [(x, 0.0) for x in points]
top = [(x, 1.0) for x in points]
left = [(0.0, y) for y in points[1:-1]]
right = [(1.0, y) for y in points[1:-1]]
boundary = np.array(bottom + top + left + right, dtype=np.float64)
if boundary.shape[0] == 0:
raise ValueError("resolution is too small to build boundary points")
repeats = int(math.ceil(boundary_points / boundary.shape[0]))
return np.tile(boundary, (repeats, 1))[:boundary_points]
def make_beno_arrays(cfg):
data_cfg = cfg.datapipe.data
fake_cfg = cfg.fake_data
total_samples = int(data_cfg.ntrain) + int(data_cfg.ntest)
resolution = int(data_cfg.resolution)
boundary_points = int(fake_cfg.boundary_points)
rng = np.random.default_rng(int(fake_cfg.seed))
axis = np.linspace(0.0, 1.0, resolution, dtype=np.float64)
yy, xx = np.meshgrid(axis, axis, indexing="ij")
coords = np.stack([xx.reshape(-1), yy.reshape(-1)], axis=-1)
cell_state = np.zeros((resolution, resolution), dtype=np.float64)
cell_state[0, :] = 1.0
cell_state[-1, :] = 1.0
cell_state[:, 0] = 1.0
cell_state[:, -1] = 1.0
cell_state = cell_state.reshape(-1)
boundary_xy = square_boundary(axis, boundary_points)
rhs = np.zeros((total_samples, resolution * resolution, 4), dtype=np.float64)
sol = np.zeros((total_samples, resolution * resolution, 1), dtype=np.float64)
bc = np.zeros((total_samples, boundary_points, 4), dtype=np.float64)
for sample_idx in range(total_samples):
phase = 0.25 * sample_idx
amplitude = 1.0 + 0.1 * sample_idx
forcing = (
amplitude * np.sin(np.pi * xx + phase) * np.sin(np.pi * yy)
+ 0.15 * np.cos(2.0 * np.pi * xx) * np.sin(np.pi * yy + phase)
)
solution = 0.25 * forcing + 0.05 * (xx + yy)
if fake_cfg.noise_std:
solution += float(fake_cfg.noise_std) * rng.standard_normal(solution.shape)
boundary_value = (
0.05 * sample_idx
+ 0.1 * boundary_xy[:, 0]
- 0.08 * boundary_xy[:, 1]
)
rhs[sample_idx, :, 0:2] = coords
rhs[sample_idx, :, 2] = forcing.reshape(-1)
rhs[sample_idx, :, 3] = cell_state
sol[sample_idx, :, 0] = solution.reshape(-1)
bc[sample_idx, :, 0:2] = boundary_xy
bc[sample_idx, :, 2] = boundary_value
return rhs, sol, bc
def clear_matching_cache(cfg):
cache_dir = Path(cfg.datapipe.source.cache_dir)
prefix = cfg.datapipe.source.file_prefix
for split, count in (("train", cfg.datapipe.data.ntrain), ("test", cfg.datapipe.data.ntest)):
cache_file = cache_dir / f"cached_{prefix}_{split}_{count}.pt"
if cache_file.exists():
cache_file.unlink()
def main():
cfg = load_config()
data_dir = Path(cfg.datapipe.source.data_dir)
data_dir.mkdir(parents=True, exist_ok=True)
rhs, sol, bc = make_beno_arrays(cfg)
prefix = cfg.datapipe.source.file_prefix
np.save(data_dir / f"RHS_{prefix}_all.npy", rhs)
np.save(data_dir / f"SOL_{prefix}_all.npy", sol)
np.save(data_dir / f"BC_{prefix}_all.npy", bc)
clear_matching_cache(cfg)
print(f"Fake BENO data written to {data_dir}")
print(f"RHS shape={rhs.shape}, SOL shape={sol.shape}, BC shape={bc.shape}")
if __name__ == "__main__":
main()