Você está na página 1de 21

25/11/2020 Aula 2.

ipynb - Colaboratory

UNIVERSIDADE FEDERAL DO RIO DE JANEIRO - UFRJ

Programa de Pós Graduação em Informática

Laboratório de Combinatória e Computação Cientí ca

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 1/21
25/11/2020 Aula 2.ipynb - Colaboratory

Abrindo a caixa-preta dos elementos nitos

Objetivos
1) Despertar o interesse no estudo do método dos elementos nitos

2) Mostrar algumas técnicas da implementação

3) Mostrar como determinar as funções de interpolação

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 2/21
25/11/2020 Aula 2.ipynb - Colaboratory

Abrindo a caixa-preta dos elementos nitos

O que NÃO vamos fazer


1) Ensinar a programar. Os códigos aqui apresentados têm o objetivo apenas didático. Para
códigos mais completos visite https://dcc.ufrj.br/~rincon/#book

2) Apresentar demonstações, estimativa de erro etc

3) Esgotar o assunto Elementos Finitos. Para quem se interessar, convido a participar da


discilina Análise Numérica I (MAB766) do PPGI, com início em 4 de janeiro de 2021 (inscriçõs
entre 2 e 8 de janeiro)

Abrindo a caixa-preta dos elementos nitos


Sumário
1) Problema do calor: da Formulação Fraca à Formulação Matricial

2) Montando o sistema linear pela ótica dos elementos nitos

2.1) Discretização do domínio e funções de interpolação

2.2) Restringindo ao domínio do elemento nito

2.3) Relação entre matrizes e vetores locais com a matriz e o vetor globais

2.4) Cálculo de matizes e vetores locais

3) Um exemplo simples

4) Construindo um elemento nito quadrilátero

5) Notas sobre elementos nitos triangulares

Abrindo a caixa-preta dos elementos nitos

Referências
1) Introdução ao Método de Elementos Finito - Análise e Aplicação - (3º Edição)

Autores: Mauro A. Rincon e I-Shih Liu

ISBN: 85-87674-05-6
https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 3/21
25/11/2020 Aula 2.ipynb - Colaboratory

Instituto de Matemática - UFRJ - (2015)

https://dcc.ufrj.br/~rincon/#book

2)

3)

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 4/21
25/11/2020 Aula 2.ipynb - Colaboratory

Vamos agora implementar a montagem da matriz global


Sejam LG e EQ como abaixo:

a\e 1 2 3 4 5 6 7 8

1 2 4 5 8 6 7 10 12

LG : 2 1 7 7 15 7 14 15 15

3 3 6 4 10 8 15 12 14

4 4 2 3 9 9 8 11 13

A 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
EQ :
i 1 0 2 3 4 0 5 6 0 0 0 7 8 9 10

1 import numpy as np
2 import matplotlib.pyplot as plt
3 from sympy import *
4 import math
5 from numpy import linalg as la

1 # propriedade do material
2 Q = [[1.0,0.0],[0.0,1.0]]

1 #Vamos definir alguns dados da malha
2 nel = 8
3 nnos = 15
4 nosp = 5
5 neq = nnos - nosp

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 5/21
25/11/2020 Aula 2.ipynb - Colaboratory

1 # Vamos definir as estruturas acima
2 LGMalha1 = [[2, 4, 5, 8,  6, 7,  10, 12],
3       [1, 7, 7, 15, 7, 14, 15, 15],
4       [3, 6, 4, 10, 8, 15, 12, 14],
5       [4, 2, 3, 9,  9, 8,  11, 13]]
6 EQMalha1 = [1,0,2,3,4,0,5,6,0,0,0,7,8,9,10]

