From 378a3b16760adaeabea30c1e648b272056d2494e Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Wed, 13 May 2026 22:01:48 +0200 Subject: [PATCH] aggiunta suite di test fisici per fdm/solver.py Co-Authored-By: Claude Sonnet 4.6 --- tests/__init__.py | 0 tests/test_fdm_solver.py | 70 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/test_fdm_solver.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_fdm_solver.py b/tests/test_fdm_solver.py new file mode 100644 index 0000000..a8a0cbf --- /dev/null +++ b/tests/test_fdm_solver.py @@ -0,0 +1,70 @@ +import numpy as np +import pytest +import sys, os +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +import config + + +def run_solver_with(x_src): + """Run solver with a temporary X_SRC override.""" + original = config.X_SRC + config.X_SRC = x_src + try: + from fdm import solver + import importlib + importlib.reload(solver) + return solver.solve() + finally: + config.X_SRC = original + + +def test_shape(): + """Output deve avere forma (NX, NT).""" + T, x, t = run_solver_with(0.0) + assert T.shape == (config.NX, config.NT) + assert len(x) == config.NX + assert len(t) == config.NT + + +def test_initial_condition(): + """La prima colonna deve essere uniforme a T0.""" + T, x, t = run_solver_with(0.0) + np.testing.assert_allclose(T[:, 0], config.T0) + + +def test_temperature_increases_near_source_center(): + """Con x_src=0.5 e a fine simulazione, il nodo centrale + deve essere più caldo di quello iniziale.""" + T, x, t = run_solver_with(0.5) + i_src = int(np.argmin(np.abs(x - 0.5))) + assert T[i_src, -1] > config.T0 + + +def test_temperature_increases_near_source_left(): + """Con x_src=0.0 il nodo sinistro deve scaldarsi.""" + T, x, t = run_solver_with(0.0) + assert T[0, -1] > config.T0 + + +def test_temperature_increases_near_source_right(): + """Con x_src=L il nodo destro deve scaldarsi.""" + T, x, t = run_solver_with(config.L) + assert T[-1, -1] > config.T0 + + +def test_x_src_position_affects_profile(): + """Spostandosi la sorgente da 0.1 a 0.9, il massimo del profilo + finale deve spostarsi verso destra.""" + T_left, x, _ = run_solver_with(0.1) + T_right, _, _ = run_solver_with(0.9) + x_max_left = x[np.argmax(T_left[:, -1])] + x_max_right = x[np.argmax(T_right[:, -1])] + assert x_max_right > x_max_left + + +def test_no_nan_or_inf(): + """La soluzione non deve contenere NaN o Inf.""" + for x_src in [0.0, 0.25, 0.5, 0.75, 1.0]: + T, _, _ = run_solver_with(x_src) + assert np.all(np.isfinite(T)), f"NaN/Inf con x_src={x_src}"