Equação de Águas Rasas: mudanças entre as edições
Linha 210: | Linha 210: | ||
No desenvolvimento do programa não foi conseguido alcançar os resultados esperados, pois o sistema não converge após um tempo. Mesmo assim, vamos apresentar o código | No desenvolvimento do programa não foi conseguido alcançar os resultados esperados, pois o sistema não converge após um tempo. Mesmo assim, vamos apresentar o código escrito na linguagem [https://www.python.org/ ''Python''], pois não conseguimos entender o erro. | ||
Foi cosiderada uma superfície constante e, desta forma, suas derivadas são nulas e não interferem no cálculo. | Foi cosiderada uma superfície constante e, desta forma, suas derivadas são nulas e não interferem no cálculo. | ||
<source lang="python"> | <source lang="python"> | ||
Linha 225: | Linha 223: | ||
from matplotlib import animation | from matplotlib import animation | ||
import matplotlib.patches as mpatches | import matplotlib.patches as mpatches | ||
from IPython.display import HTML, Image | |||
#%% Parametros | #%% Parametros | ||
Linha 293: | Linha 292: | ||
""" | """ | ||
Função que retorna os valores de | Função que retorna os valores de profundidade, velocidade em x e em y | ||
no próximo tempo | no próximo tempo | ||
Parametros | Parametros | ||
----------- | ----------- | ||
h : | h : array | ||
profundidade no tempo t | profundidade no tempo t | ||
vx : | vx : array | ||
velocidade em x no tempo t | velocidade em x no tempo t | ||
vy : | vy : array | ||
velocidade em y no tempo t | velocidade em y no tempo t | ||
Retorna | Retorna | ||
----------- | ----------- | ||
prox_h : | prox_h : array | ||
profundidade no tempo t + dt | profundidade no tempo t + dt | ||
prox_u : | prox_u : array | ||
velocidade em x no tempo t + dt | velocidade em x no tempo t + dt | ||
prox_v : | prox_v : array | ||
velocidade em y no tempo t + dt | velocidade em y no tempo t + dt | ||
""" | """ | ||
# Inicializa os vetores para armazenarem os resultados calculados | # Inicializa os vetores para armazenarem os resultados calculados | ||
prox_h = np.ones(shape = (np.shape(h)), dtype = np.float64) | prox_h = np.ones(shape = (np.shape(h)), dtype = np.float64) | ||
Linha 324: | Linha 322: | ||
prox_v = np.ones(shape = (np.shape(vy)), dtype = np.float64) | prox_v = np.ones(shape = (np.shape(vy)), dtype = np.float64) | ||
# Loop nos pontos discretizados | # Loop nos pontos discretizados | ||
for i in range(1, NX - 1): | for i in range(1, NX - 1): | ||
for j in range(1, NY - 1): | for j in range(1, NY - 1): | ||
# Alturas e velocidades conforme a posicao do ponto: | # Alturas e velocidades conforme a posicao do ponto: | ||
Linha 343: | Linha 335: | ||
h_l = h[i, j] | h_l = h[i, j] | ||
u_l = -vx[i, j] | |||
u_l = 0 | # u_l = 0 | ||
v_l = vy[i, j] | v_l = vy[i, j] | ||
Linha 357: | Linha 349: | ||
h_r = h[i, j] | h_r = h[i, j] | ||
u_r = -vx[i, j] | |||
u_r = 0 | # u_r = 0 | ||
v_r = vy[i, j] | v_r = vy[i, j] | ||
Linha 371: | Linha 363: | ||
h_d = h[i, j] | h_d = h[i, j] | ||
u_d = vx[i, j] | u_d = vx[i, j] | ||
v_d = - vy[i, j] | |||
v_d = 0 | # v_d = 0 | ||
else: | else: | ||
Linha 386: | Linha 378: | ||
h_up = h[i, j] | h_up = h[i, j] | ||
u_up = vx[i, j] | u_up = vx[i, j] | ||
v_up = 0 | # v_up = 0 | ||
v_up = - vy[i, j] | |||
else: | else: | ||
Linha 401: | Linha 393: | ||
h_ij = h[i, j] - \ | h_ij = h[i, j] - \ | ||
(h_r * u_r - h_l * u_l) * fator_x - \ | (h_r * u_r - h_l * u_l) * fator_x - \ | ||
(h_up * v_up - h_d * v_d) * fator_y | |||
prox_h[i, j] = h_ij | prox_h[i, j] = h_ij | ||
Linha 407: | Linha 399: | ||
# ## Segunda equação | # ## Segunda equação | ||
hu_ij = | hu_ij = (h[i, j] * vx[i, j]) - \ | ||
fator_x * ( | fator_x * ( | ||
((h_r * (u_r ** 2)) + (1/2 * g * (h_r ** 2))) -\ | ((h_r * (u_r ** 2)) + (1/2 * g * (h_r ** 2))) -\ | ||
Linha 414: | Linha 406: | ||
(h_up * u_up * v_up ) - (h_d * u_d * v_d) | (h_up * u_up * v_up ) - (h_d * u_d * v_d) | ||
) | ) | ||
prox_u[i, j] = hu_ij / h_ij | prox_u[i, j] = hu_ij / h_ij | ||
# # ## Terceira Equação | # # ## Terceira Equação | ||
Linha 431: | Linha 420: | ||
) | ) | ||
prox_v[i, j] = hv_ij / (h_ij) | prox_v[i, j] = hv_ij / (h_ij) | ||
return prox_h, prox_u, prox_v | return prox_h, prox_u, prox_v | ||
</source> | |||
<source lang="python"> | |||
#%% Cálculo | |||
# Resolve para cada passo de tempo | |||
for t in time_interval: | |||
h, u, v = resolve_pdes(h_ant, u_ant, v_ant) # valores das variaveis no tempo = t + dt | |||
h[0, :] = h[1, :] | |||
h[:, 0] = h[:, 1] | |||
v[0, :] = v[1, :] | |||
v[:, 0] = v[:, 1] | |||
u[0, :] = u[1, :] | |||
u[:, 0] = u[:, 1] | |||
# adicionar essas variáveis em listas pra conseguir plotar dps | |||
hist_h.append(h); hist_u.append(u); hist_v.append(v) | |||
# Coloca as variaveis atuais como anteriores pro proximo calculo | |||
h_ant = np.copy(h) | |||
u_ant = np.copy(u) | |||
v_ant = np.copy(v) | |||
</source> | |||
<source lang="python"> | |||
#%% Gráfico animado | |||
# Reorganiza os vetores para plotar | |||
x_2d = X[0] | |||
y_2d = Y[0] | |||
for i in range(1,len(X)): | |||
x_2d = np.append(x_2d, X[i]) | |||
y_2d = np.append(y_2d, Y[i]) | |||
def animate(i): | |||
plt.clf() # limpa a figura, pra nao ficar sobrepondo figs | |||
# titulos | |||
plt.suptitle('Evolução da onda', fontsize=14) | |||
plt.title(f'Tempo: {round(dt*i, 3)}', fontsize=12) | |||
# plot | |||
plt.scatter(x_2d, y_2d, c=hist_h[0::8][i], marker='.') | |||
plt.colorbar() | |||
# axis | |||
# fig = plt.figure(figsize=(16,9)) | |||
# ax = fig.gca(projection='3d') | |||
fig, ax = plt.subplots() | |||
ani = animation.FuncAnimation(fig, animate, frames = len(hist_h[0::8]), repeat=False, interval=0.1) | |||
#%% Salvar o gif | |||
ani.save('onda.gif', writer='imagemagick', fps=5) | |||
</source> | </source> | ||
== Referências == | == Referências == | ||
<references/> | <references/> |
Edição das 08h38min de 8 de outubro de 2021
Em construção Grupo: Gabriel Schmökel, Julia Remus e Pedro Inocêncio Rodrigues Terra
Introdução
Tsunami é um fenômeno da natureza caracterizado por uma sucessão de ondas marinhas, que devido ao seu grande volume e alta velocidade, podem se tornar catastróficas ao atingir a costa. Sismos, erupções vulcânicas, deslizamentos de terra, impactos e outros movimentos submarinos são a causa para a formação deste evento, sendo a grande maioria provocado pelos movimentos das placas tectônicas.
Formação de um Tsunami
Vamos analisar a sequência de passos da formação de uma Tsunami formada a partir de um abalo sísmico:
I. A convergência das placas tectônicas, devido as correntes de convecção, faz com que existam forças de tensão entre as placas.
IMAGEM
A tensão entre as placas eventualmente ultrapassa o limite máximo, o que provoca o deslizamento brusco de uma das placas sobre a outra, gerando um grande deslocamento de volume de água na vertical. Como a tsunami ocorre em grandes profundidades, ela pode passar despercebida para um barco que navega nas proximidades, uma vez que amplitude da onda é menor.
IMAGEM
II. A onda gerada se propaga ao longo de todas as direções do plano da água.
IMAGEM
III. A medida que a onda se aproxima da superfície ela diminui sua velocidade e aumenta sua amplitude
IMAGEM
Temos o interesse de descrever fisicamente a propagação da Tsunami de acordo com a topografia da água e do mar, por essa razão não iremos estudar o efeito físico que causou o deslocamento do volume de água.
Teoria
Derivação das EQs. de Águas Rasas
Para obter as equações de águas rasas devemos partir da equação da continuidade e das equações da quantidade de movimento de Navier-Stokes:
é a densidade; p é a pressão; é o vetor velocidade do fluído, onde u,v e w são as velocidades das partículas que compõe o fluído nas direções x,y,z; é o vetor aceleração da gravidade; é o tensor tensão, onde as componentes deste tensor são as tensões normais e tangenciais de cisalhamento, expressas por , no qual indica a direção e o plano normal.
Introduzindo as condições de contorno [1] para a superfície e para a profundidade do oceano :
, onde
, onde
é o deslocamento vertical da água sobre a superfície em repouso, é o vetor velocidade do fluído nas direções horizontais x e y.
A equação da continuidade em (3) pode ser simplificada, já que a densidade do fluído no oceano não varia significativamente com o tempo e a posição.
Integrando a expressão da continuidade em (6), utilizando a regra da integral de Leibniz [1], com os limites indo de até chegamos na seguinte expressão:
Teorema de Leibniz:
Substituindo as condições de contorno da profundidade (5) em (7) obtemos:
Substituindo a condição de contorno da superfície (4) em (9):
(10) é a primeira das equações das águas rasas que obtemos, onde é o comprimento da água total do fundo do oceano até a amplitude da onda. Podemos expressar (10) através do fluxo de descarga nas direções x e y, estás quantidades estão relacionadas com as velocidades da seguinte forma [1]:
Substituindo (11) e (12) em (10) chegamos na representação do fluxo de descarga para uma das equações de águas rasas.
Escrevendo as quantidades de movimento de Navier-Stokes nas componentes x,y e z:
Falhou ao verificar gramática (MathML com retorno SVG ou PNG (recomendado para navegadores modernos e ferramentas de acessibilidade): Resposta inválida ("Math extension cannot connect to Restbase.") do servidor "https://wikimedia.org/api/rest_v1/":): {\displaystyle \frac{\partial u}{\partial t} + u\frac{\partial u}{\partial x} + v\frac{\partial u}{\partial y} + w\frac{\partial u}{\partial z} +\frac{1}{\rho}\frac{\partial P}{\partial x} +g_x = 0 \qquad (14) }
Falhou ao verificar gramática (erro de sintaxe): {\displaystyle \frac{\partial v}{\partial t} + u\frac{\partial v}{\partial x} + v\frac{\partial v}{\partial y} + w\frac{\partial v}{\partial z} +\frac{1}{\rho}\frac{\partial P}{\partial x} +g_y = 0 \qquad (15) }
Na componente z em (15) negligenciamos a aceleração das partículas, pois a aceleração da gravidade é muito maior. Também tomamos como nulos as componentes e em (14) e passamos a definir .
Resolvendo equação diferencial da componente z em (16) podemos obter a pressão, a qual é hidrostática.
Substituindo a pressão em (14):
Integrando a equação (18) em relação a componente z com os limites indo
Integrando a expressão (18), utilizando a regra da integral de Leibniz [1] e as condições de contorno (4) e (5), com os limites indo de até chegamos em outra das equações de águas rasas:
Generalizando a equação (18), para a componente y, obtemos a última das equações de águas rasas:
Na representação de fluxo de cargas as expressões (18) e (19) são apresentadas respectivamente como:
Iremos escrever as equações das águas rasas considerando o tensor de estresse . Os elementos deste tensor são responsáveis por causar nas partículas tensões tangenciais e perpendiculares, onde as tensões tangenciais são representadas por elementos onde , e as perpendiculares por elementos onde
Decompondo nas componentes x,y, e z de presente em (4):
Considerando o fluído Newtoniano, então as tensões de cisalhamento serão proporcionais a uma taxa de deformação, onde a constante de deformidade é a viscosidade.
Substituindo (25),(26) em (25), integrando em relação a componente z, utilizando a regra de Leibnz e as condições de contorno (3) e (4), obtemos:
Onde é a constante de viscosidade turbulenta, é uma força de resistividade relativa ao movimento do fluído com o fundo do oceano na direção x. Podemos negligenciar a constante de turbulência na situação em que não temos inclinações abrutas no fundo do mar. [1].
Considerando que o fluído é uniforme, então a expressão para Falhou ao verificar gramática (erro de sintaxe): {\displaystyle \frac{\tau_x}{\rho} é } é:
é o coeficiente de fricção, porém o coeficiente de rugosidade de Manning é mais usado, alguns valores deste coeficiente são:
- Cimento puro e metal liso
- Terra lisa
- Pedras, ervas daninhas
- Péssimo relevo de canal
- Bom relevo de canal
O coeficiente de fricção e o de rugosidade de Meanning estão relacionados por:
Substituindo (30) em (29) obtemos:
Generalizando a expressão (31) para a componente y.
Adicionando, repectivamente, (31) e (32) nas expressões (20) e (21), obtemos as equações de águas rasas considerando as forças de fricção do fundo do oceano.
Forma Conservativa
Um modelo mais simples - desconsiderando a fricção, viscosidade do líquido e as forças de Coriolis sobre ele - pode ser obtido [2][3]. Para desenvolvê-lo são necessárias algumas premissas:
- O comprimento da onda é muito maior que as contribuições na direção
- A aceleração na direção da velocidade na direção é zero
- As componentes das velocidades em e em ( e ) não variam em
O sistema então pode ser descrito pelas seguintes equações:
Onde é a altura do fluido desde a base, são as velocidades médias na direções , é a constante gravitacional e é função que descreve a superfície onde acontece o movimento [1].
Desenvolvimento do cálculo
Forma conservativa 2D
Para descrever numericamente o fenômeno foi utilizado discretização por diferenças finitas e o método pra frente no tempo e no espaço (FTCS). As equações discretizadas podem ser observadas abaixo.
No desenvolvimento do programa não foi conseguido alcançar os resultados esperados, pois o sistema não converge após um tempo. Mesmo assim, vamos apresentar o código escrito na linguagem Python, pois não conseguimos entender o erro.
Foi cosiderada uma superfície constante e, desta forma, suas derivadas são nulas e não interferem no cálculo.
#%% Bibliotecas
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import animation
import matplotlib.patches as mpatches
from IPython.display import HTML, Image
#%% Parametros
L_xf = 10.0 # m
L_x0 = -L_xf
NX = 100
dx = (L_xf - L_x0) / NX
L_yf = 10.0 # m
L_y0 = -L_yf
NY = 100
dy = (L_yf - L_y0) / NY
N_INNER = (NX - 2) * (NY - 2)
g = 9.8 # m /s^2
# Tempo
dt = 0.002
Nt = 1000
time_interval = np.arange(0, Nt*dt, dt)
#%% Discretização do espaço x-y
x = np.linspace(L_x0, L_xf, NX-1)
y = np.linspace(L_y0, L_yf, NY-1)
X, Y = np.meshgrid(x, y)
#%% Condições iniciais, em distribuição gaussiana
sigma = 0.6
sigma_v = 0.6
h_2d = 0.8 * np.exp(-(((X)**2 / 2*(sigma**2)) + ((Y)**2 / 2*(sigma**2))))
u_2d = 0.1 * np.exp(-(((X)**2 / 2*(sigma_v**2)) + ((Y)**2 / 2*(sigma_v**2))))
v_2d = 0.1 * np.exp(-(((X)**2 / 2*(sigma_v**2)) + ((Y)**2 / 2*(sigma_v**2))))
#%% Vetores das variáveis anteriores e historico das variaveis
h_ant = np.copy(h_2d)
v_ant = np.copy(v_2d)
u_ant = np.copy(u_2d)
# Inicilização das listas para armazenar os valores
hist_h, hist_u, hist_v = [], [], []
Função para resolução das equações diferenciais com FTCS.
#%% Equação diferencial
# Fator de multiplicacao
fator_x = (dt / (2*(dx)))
fator_y = (dt / (2*(dy)))
def resolve_pdes(h, vx, vy):
"""
Função que retorna os valores de profundidade, velocidade em x e em y
no próximo tempo
Parametros
-----------
h : array
profundidade no tempo t
vx : array
velocidade em x no tempo t
vy : array
velocidade em y no tempo t
Retorna
-----------
prox_h : array
profundidade no tempo t + dt
prox_u : array
velocidade em x no tempo t + dt
prox_v : array
velocidade em y no tempo t + dt
"""
# Inicializa os vetores para armazenarem os resultados calculados
prox_h = np.ones(shape = (np.shape(h)), dtype = np.float64)
prox_u = np.ones(shape = (np.shape(vx)), dtype = np.float64)
prox_v = np.ones(shape = (np.shape(vy)), dtype = np.float64)
# Loop nos pontos discretizados
for i in range(1, NX - 1):
for j in range(1, NY - 1):
# Alturas e velocidades conforme a posicao do ponto:
# _l : ponto a esquerda, _r: ponto a direita, _up: ponto acima, _d: abaixo
# Condicao a esquerda ------------------
if i == 1: # primeiro x interno
h_l = h[i, j]
u_l = -vx[i, j]
# u_l = 0
v_l = vy[i, j]
else:
h_l = h[i-1, j]
u_l = vx[i-1, j]
v_l = vy[i-1, j]
# --------------------------------------
# Condicao a direita -------------------
if i == NX - 2: # ultimo x interno
h_r = h[i, j]
u_r = -vx[i, j]
# u_r = 0
v_r = vy[i, j]
else:
h_r = h[i+1, j]
u_r = vx[i+1, j]
v_r = vy[i+1, j]
# --------------------------------------
# Condicao abaixo ----------------------
if j == 1: # primeiro y interno
h_d = h[i, j]
u_d = vx[i, j]
v_d = - vy[i, j]
# v_d = 0
else:
h_d = h[i, j - 1]
v_d = vy[i, j - 1]
u_d = vx[i, j - 1]
# --------------------------------------
# Condicao acima ----------------------
if j == NY - 2: # utlimo y interno
h_up = h[i, j]
u_up = vx[i, j]
# v_up = 0
v_up = - vy[i, j]
else:
h_up = h[i, j + 1]
v_up = vy[i, j + 1]
u_up = vx[i, j + 1]
# --------------------------------------
## Primeira Equação
h_ij = h[i, j] - \
(h_r * u_r - h_l * u_l) * fator_x - \
(h_up * v_up - h_d * v_d) * fator_y
prox_h[i, j] = h_ij
# ## Segunda equação
hu_ij = (h[i, j] * vx[i, j]) - \
fator_x * (
((h_r * (u_r ** 2)) + (1/2 * g * (h_r ** 2))) -\
((h_l * (u_l ** 2)) + (1/2 * g * (h_l ** 2)))
) - fator_y * (
(h_up * u_up * v_up ) - (h_d * u_d * v_d)
)
prox_u[i, j] = hu_ij / h_ij
# # ## Terceira Equação
hv_ij = (h[i, j] * vy[i, j]) - \
fator_x * (
(h_r * u_r * v_r) - (h_l * u_l * v_l)
) - \
fator_y * (
((h_up * (v_up ** 2)) + (1/2 * g * (h_up ** 2))) - \
((h_d * (v_d ** 2)) + (1/2 * g * (h_d ** 2)))
)
prox_v[i, j] = hv_ij / (h_ij)
return prox_h, prox_u, prox_v
#%% Cálculo
# Resolve para cada passo de tempo
for t in time_interval:
h, u, v = resolve_pdes(h_ant, u_ant, v_ant) # valores das variaveis no tempo = t + dt
h[0, :] = h[1, :]
h[:, 0] = h[:, 1]
v[0, :] = v[1, :]
v[:, 0] = v[:, 1]
u[0, :] = u[1, :]
u[:, 0] = u[:, 1]
# adicionar essas variáveis em listas pra conseguir plotar dps
hist_h.append(h); hist_u.append(u); hist_v.append(v)
# Coloca as variaveis atuais como anteriores pro proximo calculo
h_ant = np.copy(h)
u_ant = np.copy(u)
v_ant = np.copy(v)
#%% Gráfico animado
# Reorganiza os vetores para plotar
x_2d = X[0]
y_2d = Y[0]
for i in range(1,len(X)):
x_2d = np.append(x_2d, X[i])
y_2d = np.append(y_2d, Y[i])
def animate(i):
plt.clf() # limpa a figura, pra nao ficar sobrepondo figs
# titulos
plt.suptitle('Evolução da onda', fontsize=14)
plt.title(f'Tempo: {round(dt*i, 3)}', fontsize=12)
# plot
plt.scatter(x_2d, y_2d, c=hist_h[0::8][i], marker='.')
plt.colorbar()
# axis
# fig = plt.figure(figsize=(16,9))
# ax = fig.gca(projection='3d')
fig, ax = plt.subplots()
ani = animation.FuncAnimation(fig, animate, frames = len(hist_h[0::8]), repeat=False, interval=0.1)
#%% Salvar o gif
ani.save('onda.gif', writer='imagemagick', fps=5)
Referências
- ↑ 1,0 1,1 1,2 1,3 1,4 https://docplayer.net/49487265-Lecture-8-the-shallow-water-equations.html Erro de citação: Etiqueta inválida
<ref>
; Nome "Hopf" definido várias vezes com conteúdo diferente Erro de citação: Etiqueta inválida<ref>
; Nome "Hopf" definido várias vezes com conteúdo diferente Erro de citação: Etiqueta inválida<ref>
; Nome "Hopf" definido várias vezes com conteúdo diferente Erro de citação: Etiqueta inválida<ref>
; Nome "Hopf" definido várias vezes com conteúdo diferente - ↑ GARCÍA-NAVARRO, P; et al. The shallow water equations: An example of hyperbolic system. Espanha: 2008. Disponível em: <https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.571.1364&rep=rep1&type=pdf>
- ↑ KUHBACHER, Christian. Shallow Water: Derivation and Applications. Disponível em: <http://www.mathematik.tu-dortmund.de/lsiii/cms/papers/Kuehbacher2009.pdf>