# 2Eva_IT2010_T2 Movimiento angularimport numpy as np
import matplotlib.pyplot as plt
defrungekutta2_fg(f,g,x0,y0,z0,h,muestras):
tamano = muestras + 1
estimado = np.zeros(shape=(tamano,3),dtype=float)
# incluye el punto [x0,y0,z0]
estimado[0] = [x0,y0,z0]
xi = x0
yi = y0
zi = z0
for i inrange(1,tamano,1):
K1y = h * f(xi,yi,zi)
K1z = h * g(xi,yi,zi)
K2y = h * f(xi+h, yi + K1y, zi + K1z)
K2z = h * g(xi+h, yi + K1y, zi + K1z)
yi = yi + (K1y+K2y)/2
zi = zi + (K1z+K2z)/2
xi = xi + h
estimado[i] = [xi,yi,zi]
return(estimado)
# INGRESO theta = y
ft = lambda t,y,z: z
gt = lambda t,y,z: -10*np.sin(y)
t0 = 0
y0 = 0
z0 = 0.1
h=0.2
muestras = 5
# PROCEDIMIENTO
tabla = rungekutta2_fg(ft,gt,t0,y0,z0,h,muestras)
# SALIDAprint(' [ t, \t\t y, \t dyi/dti=z]')
print(tabla)
# Grafica
ti = np.copy(tabla[:,0])
yi = np.copy(tabla[:,1])
zi = np.copy(tabla[:,2])
plt.subplot(121)
plt.plot(ti,yi)
plt.xlabel('ti')
plt.title('yi')
plt.subplot(122)
plt.plot(ti,zi, color='green')
plt.xlabel('ti')
plt.title('dyi/dti')
plt.show()
siendo λ = 1, al tener la malla en cuadrícula Δx=Δy
ui+1,j−4ui,j+ui−1,j+ui,j+1+ui,j−1=20Δx2
despejando u[i,j]
ui,j=41(ui+1,j+ui−1,j+ui,j+1+ui,j−1−20Δx2)
Para el ejercicio, se debe usar las fronteras para los valores de cálculo que se puede hacer de dos formas:
1. Por posición del valor en la malla [i,j]
2. Por valor xi,yj que es la forma usada cuando la función es contínua.
1. Por posición del valor en la malla
Se busca la posición de la esquina derecha ubicada en xi = 0 y yj=1.5 y se la ubica como variable ‘desde’ como referencia para ubicar los valores de las fronteras usando los índices i, j.
# valores en fronteras# busca poscición de esquina izquierda
desde = -1
for j inrange(0,m,1):
if ((yj[j]-1.5)<tolera):
desde = j
# llena los datos de bordes de placafor j inrange(0,m,1):
if (yj[j]>=1):
u[j-desde,j] = Ta
u[n-1,j] = Tb(xi[n-1],yj[j])
for i inrange(0,n,1):
if (xi[i]>=1):
u[i,m-1]=Td
u[i,desde-i] = Tc(xi[i],yj[i])
# valor inicial de iteración
2. Por valor xi, yj
Se establecen las ecuaciones que forman la frontera:
que se usan como condición para hacer el cálculo en cada nodo
if ((yj[j]-yjmin)>tolera and (yj[j]-yjmax)<-tolera):
u[i,j] = (u[i-1,j]+u[i+1,j]+u[i,j-1]+u[i,j+1]-20*(dx**2))/4
Para minimizar errores por redondeo o truncamiento al seleccionar los puntos, la referencia hacia cero se toma como «tolerancia»; en lugar de más que cero o menos que cero.
Con lo que se obtiene el resultado mostrado en la gráfica aumentando la resolución con Δx=Δy=0.05:
# Ecuaciones Diferenciales Parciales# Elipticas. Método iterativo para placa NO rectangularimport numpy as np
# INGRESO# Condiciones iniciales en los bordes
Ta = 100
Tb = lambda x,y:(100/2.5)*y
Tc = lambda x,y: 100-(100/1.5)*x
Td = 100
# dimensiones de la placa no rectangular
x0 = 0
xn = 1.5
y0 = 0
yn = 2.5
ymin = lambda x,y: 1.5-(1.5/1.5)*x
ymax = lambda x,y: 1.5+(1/1)*x
# discretiza, supone dx=dy
dx = 0.05
dy = 0.05
maxitera = 100
tolera = 0.0001
# PROCEDIMIENTO
xi = np.arange(x0,xn+dx,dx)
yj = np.arange(y0,yn+dy,dy)
n = len(xi)
m = len(yj)
# Matriz u
u = np.zeros(shape=(n,m),dtype = float)
# valores en fronteras# busca posición de esquina izquierda
desde = -1
for j inrange(0,m,1):
if ((yj[j]-1.5)<tolera): desde = j
# llena los datos de bordes de placa for j inrange(0,m,1): if (yj[j]>=1):
u[j-desde,j] = Ta
u[n-1,j] = Tb(xi[n-1],yj[j])
for i inrange(0,n,1):
if (xi[i]>=1):
u[i,m-1]=Td
u[i,desde-i] = Tc(xi[i],yj[i])
# valor inicial de iteración# se usan los valores cero# iterar puntos interiores
itera = 0
converge = 0
whilenot(itera>=maxitera and converge==1):
itera = itera + 10000
nueva = np.copy(u)
for i inrange(1,n-1):
for j inrange(1,m-1):
yjmin = ymin(xi[i],yj[j])
yjmax = ymax(xi[i],yj[j])
if ((yj[j]-yjmin)>tolera and (yj[j]-yjmax)<-tolera):
u[i,j] = (u[i-1,j]+u[i+1,j]+u[i,j-1]+u[i,j+1]-20*(dx**2))/4
diferencia = nueva-u
erroru = np.linalg.norm(np.abs(diferencia))
if (erroru<tolera):
converge=1
# SALIDA
np.set_printoptions(precision=2)
print('converge = ', converge)
print('xi=')
print(xi)
print('yj=')
print(yj)
print('matriz u')
print(u)
Para incorporar la gráfica en forma de superficie.
# Gráficaimport matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
X, Y = np.meshgrid(xi, yj)
U = np.transpose(u) # ajuste de índices fila es x
figura = plt.figure()
ax = Axes3D(figura)
ax.plot_surface(X, Y, U, rstride=1, cstride=1, cmap=cm.Reds)
plt.title('EDP elíptica')
plt.xlabel('x')
plt.ylabel('y')
plt.show()
Dado que las fórmlas de error usadas tienen error del orden h: O(h), el error de las fórmulas es del orden de:
h= dia[1]-dia[0] = 2-1 = 1
literal c
Para el día dos se observa un decrecimiento en la producción, tal como lo refleja el valor negativo de la primera derivada.
Sin embargo para el día siguiente, la producción no mantiene la tasa de decrecimiento, se observa la segunda derivada positiva, Empieza a «acelerar».
Las instrucciones en Python para la tabla presentada son:
# 2Eva_IT2008_T1_MN Producción petroleoimport numpy as np
import matplotlib.pyplot as plt
# INGRESO
dia = np.array( [1., 2, 3, 4, 5, 6, 7, 8, 9, 10])
produccion = [3345., 3245, 3211, 3309, 3351, 3412, 3230, 3135, 3132, 3129]
produccion = np.array(produccion, dtype = float)
# PROCEDIMIENTO
n = len(dia)
# primera derivada
dp = np.zeros(n,dtype=float)
for i inrange(0,n-1,1):
dp[i] = (produccion[i+1]-produccion[i])/(dia[i+1]-dia[i])
# segunda derivada
d2p = np.zeros(n,dtype=float)
h = dia[1]-dia[0]
for i inrange(0,n-2,1):
d2p[i] = (produccion[i]-2*produccion[i+1]+ produccion[i+2])/(h**2)
tabla = np.concatenate(([dia],[produccion],[dp],[d2p]),axis=0)
tabla = np.transpose(tabla)
# SALIDAprint(" [ dia, prod, dprod, d2prod]")
print(tabla)
# gráfica
plt.subplot(121)
plt.plot(dia,produccion)
plt.xlabel('dia')
plt.ylabel('producción')
plt.grid()
plt.subplot(122)
plt.plot(dia,dp,color='green',label='dp')
plt.xlabel('dia')
plt.plot(dia,d2p,color='orange',label='d2p')
plt.axhline(0)
plt.legend()
plt.grid()
plt.show()