mirror of
https://github.com/BreizhHardware/py_CIPA3.git
synced 2026-03-18 21:30:27 +01:00
update exercise 2: enhance heat equation simulation in Jupyter notebook, improve matrix construction and add temperature profile visualization
This commit is contained in:
@@ -1,18 +1,83 @@
|
|||||||
# Eq en régime permanent
|
import numpy as np
|
||||||
# d2T / dx2 = 0
|
import matplotlib.pyplot as plt
|
||||||
# T(x =0) = T0
|
import matplotlib.cm as cm
|
||||||
# T(x = 1) = T1
|
|
||||||
# T(i)i E [0, N+1]
|
|
||||||
# x(i+1) - x(i) = deltaX = 1/N
|
|
||||||
# d2T/dx2 = (T(i-1) - 2*T(i) + T(i+1))/deltaX**2
|
|
||||||
|
|
||||||
# Question 1: Résoudre cette équation pour les conditions aux bord
|
# Constantes et paramètres
|
||||||
# d2T / dx2 => dT / dx = A => T(x) = Ax + b
|
N = 1000
|
||||||
# Ici b = T0 d'où T(x) = Ax + T0
|
delta_x = 1 / N
|
||||||
# T1 - T0 / 1 - 0 = A = T1 - T0 donc T(x) = (T1 - T0)x + T0
|
delta_x2 = delta_x**2
|
||||||
# Question 2: Ecrire l'équation de la chaleur discrétisée pour i E [1, N-2], puis pour i = 0 et i = N
|
D = 1
|
||||||
# d2T/dx2 = 0
|
delta_t = 0.9 * (delta_x2 / 2 * D)
|
||||||
# T(i+1) - 2*T(i) + T(i-1) = 0
|
T0 = 0
|
||||||
# Pour i = 0
|
T1 = 0
|
||||||
# -2T0 + T(1) = -T0-
|
|
||||||
# Pour i = N
|
if delta_t < (delta_x2 / 2 * D):
|
||||||
|
M = np.zeros((N + 1, N + 1))
|
||||||
|
|
||||||
|
# Remplissage de la matrice M
|
||||||
|
for i in range(N + 1):
|
||||||
|
if i == 0:
|
||||||
|
M[i, i] = 1 - 2 * delta_t * D / delta_x2
|
||||||
|
M[i, i + 1] = delta_t * D / delta_x2
|
||||||
|
elif i == N:
|
||||||
|
M[i, i - 1] = delta_t * D / delta_x2
|
||||||
|
M[i, i] = 1 - 2 * delta_t * D / delta_x2
|
||||||
|
else:
|
||||||
|
M[i, i - 1] = delta_t * D / delta_x2
|
||||||
|
M[i, i] = 1 - 2 * delta_t * D / delta_x2
|
||||||
|
M[i, i + 1] = delta_t * D / delta_x2
|
||||||
|
|
||||||
|
# Vecteur spatial pour tracer
|
||||||
|
x = np.linspace(0, 1, N + 1)
|
||||||
|
|
||||||
|
# Condition initiale T₀(x) = sin(πx)
|
||||||
|
T = np.sin(np.pi * x)
|
||||||
|
T[0] = T0
|
||||||
|
T[N] = T1
|
||||||
|
|
||||||
|
# Temps de simulation
|
||||||
|
temps_final = 0.1
|
||||||
|
nb_iterations = int(temps_final / delta_t)
|
||||||
|
|
||||||
|
# Nombre de courbes souhaité
|
||||||
|
nb_courbes = 100000
|
||||||
|
|
||||||
|
# Sauvegarder plus de profils à différents temps
|
||||||
|
profils = [T.copy()]
|
||||||
|
iterations_sauvegarde = np.linspace(0, nb_iterations, nb_courbes, dtype=int)
|
||||||
|
temps_sauvegarde = [0] + [i * delta_t for i in iterations_sauvegarde[1:]]
|
||||||
|
|
||||||
|
# Simulation de l'évolution temporelle
|
||||||
|
for n in range(nb_iterations):
|
||||||
|
T = M @ T
|
||||||
|
if n in iterations_sauvegarde:
|
||||||
|
profils.append(T.copy())
|
||||||
|
|
||||||
|
# Tracer les profils de température avec un dégradé de couleurs
|
||||||
|
plt.figure(figsize=(12, 8))
|
||||||
|
colormap = cm.viridis
|
||||||
|
|
||||||
|
# Affichage des courbes avec un dégradé de couleurs
|
||||||
|
for i, t in enumerate(temps_sauvegarde):
|
||||||
|
if i < len(profils):
|
||||||
|
couleur = colormap(i / len(temps_sauvegarde))
|
||||||
|
plt.plot(x, profils[i], color=couleur, alpha=0.7)
|
||||||
|
|
||||||
|
# Afficher seulement quelques légendes pour éviter l'encombrement
|
||||||
|
indices_legende = np.linspace(0, len(temps_sauvegarde) - 1, 10, dtype=int)
|
||||||
|
for i in indices_legende:
|
||||||
|
if i < len(profils):
|
||||||
|
couleur = colormap(i / len(temps_sauvegarde))
|
||||||
|
plt.plot([], [], color=couleur, label=f"t = {temps_sauvegarde[i]:.4f}s")
|
||||||
|
|
||||||
|
plt.xlabel("Position x")
|
||||||
|
plt.ylabel("Température T")
|
||||||
|
plt.title("Évolution de la température au cours du temps (50 courbes)")
|
||||||
|
plt.legend(loc="upper right")
|
||||||
|
plt.grid(True)
|
||||||
|
plt.colorbar(plt.cm.ScalarMappable(cmap=colormap), label="Temps (s)", ax=plt.gca())
|
||||||
|
plt.show()
|
||||||
|
else:
|
||||||
|
print("Constante incorrect")
|
||||||
|
print(f"delta_t = {delta_t}")
|
||||||
|
print(f"(delta_x2 / 2 * D) = {(delta_x2 / 2 * D)}")
|
||||||
|
|||||||
@@ -250,22 +250,30 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {},
|
"metadata": {
|
||||||
|
"jupyter": {
|
||||||
|
"is_executing": true
|
||||||
|
},
|
||||||
|
"ExecuteTime": {
|
||||||
|
"start_time": "2025-04-01T09:53:17.236001Z"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"source": [
|
||||||
"import numpy as np\n",
|
"import numpy as np\n",
|
||||||
"import matplotlib.pyplot as plt\n",
|
"import matplotlib.pyplot as plt\n",
|
||||||
|
"import matplotlib.cm as cm\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Constantes et paramètres\n",
|
"# Constantes et paramètres\n",
|
||||||
"N = 10\n",
|
"N = 1000\n",
|
||||||
"delta_t = (delta_x2 / 2 * D)\n",
|
"delta_x = 1/N\n",
|
||||||
"delta_x2 = 1/N\n",
|
"delta_x2 = delta_x**2\n",
|
||||||
"D = 1\n",
|
"D = 1\n",
|
||||||
|
"delta_t = 0.9 * (delta_x2 / 2 * D)\n",
|
||||||
"T0 = 0\n",
|
"T0 = 0\n",
|
||||||
"T1 = 0\n",
|
"T1 = 0\n",
|
||||||
"\n",
|
"\n",
|
||||||
"if delta_t < (delta_x2 / 2 * D):\n",
|
"if delta_t < (delta_x2 / 2 * D):\n",
|
||||||
"\n",
|
|
||||||
" M = np.zeros((N + 1, N + 1))\n",
|
" M = np.zeros((N + 1, N + 1))\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Remplissage de la matrice M\n",
|
" # Remplissage de la matrice M\n",
|
||||||
@@ -281,9 +289,6 @@
|
|||||||
" M[i, i] = (1 - 2 * delta_t * D / delta_x2)\n",
|
" M[i, i] = (1 - 2 * delta_t * D / delta_x2)\n",
|
||||||
" M[i, i + 1] = delta_t * D / delta_x2\n",
|
" M[i, i + 1] = delta_t * D / delta_x2\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Affichage de la matrice M\n",
|
|
||||||
" print(f\"Matrice M: {M}\")\n",
|
|
||||||
"\n",
|
|
||||||
" # Vecteur spatial pour tracer\n",
|
" # Vecteur spatial pour tracer\n",
|
||||||
" x = np.linspace(0, 1, N+1)\n",
|
" x = np.linspace(0, 1, N+1)\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -296,30 +301,44 @@
|
|||||||
" temps_final = 0.1\n",
|
" temps_final = 0.1\n",
|
||||||
" nb_iterations = int(temps_final / delta_t)\n",
|
" nb_iterations = int(temps_final / delta_t)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Sauvegarder quelques profils à différents temps\n",
|
" # Nombre de courbes souhaité\n",
|
||||||
|
" nb_courbes = 100000\n",
|
||||||
|
"\n",
|
||||||
|
" # Sauvegarder plus de profils à différents temps\n",
|
||||||
" profils = [T.copy()]\n",
|
" profils = [T.copy()]\n",
|
||||||
" temps_sauvegarde = [0, 0.01, 0.02, 0.05, 0.1]\n",
|
" iterations_sauvegarde = np.linspace(0, nb_iterations, nb_courbes, dtype=int)\n",
|
||||||
" indices_sauvegarde = [int(t/delta_t) for t in temps_sauvegarde[1:]]\n",
|
" temps_sauvegarde = [0] + [i * delta_t for i in iterations_sauvegarde[1:]]\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Simulation de l'évolution temporelle\n",
|
" # Simulation de l'évolution temporelle\n",
|
||||||
" for n in range(nb_iterations):\n",
|
" for n in range(nb_iterations):\n",
|
||||||
" T = M @ T\n",
|
" T = M @ T\n",
|
||||||
" if n+1 in indices_sauvegarde:\n",
|
" if n in iterations_sauvegarde:\n",
|
||||||
" profils.append(T.copy())\n",
|
" profils.append(T.copy())\n",
|
||||||
"\n",
|
"\n",
|
||||||
" print(f\"Solution profils: {profils}\")\n",
|
" # Tracer les profils de température avec un dégradé de couleurs\n",
|
||||||
|
" plt.figure(figsize=(12, 8))\n",
|
||||||
|
" colormap = cm.viridis\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Tracer les profils de température\n",
|
" # Affichage des courbes avec un dégradé de couleurs\n",
|
||||||
" plt.figure(figsize=(10, 6))\n",
|
|
||||||
" for i, t in enumerate(temps_sauvegarde):\n",
|
" for i, t in enumerate(temps_sauvegarde):\n",
|
||||||
" if i < len(profils):\n",
|
" if i < len(profils):\n",
|
||||||
" plt.plot(x, profils[i], label=f't = {t}s')\n",
|
" couleur = colormap(i / len(temps_sauvegarde))\n",
|
||||||
|
" plt.plot(x, profils[i], color=couleur, alpha=0.7)\n",
|
||||||
|
"\n",
|
||||||
|
" # Afficher seulement quelques légendes pour éviter l'encombrement\n",
|
||||||
|
" indices_legende = np.linspace(0, len(temps_sauvegarde)-1, 10, dtype=int)\n",
|
||||||
|
" for i in indices_legende:\n",
|
||||||
|
" if i < len(profils):\n",
|
||||||
|
" couleur = colormap(i / len(temps_sauvegarde))\n",
|
||||||
|
" plt.plot([], [], color=couleur, label=f't = {temps_sauvegarde[i]:.4f}s')\n",
|
||||||
"\n",
|
"\n",
|
||||||
" plt.xlabel('Position x')\n",
|
" plt.xlabel('Position x')\n",
|
||||||
" plt.ylabel('Température T')\n",
|
" plt.ylabel('Température T')\n",
|
||||||
" plt.title('Évolution de la température au cours du temps')\n",
|
" plt.title('Évolution de la température au cours du temps (50 courbes)')\n",
|
||||||
" plt.legend()\n",
|
" plt.legend(loc='upper right')\n",
|
||||||
" plt.grid(True)\n",
|
" plt.grid(True)\n",
|
||||||
|
" plt.colorbar(plt.cm.ScalarMappable(cmap=colormap),\n",
|
||||||
|
" label='Temps (s)', ax=plt.gca())\n",
|
||||||
" plt.show()\n",
|
" plt.show()\n",
|
||||||
"else:\n",
|
"else:\n",
|
||||||
" print(\"Constante incorrect\")\n",
|
" print(\"Constante incorrect\")\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user