YAYA20's picture
Update app.py
2a380dc verified
Raw
History Blame Contribute Delete
8.69 kB
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import panel as pn
# Définition du thème sombre
#pio.templates.default = "plotly_dark"
# Activer les extensions KaTeX et MathJax
pn.extension('katex', 'mathjax', 'plotly')
# Definir les widgets pour les parametres 1D
alpha_1d = pn.widgets.FloatSlider(name='Alpha (1D)', start=0.1, end=2, step=0.1, value=1)
longueur_1d = pn.widgets.FloatSlider(name='Longueur (1D)', start=5, end=20, step=1, value=10)
nombre_points_1d = pn.widgets.IntSlider(name='Nombre de points (1D)', start=50, end=200, step=10, value=100)
nombre_pas_temps_1d = pn.widgets.IntSlider(name='Nombre de pas de temps (1D)', start=50, end=200, step=10, value=100)
pas_temps_1d = pn.widgets.FloatSlider(name='Pas de temps (1D)', start=0.01, end=0.1, step=0.01, value=0.05)
# Definir les widgets pour les parametres 2D
alpha_2d = pn.widgets.FloatSlider(name='Alpha (2D)', start=0.1, end=2, step=0.1, value=1)
longueur_2d = pn.widgets.FloatSlider(name='Longueur (2D)', start=5, end=20, step=1, value=10)
temps_total_2d = pn.widgets.FloatSlider(name='Temps total (2D)', start=1, end=10, step=1, value=5)
nombre_points_x_2d = pn.widgets.IntSlider(name='Nombre de points en x (2D)', start=50, end=200, step=10, value=100)
nombre_points_y_2d = pn.widgets.IntSlider(name='Nombre de points en y (2D)', start=50, end=200, step=10, value=100)
nombre_pas_temps_2d = pn.widgets.IntSlider(name='Nombre de pas de temps (2D)', start=50, end=200, step=10, value=100)
pas_temps_2d = pn.widgets.FloatSlider(name='Pas de temps (2D)', start=0.01, end=0.1, step=0.01, value=0.05)
# Creer un template Bootstrap
template = pn.template.BootstrapTemplate(title="Equations de Transport 1D et 2D")
# Créer un template Bootstrap
template = pn.template.BootstrapTemplate(title="Simulation Numérique Interactive des Équations de Transport 1D et 2D | Méthodes des Différences Finies (Schémas Décentrés à Gauche et à Droite) avec Solution Analytique")
# Ajouter un logo à la barre latérale
logo = pn.pane.PNG("logo_unchk.png", width=320)
template.sidebar.append(logo)
# Ajouter les informations sur le PÔLE STN
info_stn = pn.pane.Markdown(
"### PÔLE STN\n"
"#### Master en Modélisation mathématique, analyse et simulation numériques. "
"[Lien vers le site de l'université](https://www.unchk.sn/nos-formations/formations-initiales/pole-sciences-technologie-et-numerique-stn/master-en-modelisation-mathematique-analyse-et-simulation-numeriques/)"
)
template.sidebar.append(info_stn)
# Titre pour les formules mathématiques
math_title = pn.pane.Markdown("<h3 style='font-size: 16pt; font-weight: bold;'>Formules Mathématiques</h3>")
template.sidebar.append(math_title)
# Formules de l'équation de transport en 1D et 2D
# Formules de l'équation de transport en 1D et 2D
transport_eq_1d = pn.pane.LaTeX(r"""
$$
\frac{\partial u}{\partial t} + a \frac{\partial u}{\partial x} = 0
$$
""", styles={'font-size': '16pt'})
transport_eq_2d = pn.pane.LaTeX(r"""
$$
\frac{\partial u}{\partial t} + a \frac{\partial u}{\partial x} + b \frac{\partial u}{\partial y} = 0
$$
""", styles={'font-size': '16pt'})
# Ajouter les formules à la barre latérale
template.sidebar.append(transport_eq_1d)
template.sidebar.append(transport_eq_2d)
# Titre pour les parametres 1D
params_1d_title = pn.pane.Markdown("<h3 style='font-size: 16pt; font-weight: bold;'>Parametres de l'equation de transport 1D</h3>")
template.sidebar.append(params_1d_title)
# Ajouter les widgets des parametres 1D a la barre laterale
template.sidebar.extend([alpha_1d, longueur_1d, nombre_points_1d, nombre_pas_temps_1d, pas_temps_1d])
# Titre pour les parametres 2D
params_2d_title = pn.pane.Markdown("<h3 style='font-size: 16pt; font-weight: bold;'>Parametres de l'equation de transport 2D</h3>")
template.sidebar.append(params_2d_title)
# Ajouter les widgets des parametres 2D a la barre laterale
template.sidebar.extend([alpha_2d, longueur_2d, temps_total_2d, nombre_points_x_2d, nombre_points_y_2d, nombre_pas_temps_2d, pas_temps_2d])
# Fonction pour mettre a jour les graphiques
def update_plots(alpha_1d, longueur_1d, nombre_points_1d, nombre_pas_temps_1d, pas_temps_1d, alpha_2d, longueur_2d, temps_total_2d, nombre_points_x_2d, nombre_points_y_2d, nombre_pas_temps_2d, pas_temps_2d):
# Resolution de l'equation de transport 1D decentree a gauche
x_1d = np.linspace(0, longueur_1d, nombre_points_1d)
dx_1d = x_1d[1] - x_1d[0]
u_left_1d = np.sin(x_1d)
for n in range(nombre_pas_temps_1d):
u_left_1d[1:] -= alpha_1d * pas_temps_1d / dx_1d * (u_left_1d[1:] - u_left_1d[:-1])
u_left_1d[0] = u_left_1d[-1] # Condition periodique
# Resolution de l'equation de transport 1D decentree a droite
u_right_1d = np.sin(x_1d)
for n in range(nombre_pas_temps_1d):
u_right_1d[:-1] -= alpha_1d * pas_temps_1d / dx_1d * (u_right_1d[1:] - u_right_1d[:-1])
u_right_1d[-1] = u_right_1d[0] # Condition periodique
# Solution analytique pour 1D
u_exact_1d = np.sin(x_1d - alpha_1d * nombre_pas_temps_1d * pas_temps_1d)
# Resolution de l'equation de transport 2D decentree a gauche
x_2d = np.linspace(0, longueur_2d, nombre_points_x_2d)
y_2d = np.linspace(0, longueur_2d, nombre_points_y_2d)
X, Y = np.meshgrid(x_2d, y_2d)
dx_2d = x_2d[1] - x_2d[0]
dy_2d = y_2d[1] - y_2d[0]
u_left_2d = np.sin(X) * np.sin(Y)
for n in range(nombre_pas_temps_2d):
u_left_2d[1:, :] -= alpha_2d * pas_temps_2d / dx_2d * (u_left_2d[1:, :] - u_left_2d[:-1, :])
u_left_2d[:, 1:] -= alpha_2d * pas_temps_2d / dy_2d * (u_left_2d[:, 1:] - u_left_2d[:, :-1])
u_left_2d[-1, :] = u_left_2d[0, :] # Condition periodique
u_left_2d[:, -1] = u_left_2d[:, 0] # Condition periodique
# Resolution de l'equation de transport 2D decentree a droite
u_right_2d = np.sin(X) * np.sin(Y)
for n in range(nombre_pas_temps_2d):
u_right_2d[:-1, :] -= alpha_2d * pas_temps_2d / dx_2d * (u_right_2d[1:, :] - u_right_2d[:-1, :])
u_right_2d[:, :-1] -= alpha_2d * pas_temps_2d / dy_2d * (u_right_2d[:, 1:] - u_right_2d[:, :-1])
u_right_2d[-1, :] = u_right_2d[0, :] # Condition periodique
u_right_2d[:, -1] = u_right_2d[:, 0] # Condition periodique
# Solution analytique pour 2D
u_exact_2d = np.sin(X - alpha_2d * temps_total_2d) * np.sin(Y - alpha_2d * temps_total_2d)
# Creer la figure pour les graphiques 1D et 2D
fig = make_subplots(
rows=2, cols=3,
specs=[[{'type': 'scatter'}, {'type': 'scatter'}, {'type': 'scatter'}],
[{'type': 'surface'}, {'type': 'surface'}, {'type': 'surface'}]],
subplot_titles=('1D Decentre a Gauche', '1D Decentre a Droite', 'Solution Analytique 1D',
'2D Decentre a Gauche', '2D Decentre a Droite', 'Solution Analytique 2D')
)
# Ajouter les traces 1D
fig.add_trace(go.Scatter(x=x_1d, y=u_left_1d, mode='lines', name='1D Decentre a Gauche'), row=1, col=1)
fig.add_trace(go.Scatter(x=x_1d, y=u_right_1d, mode='lines', name='1D Decentre a Droite'), row=1, col=2)
fig.add_trace(go.Scatter(x=x_1d, y=u_exact_1d, mode='lines', name='Solution Analytique 1D'), row=1, col=3)
# Ajouter les traces 2D
fig.add_trace(go.Surface(z=u_left_2d, x=X, y=Y, colorscale='Viridis', name='2D Decentre a Gauche'), row=2, col=1)
fig.add_trace(go.Surface(z=u_right_2d, x=X, y=Y, colorscale='Viridis', name='2D Decentre a Droite'), row=2, col=2)
fig.add_trace(go.Surface(z=u_exact_2d, x=X, y=Y, colorscale='Viridis', name='Solution Analytique 2D'), row=2, col=3)
fig.update_layout(title_text='2D Transport Equation', template="plotly_dark")
fig.update_layout(height=1500, width=1750,
title_text='Solutions des equations de transport 1D et 2D',
font_color="white" , # Couleur du texte en blanc pour le thème sombre
legend=dict(
x=0.5, # Position horizontale
y=0.5, # Position verticale
traceorder='normal',
orientation='v' # Orientation verticale
))
return fig
# Lier la fonction de mise a jour aux widgets
interactive_plot = pn.bind(update_plots, alpha_1d, longueur_1d, nombre_points_1d, nombre_pas_temps_1d, pas_temps_1d, alpha_2d, longueur_2d, temps_total_2d, nombre_points_x_2d, nombre_points_y_2d, nombre_pas_temps_2d, pas_temps_2d)
# Ajouter la figure mise a jour au template
template.main.append(pn.pane.Plotly(interactive_plot))
# Afficher le template
template.servable()