1. Ejercicio g): 𝐹𝐺 y 𝐹𝑃
𝑙1 = 6 cm
𝑙2 = 8 cm 𝑟
𝑠
𝑞𝑣 = 10
kg
𝑐𝑚3𝑠
𝑥
𝑦
2. Matriz de coordenadas de los nodos y
matriz de conectividades
#Matriz de coordenadas de los nodos
X = np.array([[0,0],
[1,4],
[2,8],
[4,0],
[4,8],
[8,0],
[7,4],
[6,8]]) #cm
#Matriz de conectividades
#Se colocan las numeraciones globales de los nodos en las posiciones locales
MC = np.array([8,3,1,6,5,2,4,7])
1
2
3 4
8
5
6
7
4. Funciones de forma
#Funciones de forma
def funcion_H(r,s):
h8 = 1/2*(1-s**2)*(1+r)
h7 = 1/2*(1-r**2)*(1-s)
h6 = 1/2*(1-s**2)*(1-r)
h5 = 1/2*(1-r**2)*(1+s)
h4 = 1/4*(1+r)*(1-s) - h7/2 - h8/2
h3 = 1/4*(1-r)*(1-s) - h6/2 - h7/2
h2 = 1/4*(1-r)*(1+s) - h5/2 - h6/2
h1 = 1/4*(1+r)*(1+s) - h5/2 - h8/2
H = np.array([h1,h2,h3,h4,h5,h6,h7,h8])
return H
5. Derivadas de las funciones de forma
Se colocan las derivadas de las funciones de
forma respecto de las coordenadas locales en
una matriz como la siguiente:
𝑑𝐻 =
𝜕ℎ1
𝜕𝑟
𝜕ℎ2
𝜕𝑟
…
𝜕ℎ8
𝜕𝑟
𝜕ℎ1
𝜕𝑠
𝜕ℎ2
𝜕𝑠
…
𝜕ℎ8
𝜕𝑠
7. Matriz jacobiana
Las coordenadas globales interpoladas son:
𝑍𝛼 = ℎ𝑖 𝑍𝛼
𝑖
Con 𝑍𝛼 = 𝑥 si 𝛼 = 1, o 𝑍𝛼 = 𝑦 si 𝛼 = 2, teniendo el índice 𝑖 en
suma: 𝑖 = 1,2,3, … , 8
La matriz jacobiana de la transformación de coordenadas
globales (𝑍𝛼) a locales (𝜃𝑙) es:
𝐽 =
𝜕𝑥
𝜕𝑟
𝜕𝑦
𝜕𝑟
𝜕𝑥
𝜕𝑠
𝜕𝑦
𝜕𝑠
Por lo tanto, se puede intuir que:
𝐽𝑙𝛼 =
𝜕𝑍𝛼
𝜕𝜃𝑙
=
𝜕ℎ𝑖
𝜕𝜃𝑙
𝑍𝛼
𝑖
= 𝑑𝐻𝑙𝑖 𝑍𝛼
𝑖
Coordenada 𝑍𝛼
del
nodo 𝑖
8. Matriz Jacobiana
#Matriz jacobiana
def funcion_matrizJ(r,s,X,MC,dH):
#Se inicializan las derivadas en cero
xr, xs, yr, ys = 0, 0, 0, 0
#Se realizan las sumatorias para las 8 funciones de forma
for i in range(8):
xr += dH[0][i]*X[int(MC[i]-1)][0]
xs += dH[1][i]*X[int(MC[i]-1)][0]
yr += dH[0][i]*X[int(MC[i]-1)][1]
ys += dH[1][i]*X[int(MC[i]-1)][1]
#Se insertan las derivadas en la matriz jacobiana
matrizJ = np.array([[xr,yr],
[xs,ys]])
return matrizJ
9. Matriz B (𝛻𝐻)
Sabiendo que la inversa de la matriz jacobiana es:
𝐽 −1
=
𝜕𝑟
𝜕𝑥
𝜕𝑠
𝜕𝑥
𝜕𝑟
𝜕𝑦
𝜕𝑠
𝜕𝑦
Se obtienen las derivadas de las funciones de forma
respecto de las coordenadas globales usando la
regla de la cadena:
𝜕ℎ𝑖
𝜕𝑍𝛼
=
𝜕ℎ𝑖
𝜕𝜃𝑙
𝜕𝜃𝑙
𝜕𝑍𝛼
= 𝑑𝐻𝑙𝑖 𝐽𝛼𝑙
−1
⇒ 𝐵 = 𝐽 −1
⋅ [𝑑𝐻]
10. Matriz B
#Matriz B (gradiente de H)
def funcion_matrizB(matrizJ,dH):
#Inversa de la matriz jacobiana
matrizJ_inv = np.linalg.inv(matrizJ)
#Matriz B
B = np.matmul(matrizJ_inv,dH)
return B
11. Tabla de integración por Gauss-
Legendre
#Integracion por Gauss-Legendre
def intregralGauss(nGauss):
#Iniciamos los vectores de pesos y posiciones de Gauss en cero
w = np.zeros(int(nGauss)) #pesos
r = np.zeros(int(nGauss)) #posiciones
#Introducimos los valores de la tabla para cada n
if nGauss==1:
w[0] = 2
r[0] = 0
elif nGauss==2:
r[0] = np.sqrt(1/3)
r[1] = -np.sqrt(1/3)
w[0] = 1
w[1] = 1
elif nGauss==3:
r[0] = 0
r[1] = np.sqrt(3/5)
r[2] = -np.sqrt(3/5)
w[0] = 8/9
w[1] = 5/9
w[2] = 5/9
elif nGauss==4:
r[0] = np.sqrt((3-2*np.sqrt(6/5))/7)
r[1] = -np.sqrt((3-2*np.sqrt(6/5))/7)
r[2] = np.sqrt((3+2*np.sqrt(6/5))/7)
r[3] = -np.sqrt((3+2*np.sqrt(6/5))/7)
w[0] = (18+np.sqrt(30))/36
w[1] = (18+np.sqrt(30))/36
w[2] = (18-np.sqrt(30))/36
w[3] = (18-np.sqrt(30))/36
return r,w
𝑤𝑖
13. Pesos de Petrov
Se tiene el vector velocidad: v = 2 2
cm
s
Se calcula su norma:
𝑉 = 22 + 22 = 2 2
cm
s
Se definen las longitudes características:
𝑙1 = 6 cm ; 𝑙2 = 8 cm
Sabiendo que la difusividad es 𝑘 = 0,001
𝑐𝑚2
𝑠
, se
calculan los números de Peclet en cada dirección:
𝑃𝑒1 =
𝑣1𝑙1
2𝑘
= 6000 ; 𝑃𝑒2 =
𝑣2𝑙2
2𝑘
= 8000
14. Pesos de Petrov
Se calculan los coeficientes auxiliares:
𝛼1 = coth 𝑃𝑒1 −
1
𝑃𝑒1
=
5999
6000
𝛼2 = coth 𝑃𝑒2 −
1
𝑃𝑒2
=
7999
6000
Se calcula el tiempo intrínseco:
𝜏 =
𝛼1𝑣1𝑙1
2𝑉2
+
𝛼2𝑣2𝑙2
2𝑉2
= 1,74975 s
Finalmente, se calcula el vector de pesos de Petrov:
𝑊 = 𝜏 v ⋅ [𝐵]
15. Pesos de Petrov
def petrov(r,s,X,MC):
#Difusividad
k = 0.001 #cm^2/s
#Vector velocidad
v = np.array([2,2]) #cm/s
#Norma del vector velocidad
V = np.sqrt(v[0]**2 + v[1]**2)
#Longitudes caracteristicas en cada direccion
l1 = 6 #cm
l2 = 8 #cm
#Numero de Peclet en cada direccion
Pe1 = v[0]*l1/(2*k)
Pe2 = v[1]*l2/(2*k)
#Coeficiente alpha
α1 = 1/np.tanh(abs(Pe1)) - 1/abs(Pe1)
α2 = 1/np.tanh(abs(Pe2)) - 1/abs(Pe2)
#Tiempo intrinseco
τ = α1*v[0]*l1/(2*V**2) + α2*v[1]*l2/(2*V**2)
#Derivadas de las funciones de forma
dH = funcion_dH(r,s)
#Jacobiana
matrizJ = funcion_matrizJ(r,s,X,MC,dH)
#Matriz B
B = funcion_matrizB(matrizJ,dH)
#Vector de pesos de Petrov
W = τ*np.matmul(v,B)
return W
16. Vectores de fuerzas
Se calculan los vectores de fuerzas de Galerkin y Petrov
locales de acuerdo a las siguientes expresiones:
𝐹𝐺
(𝑒)
=
𝑉
𝑞𝑣 𝐻𝑑𝑉 = 𝑒𝑠𝑝
−1 −1
1 1
𝑞𝑣 𝐻(𝑟, 𝑠) 𝐽 (𝑟, 𝑠)𝑑𝑟 𝑑𝑠
𝐹𝑃
(𝑒)
=
𝑉
𝑞𝑣 𝑊𝑑𝑉 = 𝑒𝑠𝑝
−1 −1
1 1
𝑞𝑣 𝑊(𝑟, 𝑠) 𝐽 (𝑟, 𝑠)𝑑𝑟 𝑑𝑠
Supongo espesor unitario (𝑒𝑠𝑝 = 1).
17. Vectores de fuerzas
Integrando numéricamente por Gauss, se tiene:
𝐹𝐺
(𝑒)
=
𝑖=1
𝑛
𝑗=1
𝑛
𝑞𝑣 𝑤𝑖𝑤𝑗 𝐻 𝑟𝑖, 𝑠𝑗 𝐽 𝑟𝑖, 𝑠𝑗
𝐹𝑃
(𝑒)
=
𝑖=1
𝑛
𝑗=1
𝑛
𝑞𝑣 𝑤𝑖𝑤𝑗 𝑊 𝑟𝑖, 𝑠𝑗 𝐽 𝑟𝑖, 𝑠𝑗
Siendo el número de puntos de Gauss: 𝑛 = 3
18. Vectores de fuerzas
Finalmente, para obtener los vectores de fuerzas
con la numeración global de los nodos, se utiliza
la matriz de conectividades:
Nodo local Nodo global
𝑖 𝑀𝐶𝑖
19. Vectores de fuerzas
#Vectores de fuerzas externas de Galerkin y Petrov
def vecF(qv,X,MC,nGauss):
#Se obtienen los pesos y puntos de Gauss
x,w = intregralGauss(nGauss)
#Se inicializan los vectores con ceros
FGL = np.zeros((8,1))
FPL = np.zeros((8,1))
#Se recorren los puntos de Gauss
for i in range(nGauss):
for j in range(nGauss):
#Posiciones de Gauss
r = x[i]
s = x[j]
#Funciones de forma
H = funcion_H(r,s)
#Derivadas de las funciones de forma
dH = funcion_dH(r,s)
#Matriz jacobiana
matrizJ = funcion_matrizJ(r,s,X,MC,dH)
#Determinante jacobiano
J = abs(np.linalg.det(matrizJ))
#Vector de pesos de Petrov
W = petrov(r,s,X,MC)
#Vector de fuerzas de Galerkin local
FGL += w[i]*w[j]*J*qv*np.reshape(H,(8,1))
#Vector de fuerzas de Petrov local
FPL += w[i]*w[j]*J*qv*np.reshape(W,(8,1))
#Se inicializan los vectores de fuerzas con orden global
FG = np.zeros((8,1))
FP = np.zeros((8,1))
#Se llenan los vectores de fuerzas (ensamble)
for l in range(8):
FG[int(MC[l])-1] += FGL[l]
FP[int(MC[l])-1] += FPL[l]
return FG, FP