1 #Vamos definir as coordenadas dos nós da malha
2 pxMalha1 = [1.0, 2.0, 0.0, 2.0, 2.0, 3.0, 4.0, 5.0, 5.0, 7.0, 8.0, 8.0, 7.5, 6.0
3 pyMalha1 = [2.0, 2.5, 1.0, 1.5, 0.0, 3.0, 0.5, 1.0, 3.0, 3.0, 1.5, 1.0, 0.2, 0.0

1 # Gerando grafico da malha
2 xg = [0,0,0,0,0]
3 yg = [0,0,0,0,0]
4  
5 for e in range(nel):
6   for a in range(4):
7     xg[a] = pxMalha1[LGMalha1[a][e]-1]
8     yg[a] = pyMalha1[LGMalha1[a][e]-1]
9   xg[a+1] = xg[0]
10   yg[a+1] = yg[0]
11   plt.plot(xg, yg)
12   plt.scatter(xg, yg, marker="*", color='red')

1 def calculaKe(e):
2   for a in range(4):
3     for b in range(4):
4       Ke[a][b] = 1.0
5   return Ke

1 def acumulaKe(Ke):
2   for a in range(4):
3     for b in range(4):
4       i = EQMalha1[LGMalha1[a][e]-1]
5       j = EQMalha1[LGMalha1[b][e]-1]
6       if (i!=0) and (j!=0):
7         K[i-1][j-1] = K[i-1][j-1] + Ke[a][b]
8   return K
https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 6/21
25/11/2020 Aula 2.ipynb - Colaboratory

1 # Vamos montar a matriz local K
2  
3 # Cria a matriz global K com zeros
4 K = [ ]
5 for i in range ( neq ):
6   list.append(K,[ 0.0 ]*neq )
7  
8 # Cria a matriz local Ke com zeros  
9 Ke = [ ]
10 for i in range ( 4 ):
11   list.append(Ke,[0]*4 )
12  
13 # percorre os elementos finitos montando Ke e acumulando em K  
14 for e in range(nel):
15   # Calcula Ke. Por enquanto será formada de um
16   Ke = calculaKe(e)
17   K = acumulaKe(Ke)
18 for i in range (neq):
19   print(K[i])

[1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[1.0, 2.0, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[1.0, 2.0, 3.0, 1.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[0.0, 1.0, 2.0, 1.0, 4.0, 2.0, 0.0, 0.0, 1.0, 1.0]
[0.0, 0.0, 0.0, 0.0, 2.0, 3.0, 0.0, 0.0, 1.0, 2.0]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 1.0, 1.0, 2.0]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0]
[0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0]
[0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 2.0, 1.0, 2.0, 4.0]

A 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
EQ :
i 1 0 2 3 4 0 5 6 0 0 0 7 8 9 10

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 7/21
25/11/2020 Aula 2.ipynb - Colaboratory

2.4) Cálculo de matizes e vetores locais


Vamos agora ver como determinar cada uma das matrizes locais.

Vimos que os elementos da matriz local K e são dados por

e e T e
K = a(Φa , Φb ) = ∫ (∇Φa )  Q (∇Φ ) dΩe , 1 ≤ a, b ≤ 4
ab b
Ωe

Ou seja, precisamos resolver uma integral dupla no domínio de cada elemento nito.

Como cada elemento nito pode ser um quadrilátero qualquer, é razoável efetuarmos uma
mudança de variáveis para facilitar este cálculo.

Assim, ao invés de usarmos funções de interpolação Φea (x, y),  a = 1, 2, 3, 4 usaremos


funções de interpolação Φa (ξ, η),  a = 1, 2, 3, 4 .

Para a mudança de variáveis, temos


∂ Φa ∂ Φa ∂ ξ ∂ Φa ∂ η
= + , a = 1, 2, 3, 4
∂x ∂ξ ∂x ∂η ∂x

∂ Φa ∂ Φa ∂ ξ ∂ Φa ∂ η
= + , a = 1, 2, 3, 4
∂y ∂ξ ∂y ∂η ∂y

Na forma matricial temos


∂Φa ∂ξ ∂η ∂Φa

⎡ ⎤ ⎡ ⎤⎡ ∂ξ

∂x ∂x ∂x −1
∇Φa (x, y) = = = J ∇Φa (ξ, η), a = 1, 2, 3, 4,
∂Φa ∂ξ ∂η ∂Φa
⎣ ⎦ ⎣ ⎦⎣ ⎦
∂y ∂y ∂y ∂η

onde
https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 8/21
25/11/2020 Aula 2.ipynb - Colaboratory

xξ yξ
J = [ ]
xη yη

é a matriz jacobiana da transformação.

Assim, cada elemento da matriz local pode ser escrito da seguinte forma:

e T −T −1
K = ∫ (∇Φa (ξ, η))  J  Q J  (∇Φb (ξ, η))  det(J ) dΩb
ab
Ωb

Fazendo
∂Φ1 ∂Φ2 ∂Φ3 ∂Φ4
⎡ (ξ, n) (ξ, n) (ξ, n) (ξ, n) ⎤
∂ξ ∂ξ ∂ξ ∂ξ
D =
∂Φ1 ∂Φ2 ∂Φ3 ∂Φ4
⎣ (ξ, n) (ξ, n) (ξ, n) (ξ, n) ⎦
∂η ∂η ∂η ∂η

a matriz local K e é escrita matricialmente como

e T −T −1
K = ∫ D  J  Q J  D  det(J ) dΩb
Ωb

Para o cálculo do jacobiano e de seu determinante vamos considerar a formulação


isoparamétrica, ou seja, vamos usar as mesmas funções de interpolação Φ(ξ, η) para interpolar
as coordenadas espaciais e a temperatura.

Assim,
4

x = ∑ xa Φa (ξ, n)

a=1

y = ∑ y a Φa (ξ, n)

a=1

onde (xa , y a ) são as coordenadas do nó a, a = 1, 2, 3, 4 do elemento nito e

Logo,

4 ∂Φa 4 ∂Φa ∂Φ1 ∂Φ2

xξ yξ ⎡ ∑ a=1 xa (ξ, n) ∑
a=1
ya (ξ, n) ⎤ ⎡ (ξ, η) (ξ, η)
∂ξ ∂ξ ∂ξ ∂ξ
J = [ ] = =
4 ∂Φa 4 ∂Φa ∂Φ1 ∂Φ2
xη yη ⎣∑ xa (ξ, n) ∑ ya (ξ, n) ⎦ ⎣ (ξ, η) (ξ, η)
a=1 ∂η a=1 ∂η ∂η ∂η

Precisamos agora das funções de interpolação de nidas no elemento biunitário Ωb .

Sabemos que elas devem ser tais que

1 se b = a
Φa (ξ b , η b ) = { , 1 ≤ a, b ≤ 4
0 se b ≠ a

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 9/21
25/11/2020 Aula 2.ipynb - Colaboratory

e são funções lineares em cada direção, já que temos dois nós em cada direção.

Neste ponto, vamos de nir essas funções por inspeção (vamos ver como de ni-las depois).

Assim, com
ξ 1 = (−1, −1)

ξ 2 = (1, −1)

ξ 3 = (1, 1)

ξ 4 = (−1, 1)

temos o seguinte:
1−η
(1 − ξ)(1 − η) −
4
Φ1 (ξ, η) = ⇒ ∇Φ1 = [ ]
1−ξ
4

4
1−η
(1 + ξ)(1 − η)
4
Φ2 (ξ, η) = ⇒ ∇Φ2 = [ ]
1+ξ
4

4
1+η
(1 + ξ)(1 + η)
4
Φ3 (ξ, η) = ⇒ ∇Φ3 = [ ]
1+ξ
4
4
1+η
(1 − ξ)(1 + η) −
4
Φ4 (ξ, η) = ⇒ ∇Φ4 = [ ]
1−ξ
4
4

1 # Define as funções de interpolação
2 def Phi1(xi,eta):
3   return (1-xi)*(1-eta)/4
4  
5 def Phi2(xi,eta):
6   return (1+xi)*(1-eta)/4
7  
8 def Phi3(xi,eta):
9   return (1+xi)*(1+eta)/4
10  
11 def Phi4(xi,eta):
12 return (1-xi)*(1+eta)/4
https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 10/21
25/11/2020 Aula 2.ipynb - Colaboratory
12   return (1 xi) (1+eta)/4

1 # Define as derivada das funções de interpolação
2 def dPhi1dxi(xi,eta):
3   return -1*(1-eta)/4
4 def dPhi1deta(xi,eta):
5   return -1*(1-xi)/4
6  
7 def dPhi2dxi(xi,eta):
8   return (1-eta)/4
9 def dPhi2deta(xi,eta):
10   return -1*(1+xi)/4
11  
12 def dPhi3dxi(xi,eta):
13   return (1+eta)/4
14 def dPhi3deta(xi,eta):
15   return (1+xi)/4
16  
17 def dPhi4dxi(xi,eta):
18   return -1*(1+eta)/4
19 def dPhi4deta(xi,eta):
20   return (1-xi)/4

Vamos determinar o jacobiano para algumas elementos nitos.

Vamos começar com elementos nitos bem comportados

1 # Elemento finito biunitário
2 coordb = [[-1.0,-1.0],[3.0,-1.0],[3.0,1.0],[-1.0,1.0]]
3 print(coordb[0][1])
4 plt.plot([coordb[0][0],coordb[1][0],coordb[2][0],coordb[3][0],coordb[0][0]], [co
5 plt.scatter([coordb[0][0],coordb[1][0],coordb[2][0],coordb[3][0]], [coordb[0][1

-1.0
<matplotlib.collections.PathCollection at 0x7f6b6eeef8d0>

1 # Calculando o jacobiano
2 xi  = 0.5
3 eta = 0.45
4 D=[[dPhi1dxi(xi,eta), dPhi2dxi(xi,eta), dPhi3dxi(xi,eta), dPhi4dxi(xi,eta)],[dPh
https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 11/21
25/11/2020 Aula 2.ipynb - Colaboratory
5 print(D)
6 J=[[0.0,0.0],[0.0,0.0]]
7 for i in range(2):
8   for j in range(2):
9     soma = 0.0
10     for k in range(4):
11       soma = soma + D[i][k] * coordb[k][j]
12     J[i][j] = soma  
13 print('Matriz jacobiana J= ',J)
14 detJ = J[0][0]*J[1][1]-J[0][1]*J[1][0]
15 print('Determinante do jacobiano: det(J) = ',detJ)

[[-0.1375, 0.1375, 0.3625, -0.3625], [-0.125, -0.375, 0.375, 0.125]]


Matriz jacobiana J= [[2.0, 0.0], [0.0, 1.0]]
Determinante do jacobiano: det(J) = 2.0

Temos agora condições de determinar uma matriz local de nossa malha.

Para isso, vamos considerar e = 5

1 # coordenadas do nó e=5
2 coord5 = [[3.0,3.0],[4.0,0.5],[5.0,1.0],[5.0,3.0]]
3 print(coord5[0][1])
4 plt.plot([coord5[0][0],coord5[1][0],coord5[2][0],coord5[3][0],coord5[0][0]], [co
5 plt.scatter([coord5[0][0],coord5[1][0],coord5[2][0],coord5[3][0]], [coord5[0][1

3.0
<matplotlib.collections.PathCollection at 0x7f6b6f4940b8>

Para este elemento, temos:

1 # Calculando o jacobiano
2 xi  = 0.5
3 eta = 0.0
4 D=[[dPhi1dxi(xi,eta), dPhi2dxi(xi,eta), dPhi3dxi(xi,eta), dPhi4dxi(xi,eta)],[dPh
5 J=[[0.0,0.0],[0.0,0.0]]
6 for i in range(2):
7   for j in range(2):
8     soma = 0.0
9     for k in range(4):
https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 12/21
25/11/2020 Aula 2.ipynb - Colaboratory
g
10       soma = soma + D[i][k] * coord5[k][j]
11     J[i][j] = soma  
12 print('Matriz jacobiana J= ',J)
13 detJ = J[0][0]*J[1][1]-J[0][1]*J[1][0]
14 print('Determinante do jacobiano: det(J) = ',detJ)

Matriz jacobiana J= [[0.25, -1.125], [0.625, 0.1875]]


Determinante do jacobiano: det(J) = 0.75

Vamos agora determinar uma matriz local.

Vimos que

e T −T −1
K = ∫ D  J  Q J  D  det(J ) dΩb
Ωb

Logo, precisamos utilizar algum método numérico de integração. Vamos usar a quadratura
gaussiana com dois pontos de gauss em cada direção.

Neste método, temos


1 1 npg

∫ ∫ g(ξ, η) dξ dη = ∑ g(ξ k , η k ) wk


−1 −1
k=1

onde (ξ k , ηk ) são os pontos de Gauss e wk os pesos de Gauss, com k = 1, 2, . . . , npg e npg


a quantidade de pontos de Gauss considerados.

Assim,

e T −T −1
K = ∫ D  J  Q J  D  det(J ) dΩb =
Ωb

1 1
T −T −1
= ∫ ∫ D  J  Q J  D  det(J ) dΩb =
−1 −1

npg

T −T −1
= ∑[D(ξ k , η k )]  [J (ξ k , η k )]  Q  [J (ξ k , η k )]  D(ξ k , η k )  det(J (ξ k , η k ))wk

k=1

Sabemos que a quadratura gaussiana com npg calcula o valor exato de integrais de polinômios
de grau menor ou igual a 2npg − 1 . Vamos considerar dois pontos de Gauss em cada direção.

Assim, com npg = 4 temos

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 13/21
25/11/2020 Aula 2.ipynb - Colaboratory

√ (3) √ (3)
(ξ 1 , η 1 ) = ( , )
3 3

−√ (3) √ (3)
(ξ 2 , η 2 ) = ( , )
3 3

−√ (3) −√ (3)
(ξ 3 , η 3 ) = ( , )
3 3

√ (3) −√ (3)
(ξ 4 , η 4 ) = ( , )
3 3

e wk = 1,  k = 1, 2, 3, 4 .

Logo,
4

e T −T −1
K = ∑[D(ξ k , η k )]  [J (ξ k , η k )]  Q  [J (ξ k , η k )]  D(ξ k , η k )  det(J (ξ k , η k ))

k=1

Vamos determinar K 5 :

1 ptG = [[sqrt(3.0)/3.0,sqrt(3.0)/3.0],[-sqrt(3.0)/3.0,sqrt(3.0)/3.0],[-sqrt(3.0)/
2 pG = [1,1,1,1]
3 e=5
4  
5 # Cria a matriz global K com zeros
6 K5 = [ ]
7 for i in range ( 4 ):
8   list.append(K5,[ 0.0 ]*4 )
9  
10 for pg in range(4):
11   # monta matriz com derivadas das funcoes de interpolacao no potno de gauss
12   D=[[dPhi1dxi(ptG[pg][0],ptG[pg][1]), dPhi2dxi(ptG[pg][0],ptG[pg][1]), dPhi3dxi
13   # determina matriz jacobiana
14   J=[[0.0,0.0],[0.0,0.0]]
15   for i in range(2):
16     for j in range(2):
17       soma = 0.0
18       for k in range(4):
19         soma = soma + D[i][k] * coord5[k][j] #  <<<<<<<---------- ALTERE AQUI PA
20       J[i][j] = soma  
21   # determinante jacobiano
22   detJ = J[0][0]*J[1][1]-J[0][1]*J[1][0]
23   # matriz inversa do jacobiano
24   invJ = [[J[1][1]/detJ, -J[0][1]/detJ],[-J[1][0]/detJ, J[0][0]/detJ]]
25   for a in range(4):
26     for b in range(4):
27       for p in range(2):
28         for k in range(2):
29           for L in range(2):
30             for m in range(2):
https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 14/21
25/11/2020 Aula 2.ipynb - Colaboratory

31               K5[a][b] = K5[a][b]+D[p][a]*invJ[k][p]*Q[k][L]*J[L][m]*D[m][b]*pG
32           

1 for i in range(4):
2   print(K5[i])

[-0.468750000000000, -0.270833333333333, 0.291666666666667, 0.447916666666666


[0.166666666666667, -0.666666666666667, 0.166666666666667, 0.333333333333333]
[0.182291666666667, 0.541666666666667, -0.593750000000000, -0.130208333333333
[0.119791666666667, 0.395833333333333, 0.135416666666667, -0.651041666666667]

Agora vamos juntar os códigos feitos anteriormente para determinarmos a matriz global K da
malha.

Vamos inicialmente rede nir a função que calcula a matriz local K e .

1 def calculaKe(e):
2   # inicia a matriz Ke
3   for a in range(4):
4     for b in range(4):
5       Ke[a][b] = 0.0
6   # pega as coordenadas dos nós do elemento finito e
7   coord = [ [ px[LG[0][e]-1],py[LG[0][e]-1] ], [ px[LG[1][e]-1],py[LG[1][e]-1] 
8   for pg in range(4):
9     # monta matriz com derivadas das funcoes de interpolacao no potno de gauss
10     D=[[dPhi1dxi(ptG[pg][0],ptG[pg][1]), dPhi2dxi(ptG[pg][0],ptG[pg][1]), dPhi3d
11     # cria a matriz J
12     J=[[0.0,0.0],[0.0,0.0]]
13     # efetua o produto D * coord, ou seja, determina J
14     for i in range(2):
15       for j in range(2):
16         soma = 0.0
17         for k in range(4):
18           soma = soma + D[i][k] * coord[k][j]
19         J[i][j] = soma  
20     # determinante jacobiano
21     detJ = J[0][0]*J[1][1]-J[0][1]*J[1][0]
22     if (detJ<=0):
23       print('DETERMINANTE JACOBIANO MENOR QUE ZERO NO ELEMENTO FINITO ',e)
24       exit
25     # matriz inversa do jacobiano
26     invJ = [[J[1][1]/detJ, -J[0][1]/detJ],[-J[1][0]/detJ, J[0][0]/detJ]]
27     # calcula a matriz local Ke
28     for a in range(4):
29       for b in range(4):
30         for p in range(2):
31           for k in range(2):
32             for L in range(2):
33               for m in range(2):
34                 Ke[a][b] = Ke[a][b]+D[p][a]*invJ[k][p]*Q[k][L]*J[L][m]*D[m][b]*p
35   return Ke

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 15/21
25/11/2020 Aula 2.ipynb - Colaboratory

Vamos rede nir a função que acumula K e em K

1 def acumulaKe(Ke,K,e):
2   for a in range(4):
3     for b in range(4):
4       i = EQ[LG[a][e]-1]
5       j = EQ[LG[b][e]-1]
6       if (i!=0) and (j!=0):
7         K[i-1][j-1] = K[i-1][j-1] + Ke[a][b]
8   return K

Agora vamos percorrer os elementos nitos, montando a matriz local K e de cada um deles e
armazenando na matriz global K :

1 def montaK(K):
2   # inicia a matriz local Ke
3   Ke = [ ]
4   for i in range ( 4 ):
5     list.append(Ke,[ 0.0 ]*4 )
6   
7   for e in range(nel):
8     Ke = calculaKe(e)
9     K = acumulaKe(Ke,K,e)
10  
11   return K

Por uma questão de didática vamos, sem muito detalhamento, montar o vetor F , considerando
f = 0 em Ω e, como já considerado na malha, apenas condições de contorno prescritas.

Nessas condições, temos como vetor global

F i = −a(p, Φi (ξ, η)), 1 ≤ i ≤ neq

sendo p a função que de ne a temperatura prescrita nos nós.

Inicialmente, vamos considerar um vetor P de nnos elementos que armazena os valores


prescritos da temperatura. Logicamente, nos nós onde não há temperatura prescrita o valor é
igual a zero.

Assim,

P = [0, 100, 0, 0, 0, 100, 0, 0, 100, 100, 100, 0, 0, 0, 0]

onde, SPG, escolhemos como valor prescrito a temperatura 100 em todos os nós do contorno
Γp .

Vamos usar as funções de interpolação Φ para interpolar a função p em cada elemento nito,
ou seja,

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 16/21
25/11/2020 Aula 2.ipynb - Colaboratory
4

p(x, y) = ∑ pb Φb (ξ, η)

b=1

onde pb é o valor prescrito no nó local a.

Assim, o vetor local F e é de nido por


4 4

e
Fa = −a(∑ pb Φb (ξ, η), Φa (ξ, η)) = − ∑ pb a(Φb (ξ, η), Φa (ξ, η)), 1 ≤ a ≤ 4

b=1 b=1

Logo,
4

e e
Fa = − ∑ pb K
ab

b=1

Ou seja, F e é o resultado do produto de K e por um vetor de 4 elementos que armazena as


temperaturas prescritas nos nós do elemento nito e.

1 # funcao que calcula Fe
2 def calculaFe(e):
3   # inicia a matriz local Ke
4   Ke = [ ]
5   for i in range ( 4 ):
6     list.append(Ke,[ 0.0 ]*4 )
7  
8   # inicia o vetor Fe e o vetor pe de temperaturas locais prescritas
9   Fe = [0.0, 0.0, 0.0, 0.0]
10   tempP = [0.0, 0.0, 0.0, 0.0]
11   # pega as temperaturas prescritas no elemento finito e
12   for a in range(4):
13       tempP[a] = P[LG[a][e]-1]
14   # chama a funcao que calcula Ke
15   Ke = calculaKe(e)
16   for i in range(4):
17     soma = 0.0
18     for j in range(4):
19       soma = soma - Ke[i][j] * tempP[j]
20     Fe[i] =  soma 
21   return Fe
22   
23   
24   

1 # funcao que acumula os valores do vetor local Fe no vetor global F
2 def acumulaFe(Fe,F,e):
3   for a in range(4):
4       i = EQ[LG[a][e]-1]
5       if (i!=0):
6         F[i-1] = F[i-1] + Fe[a]
7   return F

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 17/21
25/11/2020 Aula 2.ipynb - Colaboratory

1 def montaF(F):
2   # percorre os elementos finitos, montando o vetor local Fe e acumulando em F
3   # inicia o vetor local Fe
4   Fe = [0.0, 0.0, 0.0, 0.0]
5  
6   for e in range(nel):
7     Fe = calculaFe(e)
8     F = acumulaFe(Fe,F,e)
9   return F

3) Um exemplo simples

1 # LG e EQ
2 LG=[ [1,2,3,4,6,7,8,9], 
3     [2,3,4,5,7,8,9,10], 
4     [7,8,9,10,12,13,14,15],
5     [6,7,8,9,11,12,13,14]]
6 #EQ=[0,1,2,3,0,0,4,5,6,0,0,7,8,9,0]
7 EQ=[0,1,2,0,0,0,3,4,5,0,0,6,7,0,0]  # usar este com neq=7
8 # define o vetor com temperaturas prescritas
9 #P = [0, 0, 0, 0, 100, 0, 0, 0, 0, 100, 0, 0, 0, 0, 100]
10 P = [0, 0, 0, 100, 100, 0, 0, 0, 0, 100, 0, 0, 0, 100, 100]  # usar este com neq
11 # valores
12 nnos = 15
13 neq = 7
14 nel = 8
15 # coordenadas
16 px=[0,2,4,6,8,0,2,4,6,8,0,2,4,6,8]
17 py=[0,0,0,0,0,2,2,2,2,2,4,4,4,4,4]
18  
19 # Gerando grafico da malha
20 xg = [0,0,0,0,0]
21 yg = [0,0,0,0,0]
22 for e in range(nel):
23   for a in range(4):
24     xg[a] = px[LG[a][e]-1]
25     yg[a] = py[LG[a][e]-1]
26   xg[a+1] = xg[0]
27   yg[a+1] = yg[0]
28   plt.plot(xg, yg)
29   plt.scatter(xg, yg, marker="*", color='red')

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 18/21
25/11/2020 Aula 2.ipynb - Colaboratory

1 # inicia a matriz global K
2 K = [ ]
3 for i in range ( neq ):
4   list.append(K,[ 0.0 ]*neq )
5  
6 # chama funcao que monta a matriz global K
7 K = montaK(K)
8  
9 # inicia o vetor global F
10 F = [ ]
11 for i in range ( neq ):
12   list.append(F,0.0 )
13  
14 # chama funcao que monta o vetor global F
15 F = montaF(F)
16  
17 # exibe matriz K e vetor F
18 for i in range(neq):
19   print('K[',i,'] = ',K[i])
20 print('-----')
21 print('F = ',F)

K[ 0 ] = [1.33333333333333, -0.166666666666667, -0.333333333333333, -0.33333


K[ 1 ] = [-0.166666666666667, 1.33333333333333, -0.333333333333333, -0.33333
K[ 2 ] = [-0.333333333333333, -0.333333333333333, 2.66666666666667, -0.33333
K[ 3 ] = [-0.333333333333333, -0.333333333333333, -0.333333333333333, 2.6666
K[ 4 ] = [0.0, -0.333333333333333, 0.0, -0.333333333333333, 2.66666666666667
K[ 5 ] = [0.0, 0.0, -0.333333333333333, -0.333333333333333, 0.0, 1.333333333
K[ 6 ] = [0.0, 0.0, -0.333333333333333, -0.333333333333333, -0.3333333333333
-----
F = [0, 16.6666666666667, 0, 66.6666666666667, 166.666666666667, 0, 16.66666

1 ################################################
2 # Resolvendo o sistema linear pelo método da fatoração LU
3 ################################################
4 # vetor de solucao do sistema linear
5 solnum = np.zeros(neq)
6 # vetor auxiliar que armazena a solucao de Ly=b
7 yvetor = solnum.copy()
8 # transforma K, um alista de lista, em array
9 Umatriz = np.array(K) # Kmatriz.copy()
10 # transforma F, uma lista, em array
11 b = np.array(F)
12  
13 Lmatriz = np.zeros((neq, neq ))
14  
15 for i in range(neq):
16     Lmatriz[i,i] = 1
17     for k in range(i):
18         Lmatriz[i,k] = Umatriz[i,k]/Umatriz[k,k]
https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 19/21
25/11/2020 Aula 2.ipynb - Colaboratory

19         Umatriz[i] = Umatriz[i] - (Umatriz[i,k]/Umatriz[k,k])*Umatriz[k]
20  
21 for i in range(neq):
22     yvetor[i] = (b[i] - np.sum(Lmatriz[i]*yvetor))/Lmatriz[i,i]
23 for i in range(neq)[::-1]:
24     solnum[i] = (yvetor[i] - np.sum(Umatriz[i]*solnum))/Umatriz[i,i]
25  
26 print("A solucao do sistema eh", solnum)
27  

A solucao do sistema eh [31.00775194 61.14341085 30.8624031 62.59689922 85.6


61.14341085]

1 # preparando vetor com resultado, incluindo os valores prescritos
2 # inicia o vetor solucao u
3 u = [ ]
4 for i in range ( nnos ):
5   list.append(u,[ 0.0 ]*nnos )
6 for i in range(nnos):
7   if (EQ[i]==0):
8     u[i] = P[i]
9   else:
10     u[i] = solnum[EQ[i]-1]
11  
12 # Gerando grafico da malha
13 xg = [0,0,0,0,0]
14 yg = [0,0,0,0,0]
15 for e in range(nel):
16   for a in range(4):
17     xg[a] = px[LG[a][e]-1]
18     yg[a] = py[LG[a][e]-1]
19   xg[a+1] = xg[0]
20   yg[a+1] = yg[0]
21   umedia = (u[LG[0][e]-1]+u[LG[1][e]-1]+u[LG[2][e]-1]+u[LG[3][e]-1])/4.0
22   if (umedia<50):
23     cor = (0.0, umedia/50.0, 1-umedia/50.0)
24   else:
25     cor = ((umedia-50)/50.0, 1-(umedia-50)/50.0, 0.0)
26   plt.plot(xg, yg, color=cor)
27 plt.scatter(px, py, c=u, s=100, cmap="jet")
28 plt.colorbar()
29 plt.show()

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 20/21
25/11/2020 Aula 2.ipynb - Colaboratory

https://colab.research.google.com/drive/1qMg_sPFLFT4AXcJWyH7Vou9u6Ob_q-I6#scrollTo=hW6VyMMmFatV&printMode=true 21/21

Você também pode gostar