diff --git a/coverage-report.pdf b/coverage-report.pdf new file mode 100644 index 0000000..9ddde60 Binary files /dev/null and b/coverage-report.pdf differ diff --git a/diffusion2d.py b/diffusion2d.py index 51a07f2..64c332d 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -38,6 +38,10 @@ def __init__(self): self.dt = None def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): + assert type(w) == float + assert type(h) == float + assert type(dx) == float + assert type(dy) == float self.w = w self.h = h self.dx = dx @@ -45,7 +49,10 @@ def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): self.nx = int(w / dx) self.ny = int(h / dy) - def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): + def initialize_physical_parameters(self, d=4., T_cold=300.0, T_hot=700.0): + assert type(d) == float + assert type(T_cold) == float + assert type(T_hot) == float self.D = d self.T_cold = T_cold self.T_hot = T_hot diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7552c4e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +numpy +pytest +matplotlib \ No newline at end of file diff --git a/tests/integration/test_diffusion2d.py b/tests/integration/test_diffusion2d.py index fd026b4..62fea93 100644 --- a/tests/integration/test_diffusion2d.py +++ b/tests/integration/test_diffusion2d.py @@ -3,17 +3,76 @@ """ from diffusion2d import SolveDiffusion2D +import pytest +import numpy as np -def test_initialize_physical_parameters(): +@pytest.fixture +def solver(): + return SolveDiffusion2D() + + +def test_initialize_physical_parameters(solver): """ Checks function SolveDiffusion2D.initialize_domain """ - solver = SolveDiffusion2D() + solver.initialize_domain(w=2.0, h=4.0, dx=0.1, dy=0.1) + + assert solver.nx == 20 + assert solver.ny == 40 + assert solver.dx == 0.1 + assert solver.dy == 0.1 + assert solver.w == 2.0 + assert solver.h == 4.0 + + solver.initialize_physical_parameters(d=4.0, T_cold=300.0, T_hot=700.0) + assert solver.D == 4.0 + assert solver.T_cold == 300.0 + assert solver.T_hot == 700.0 -def test_set_initial_condition(): + expected_dt = 0.000625 + + assert pytest.approx(solver.dt) == expected_dt + + +def test_set_initial_condition(solver): """ Checks function SolveDiffusion2D.get_initial_function """ - solver = SolveDiffusion2D() + solver.initialize_domain(w=10.0, h=10.0, dx=0.1, dy=0.1) + + assert solver.dx == 0.1 + assert solver.dy == 0.1 + assert solver.w == 10.0 + assert solver.h == 10.0 + + solver.initialize_physical_parameters(d=4.0, T_cold=300.0, T_hot=700.0) + + assert solver.D == 4.0 + assert solver.T_cold == 300.0 + assert solver.T_hot == 700.0 + + expected_dt = 0.000625 + + assert pytest.approx(solver.dt) == expected_dt + + u = solver.T_cold * np.ones((solver.nx, solver.ny)) + + # Initial conditions - circle of radius r centred at (cx,cy) (mm) + r, cx, cy = 2, 5, 5 + r2 = r ** 2 + for i in range(solver.nx): + for j in range(solver.ny): + p2 = (i * solver.dx - cx) ** 2 + (j * solver.dy - cy) ** 2 + if p2 < r2: + u[i, j] = solver.T_hot + + solver_u = solver.set_initial_condition() + + assert np.allclose(solver_u, u) + assert solver_u.shape == (100, 100) + assert solver_u[0, 0] == 300.0 + assert solver_u[50, 50] == 700.0 + assert np.all((solver_u == 300.0) | (solver_u == 700.0)) + assert np.all(solver_u >= 300.0) and np.all(solver_u <= 700.0) diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index c4277ff..5863374 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -3,24 +3,65 @@ """ from diffusion2d import SolveDiffusion2D +import numpy as np +import pytest -def test_initialize_domain(): - """ - Check function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() +@pytest.fixture +def solver(): + """Fixture to provide a fresh instance of the solver for each test.""" + return SolveDiffusion2D() -def test_initialize_physical_parameters(): - """ - Checks function SolveDiffusion2D.initialize_domain - """ - solver = SolveDiffusion2D() +def test_initialize_domain(solver): + """initialize_domain sets attributes and computes nx/ny correctly.""" + solver.initialize_domain(w=2.0, h=4.0, dx=0.1, dy=0.1) + + assert solver.nx == 20 + assert solver.ny == 40 + assert solver.dx == 0.1 + assert solver.dy == 0.1 + assert solver.w == 2.0 + assert solver.h == 4.0 + + +def test_initialize_physical_parameters(solver): + """initialize_physical_parameters stores values and computes stable dt.""" + # Manually setting dependencies to avoid calling initialize_domain + solver.dx = 0.1 + solver.dy = 0.1 + + solver.initialize_physical_parameters(d=4.0, T_cold=300.0, T_hot=700.0) + + expected_dt = 0.000625 + assert solver.D == 4.0 + assert solver.T_cold == 300.0 + assert solver.T_hot == 700.0 + + assert pytest.approx(solver.dt) == expected_dt -def test_set_initial_condition(): +def test_set_initial_condition(solver): """ - Checks function SolveDiffusion2D.get_initial_function + Checks function SolveDiffusion2D.set_initial_function """ - solver = SolveDiffusion2D() + solver.nx = 100 + solver.ny = 100 + solver.dx = 0.1 + solver.dy = 0.1 + solver.T_cold = 300.0 + solver.T_hot = 700.0 + + u = solver.set_initial_condition() + + # Check shape + assert u.shape == (100, 100) + + # Check a corner (should be cold) + assert u[0, 0] == 300.0 + + # Check the center (5, 5) -> index (50, 50) (should be hot) + assert u[50, 50] == 700.0 + + # Check that we actually have both temperatures present + assert np.all((u == 300.0) | (u == 700.0)) diff --git a/tox.toml b/tox.toml new file mode 100644 index 0000000..a11b98c --- /dev/null +++ b/tox.toml @@ -0,0 +1,7 @@ +requires = ["tox>=4"] +env_list = ["pytest_testing"] + +[env.pytest_testing] +description = "Run pytest" +deps = ["-r requirements.txt"] +commands = [["python","-m","pytest"]]