import sys import os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import math import config def test_x_src_within_domain(): assert 0.0 <= config.X_SRC <= config.L def test_t_step_before_t_end(): assert 0.0 < config.T_STEP < config.T_END def test_gauss_sigma_positive(): assert config.GAUSS_SIGMA > 0.0 def test_physics_positive(): assert config.ALPHA > 0.0 assert config.K > 0.0 assert config.H_CONV > 0.0 assert config.L > 0.0 assert config.T_END > 0.0 def test_training_hyperparameters_positive(): assert config.PATIENCE > 0 assert config.EPOCHS > 0 assert config.LR_ADAM > 0.0 assert config.SCHED_MIN_LR > 0.0 assert config.SCHED_FACTOR > 0.0 assert config.SCHED_PATIENCE > 0 def test_lr_ordering(): """Min LR deve essere inferiore all'LR iniziale.""" assert config.SCHED_MIN_LR < config.LR_ADAM def test_sched_patience_lt_patience(): """Lo scheduler deve poter agire prima che scatti l'early stopping.""" assert config.SCHED_PATIENCE < config.PATIENCE def test_cfl_stability(): """La griglia FDM deve soddisfare la condizione CFL (r ≤ 0.5).""" dx = config.L / (config.NX - 1) dt = config.T_END / (config.NT - 1) r = config.ALPHA * dt / dx ** 2 assert r <= 0.5, f"CFL violata: r={r:.4f} > 0.5" def test_grid_dimensions(): assert config.NX >= 2 assert config.NT >= 2 assert config.N_F >= 1 assert config.N_IC >= 1 assert config.N_BC >= 1 def test_pde_scale_covers_source_peak(): """_pde_scale in model.py deve coprire il picco gaussiano della sorgente.""" from model import _pde_scale src_peak = config.ALPHA * config.Q_VAL / ( config.K * config.GAUSS_SIGMA * math.sqrt(2 * math.pi) ) assert _pde_scale >= src_peak ** 2 - 1e-6, ( f"_pde_scale={_pde_scale:.1f} < src_peak²={src_peak**2:.1f}: " "la loss PDE non è normalizzata correttamente" )