Lista 00 · Modelos, numpy e o passo de Euler¶
Acompanha o capítulo 0.
O primeiro exercício é à mão; os outros usam numpy e o passo de Euler —
próximo = agora + taxa × passo — em física, culinária, saúde e eletrônica.
Como esta lista funciona
Abra o caderno no Colab, escreva a sua solução no lugar do # TODO e rode a
célula de teste logo abaixo. Ela mesma diz o que passou e o que falhou — você
não precisa esperar correção de ninguém.
O código de cada exercício também está aqui embaixo, caso você prefira colar num editor local. Os testes comparam números com tolerância.
Exercícios marcados com ✏️ são à mão, no papel, com 4 casas decimais — como na parte em papel das avaliações.
Exercício 01¶
✏️ À mão. Um paraquedista de \(m = 68{,}1\) kg salta parado. O modelo é \(\dfrac{dv}{dt} = g - \dfrac{c}{m}v^2\), com \(g = 9{,}81\) m/s² e \(c = 0{,}25\) kg/m.
a) Com o passo \(\Delta t = 2\) s, faça três passos de Euler e preencha a tabela (duas casas decimais):
| \(t\) (s) | \(v\) (m/s) | taxa \(g - \frac{c}{m}v^2\) | \(v + \text{taxa}\cdot\Delta t\) |
|---|---|---|---|
| 0 | 0 | ||
| 2 | |||
| 4 |
b) Os valores exatos são \(v(2) = 18{,}73\), \(v(4) = 33{,}11\) e \(v(6) = 42{,}08\) m/s. Euler erra para cima ou para baixo? Explique por quê, pensando na taxa usada em cada passo.
Exercício 02¶
Paraquedismo. A velocidade terminal é aquela em que o arrasto iguala o peso:
\(v_t = \sqrt{\dfrac{gm}{c}}\), com \(g = 9{,}81\) m/s². Escreva v_terminal(m, c).
Com o paraquedas aberto, \(c\) fica cerca de 50 vezes maior. Qual a nova velocidade terminal, em km/h?
import numpy as np
def v_terminal(m, c):
"""Velocidade terminal (m/s) de um corpo de massa m e arrasto c."""
# TODO: g = 9.81 e np.sqrt
pass
# --- testes (não altere) ---
assert abs(v_terminal(68.1, 0.25) - 51.69375204026111) < 1e-9
assert abs(v_terminal(68.1, 12.5) - 7.310600522528912) < 1e-9, "paraquedas aberto"
assert abs(v_terminal(9.81, 1) - 9.81) < 1e-9
print("Exercício 02: todos os testes passaram!")
Exercício 03¶
Escreva passo_euler(valor, taxa, dt), que devolve o próximo valor pelo passo
de Euler: próximo = agora + taxa × passo.
def passo_euler(valor, taxa, dt):
"""Um passo de Euler: o próximo valor."""
# TODO: uma linha só
pass
# --- testes (não altere) ---
assert abs(passo_euler(0, 9.81, 2) - 19.62) < 1e-9
assert abs(passo_euler(90, -2.925, 1) - 87.075) < 1e-9, "taxa negativa: o valor diminui"
assert abs(passo_euler(5, 0, 10) - 5) < 1e-9, "taxa zero: nada muda"
print("Exercício 03: todos os testes passaram!")
Exercício 04¶
Paraquedismo. Escreva velocidade_euler(m, c, dt, t_final), que parte de
\(v = 0\) e aplica o passo de Euler com a taxa \(g - \frac{c}{m}v^2\) até chegar
a t_final. O número de passos é round(t_final / dt).
velocidade_euler(68.1, 0.25, 2, 6) # -> ≈ 46.30 (a tabela do ex01)
velocidade_euler(68.1, 0.25, 0.25, 12) # -> ≈ 50.78
A velocidade exata em \(t = 12\) s é \(50{,}62\) m/s. Qual dt deixa o erro
abaixo de \(0{,}01\) m/s?
def velocidade_euler(m, c, dt, t_final):
"""Velocidade do paraquedista em t_final pelo método de Euler."""
g = 9.81
v = 0.0
# TODO: laço com round(t_final / dt) passos; em cada um, a taxa e o passo
return v
# --- testes (não altere) ---
assert abs(velocidade_euler(68.1, 0.25, 2, 6) - 46.29832087760171) < 1e-6, "três passos, como no ex01"
assert abs(velocidade_euler(68.1, 0.25, 0.25, 12) - 50.775320040750785) < 1e-6
assert abs(velocidade_euler(90, 0.3, 1, 1) - 9.81) < 1e-9, "o primeiro passo só tem a gravidade"
print("Exercício 04: todos os testes passaram!")
Exercício 05¶
Culinária / física. Pela lei de resfriamento de Newton, um café esfria a uma
taxa \(\dfrac{dT}{dt} = k\,(T_{\text{sala}} - T)\). Escreva
temperaturas_cafe(T0, T_sala, k, dt, n), que devolve uma lista com a
temperatura inicial e as n temperaturas seguintes, a cada passo dt.
Compare com as medições do capítulo 0 (\(77{,}4\) e \(66{,}8\) °C em 5 e 10 min).
O que muda se você usar dt = 1 e n = 10?
def temperaturas_cafe(T0, T_sala, k, dt, n):
"""Lista com a temperatura inicial e as n seguintes, pelo método de Euler."""
T = T0
temperaturas = [T]
# TODO: n passos; em cada um, a taxa, o passo de Euler e o append
return temperaturas
# --- testes (não altere) ---
r = temperaturas_cafe(90, 25, 0.045, 5, 2)
assert len(r) == 3, "a inicial e mais duas"
assert abs(r[1] - 75.375) < 1e-9 and abs(r[2] - 64.040625) < 1e-9
r = temperaturas_cafe(25, 25, 0.045, 5, 4)
assert r == [25, 25, 25, 25, 25], "à temperatura da sala, nada muda"
assert abs(temperaturas_cafe(90, 25, 0.045, 1, 10)[-1] - 66.01541144103616) < 1e-9
print("Exercício 05: todos os testes passaram!")
Exercício 06¶
Quando dá para beber? Um café a 90 °C, numa sala a 25 °C, com \(k = 0{,}045\)
por minuto. Escreva minutos_para_esfriar(T0, T_sala, k, dt, limite), que
avança o passo de Euler enquanto a temperatura estiver acima de limite e
devolve o instante (em minutos) em que ela chegou a limite ou abaixo.
Use um while. A resposta exata, para 60 °C, é \(\ln(65/35)/0{,}045 \approx 13{,}76\)
min. Quanto Euler dá com dt = 1? E com dt = 0.1?
def minutos_para_esfriar(T0, T_sala, k, dt, limite):
"""Primeiro instante (min) em que a temperatura fica em limite ou abaixo."""
T = T0
t = 0.0
# TODO: while T > limite: um passo de Euler e t avança dt
return t
# --- testes (não altere) ---
assert abs(minutos_para_esfriar(90, 25, 0.045, 1, 60) - 14.0) < 1e-6
assert abs(minutos_para_esfriar(90, 25, 0.045, 0.1, 60) - 13.799999999999967) < 1e-6
assert minutos_para_esfriar(50, 25, 0.045, 1, 60) == 0, "já está abaixo do limite"
print("Exercício 06: todos os testes passaram!")
Exercício 07¶
Eletrônica. Um capacitor de \(C\) farads, descarregado, é ligado a uma fonte de
\(V_f\) volts por um resistor de \(R\) ohms. A tensão nele muda a uma taxa
\(\dfrac{dV}{dt} = \dfrac{V_f - V}{RC}\). Escreva tensao_capacitor(Vf, R, C, dt, t_final).
A exata é \(V_f(1 - e^{-t/RC})\). Com \(RC = 1\) s, \(V(1) = 3{,}161\) V. Reduza dt
até o erro ficar abaixo de 1 mV. Quantos passos foram necessários?
def tensao_capacitor(Vf, R, C, dt, t_final):
"""Tensão no capacitor (V) em t_final, partindo de 0 V, pelo método de Euler."""
V = 0.0
# TODO: o mesmo laço do paraquedista (ex04), com outra taxa
return V
# --- testes (não altere) ---
assert abs(tensao_capacitor(5, 10e3, 100e-6, 0.1, 1) - 3.2566077995000002) < 1e-6
assert abs(tensao_capacitor(12, 1e3, 1e-3, 0.01, 3) - 11.411509271144569) < 1e-6
assert abs(tensao_capacitor(5, 10e3, 100e-6, 0.001, 1) - 5 * (1 - 2.718281828 ** -1)) < 0.002, "dt pequeno: perto da exata"
print("Exercício 07: todos os testes passaram!")
Exercício 08¶
numpy — farmacologia. A concentração de um remédio no sangue foi medida de hora em hora:
Escreva pico(t, y), que devolve a tupla (instante, valor) do maior
valor de y. Use np.argmax, que devolve a posição do maior.
import numpy as np
def pico(t, y):
"""(instante, valor) do maior valor de y."""
# TODO: a posição do maior com np.argmax; depois t e y nessa posição
pass
# --- testes (não altere) ---
import numpy as np
t = np.array([0, 1, 2, 3, 4, 5, 6])
c = np.array([0, 8.2, 11.9, 12.6, 11.8, 10.4, 8.9])
assert pico(t, c) == (3, 12.6)
assert pico(np.array([10, 20, 30]), np.array([5.0, 1.0, 2.0])) == (10, 5.0), "o pico pode ser o primeiro"
print("Exercício 08: todos os testes passaram!")