Testes: test_edos
Testes para o módulo codigos.edos.
Cobre solver Runge-Kutta (ordens 1-4) para EDOs escalares e sistemas, bem como validações de entradas e tratamento de passos/resíduos.
Conteúdo dos testes:
1"""Testes para o módulo `codigos.edos`.
2
3Cobre solver Runge-Kutta (ordens 1-4) para EDOs escalares e sistemas, bem
4como validações de entradas e tratamento de passos/resíduos."""
5
6import numpy as np
7import pytest
8import math
9from codigos import edos
10
11def test_runge_kutta_scalar_exp():
12 """Verifica RK (4ª ordem) para dy/dx = y com y(0)=1; y(1) ≈ e."""
13 x_vals, y_vals = edos.runge_kutta('y', 0.0, 1.0, 0.01, 1.0, 4)
14 approx = y_vals[-1]
15 assert abs(approx - np.exp(1.0)) < 5e-4
16
17
18def test_runge_kutta_system_exp():
19 """Sistema simples: u0' = u0, u1' = 2*u1; verifica solução analítica em t=1."""
20 funcs = ['y[1]', '2*y[2]']
21 t_vals, u_vals = edos.runge_kutta_sistema(funcs, np.array([1.0, 1.0]), 0.0, 1.0, 0.001, 4)
22 u_end = u_vals[-1]
23 assert abs(u_end[0] - np.exp(1.0)) < 1e-4
24 assert abs(u_end[1] - np.exp(2.0)) < 1e-3
25
26
27def test_passos_edo_with_m():
28 """Verifica cálculo de h e xn dado número de subintervalos m."""
29 h, xn = edos.passos_edo(0.0, 1.0, 0.0, m=10)
30 assert pytest.approx(h) == 0.1
31 assert xn == 1.0
32
33
34def test_runge_kutta_orders_accuracy():
35 """Valida precisão aproximada por ordem do método Runge-Kutta."""
36 exact = math.e
37 h = 0.001
38 tol_order = {1:5e-3, 2:1e-4, 3:5e-5, 4:1e-6}
39 for order, tol in tol_order.items():
40 x_vals, y_vals = edos.runge_kutta('y', 0.0, 1.0, h, 1.0, order)
41 approx = y_vals[-1]
42 assert abs(approx - exact) < tol
43
44
45def test_runge_kutta_h_nonpositive_raises():
46 """h <= 0 deve levantar ValueError."""
47 with pytest.raises(ValueError):
48 edos.runge_kutta('y', 0.0, 1.0, 0.0, 1.0, 4)
49
50
51def test_runge_kutta_sistema_last_step():
52 """Garante que o tempo final coincide exatamente com tf quando o último passo é menor que h."""
53 funcs = ['y[1]', 'y[2]']
54 t_vals, u_vals = edos.runge_kutta_sistema(funcs, np.array([1.0,1.0]), 0.0, 1.0, 0.3, 4)
55 assert pytest.approx(t_vals[-1], rel=1e-12) == 1.0
56
57
58def test_runge_kutta_sistema_predator_prey():
59 """Teste qualitativo da simulação de Lotka-Volterra (predador-presa)."""
60 funcs = ['y[1] - y[1]*y[2]', '-y[2] + y[1]*y[2]']
61 t_vals, u_vals = edos.runge_kutta_sistema(funcs, np.array([2.0, 1.0]), 0.0, 0.5, 0.01, 4)
62 # Check that values are positive and reasonable
63 assert all(u > 0 for u in u_vals.flatten())
64 assert u_vals[0][0] == 2.0 # initial
65 assert u_vals[0][1] == 1.0
66
67
68def test_runge_kutta_negative_h_raises():
69 with pytest.raises(ValueError):
70 edos.runge_kutta('y', 0.0, 1.0, -0.1, 1.0, 4)
71
72
73def test_runge_kutta_invalid_order_raises():
74 with pytest.raises(ValueError):
75 edos.runge_kutta('y', 0.0, 1.0, 0.1, 1.0, 0)
Resumo das funções de teste:
test_runge_kutta_scalar_exp: Verifica RK (4ª ordem) para dy/dx = y com y(0)=1; y(1) ≈ e.
test_runge_kutta_system_exp: Sistema simples: u0’ = u0, u1’ = 2*u1; verifica solução analítica em t=1.
test_passos_edo_with_m: Verifica cálculo de h e xn dado número de subintervalos m.
test_runge_kutta_orders_accuracy: Valida precisão aproximada por ordem do método Runge-Kutta.
test_runge_kutta_h_nonpositive_raises: h <= 0 deve levantar ValueError.
test_runge_kutta_sistema_last_step: Garante que o tempo final coincide exatamente com tf quando o último passo é menor que h.
test_runge_kutta_sistema_predator_prey: Teste qualitativo da simulação de Lotka-Volterra (predador-presa).
test_runge_kutta_negative_h_raises: _Sem docstring._
test_runge_kutta_invalid_order_raises: _Sem docstring._