Considere uma corda elástica de comprimento L cujas extremidades estão fixas. A corda é posta em movimento sem velocidade inicial a partir de uma posição inicial u(x, 0)=f(x). Em cada um dos Problemas 1 a 4, execute os seguintes passos. Deixe L=10 e a=1 nas partes (b) a (d).
(d) Construa uma animação da solução no tempo por pelo menos um período.
3. f(x)=8 x(L-x)^2 / L^3

Passo 1

Estamos resolvendo o problema da onda numa corda de comprimento fixo L com extremidades presas, velocidade de propagação a e condicionada pela forma inicial u(x,0)=f(x)=8x(L−x)²/L³, sem velocidade inicial. Na parte (d) queremos montar uma animação da solução u(x,t) para um período completo com L=10 e a=1.

Passo 2

Para extremidades presas temos a expansão em série de senos:
u(x,t)=sumn=1^inftyAncosl(npi a tLr)sinl(npi xLr),
onde os coeficientes são
An=2Lintegral0^Lf(x)sinl(npi xLr),dx

Passo 3

Para implementar a animação numericamente, truncamos a série em N termos (por exemplo N=50) e calculamos cada A_n por quadratura numérica: geramos um vetor x no intervalo [0,L], avaliamos f(x)·sin(nπx/L) e usamos método trapezoidal para aproximar a integral.

Passo 4

Definimos então uma grade de posições x e de instantes t que cubra ao menos um período completo T=2L/a. Construímos uma função u(x,t) que soma até N termos:
u(x,t)approxsumn=1^NAncosl(npi a tLr)sinl(npi xLr)

Passo 5

Usamos matplotlib.animation.FuncAnimation para criar a animação, definindo uma função de atualização que recalcula u(x,t_k) e atualiza o gráfico para cada quadro k.

Resposta

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# parâmetros
L = 10.0
a = 1.0
N = 50             # número de modos na série
nx = 500           # pontos no espaço
nt = 200           # quadros da animação

# definição de f(x)
def f(x):
    return 8 * x * (L - x)**2 / L**3

# malha espacial
x = np.linspace(0, L, nx)

# cálculo dos coeficientes A_n via regra do trapézio
def compute_An(n):
    y = f(x) * np.sin(n * np.pi * x / L)
    return (2.0 / L) * np.trapz(y, x)

A_n = np.array([compute_An(n) for n in range(1, N+1)])

# função que calcula u(x,t) truncada em N modos
def u_xt(t):
    n = np.arange(1, N+1)
    # forma vetorizada: (A_n * cos(...) * sin(...)) somados
    modes = A_n[:, None] * np.cos(n * np.pi * a * t / L)[:, None] * \
            np.sin(n * np.pi * x[None, :] / L)
    return modes.sum(axis=0)

# preparar figura
total_time = 2 * L / a        # um período completo
ts = np.linspace(0, total_time, nt)

fig, ax = plt.subplots()
line, = ax.plot(x, u_xt(0), lw=2)
ax.set_xlim(0, L)
ax.set_ylim(1.2 * f(x).min(), 1.2 * f(x).max())
ax.set_xlabel('x')
ax.set_ylabel('u(x,t)')
ax.set_title('Animação da onda na corda')

# função de atualização para cada quadro
def update(frame):
    t = ts[frame]
    y = u_xt(t)
    line.set_data(x, y)
    ax.set_title(f't = {t:.2f} s')
    return line,

anim = FuncAnimation(fig, update, frames=nt, blit=True, interval=50)

# para salvar como GIF ou MP4:
# anim.save('onda_corda.gif', writer='imagemagick', fps=30)
# ou
# anim.save('onda_corda.mp4', writer='ffmpeg', fps=30)

plt.show()

Exercícios relacionados