s1Eva2018TI_T3 Temperatura en nodos de placa

Ejercicio: 1Eva2018TI_T3 Temperatura en nodos de placa

Placa Temperatura 03

literal a

Plantear el sistema de ecuaciones. Usando el promedio para cada nodo interior, según el enunciado:

La temperatura en los nodos de la malla de una placa se puede calcular con el promedio de las temperaturas de los 4 nodos vecinos de la izquierda, derecha, arriba y abajo.

a=\frac{50+c+100+b}{4} b=\frac{a+30+50+d}{4} c=\frac{a+60+100+d}{4} d=\frac{b+60+c+30}{4}

que reordenando se convierte en:

4a=150+c+b 4b=a+80+d 4c=a+160+d 4d=b+c+90

simplificando:

4a-b-c= 150 a-4b+d = -80 a-4c+d = -160 b+c-4d = -90

que a forma matricial se convierte en:

A = [[ 4, -1, -1, 0],
     [ 1, -4,  0, 1],
     [ 1,  0, -4, 1],
     [ 0,  1,  1,-4]]
B = [150,-80,-160,-90]

Observación: la matriz A ya es diagonal dominante, no requiere pivotear por filas. Para usar el algoritmo se requiere convertir A y B en arreglos:

A = np.array(A, dtype=float)
B = np.array(B, dtype=float)

El número de condición es:

np.linalg.cond(A) = 3.0

que es cercano a 1 en un orden de magnitud, por lo que la solución matricial es "estable" y los cambios en los coeficientes afectan proporcionalmente a los resultados. Se puede aplicar métodos iterativos sin mayores inconvenientes.

b y c) método de Jacobi para sistemas de ecuaciones, con vector inicial

X(0) = [60.0,40,70,50]

reemplazando los valores iniciales en cada ecuación sin cambios.

iteración 1

a=\frac{50+70+100+40}{4} = 65 b=\frac{60+30+50+50}{4} = 47.5 c=\frac{60+60+100+50}{4} = 67.5 d=\frac{40+60+70+30}{4} = 50
X(1) = [65,47.5,67.5,50]

vector de error = [ |65-60|,|47.5-40|,|67.5-70|,|50-50|]
  = [ |5|,|7.5|,|-2.5|,|0| ]
errormax = 7.5

iteración 2
a=\frac{50+67.5+100+47.5}{4} = 66.25

b=\frac{65+30+50+50}{4} = 48.75 c=\frac{65+60+100+50}{4} = 68.75 d=\frac{47.5+60+67.7+30}{4} = 51.3
X(2) = [66.25,48.75,68.75,51.3]

vector de error = [ |66.25-65|, |48.75-47.5|,|68.75-67.5|,|51.3-50| ] 
  = [ |1.25|,|1.25|,|1.25|,|1.3| ]
errormax = 1.3

iteración 3

a=\frac{50+68.75+100+48.75}{4} = 66.875 b=\frac{66.25+30+50+51.3}{4} = 49.38 c=\frac{66.25+60+100+51.3}{4} = 69.3875 d=\frac{48.75+60+68.75+30}{4} = 51.875
X(2) = [66.875,49.38,69.3875,51.875]

vector de error = [ |66.875-66.25|,|49.38-48.75|,|69.3875-68.75|,|51.875-51.3| ]
    = [ |0.655|,|0,63|,|0.6375|,|0.575| ]
errormax = 0.655
con error relativo de:
100*0.655/66.875 = 0.97%

siguiendo las iteraciones se debería llegar a:

>>> np.linalg.solve(A,B)
array([67.5, 50., 70., 52.5])

Algoritmo en Python

Matriz aumentada
[[   4.   -1.   -1.    0.  150.]
 [   1.   -4.    0.    1.  -80.]
 [   1.    0.   -4.    1. -160.]
 [   0.    1.    1.   -4.  -90.]]
Pivoteo parcial:
  Pivoteo por filas NO requerido
Iteraciones Jacobi
itera,[X]
     ,errado,|diferencia|
0 [60. 40. 70. 50.]
  nan
1 [65.  47.5 67.5 50. ]
  7.5 [5.  7.5 2.5 0. ]
2 [66.25 48.75 68.75 51.25]
  1.25 [1.25 1.25 1.25 1.25]
3 [66.875 49.375 69.375 51.875]
  0.625 [0.625 0.625 0.625 0.625]
4 [67.1875 49.6875 69.6875 52.1875]
  0.3125 [0.3125 0.3125 0.3125 0.3125]
5 [67.3438 49.8438 69.8438 52.3438]
  0.15625 [0.1562 0.1562 0.1562 0.1562]
6 [67.4219 49.9219 69.9219 52.4219]
  0.078125 [0.0781 0.0781 0.0781 0.0781]
7 [67.4609 49.9609 69.9609 52.4609]
  0.0390625 [0.0391 0.0391 0.0391 0.0391]
8 [67.4805 49.9805 69.9805 52.4805]
  0.01953125 [0.0195 0.0195 0.0195 0.0195]
9 [67.4902 49.9902 69.9902 52.4902]
  0.009765625 [0.0098 0.0098 0.0098 0.0098]
10 [67.4951 49.9951 69.9951 52.4951]
  0.0048828125 [0.0049 0.0049 0.0049 0.0049]
11 [67.4976 49.9976 69.9976 52.4976]
  0.00244140625 [0.0024 0.0024 0.0024 0.0024]
12 [67.4988 49.9988 69.9988 52.4988]
  0.001220703125 [0.0012 0.0012 0.0012 0.0012]
