#!/usr/bin/python # -*- coding: utf-8 -*- """ Ejemplo del Metodo de Diferencias Finitas para resolver la ecuacion diferencial parcial: Uxx=-Pi*Pi*cos(Pix) xi<=U<=xf U(xi)=vi y U(xf)=vf con solucion analitica: cos(pix) Para conocer mas del metodo ver: http://132.248.182.159/acl/MDF Autor: Antonio Carrillo Ledesma http://mmc.geofisica.unam.mx/acl """ # 2.X compatible from __future__ import print_function import sys if sys.version[0] == '2': input = raw_input import math def LadoDerecho(x): "Lado derecho de la ecuacion diferencial parcial" return -math.pi * math.pi * math.cos(math.pi * x) def Jacobi(A, b, N, iter): "Resuelve Ax=b usando el metodo Jacobi" sum = 0 x = [0] * N xt = [0] * N for m in range(iter): for i in range(N): sum = 0.0 for j in range(N): if i == j: continue sum += A[i][j] * x[j] xt[i] = (1.0 / A[i][i]) * (b[i] - sum) for i in range(N): x[i] = xt[i]; return x def GaussSeidel(A, b, N, iter): "Resuelve Ax=b usando el metodo GaussSeidel" sum = 0 x = [0] * N for m in range(iter): for i in range(N): sum = 0.0 for j in range(N): if i == j: continue sum += A[i][j] * x[j] x[i] = (1.0 / A[i][i]) * (b[i] - sum) return x # MDF1DD if __name__ == '__main__': xi = 0.0 # Inicio del diminio xf = 1.0 # Fin del dominio vi = 1.0 # Valor en la frontera xi vf = -1.0 # Valor en la frontera xf n = 11 # Particion N = n-2 # Incognitas h = (xf - xi) / (n - 1); # Incremento en la malla # Declaracion de la matriz A y los vectores b y x A = [] # Matriz A for i in range(N): A.append([0]*N) b = [0] * N # Vector b x = [0] * N # Vector x # Stencil R = 1 / (h * h) P = -2 / (h * h) Q = 1 / (h * h) # Primer renglon de la matriz A y vector b A[0][0] = P A[0][1] = Q b[0] = LadoDerecho(xi) - vi * R print(b) # Renglones intermedios de la matriz A y vector b for i in range(1,N-1): A[i][i - 1] = R A[i][i] = P A[i][i + 1] = Q b[i] = LadoDerecho(xi + h * (i + 1)) # Renglon final de la matriz A y vector b A[N - 1][N - 2] = R A[N - 1][N - 1] = P b[N - 1] = LadoDerecho(xi + h * N - 2) - vf * Q # Resuelve por el metodo Jacobi for i in range(N): for j in range(N): print(' ', A[i][j],end='') print("") print(b) x = Jacobi(A, b, N, N*14) print(x) # Solucion print(xi, vi) for i in range(N): print(xi + h * (i + 1), x[i]) print(xf, vf) # Resuelve por el metodo Gauss-Seidel for i in range(N): for j in range(N): print(' ', A[i][j],end='') print("") print(b) x = GaussSeidel(A, b, N, N*7) print(x) # Solucion print(xi, vi) for i in range(N): print(xi + h * (i + 1), x[i]) print(xf, vf)