Projet H5P Ondes internes océaniques

Ce JupyterNotebook présente les codes Python utilisés pour illustrer le phénomène des ondes internes abordé dans le cours Couche Limite Atmosphérique. Trois codes ont été utilisés et sont dérits ci-dessous.

Chaque code fait intervenir une onde interne avec les mêmes propriétés qui sont :

  • une fréquence de Brunt-Väisälä $N$ égale à $0.001 s^{-1}$
  • une vitesse de la forme $U=U_mcos(lx+mz-\omega t)$

avec $U_m$ prise égale à $1 m/s$ ; $l$ et $m$ les nombres d'onde horizontal et vertical définis par $l=2\pi/d_x$ et $m=2\pi/d_z$ avec $d_x$ et $d_z$ les longueurs caractéristiques que l'on prend toutes deux égales à $10m$.

1) Onde interne suivant son vecteur d'onde

Ce code permet de tracer une onde interne suivant son vecteur d'onde d'angle $\theta$. On choisit un angle $\theta$ égale à $\frac{\pi}{6}$.

In [2]:
"""
Created on Tue Nov 29 15:04:55 2022

@author: alicelegendre
"""

import matplotlib.pyplot as plt
import numpy as np

#Définition des paramètres

l=1
m=1
Um=1
N=0.001
theta=np.pi/6

K=np.sqrt(l**2+m**2)
w=np.sqrt(N**2*l**2/K**2)

x=np.arange(0,10,0.1)
z=np.arange(0,10,0.1)


def u(temps):
    u1=np.zeros((len(x),len(z)))
    uz0=np.zeros((len(x)))
    for i in range(len(x)):
        for j in range(len(z)):
            u1[i,j]=Um*np.cos(l*x[i]+m*z[j]-w*temps)
        uz0[i]=u1[i,0]  #valeur de la vitesse en z=0
    return u1, uz0


#Création fonction inclinée
u, uzz0 = u(0)
c, s = np.cos(theta), np.sin(theta)
rot_matrix = np.array(((c, s), (-s, c)))
uIncline = np.array([x, uzz0]).T @ rot_matrix



plt.figure(1)
plt.plot(uIncline[:, 0], uIncline[:, 1],label='Onde interne')
plt.axis('equal')  # so angles on the screen look like the real angles
plt.arrow(0, 0, 7.5, 6*np.cos(theta), head_width = 0.1, width = 0.01, color='darkred')
plt.plot([-1,-1],[-1,-1],'darkred',label='K̲')
plt.ylim(0,6)
plt.xlim(0,8)
plt.xlabel('x (m)')
plt.ylabel('z (m)')
plt.legend(loc='upper left')
plt.title('Onde interne suivant son vecteur d\'onde K̲')
Out[2]:
Text(0.5, 1.0, "Onde interne suivant son vecteur d'onde K̲")

2) Evolution temporelle d'une onde interne

Ce code permet de tracer l'évolution temporelle d'une onde interne dans le plan $(x,z)$.

Il utilise le module animation de la bibliothèque matplotlib afin d'obtenir une figure animée pouvant être enregistrée en tant que gif.

In [1]:
"""
Created on Mon Nov 28 10:47:34 2022

@author: alicelegendre
"""

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


# Définition des paramètres 
wavelength = 10
l=2*np.pi/wavelength 
m=2*np.pi/wavelength 
Um=1
dt = 50 #pas de temps
N=0.001 #fréquence de Brunt-Vaisala

K=np.sqrt(l**2+m**2)
w=np.sqrt(N**2*l**2/K**2)

x=np.arange(0,30,0.1)
z=np.arange(0,30,0.1)


# Création de la figure animée
fig = plt.figure() 
line, = plt.plot([], []) 
plt.xlim(0, 30)
plt.ylim(0, 5)

def init():
    line.set_data([], [])
    return line,

def animate(i): 
    t = i * dt
    y = Um*np.cos(l*x+m*z[30]-w*t)+z[30]
    line.set_data(x, y)
    return line,
 
ani = animation.FuncAnimation(fig, animate, init_func=init, frames=500, interval=1, blit=True, repeat=False)
titre = 'Evolution temporelle d\'une onde interne'
plt.title(titre)
plt.xlabel('x (m)')
plt.ylabel('z (m)')    
ani.save(titre+'.gif', writer='pillow')  
plt.show()

