f(xx,yy)=-q(xx,yy)/K # o que aparece do lado direito da EDP
fc=matrix([[RR(f(x[i],y[j])) for j in range(m+1)] for i in range(n+1)]) # matriz de discretização do f das diferenças finitas (f é coeficiente da EDP)
Fc=matrix([[RR(F(-x[i]+x[ns],y[j]-y[m-ms])) if (i!=ns) & (j!=m-ms) else 0. for j in range(m+1)] for i in range(n+1)]) # usada pra discretizar a integral que aparece na condição de contorno
q2c=matrix([[RR(q2(x[i],y[j])) for j in range(m+1)] for i in range(n+1)]) # para fonte externa
# Step 3 # inicialização das matrizes de discretização
w=matrix([[0. for j in range(m+1)] for i in range(n+1)]) # Phi_i (solução discretizada)
w0=matrix([[0. for j in range(m+1)] for i in range(n+1)]) # Phi_(i-1) (solução da etapa anterior) B=matrix([[0. for j in range(m+1)] for i in range(n+1)]) # beta_i
g=matrix([[0. for j in range(m+1)] for i in range(n+1)]) # o que aparece à esquerda da condição de contorno discretizado
wmax=0. # max phi
wint=0. # int phi
wmaxb=0. # max boundary phi
wmaxbo=0. # max outside boundary phi wpb=0. # boundary point phi
# table
points=[(ns,m),(ns,ms+(m-ms)/2),(ns+(n-ns)/2,ms+(m-ms)/2),(n,ms+(m-ms)/2),(n,m/2)] # coordenadas dos pontos a serem plotados
step=50.
digits_=5.
dg_=1.
coordpoints=[(numerical_approx(x[pt[0]],digits=dg_),numerical_approx(y[pt[1]],digits=dg_)) for pt in points] # converte coordenadas inteiras da malha em coordenadas cartesianas levando em conta os incrementos horizontal e vertical
table_=[] # inicializa a tabela que será populada com os pontos
# Step 4
L=RR(h^2/k^2) # L e M são variáveis convenientes que aparecem com frequência nas fórmulas de diferenças finitas M=RR(2*(1+L))
l=1 # contador no loop do gauss seidel (sistema linear) ll=1 # contador no loop das phi_i
# Step 5 perform Gauss-Seidel iterations #Solução do sistema de equações (da esquerda pra direita, de cima pra baixo)
while ll<=imax: # checa número máximo de iterações das phi_i
while l<=Nmax: # checa o número máximo de iterações do gauss seidel
z=RR((-h^2*fc[ns,m]+2*(h+L*k)*g[ns,m]+2*w[ns+1,m]+2*L*w[ns,m-1])/(M-2*(h+L*k)*A)) # encontra os valores das phi_i
NORM=abs(z-w[ns,m]) # calculando a distância entre as aproximações sucessivas w[ns,m]=z # recicla o w
for i in range(ns+1,n): # percorre bordo horizontal superior
z=RR((-h^2*fc[i,m]+2*L*k*g[i,m]+w[i+1,m]+w[i-1,m]+2*L*w[i,m-1])/(M-2*L*k*A)) if abs(w[i,m]-z)>NORM:
if l>Nmax: # checa se estourou o número máximo de iterações do gauss seidel print('Maximum number of iterations exceeded')
break NORMi=0.
for i in range(n+1):
for j in range(m+1):
if abs(w[i,j]-w0[i,j])>NORMi:
NORMi=abs(w[i,j]-w0[i,j])
if floor(ll/Ngua)==ll/Ngua: # plota os gráficos bidimensionais wmax=max(w.list())
Pmax+=point((ll,wmax))
wint=RR(h*k*sum(w[i,j] for i in range(n) for j in range(m) if (i>=ns)|(j<=m-ms))) Pint+=point((ll,wint))
wmaxb=max(max(w[ns,j] for j in range(m-ms+1,m+1)),max(w[i,m-ms] for i in range(ns))) wmaxbo=max(max(w[n,j] for j in range(m+1)),max(w[i,0] for i in range(n+1)))
if ((i,j) in points) and (floor(ll/step)==ll/step):
table_.append((ll,w[i,j]))
plot(P.rotate(axis,angle)).save(filename = 'plot-%s.png' %(ll)) if animON:
plots.append(plot(P.rotate(axis,angle)))
if floor(ll/Ngua)!=ll/Ngua: # parte repetida do código devido a divisão em casos wmax=max(w.list())
Pmax+=point((ll,wmax))
wint=RR(h*k*sum(w[i,j] for i in range(n) for j in range(m) if (i>=ns)|(j<=m-ms))) Pint+=point((ll,wint))
wmaxb=max(max(w[ns,j] for j in range(m-ms+1,m+1)),max(w[i,m-ms] for i in range(ns))) wmaxbo=max(max(w[n,j] for j in range(m+1)),max(w[i,0] for i in range(n+1)))
if ((i,j) in points) and (floor(ll/step)==ll/step):
table_.append((ll,w[i,j]))
plot(P.rotate(axis,angle)).save(filename = 'plot-%s.png' %(ll-1)) if animON:
plots.append(plot(P.rotate(axis,angle))) if floor((ll-1)/Ngua)!=(ll-1)/Ngua:
wmax=max(w.list()) Pmax+=point((ll-1,wmax))
wint=RR(h*k*sum(w[i,j] for i in range(n) for j in range(m) if (i>=ns)|(j<=m-ms))) Pint+=point((ll-1,wint))
wmaxb=max(max(w[ns,j] for j in range(m-ms+1,m+1)),max(w[i,m-ms] for i in range(ns))) wmaxbo=max(max(w[n,j] for j in range(m+1)),max(w[i,0] for i in range(n+1)))
if ((i,j) in points) and (floor(ll/step)==ll/step):
table_.append((ll,w[i,j]))
plot(P.rotate(axis,angle)).save(filename = 'plot-%s.png' %(ll-1)) if animON:
plots.append(plot(P.rotate(axis,angle))) if floor((ll-1)/Ngua)!=(ll-1)/Ngua:
wmax=max(w.list()) Pmax+=point((ll-1,wmax))
wint=RR(h*k*sum(w[i,j] for i in range(n) for j in range(m) if (i>=ns)|(j<=m-ms))) Pint+=point((ll-1,wint))
wmaxb=max(max(w[ns,j] for j in range(m-ms+1,m+1)),max(w[i,m-ms] for i in range(ns))) wmaxbo=max(max(w[n,j] for j in range(m+1)),max(w[i,0] for i in range(n+1)))
plot(Pmax).save(filename = 'Fator de forma tese.png') plot(Pint).save(filename = 'Fator de forma tese-energia.png') plot(Pmaxb).save(filename = 'bordas.png')
plot(Ppb).save(filename = 'pontoguara.png') if animON: