Introduction aux mathématiques numériques
Ceci est le "Bonjour, monde!" des PDE (Partial Differential Equations). L'équation de Laplace ou de diffusion apparaît souvent en physique, par exemple l'équation de la chaleur, la déformation, la dynamique des fluides, etc. et pas chanter "99 bouteilles de bière, ..." cette tâche est donnée en 1D. Vous pouvez interpréter cela comme une robe en caoutchouc attachée à un mur aux deux extrémités avec une certaine force appliquée.
Sur un [0,1]
domaine, trouvez une fonction u
pour une fonction source donnée f
et des valeurs limites u_L
et u_R
telles que:
-u'' = f
u(0) = u_L
u(1) = u_R
u''
désigne la dérivée seconde de u
Cela peut être résolu purement théorique mais votre tâche est de le résoudre numériquement sur un domaine discrétisé x pour les N
points:
- x =
{i/(N-1) | i=0..N-1}
ou 1:{(i-1)/(N-1) | i=1..N}
h = 1/(N-1)
est l'espacement
Contribution
f
comme fonction ou expression ou chaîneu_L
, enu_R
tant que valeurs à virgule flottanteN
comme entier> = 2
Production
- Array, List, une sorte de chaîne séparée de
u
telle sorte queu_i == u(x_i)
Exemples
Exemple 1
Entrée: f = -2
, u_L = u_R = 0
, N = 10
(Ne pas prendre f=-2
mal, ce n'est pas une valeur , mais une fonction constante que le rendement -2
pour tous x
Il est comme une force de gravité constante sur notre corde..)
Production: [-0.0, -0.09876543209876543, -0.1728395061728395, -0.22222222222222224, -0.24691358024691357, -0.24691358024691357, -0.22222222222222224, -0.1728395061728395, -0.09876543209876547, -0.0]
Il existe une solution exacte simple: u = -x*(1-x)
Exemple 2
Entrée: f = 10*x
, u_L = 0
u_R = 1
, N = 15
(Ici il y a beaucoup de vent debout sur le côté droit)
Production: [ 0., 0.1898688, 0.37609329, 0.55502915, 0.72303207, 0.87645773, 1.01166181, 1.125, 1.21282799, 1.27150146, 1.29737609, 1.28680758, 1.2361516, 1.14176385, 1.]
La solution exacte pour cela indique: u = 1/3*(8*x-5*x^3)
Exemple 3
Entrée: f = sin(2*pi*x)
, u_L = u_R = 1
, N = 20
(Quelqu'un a brisé la gravité ou il y a une sorte de haut et sous le vent)
Production: [ 1., 1.0083001, 1.01570075, 1.02139999, 1.0247802, 1.0254751, 1.02340937, 1.01880687, 1.01216636, 1.00420743, 0.99579257, 0.98783364, 0.98119313, 0.97659063, 0.9745249, 0.9752198, 0.97860001, 0.98429925, 0.9916999, 1.]
Ici, la solution exacte est u = (sin(2*π*x))/(4*π^2)+1
Exemple 4
Entrée: f = exp(x^2)
, u_L = u_R = 0
,N=30
Production:
[ 0. 0.02021032 0.03923016 0.05705528 0.07367854 0.0890899
0.10327633 0.11622169 0.12790665 0.13830853 0.14740113 0.15515453
0.16153488 0.1665041 0.17001962 0.172034 0.17249459 0.17134303
0.16851482 0.1639387 0.15753606 0.1492202 0.13889553 0.12645668
0.11178744 0.09475961 0.07523169 0.05304738 0.02803389 0. ]
Notez la légère asymétrie
FDM
Une méthode possible pour résoudre ce problème est la méthode des différences finies :
- réécrire
-u_i'' = f_i
comme (-u_{i-1} + 2u_i - u{i+1})/h² = f_i
ce qui équivaut-u_{i-1} + 2u_i - u{i+1} = h²f_i
- Configurez les équations:
- Qui sont égaux à une équation matrice-vecteur:
- Résolvez cette équation et sortez le
u_i
Une implémentation de ceci pour démonstration en Python:
import matplotlib.pyplot as plt
import numpy as np
def laplace(f, uL, uR, N):
h = 1./(N-1)
x = [i*h for i in range(N)]
A = np.zeros((N,N))
b = np.zeros((N,))
A[0,0] = 1
b[0] = uL
for i in range(1,N-1):
A[i,i-1] = -1
A[i,i] = 2
A[i,i+1] = -1
b[i] = h**2*f(x[i])
A[N-1,N-1] = 1
b[N-1] = uR
u = np.linalg.solve(A,b)
plt.plot(x,u,'*-')
plt.show()
return u
print laplace(lambda x:-2, 0, 0, 10)
print laplace(lambda x:10*x, 0, 1, 15)
print laplace(lambda x:np.sin(2*np.pi*x), 1, 1, 20)
Implémentation alternative sans algèbre matricielle (en utilisant la méthode Jacobi )
def laplace(f, uL, uR, N):
h=1./(N-1)
b=[f(i*h)*h*h for i in range(N)]
b[0],b[-1]=uL,uR
u = [0]*N
def residual():
return np.sqrt(sum(r*r for r in[b[i] + u[i-1] - 2*u[i] + u[i+1] for i in range(1,N-1)]))
def jacobi():
return [uL] + [0.5*(b[i] + u[i-1] + u[i+1]) for i in range(1,N-1)] + [uR]
while residual() > 1e-6:
u = jacobi()
return u
Vous pouvez cependant utiliser toute autre méthode pour résoudre l'équation de Laplace. Si vous utilisez une méthode itérative, vous devez itérer jusqu'à ce que le résidu |b-Au|<1e-6
, avec b
être le vecteur de droiteu_L,f_1h²,f_2h²,...
Remarques
En fonction de votre méthode de résolution, il se peut que vous ne résolviez pas les exemples exactement aux solutions données. Au moins pour N->infinity
l'erreur devrait approcher de zéro.
Les failles standard sont interdites , les fonctions intégrées pour les PDE sont autorisées.
Prime
Un bonus de -30% pour l'affichage de la solution, graphique ou ASCII.
Gagnant
Ceci est codegolf, donc le code le plus court en octets gagne!
log(log(x))
ou sqrt(1-x^4)
qui ont une intégrale, qui n'est cependant pas exprimable dans les fonctions élémentaires.
u(x) = 1/2 (-sqrt(π) x erfi(x)+sqrt(π) erfi(1) x+e^(x^2)-e x+x-1)
n'est pas exactement calculable.
f(x) = exp(x^2)
.