3) Onde interne induite par un relief marin

Ce code permet de tracer la trajectoire d'une onde rencontrant un relief marin.

La forme du relief marin est prise aléatoirement et est codé par un polynôme $P(x)=-0.003x^3+0.0495x^2$.

Afin d'animer l'onde, nous créons plusieurs figures que nous assemblons ensuite pour donner naissance à un gif.

In [ ]:
"""
Created on Tue Nov 29 15:52:31 2022

@author: alicelegendre
"""
import matplotlib.pyplot as plt
import numpy as np
import pylab as pl
import os
import imageio

#Définition des paramètres
wavelength = 10
l=2*np.pi/wavelength 
m=2*np.pi/wavelength 
Um=1
N=0.001
K=np.sqrt(l**2+m**2)
w=np.sqrt(N**2*l**2/K**2)

x=np.arange(0,40,0.1)
z=np.arange(0,40,0.1)


#Création des fonctions de vitesse de l'onde et de création du relief

def VIT(temps):
    u1=np.zeros((len(x),len(z)))
    for i in range(len(x)):
        for j in range(len(z)):
            u1[i,j]=Um*np.cos(l*x[i]+m*z[j]-w*temps)
    return u1


def relief(x):
    r=np.zeros((len(x)))
    topo=np.zeros((len(x)))
    for i in range(-15,len(x)):
        r[i]=-0.003*x[i-15]**3+0.0495*x[i-15]**2
        if r[i]<0:
            topo[i]=0
        else :
            topo[i]=r[i]
    return topo
 

#Définition de de la vitesse de propagation
hauteur = 30
mean=z[hauteur]
maxU=mean+Um
minU=mean-Um
u=VIT(0)[:,hauteur]+mean


#Création de la trajectoire de l'onde interne rencontrant l'obstacle
    
OndeInterne=np.zeros((len(u)))
for i in range(len(OndeInterne)):
    if i < 70 :
        OndeInterne[i]=minU-Um
    elif i >= 70  and i < 120 :
        OndeInterne[i]=relief(x)[i]
    else :
        OndeInterne[i]=u[i]


#Ouverture et création d'un dossier de résultats
os.mkdir('/Users/alicelegendre/Desktop/CLAT/PlotOndeInterne')
os.chdir('/Users/alicelegendre/Desktop/CLAT/PlotOndeInterne')
filename=[]


#Affichage de la trajectoire totale
plt.figure(400)
ax = pl.subplot(111)
ax.fill_between(x, relief(x),linewidth=1, facecolor='dimgray')
plt.plot(x,relief(x),'k',label='relief')
plt.plot(x,OndeInterne, 'b', linewidth=2, label='onde interne')
plt.xlabel('x (m)')
plt.ylabel('z (m)')
plt.ylim(0,5)
plt.xlim(0,40)
plt.legend()
plt.title("Onde interne induite par un obstacle")
plt.savefig('OndeInterneTOTALE.png')
pl.show()



#Découpe de la trajectoire totale en figures contenant un point du parcours de l'onde
listX=[]
listY=[]

for j in range(int(len(OndeInterne))):
    j2=j
    listX.append(x[j2])
    listY.append(OndeInterne[j2])


for f in range(len(listX)):
    fig = plt.figure(f)
    plt.xlim(0,40)
    plt.ylim(0,5)
    ax = pl.subplot()
    ax.fill_between(x, relief(x),linewidth=1, facecolor='dimgray')
    plt.plot(x,relief(x),'k',label='relief')
    plt.plot(listX[:f], listY[:f],'.b', label='onde interne')
    plt.xlabel('x (m)')
    plt.ylabel('z (m)')
    plt.title("Onde interne induite par un obstacle")
    plt.legend()
    plt.savefig('OndeInterne%d.png'%f)
    filename.append('OndeInterne%d.png'%f)


filename.append('OndeInterneTOTALE.png')
plt.close('all')


#Creation du GIF final

with imageio.get_writer('mygif.gif', mode='I', duration = 0.0000000001) as writer:
    for name in filename:
        image = imageio.imread(name)
        writer.append_data(image)

Décembre 2022, Alice Legendre