|
|
Linha 255: |
Linha 255: |
| * Nos contornos de y: <math> \tfrac{\partial h}{\partial y} = 0</math>, discretizando essa derivada temos que: <math>h_{i, j(+/-)1} = h_{i, j}</math> | | * Nos contornos de y: <math> \tfrac{\partial h}{\partial y} = 0</math>, discretizando essa derivada temos que: <math>h_{i, j(+/-)1} = h_{i, j}</math> |
|
| |
|
| No desenvolvimento do programa não foi conseguido alcançar os resultados esperados, pois o sistema não converge: a velocidade aumenta e diminui infinitamente, fazendo com que a altura da onda aumente indefinidamente. Mesmo assim, vamos apresentar o código escrito na linguagem [https://www.python.org/ ''Python''], pois não conseguimos entender o erro. | | No desenvolvimento do programa não foi conseguido alcançar os resultados esperados, pois o sistema não converge: a velocidade aumenta e diminui infinitamente, fazendo com que a altura da onda aumente indefinidamente. O código foi 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">
| |
|
| |
| #%% 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 = [], [], []
| |
|
| |
| </source>
| |
|
| |
|
| |
| Função para resolução das equações diferenciais com FTCS.
| |
|
| |
| <source lang="python">
| |
| #%% 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
| |
| </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
| |
|
| |
|
| |
| # 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>
| |
|
| |
|
| === Forma dissipativa 2D === | | === Forma dissipativa 2D === |
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 Equações 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 (erro de sintaxe): {\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].
Forma dissipativa
As equações de águas rasas na forma não conservativa são dadas por (10),(33) e (34). Para descrever numericamente o fenômeno foi utilizado discretização por diferenças finitas, onde realizamos derivadas centradas na região espacial, e para frente no região temporal. O erro de truncamento é de ordem na região espacial, enquanto na temporal é de ordem . O método é conhecido como leap-frog method devido a discretização central na região espacial.
Discretizando a expressão (10) pelo leap-frog method:
Discretizando a expressão (33) pelo leap-frog method:
Definindo as quantidades:
Das quantidades definidades e da derivada parcial do fluxo de descarga em relação ao tempo temos a respectiva avanço temporal para M:
Generalizando a expressão (43) para o fluxo de descarga N temos:
Simulações Computacionais de Tsunamis
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.
Para os contornos foi utilizado que:
- Nos contornos de x: , discretizando essa derivada temos que:
- Nos contornos de y: , discretizando essa derivada temos que:
No desenvolvimento do programa não foi conseguido alcançar os resultados esperados, pois o sistema não converge: a velocidade aumenta e diminui infinitamente, fazendo com que a altura da onda aumente indefinidamente. O código foi 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.
Forma dissipativa 2D
Os exemplos que seguem utilizam as equações de ondas rasas (38),(43) e (44) para calcular os passos de tempo de , , , onde as funções em python atualiza_eta, atualiza_M, e atualiza_N implementam computacionalmente isto. Para implementar estás funções e outras ideias do nosso programa, o seguinte código fonte da referência foi usado como base.
def atualiza_eta(eta, M, N, dx, dy, dt, nx, ny):
for j in range(1,nx-1):
for i in range(1,ny-1):
dMdx = (M[j+1,i] - M[j-1,i]) / (2. * dx)
dNdy = (N[j,i+1] - N[j,i-1]) / (2. * dy)
eta[j, i] = eta[j, i] - dt * (dMdx + dNdy)
#Condições de contorno do problema
eta[0,:] = eta[1,:]
eta[-1,:] = eta[-2,:]
eta[:,0] = eta[:,1]
eta[:,-1] = eta[:,-2]
return eta
def atualiza_M(eta, M, N, D, g, h, n, dx, dy, dt, nx, ny):
M2 = M **2 / D
MN = M * N / D
fric = g * n**2 * M * np.sqrt(M**2 + N**2) / D**(7./3.)
for j in range(1,nx-1):
for i in range(1,ny-1):
dM2dx = (M2[j+1,i] - M2[j-1,i]) / (2. * dx)
dMNdy = (MN[j,i+1] - MN[j,i-1]) / (2. * dy)
dETAdx = (eta[j+1,i] - eta[j-1,i]) / (2. * dx)
M[j, i] = M[j, i] - dt * (dM2dx + dMNdy + g * D[j,i] * dETAdx + fric[j,i])
return M
def atualiza_N(eta, M, N, D, g, h, n, dx, dy, dt, nx, ny):
MN = M * N / D
N2 = N**2 / D
fric = g * n**2 * N * np.sqrt(M**2 + N**2) / D**(7./3.)
for j in range(1,nx-1):
for i in range(1,ny-1):
dMNdx = (MN[j+1,i] - MN[j-1,i]) / (2. * dx)
dN2dy = (N2[j,i+1] - N2[j,i-1]) / (2. * dy)
dETAdy = (eta[j,i+1] - eta[j,i-1]) / (2. * dy)
N[j, i] = N[j, i] - dt * (dMNdx + dN2dy + g * D[j,i] * dETAdy + fric[j,i])
return N
A função shallow water waves recebe os parâmetros iniciais do nosso programa, executa o Loop responsável pela atualização das variáveis da amplitude da onda e do fluxo de descarga com o tempo, através da chamada das funções atualiza M,N e eta. Posteriormente, a cada passagem dentro do loop um plot do sistema é feito. Obs: não colocamos todo código da função shallow_water na imagem a seguir, apenas a que mencionamos neste parágrafo.
def shallow_water(eta0, M0, N0, h, g, n, nt, dx, dy, dt, X, Y):
eta = eta0.copy()
M = M0.copy()
N = N0.copy()
D = eta + h
# ...
for k in range(1,nt):
eta = atualiza_eta(eta, M, N, dx, dy, dt, nx, ny)
M = atualiza_M(eta, M, N, D, g, h, n, dx, dy, dt, nx, ny)
N = atualiza_N(eta, M, N, D, g, h, n, dx, dy, dt, nx, ny)
D = eta + h
fig = plt.figure(figsize=(8.,6.))
fundo = plt.imshow(-h, 'Purples', interpolation = 'nearest', extent = limites)
amp = plt.imshow(eta, extent = limites, interpolation = 'sinc', cmap = 'seismic', alpha= 0.75, vmin=-0.4, vmax= 0.4)
#plt.title('tempo = %f', dt*n )
#plt.plot(f'Tempo {round(k*dt,3)} s')
plt.xlabel('x [m]')
plt.ylabel('y [m]')
cbar_amp = plt.colorbar(amp)
cbar_fundo = plt.colorbar(fundo)
cbar_fundo.set_label(r'$-h$ [m]')
cbar_amp.set_label(r'$\eta$ [m]')
plt.show()
Exemplo 1 - Tsunami Confinada em uma Caixa
Exemplo 2.1 - Tsunami Propagando-se em Direção a Praia
Exemplo 2.2 - Tsunami Propagando-se em Direção a Praia
Referências