13 [67.4994 49.9994 69.9994 52.4994]
  0.0006103515625 [0.0006 0.0006 0.0006 0.0006]
Metodo de Jacobi
numero de condición: 3.000000000000001
X:  [67.4994 49.9994 69.9994 52.4994]
errado: 0.0006103515625
iteraciones: 13
>>>
1Eva2018TI_T3 Temperatura Nodos Placa Jacobi Graf01.

Algoritmo en Python

# 1Eva2018TI_T3 Temperatura en nodos de placa
# Metodo de Jacobi para sistemas de ecuaciones
import numpy as np
 
def jacobi(A,B,X0, tolera, iteramax=100,
           vertabla=False, precision=4):
    ''' Método de Jacobi, tolerancia, vector inicial X0
        para mostrar iteraciones y tabla: vertabla=True
    '''
    # Matrices como arreglo, numeros reales
    A = np.array(A,dtype=float)
    B = np.array(B,dtype=float)
    X0 = np.array(X0,dtype=float)
    tamano = np.shape(A) # tamaño A
    n = tamano[0]
    m = tamano[1]
     
    # valores iniciales
    diferencia = 2*tolera*np.ones(n, dtype=float)
    errado = 2*tolera     # np.max(diferencia)
    tabla = [np.copy(X0)] # tabla de iteraciones
    tabla = np.concatenate((tabla,[[np.nan]]),
                            axis=1) # errado
 
    if vertabla==True:
        print('Iteraciones Jacobi')
        print('itera,[X]')
        print('     ,errado,|diferencia|')
        print(0,X0)
        print(' ',np.nan)
        np.set_printoptions(precision)
 
    itera = 0 # Jacobi
    X = np.copy(X0)
    Xnuevo = np.copy(X0)
    while errado>tolera and itera<=iteramax:
         
        for i in range(0,n,1): # una ecuacion
            suma = B[i]
            for j in range(0,m,1): # un coeficiente
                if (i!=j): # excepto diagonal de A
                    suma = suma-A[i,j]*X[j]
            Xnuevo[i] = suma/A[i,i]
        diferencia = abs(Xnuevo-X)
        errado = np.max(diferencia)
        X = np.copy(Xnuevo)
 
        Xfila = np.concatenate((Xnuevo,[errado]),axis=0)
        tabla = np.concatenate((tabla,[Xfila]),axis=0)
 
        itera = itera + 1
 
        if vertabla==True:
            print(itera, Xnuevo)
            print(' ',errado,diferencia)
 
    # No converge
    if (itera>iteramax):
        X = np.nan
        print('No converge,iteramax superado')
 
    if vertabla==True:
        X = [X,tabla]
    return(X)
 
def pivoteafila(A,B,vertabla=False):
    '''
    Pivotea parcial por filas, entrega matriz aumentada AB
    Si hay ceros en diagonal es matriz singular,
    Tarea: Revisar si diagonal tiene ceros
    '''
    A = np.array(A,dtype=float)
    B = np.array(B,dtype=float)
    # Matriz aumentada
    nB = len(np.shape(B))
    if nB == 1:
        B = np.transpose([B])
    AB  = np.concatenate((A,B),axis=1)
     
    if vertabla==True:
        print('Matriz aumentada')
        print(AB)
        print('Pivoteo parcial:')
     
    # Pivoteo por filas AB
    tamano = np.shape(AB)
    n = tamano[0]
    m = tamano[1]
     
    # Para cada fila en AB
    pivoteado = 0
    for i in range(0,n-1,1):
        # columna desde diagonal i en adelante
        columna = np.abs(AB[i:,i])
        dondemax = np.argmax(columna)
         
        # dondemax no es en diagonal
        if (dondemax != 0):
            # intercambia filas
            temporal = np.copy(AB[i,:])
            AB[i,:] = AB[dondemax+i,:]
            AB[dondemax+i,:] = temporal
 
            pivoteado = pivoteado + 1
            if vertabla==True:
                print(' ',pivoteado, 'intercambiar filas: ',i,'y', dondemax+i)
    if vertabla==True:
        if pivoteado==0:
            print('  Pivoteo por filas NO requerido')
        else:
            print('AB')
            print(AB)
    return(AB)
 
# PROGRAMA Búsqueda de solucion  --------
# INGRESO
A = [[ 4, -1, -1, 0.0],
     [ 1, -4,  0, 1.0],
     [ 1,  0, -4, 1.0],
     [ 0,  1,  1,-4.0]]
B = [150,-80,-160,-90]
 
X0 = [60.0,40,70,50]
tolera = 0.001
iteramax = 100
verdecimal = 4
 
# PROCEDIMIENTO
AB = pivoteafila(A,B,vertabla=True)
n,m = np.shape(AB)
A = AB[:,:n] # separa en A y B
B = AB[:,n]
 
[X, tabla] = jacobi(A,B,X0,tolera,iteramax,
                    vertabla=True,
                    precision=verdecimal)
n_itera = len(tabla)-1
errado = tabla[-1,-1]
 
# numero de condicion
ncond = np.linalg.cond(A)
 
# SALIDA
print('Metodo de Jacobi')
print('numero de condición:', ncond)
print('X: ',X)
print('errado:',errado)
print('iteraciones:', n_itera)


# GRAFICA de iteraciones
errados = tabla[:,n]
 
import matplotlib.pyplot as plt
# grafica de error por iteracion
fig2D = plt.figure()
graf = fig2D.add_subplot(111)
graf.plot(errados)
graf.set_xlabel('itera')
graf.set_ylabel('|error|')
graf.set_title('Método de Jacobi: error[itera]')
graf.grid()
 
plt.show()

Ejemplos por año