Solução numérica de equações diferenciais parciais

Documentos relacionados
Figura 8.1: Distribuição uniforme de pontos em uma malha uni-dimensional. A notação empregada neste capítulo para avaliação da derivada de uma

Prof. Lorí Viali, Dr.

7 - Distribuição de Freqüências

Prof. Lorí Viali, Dr.

Faculdade de Engenharia Optimização. Prof. Doutor Engº Jorge Nhambiu

Algarismos Significativos Propagação de Erros ou Desvios

IMPLEMENTAÇÃO DO MÉTODO DE FATORAÇÃO DE INTEIROS CRIVO QUADRÁTICO

Notas Processos estocásticos. Nestor Caticha 23 de abril de 2012

2 Principio do Trabalho Virtual (PTV)

CAPÍTULO VI Introdução ao Método de Elementos Finitos (MEF)

Análise Dinâmica de uma Viga de Euler-Bernoulli Submetida a Impacto no Centro após Queda Livre Através do Método de Diferenças Finitas

7. Resolução Numérica de Equações Diferenciais Ordinárias

Adriana da Costa F. Chaves

ANÁLISE DAS TENSÕES TÉRMICAS EM MATERIAIS CERÂMICOS. Palavras-chave: Tensões térmicas, Propriedades variáveis, Condução de calor, GITT

Análise Complexa Resolução de alguns exercícios do capítulo 1

CAPÍTULO IV DIFERENCIAÇÃO NUMÉRICA

MODELAGEM COMPUTACIONAL DA DIFUSÃO DE NÊUTRONS EM GEOMETRIA UNIDIMENSIONAL CARTESIANA

UMA ABORDAGEM ALTERNATIVA PARA O ENSINO DO MÉTODO DOS MÍNIMOS QUADRADOS NO NÍVEL MÉDIO E INÍCIO DO CURSO SUPERIOR

CORRELAÇÃO E REGRESSÃO

Palavras-Chave: Métodos Interativos da Potência e Inverso, Sistemas Lineares, Autovetores e Autovalores.

Matemática. Veículo A. Veículo B. Os gráficos das funções interceptam-se quando 50t = 80t

2 Incerteza de medição

Realimentação negativa em ampliadores

Análise de Regressão Linear Múltipla VII

Classificação e Pesquisa de Dados

Ao se calcular a média, moda e mediana, temos: Quanto mais os dados variam, menos representativa é a média.

MECÂNICA CLÁSSICA. AULA N o 7. Teorema de Liouville Fluxo no Espaço de Fases Sistemas Caóticos Lagrangeano com Potencial Vetor

Representação e Descrição de Regiões

CAPÍTULO 2 DESCRIÇÃO DE DADOS ESTATÍSTICA DESCRITIVA

Robótica. Prof. Reinaldo Bianchi Centro Universitário FEI 2016

2ª PARTE Estudo do choque elástico e inelástico.

Introdução a Combinatória- Aplicações, parte II

Curso de extensão, MMQ IFUSP, fevereiro/2014. Alguns exercício básicos

Laboratório de Mecânica Aplicada I Estática: Roldanas e Equilíbrio de Momentos

2 Lógica Fuzzy Introdução

CQ110 : Princípios de FQ

Os modelos de regressão paramétricos vistos anteriormente exigem que se suponha uma distribuição estatística para o tempo de sobrevivência.

X = 1, se ocorre : VB ou BV (vermelha e branca ou branca e vermelha)

4 Sistemas de partículas

ELETROTÉCNICA (ENE078)

Métodos numéricos para o cálculo de sistemas de equações não lineares

UNIVERSIDADE PRESBITERIANA MACKENZIE CCSA - Centro de Ciências Sociais e Aplicadas Curso de Economia

3. CIRCUITOS COM AMPOP S UTILIZADOS NOS SAPS

Emprego de MER e CRE em Poisson 1D para análise do erro de variáveis secundárias

Problema Real (avião, carro,...) Validação

Circuitos Eletrônicos Analógicos:

NOTA II TABELAS E GRÁFICOS

Índices de Concentração 1

DESENVOLVIMENTO DE UM PRÉ-PROCESSADOR PARA ANÁLISE ISOGEOMÉTRICA

CAPITULO II - FORMULAÇAO MATEMATICA

Análise de influência

Introdução ao Método dos Elementos Finitos: Estruturas Articuladas

Estatística II Antonio Roque Aula 18. Regressão Linear

Modelo linear normal com erros heterocedásticos. O método de mínimos quadrados ponderados

INTRODUÇÃO À ASTROFÍSICA

ELE0317 Eletrônica Digital II

Aula 7: Circuitos. Curso de Física Geral III F-328 1º semestre, 2014

ANÁLISE MATRICIAL DE ESTRUTURAS DE BARRAS PELO MÉTODO DE RIGIDEZ

Atividade em Soluções Eletrolíticas

PUCPR- Pontifícia Universidade Católica Do Paraná PPGIA- Programa de Pós-Graduação Em Informática Aplicada PROF. DR. JACQUES FACON

ESTUDO DE MODELOS PARA AJUSTE E PREVISÃO DE UMA SÉRIE TEMPORAL

Capítulo 26: Corrente e Resistência

Cap. 6 - Energia Potencial e Conservação da Energia Mecânica

Capítulo 16: Equilíbrio Geral e Eficiência Econômica

2 ENERGIA FIRME DE SISTEMAS HIDRELÉTRICOS

METODOLOGIA PARA O CÁLCULO DE VAZÃO DE UMA SEÇÃO TRANSVERSAL A UM CANAL FLUVIAL. Iran Carlos Stalliviere Corrêa RESUMO

Algoritmos Genéticos com Parâmetros Contínuos

PROVA DE ESTATÍSTICA & PROBABILIDADES SELEÇÃO MESTRADO/UFMG 2010/2011

3.3 Ordenação por Heap (Heapsort)

Física C Intensivo V. 2

3.6. Análise descritiva com dados agrupados Dados agrupados com variáveis discretas

Aula 6: Corrente e resistência

TEORIA DE ERROS * ERRO é a diferença entre um valor obtido ao se medir uma grandeza e o valor real ou correto da mesma.

Eletromagnetismo Aplicado

( x) Método Implícito. No método implícito as diferenças são tomadas no tempo n+1 ao invés de tomá-las no tempo n, como no método explícito.

1. CORRELAÇÃO E REGRESSÃO LINEAR

Curvas Horizontais e Verticais

CONCEITOS INICIAIS DE ESTATÍSTICA MÓDULO 2 DISTRIBUIÇÃO DE FREQÜÊNCIA - ELEMENTOS Prof. Rogério Rodrigues

Medida de Quatro Pontas Autor: Mauricio Massazumi Oka Versão 1.0 (janeiro 2000)

Eletromagnetismo. Distribuição de grandezas físicas: conceitos gerais

Departamento de Informática. Modelagem Analítica do Desempenho de Sistemas de Computação. Modelagem Analítica. Disciplina: Variável Aleatória

AULA Espaços Vectoriais Estruturas Algébricas.

Resoluções dos testes propostos

Estudo e Previsão da Demanda de Energia Elétrica. Parte II

FUNDAMENTOS DE ROBÓTICA. Modelo Cinemático de Robôs Manipuladores

CURSO ON-LINE PROFESSOR: VÍTOR MENEZES

4. ESTÁTICA E PRINCÍPIO DOS TRABALHOS VIRTUAIS 4.1. INTRODUÇÃO

5 Métodos de cálculo do limite de retenção em função da ruína e do capital inicial

MODELAGEM DE CURVAS DE MAGNETIZAÇÃO PARA SOLUÇÃO ITERATIVA DE CIRCUITOS MAGNÉTICOS NÃO LINEARES

Experiência V (aulas 08 e 09) Curvas características

Reconhecimento Estatístico de Padrões

ESPALHAMENTO ELETROMAGNÉTICO POR CORPOS DIELÉTRICOS USANDO FUNÇÕES DE BASE SOLENOIDAIS TRIDIMENSIONAIS. Sérgio A. Carvalho e Leonardo S.

3 Subtração de Fundo Segmentação por Subtração de Fundo

INTRODUÇÃO À ESTATÍSTICA ECONÔMICA 2a. Prova 11/7/2006 Profa. Ana Maria Farias Turma A hs

Controle Estatístico de Qualidade. Capítulo 8 (montgomery)

DEFINIÇÃO - MODELO LINEAR GENERALIZADO

Capítulo 1. Exercício 5. Capítulo 2 Exercício

4. MODELAMENTOS EM POLUIÇÃO DO AR: PREDITIVOS E RECEPTORES

Transcrição:

13 Solução numérca de equações dferencas parcas 13.1 Advecção pura: a onda cnemátca Consdere a equação u t + c u = 0, u(x, 0) = g(x). (13.1) x A sua solução pode ser obtda pelo método das característcas, e é Seja então o problema u(x, t) = g(x ct). (13.) u t + u = 0, x (13.3) u(x, 0) = x(1 x). (13.4) A condção ncal, juntamente com u(x, 1), u(x, ) e u(x, 3) estão mostrados na fgura 13.1. Observe que a solução da equação é uma smples onda cnemátca. 4 3 u(x, t) tempo 0.50 1 0.00 0 0 4 6 8 10 x Fgura 13.1: Condção ncal da equação 13.3. 33

Matemátca Aplcada 34 com Vamos adotar a notação u n u(x, t n ), (13.5) x = x, (13.6) t n = n t, (13.7) x = L/N x, (13.8) t = T/N t (13.9) onde L, T são os tamanhos de grade no espaço e no tempo, respectvamente, e N x, N t são os números de dvsões no espaço e no tempo. Uma manera smples de transformar as dervadas parcas em dferenças fntas na equação (13.3) é fazer u t u x,n,n = un+1 t u n = un +1 un 1 x + O( t), (13.10) + O( x ). (13.11) Substtundo na equação (13.3), obtemos o esquema de dferenças fntas explícto: u n+1 u n u n = c +1 un 1, t x u n+1 = u n c t x (un +1 un ), (13.1) 1 (com c = no nosso caso). Esse é um esquema ncondconalmente nstável, e va fracassar. Vamos fazer uma prmera tentatva, já conformados com o fracasso antecpado. Ela va servr para desenferrujar nossas habldades de programação de métodos de dferenças fntas. O programa que mplementa o esquema nstável é o onda1d-ns.py, mostrado na lstagem 13.1. Por motvos que fcarão mas claros na sequênca, nós escolhemos x = 0,01, e t = 0,0005. O programa gera um arquvo de saída bnáro, que por sua vez é lndo pelo próxmo programa na sequênca, surf1d-ns.py, mostrado na lstagem 13.. O únco trabalho deste programa é seleconar algumas lnhas da saída de onda1d-ns.py; no caso, nós o rodamos com o comando surf1d-ns.py 3 50, o que sgnfca seleconar 3 saídas (além da condção ncal), de 50 em 50 ntervalos de tempo t. Observe que para sto nós utlzamos uma lsta (v), cujos elementos são arrays. O resultado dos prmeros 750 ntervalos de tempo de smulação é mostrado na fgura 13.. Repare como a solução se torna rapdamente nstável. Repare também como a solução numérca, em t = 750 t = 0,375, anda está bastante dstante dos tempos mostrados na solução analítca da fgura 13.1 (que vão até t = 4). Claramente, o esquema explícto que nós programamos jamas nos levará a uma solução numérca satsfatóra para tempos da ordem de t = 1!

35 13.1 Advecção pura: a onda cnemátca Lstagem 13.1: onda1d-ns.py Solução de uma onda 1D com um método explícto nstável 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # onda1d-ns resolve uma equação de onda com um método 5 # explícto 6 # 7 # uso:./onda1d-ns.py 8 # ---------------------------------------------------------- 9 from future mport prnt_functon 10 from future mport dvson 11 fou = open('onda1d-ns.dat','wb') 1 dx = 0.01 13 dt = 0.0005 14 prnt('# dx = %9.4f' % dx) 15 prnt('# dy = %9.4f' % dt) 16 from numpy mport zeros 17 nx = nt(10.0/dx) # número de pontos em x 18 nt = nt(1.0/dt) # número de pontos em t 19 prnt('# nx = %9d' % nx) 0 prnt('# nt = %9d' % nt) 1 u = zeros((,nx+1),float) # apenas posções no tempo # são necessáras! 3 def CI(x): # defne a condção ncal 4 f 0 <= x <= 1.0: 5 return.0*x*(1.0-x) 6 else: 7 return 0.0 8 for n range(nx+1): # monta a condção ncal 9 x = *dx 30 u[0,] = CI(x) 31 u[0].tofle(fou) # mprme a condção ncal 3 old = False 33 new = True 34 c =.0 # celerdade da onda 35 couhalf = c*dt/(.0*dx) # metade do número de Courant 36 for n n range(nt): # loop no tempo 37 for n range(1,nx): # loop no espaço 38 u[new,] = u[old,] - couhalf*(u[old,+1] - u[old,-1]) 39 u[new,0] = 0.0 40 u[new,nx] = 0.0 41 u[new].tofle(fou) # mprme uma lnha com os novos dados 4 (old,new) = (new,old) # troca os índces 43 fou.close()

Matemátca Aplcada 36 Lstagem 13.: surf1d-ns.py Selecona alguns ntervalos de tempo da solução numérca para plotagem 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # surf1d-ns.py: mprme em <arq> <m>+1 saídas de 5 # onda1d-ns a cada <n> ntervalos de tempo 6 # 7 # uso:./surf1d-ns.py <m> <n> 8 # ---------------------------------------------------------- 9 from future mport prnt_functon 10 from future mport dvson 11 from sys mport argv 1 dx = 0.01 13 dt = 0.0005 14 prnt('# dx = %9.4f' % dx) 15 prnt('# dy = %9.4f' % dt) 16 nx = nt(10.0/dx) # número de pontos em x 17 prnt('# nx = %9d' % nx) 18 m = nt(argv[1]) # m saídas 19 n = nt(argv[]) # a cada n ntervalos de tempo 0 prnt('# m = %9d' % m) 1 prnt('# n = %9d' % n) fn = open('onda1d-ns.dat', 3 'rb') # abre o arquvo com os dados 4 from numpy mport fromfle 5 u = fromfle(fn,float,nx+1) # lê a condção ncal 6 v = [u] # ncalza a lsta da "transposta" 7 for t n range(m): # para <m> nstantes: 8 for r n range(n): # lê <r> vezes, só guarda a últma 9 u = fromfle(fn,float,nx+1) 30 v.append(u) # guarda a últma 31 founam = 'surf1d-ns.dat' 3 prnt(founam) 33 fou = open(founam,'wt') # abre o arquvo de saída 34 for n range(nx+1): 35 fou.wrte('%10.6f' % (*dx)) # escreve o "x" 36 fou.wrte('%10.6f' % v[0][]) # escreve a cond ncal 37 for k n range(1,m+1): 38 fou.wrte('%10.6f' % v[k][])# escreve o k-ésmo 39 fou.wrte('\n') 40 fou.close()

37 13.1 Advecção pura: a onda cnemátca 0.500 0.375 u(x, t) 0.50 0.50 0.15 tempo de smulação 0.00 0.000 0 4 6 8 10 x Fgura 13.: Solução numérca produzda por onda1d-ns.py, para t = 50 t, 500 t e 750 t. Por que o esquema utlzado em (13.1) fracassa? Uma forma de obter a resposta é fazer uma análse de establdade de von Neumann. A análse de establdade de von Neumann consste prmeramente em observar que, em um computador real, (13.1) jamas será calculada com precsão nfnta. O que o computador realmente calcula é um valor truncado ũ n. Por enquanto, nós só vamos fazer essa dstnção de notação, entre ũ e u, aqu, onde ela mporta. O erro de truncamento é ε n ũ n u n. (13.13) Note que (13.1) se aplca tanto para u quanto para ũ; subtrando as equações resultantes para ũ n+1 e u n+1, obtém-se a mesma equação para a evolução de ε n: onde ε n+1 = ε n Co (εn +1 εn ), (13.14) 1 Co c t (13.15) x é o número de Courant. Isso só fo possível porque (13.1) é uma equação lnear em u. Mesmo para equações não-lneares, entretanto, sempre será possível fazer pelo menos uma análse local de establdade. O próxmo passo da análse de establdade de von Neumman é escrever uma sére de Fourer para ε n, na forma t n = n t, x = x, N/ ε n = ξ l e at n e k l x, (13.16) l=1

Matemátca Aplcada 38 onde e é a base dos logartmos naturas, = 1, N = L/ x é o número de pontos da dscretzação em x, e L é o tamanho do domíno em x. Argumentando novamente com a lneardade, desta vez de (13.14), ela vale para cada modo l de (13.16), donde ξ l e a(tn+ t) e k l x = ξ l e at n e k l x Co ξl e at n e kl(+1) x ξ l e at n e k l( 1) x ; (13.17) elmnando o fator comum ξ l e at n+k l x, e a t = 1 Co e +k l x e k l x = 1 Co sen k l x. (13.18) O lado dreto é um número complexo, de manera que o lado esquerdo também tem que ser! Como conclá-los? Fazendo a = α + β, e substtundo: e (α β) t = 1 Co sen k l x; e α t cos(β t) sen(β t) = 1 Co sen k l x; e α t cos(β t) = 1, (13.19) e α t sen(β t) = Co sen(k l x). (13.0) As duas últmas equações formam um sstema não-lnear nas ncógntas α β. O sstema pode ser resolvdo: tg(β t) = Co sen(k l x) β t = arctg Co sen(k l x). Note que β 0, donde e α t > 1 va (13.19), e o esquema de dferenças fntas é ncondconalmente nstável. O método de Lax Uma alternatva que produz um esquema estável é o método de Lax: u n+1 = 1 (u n +1 + un ) 1 Co(un +1 un ). (13.1) 1 Agora que nós já sabemos que esquemas numércos podem ser nstáves, devemos fazer uma análse de establdade antes de tentar mplementar (13.1) numercamente. Vamos a sto: utlzando novamente (13.16) e substtundo em (13.1), temos ξ l e a(tn+ t) e k l x = 1 ξl e at n e kl(+1) x + ξ l e at n e k l( 1) x Co ξ l e at n e kl(+1) x ξ l e at n e k l( 1) x ; e a t = 1 e +k l x + e k l x Co e +k l x e k l x ; e a t = cos(k l x) Co sen(k l x) (13.) Nós podemos, é claro, fazer a = α β, mas há um camnho mas rápdo: o truque é perceber que se o fator de amplfcação e a t for um número complexo com módulo maor que 1, o esquema será nstável. Desejamos, portanto, que e a t 1, o que só é possível se Co 1, (13.3)

39 13.1 Advecção pura: a onda cnemátca que é o crtéro de establdade de Courant-Fredrchs-Lewy. A mágca de (13.1) é que ela ntroduz um pouco de dfusão numérca; de fato, podemos reescrevê-la na forma u n+1 t u n = c un +1 un 1 x = c un +1 un 1 x + un +1 un + u n 1 t x u n + +1 un + u n 1. (13.4) t x Não custa repetr: (13.4) é dêntca a (13.1). Porém, comparando-a com (13.1) (nosso esquema nstável ncalmente empregado), nós vemos que ela também é equvalente a esta últma, com o termo adconal x / t (u n +1 un + u n 1 )/ x. O que este termo adconal sgnfca? A resposta é uma dervada numérca de ordem. De fato, consdere as expansões em sére de Taylor u +1 = u + du d x + x 1 d u d x + O( x ), u 1 = u du d x + x 1 d u d x + O( x ), e some: u +1 + u 1 = u + d u d x x + O( x ), d u d x = u +1 u + u 1 x + O( x ). (13.5) Portanto, a equação (13.4) ou seja: o esquema de Lax (13.1) pode ser nterpretada também como uma solução aproxmada da equação de advecção-dfusão u t + c u c = D u x, com x D =. t Note que D tem dmensões de dfusvdade: D = 1. No entanto: não estamos então resolvendo a equação errada? De certa forma, sm: estamos ntroduzndo um pouco de dfusão na equação para amortecer as osclações que aparecerão em decorrênca da amplfcação dos erros de truncamento. O quanto sto nos prejudca? Não muto, desde que o efeto da dfusão seja muto menor que o da advecção que estamos tentando smular. Como a velocdade de advecção ( físca ; real ) que estamos smulando é c, precsamos comparar sto com (por exemplo) a magntude das velocdades ntroduzdas pela dfusão numérca; devemos

Matemátca Aplcada 40 portanto verfcar se D u x c u x D u x c u x 1, 1, D x c, x t x c, c t x = Co 1 Em outras palavras, nós descobrmos que o crtéro para que o esquema seja acurado do ponto de vsta físco é confltante com o crtéro de establdade: enquanto que establdade demandava Co < 1, o crtéro de que a solução seja também fscamente acurada demanda que Co 1/. Na prátca, sto sgnfca que, para c =, ou o esquema é estável com muta dfusão numérca, ou ele é nstável. Isto pratcamente elmna a possbldade de qualquer uso séro de (13.1). Mesmo assm, vamos programá-lo! O programa onda1d-lax.py está mostrado na lstagem 13.3. Ele usa os mesmos valores t = 0,0005 e x = 0,01, ou seja, Co = 0,10. O programa gera um arquvo de saída bnáro, que por sua vez é ldo pelo próxmo programa na sequênca, surf1d-lax.py, mostrado na lstagem 13.4. O únco trabalho deste programa é seleconar algumas lnhas da saída de onda1d-lax.py; no caso, nós o rodamos com o comando surf1d-lax.py 3 500, o que sgnfca seleconar 3 saídas (além da condção ncal), de 500 em 500 ntervalos de tempo t. Com sto, nós consegumos chegar até o nstante 0,75 da smulação. O resultado dos prmeros 1500 ntervalos de tempo de smulação é mostrado na fgura 13.3. Observe que agora não há osclações espúras: o esquema é estável no tempo. No entanto, a solução está agora amortecda pela dfusão numérca! Upwnd Um esquema que é conhecdo na lteratura como ndcado por representar melhor o termo advectvo em (13.1) é o esquema de dferenças regressvas; neste esquema, chamado de esquema upwnd lteralmente, corrente acma na lteratura de língua nglesa, a dscretzação utlzada é u n+1 u n = c un u n 1, x u n+1 = u n Co u n u n 1. (13.6) t Claramente, estamos utlzando um esquema de O( x) para a dervada espacal. Ele é um esquema menos acurado que os usados anterormente, mas se ele ao mesmo tempo for condconalmente estável e não ntroduzr dfusão numérca, o resultado pode ser melhor para tratar a advecção. Antes de colocarmos as mãos na massa, sabemos que devemos analsar analtcamente a establdade do esquema. Vamos a sto:

41 13.1 Advecção pura: a onda cnemátca Lstagem 13.3: onda1d-lax.py Solução de uma onda 1D com um método explícto laxtável 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # onda1d-lax resolve uma equação de onda com um método 5 # explícto 6 # 7 # uso:./onda1d-ns.py 8 # ---------------------------------------------------------- 9 from future mport prnt_functon 10 from future mport dvson 11 fou = open('onda1d-lax.dat','wb') 1 dx = 0.01 13 dt = 0.0005 14 prnt('# dx = %9.4f' % dx) 15 prnt('# dy = %9.4f' % dt) 16 from numpy mport zeros 17 nx = nt(10.0/dx) # número de pontos em x 18 nt = nt(1.0/dt) # número de pontos em t 19 prnt('# nx = %9d' % nx) 0 prnt('# nt = %9d' % nt) 1 u = zeros((,nx+1),float) # apenas posções no tempo # são necessáras! 3 def CI(x): # defne a condção ncal 4 f 0 <= x <= 1.0: 5 return.0*x*(1.0-x) 6 else: 7 return 0.0 8 for n range(nx+1): # monta a condção ncal 9 x = *dx 30 u[0,] = CI(x) 31 u[0].tofle(fou) # mprme a condção ncal 3 old = False 33 new = True 34 c =.0 # celerdade da onda 35 cou = c*dt/(dx) # número de Courant 36 prnt("co = %10.6f" % cou) 37 for n n range(nt): # loop no tempo 38 for n range(1,nx): # loop no espaço 39 u[new,] = 0.5*( (u[old,+1] + u[old,-1]) - 40 cou*(u[old,+1] - u[old,-1]) ) 41 u[new,0] = 0.0 4 u[new,nx] = 0.0 43 u[new].tofle(fou) # mprme uma lnha com os novos dados 44 (old,new) = (new,old) # troca os índces 45 fou.close()

Matemátca Aplcada 4 Lstagem 13.4: surf1d-lax.py Selecona alguns ntervalos de tempo da solução numérca para plotagem 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # surf1d-lax.py: mprme em <arq> <m>+1 saídas de 5 # onda1d-lax a cada <n> ntervalos de tempo 6 # 7 # uso:./surf1d-lax.py <m> <n> 8 # ---------------------------------------------------------- 9 from future mport prnt_functon 10 from future mport dvson 11 from sys mport argv 1 dx = 0.01 13 dt = 0.0005 14 prnt('# dx = %9.4f' % dx) 15 prnt('# dy = %9.4f' % dt) 16 nx = nt(10.0/dx) # número de pontos em x 17 prnt('# nx = %9d' % nx) 18 m = nt(argv[1]) # m saídas 19 n = nt(argv[]) # a cada n ntervalos de tempo 0 prnt('# m = %9d' % m) 1 prnt('# n = %9d' % n) fn = open('onda1d-lax.dat', 3 'rb') # abre o arquvo com os dados 4 from numpy mport fromfle 5 u = fromfle(fn,float,nx+1) # lê a condção ncal 6 v = [u] # ncalza a lsta da "transposta" 7 for t n range(m): # para <m> nstantes: 8 for r n range(n): # lê <r> vezes, só guarda a últma 9 u = fromfle(fn,float,nx+1) 30 v.append(u) # guarda a últma 31 founam = 'surf1d-lax.dat' 3 prnt(founam) 33 fou = open(founam,'wt') # abre o arquvo de saída 34 for n range(nx+1): 35 fou.wrte('%10.6f' % (*dx)) # escreve o "x" 36 fou.wrte('%10.6f' % v[0][]) # escreve a cond ncal 37 for k n range(1,m+1): 38 fou.wrte('%10.6f' % v[k][])# escreve o k-ésmo 39 fou.wrte('\n') 40 fou.close()

43 13.1 Advecção pura: a onda cnemátca 1.000 0.750 u(x, t) 0.50 0.500 0.50 tempo de smulação 0.00 0.000 0 4 6 8 10 x Fgura 13.3: Solução numérca produzda por onda1d-lax.py, para t = 500 t, 1000 t e 1500 t. ξ l e a(t n+ t) e k l x = ξ l e at n e k l x Co ξ l e at n e k l x ξ l e at n e k l( 1) x e a t e k l x = e k l x Co e k l x e k l( 1) x e a t = 1 Co 1 e k l x e a t = 1 Co + Co cos(k l x) Co sen(k l x). (13.7) Desejamos que o módulo do fator de amplfcação e a t seja menor que 1. O módulo (ao quadrado) é e a t = 1 Co + Co cos(k l x) + Co sen(k l x). Para alvar a notação, façamos Então, C k cos(k l x), S k sen(k l x). e a t = (CoS k ) + (CoC k Co + 1) = Co S k + (Co C k + Co + 1) + ( Co C k + CoC k Co) = Co (S k + C k + 1 C k) + Co(C k 1) + 1 = Co (1 C k ) + Co(C k 1) + 1. A condção para que o esquema de dferenças fntas seja estável é, então, Co (1 C k ) + Co(C k 1) + 1 1, Co Co(1 C k ) + (C k 1) 0, 1 cos(kl x) [Co 1] 0, Co 1

Matemátca Aplcada 44 1.000 0.750 u(x, t) 0.50 0.500 0.50 tempo de smulação 0.00 0.000 0 4 6 8 10 x Fgura 13.4: Solução numérca produzda pelo esquema upwnd, para t = 500 t, 1000 t e 1500 t. Reencontramos, portanto, a condção (13.3), mas em um outro esquema de dferenças fntas. A lção não deve ser mal nterpretada: longe de supor que (13.3) vale sempre, é a análse de establdade que deve refeta para cada novo esquema de dferenças fntas! O esquema upwnd, portanto, é condconalmente estável, e tudo ndca que podemos agora mplementá-lo computaconalmente, e ver no que ele va dar. Nós utlzamos os mesmos valores de t e de x de antes. As mudanças necessáras nos códgos computaconas são óbvas, e são dexadas a cargo do(a) letor(a). A fgura 13.4 mostra o resultado do esquema upwnd. Note que ele é muto melhor (para esta equação dferencal) que o esquema de Lax. No entanto, a fgura sugere que algum amortecmento também está ocorrendo, embora em grau muto menor. Exercícos Propostos 13.1 Escreva o programa onda1d-upw e surfa1d-upw, que mplementam o esquema upwnd. Reproduza a fgura 13.4. 13. Calcule a dfusvdade numérca ntroduzda pelo esquema upwnd. 13. Dfusão pura Consdere agora a equação da dfusão, com condções ncas e de contorno u t = D u x, (13.8) u(x, 0) = f (x) (13.9) u(0, t) = u(l, t) = 0. (13.30)

45 13. Dfusão pura Esta solução será vsta no capítulo 17: Em partcular, se u(x, t) = A n = L n=1 L A n e n π α L t sen nπx 0 f (x) sen nπx L L, (13.31) dx. (13.3) D =, L = 1, f (x) = x(1 x), A n = 1 0 x(1 x) sen(nπx) dx = 8 π 3 n 3 [1 ( 1)n ]. Todos os A n s pares se anulam. Fque então apenas com os ímpares: 16 A n+1 = π 3 (n + 1), 3 16 u(x, t) = π 3 (n + 1) 3 e ((n+1) π )t sen ((n + 1)πx) (13.33) n=0 O programa dfusao1d-ana.py, mostrado na lstagem 13.5, mplementa a solução analítca para t = 0,0005 e x = 0,001. Da mesma manera que os programas surf1d*.py, o programa dvsao1d-ana.py, mostrado na lstagem 13.6, selecona alguns nstantes de tempo da solução analítca para vsualzação: dvsao1d-ana.py 3 100. A fgura 13.5 mostra o resultado da solução numérca para t = 0, t = 0,05, t = 0,10 e t = 0,15. Este é pratcamente o fm do processo dfusvo, com a solução analítca tendendo rapdamente para zero. Esquema explícto Talvez o esquema explícto mas óbvo para dscretzar (13.8) seja u n+1 u n = D un +1 un + u n 1. (13.34) t x A dervada parcal em relação ao tempo é de O( t), enquanto que a dervada segunda parcal em relação ao espaço é, como vmos em (13.5), de O( x ). Mas não nos preocupemos muto, anda, com a acuráca do esquema numérco. Nossa prmera preocupação, como você já sabe, é outra: o esquema (13.34) é estável? Explctamos u n+1 em (13.34): u n+1 = u n + Fo u n +1 un + u n 1, (13.35) onde Fo = D t x (13.36)

Matemátca Aplcada 46 Lstagem 13.5: dfusao1d-ana.py Solução analítca da equação da dfusão 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # dfusao1d-ana: solução analítca de 5 # 6 # du/dt = D du^/dx^ 7 # 8 # u(x,0) = x(1-x) 9 # u(0,t) = 0 10 # u(1,t) = 0 11 # 1 # uso:./dfusao1d-ana.py 13 # ---------------------------------------------------------- 14 from future mport prnt_functon 15 from future mport dvson 16 fou = open('dfusao1d-ana.dat','wb') 17 dx = 0.001 18 dt = 0.0005 19 prnt('# dx = %9.4f' % dx) 0 prnt('# dy = %9.4f' % dt) 1 nx = nt(1.0/dx) # número de pontos em x nt = nt(1.0/dt) # número de pontos em t 3 prnt('# nx = %9d' % nx) 4 prnt('# nt = %9d' % nt) 5 from math mport p, sn, exp 6 epslon = 1.0e-6 # precsão da solução analítca 7 dpq = *p*p # p^ 8 dzpc = 16/(p*p*p) # 16/p^3 9 def ana(x,t): 30 s = 0.0 31 ds = epslon 3 n = 0 33 whle abs(ds) >= epslon: 34 dnm1 = *n + 1 # (n+1) 35 dnm1q = dnm1*dnm1 # (n+1)^ 36 dnm1c = dnm1q*dnm1 # (n+1)^3 37 ds = exp(-dnm1q*dpq*t) 38 ds *= sn(dnm1*p*x) 39 ds /= dnm1c 40 s += ds 41 n += 1 4 return s*dzpc 43 from numpy mport zeros 44 u = zeros(nx+1,float) # um array para conter a solução 45 for n n range(nt+1): # loop no tempo 46 t = n*dt 47 prnt(t) 48 for n range(nx+1): # loop no espaço 49 x = *dx 50 u[] = ana(x,t) 51 u.tofle(fou) # mprme uma lnha com os novos dados 5 fou.close()

47 13. Dfusão pura Lstagem 13.6: dvsao1d-ana.py Selecona alguns nstantes de tempo da solução analítca para vsualzação 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # dvsao1d-ana.py: mprme em <arq> <m>+1 saídas de 5 # dfusao1d-ana a cada <n> ntervalos de tempo 6 # 7 # uso:./dvsao1d-ana.py <m> <n> 8 # ---------------------------------------------------------- 9 from future mport prnt_functon 10 from future mport dvson 11 from sys mport argv 1 dx = 0.001 13 dt = 0.0005 14 prnt('# dx = %9.4f' % dx) 15 prnt('# dt = %9.4f' % dt) 16 nx = nt(1.0/dx) # número de pontos em x 17 prnt('# nx = %9d' % nx) 18 m = nt(argv[1]) # m saídas 19 n = nt(argv[]) # a cada n ntervalos de tempo 0 prnt('# m = %9d' % m) 1 prnt('# n = %9d' % n) fn = open('dfusao1d-ana.dat', 3 'rb') # abre o arquvo com os dados 4 from numpy mport fromfle 5 u = fromfle(fn,float,nx+1) # lê a condção ncal 6 v = [u] # ncalza a lsta da "transposta" 7 for t n range(m): # para <m> nstantes: 8 for r n range(n): # lê <r> vezes, só guarda a últma 9 u = fromfle(fn,float,nx+1) 30 v.append(u) # guarda a últma 31 founam = 'dvsao1d-ana.dat' 3 prnt(founam) 33 fou = open(founam,'wt') # abre o arquvo de saída 34 for n range(nx+1): 35 fou.wrte('%10.6f' % (*dx)) # escreve o "x" 36 fou.wrte('%10.6f' % v[0][]) # escreve a cond ncal 37 for k n range(1,m+1): 38 fou.wrte('%10.6f' % v[k][])# escreve o k-ésmo 39 fou.wrte('\n') 40 fou.close()

Matemátca Aplcada 48 0.5 0.4 t = 0,00 u(x, t) 0.3 0. t = 0,05 0.1 0.0 t = 0,10 t = 0,15 0 0. 0.4 0.6 0.8 1 x Fgura 13.5: Solução analítca da equação de dfusão para t = 0, t = 0,05, t = 0,10 e t = 0,15. é o número de Fourer de grade (El-Kad e Lng, 1993). A análse de establade de von Neumann agora produz ξ l e a(t n+ t) e k l x = ξ l e at n e k l x + Fo ξ l e at n e kl(+1) x ξ l e at n e k l x + ξ l e at n e k l( 1) x, e a t = 1 + Fo e +kl x + e k l x = 1 + Fo cos(k l x) 1 = 1 4Fo sen kl x A análse de establdade requer que e a t < 1: kl x kl x e a t = 1 8Fo sen + 16Fo sen 4 ou kl x kl x 8Fo sen + 16Fo sen 4 < 0, kl x kl x 8Fo sen 1 + Fo sen < 0, < 1 (13.37) Fo < 1. (13.38) Podemos agora calcular o número de Fourer que utlzamos para plotar a solução analítca (verfque nas lstagens 13.5 e 13.6): Fo = 0,0005 (0,001) = 1000.

49 13. Dfusão pura Lstagem 13.7: dfusao1d-exp.py Solução numérca da equação da dfusão: método explícto. 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # dfusao1d-exp resolve uma equação de dfusão com um método 5 # explícto 6 # 7 # uso:./dfusao1d-exp.py 8 # ---------------------------------------------------------- 9 from future mport prnt_functon 10 from future mport dvson 11 fou = open('dfusao1d-exp.dat','wb') 1 dx = 0.01 13 dt = 0.00001 14 prnt('# dx = %9.4f' % dx) 15 prnt('# dy = %9.4f' % dt) 16 from numpy mport zeros 17 nx = nt(round(1.0/dx,0)) # número de pontos em x 18 nt = nt(round(1.0/dt,0)) # número de pontos em t 19 prnt('# nx = %9d' % nx) 0 prnt('# nt = %9d' % nt) 1 u = zeros((,nx+1),float) # apenas posções no tempo # são necessáras! 3 def CI(x): # defne a condção ncal 4 f 0 <= x <= 1.0: 5 return.0*x*(1.0-x) 6 else: 7 return 0.0 8 for n range(nx+1): # monta a condção ncal 9 x = *dx 30 u[0,] = CI(x) 31 u[0].tofle(fou) # mprme a condção ncal 3 old = False 33 new = True 34 D =.0 # celerdade da onda 35 Fon = D*dt/((dx)**) # número de Fourer 36 prnt("fo = %10.6f" % Fon) 37 for n n range(nt): # loop no tempo 38 prnt(n) 39 for n range(1,nx): # loop no espaço 40 u[new,] = u[old,] + Fon*(u[old,+1] - *u[old,] + u[old,-1]) 41 u[new,0] = 0.0 # condção de contorno, x = 0 4 u[new,nx] = 0.0 # condção de contorno, x = 1 43 u[new].tofle(fou) # mprme uma lnha com os novos dados 44 (old,new) = (new,old) # troca os índces 45 fou.close() Utlzar os valores x = 0,0005 e x = 0,001 levara a um esquema nstável. Precsamos dmnur t e/ou aumentar x. Com t = 0,00001 e x = 0,01, Fo = 0,00001 (0,01) = 0, < 0,5 (OK). Repare que Fo < 1/ é um crtéro de establdade muto mas exgente do que Co < 1/ (para D = ). Nós esperamos que nosso esquema explícto agora rode muto lentamente. Mas vamos mplementá-lo. O programa que mplementa o esquema é o dfusao1d-exp.py, mostrado na lstagem 13.7. O programa dvsao1d-exp.py, mostrado na lstagem 13.8, selecona alguns nstantes de tempo da solução analítca para vsualzação: dvsao1d-exp 3 5000.

Matemátca Aplcada 50 Lstagem 13.8: dvsao1d-exp.py Selecona alguns nstantes de tempo da solução analítca para vsualzação 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # dvsao1d-exp.py: mprme em <arq> <m>+1 saídas de 5 # dfusao1d-exp a cada <n> ntervalos de tempo 6 # 7 # uso:./dvsao1d-exp.py <m> <n> 8 # ---------------------------------------------------------- 9 from future mport prnt_functon 10 from future mport dvson 11 from sys mport argv 1 dx = 0.01 13 dt = 0.00001 14 prnt('# dx = %9.4f' % dx) 15 prnt('# dt = %9.4f' % dt) 16 nx = nt(round(1.0/dx,0)) # número de pontos em x 17 nt = nt(round(1.0/dt,0)) # número de pontos em t 18 prnt('# nx = %9d' % nx) 19 m = nt(argv[1]) # m saídas 0 n = nt(argv[]) # a cada n ntervalos de tempo 1 prnt('# m = %9d' % m) prnt('# n = %9d' % n) 3 fn = open('dfusao1d-exp.dat', 4 'rb') # abre o arquvo com os dados 5 from numpy mport fromfle 6 u = fromfle(fn,float,nx+1) # lê a condção ncal 7 v = [u] # ncalza a lsta da "transposta" 8 for t n range(m): # para <m> nstantes: 9 for r n range(n): # lê <r> vezes, só guarda a últma 30 u = fromfle(fn,float,nx+1) 31 v.append(u) # guarda a últma 3 founam = 'dvsao1d-exp.dat' 33 fou = open(founam,'wt') # abre o arquvo de saída 34 for n range(nx+1): 35 fou.wrte('%10.6f' % (*dx)) # escreve o "x" 36 fou.wrte('%10.6f' % v[0][]) # escreve a cond ncal 37 for k n range(1,m+1): 38 fou.wrte('%10.6f' % v[k][])# escreve o k-ésmo 39 fou.wrte('\n') 40 fou.close()

51 13. Dfusão pura 0.5 0.4 t = 0,00 u(x, t) 0.3 0. t = 0,05 0.1 0.0 t = 0,10 t = 0,15 0 0. 0.4 0.6 0.8 1 x Fgura 13.6: Solução numérca com o método explícto (13.35) (círculos) versus a solução analítca (lnha chea) da equação de dfusão para t = 0, t = 0,05, t = 0,10 e t = 0,15. Apenas 1 a cada 5 pontos da grade numérca são mostrados, para facltar a comparação com a solução analítca. O resultado da solução numérca com o método explícto está mostrado na fgura 13.6: ele é mpressonantemente bom, embora seja computaconalmente muto caro. A escolha judcosa de t e x para obeder ao crtéro (13.38) fo fundamental para a obtenção de um bom resultado de prmera, sem a necessdade dolorosa de fcar tentando dversas combnações até que o esquema se establze e produza bons resultados. Esquemas mplíctos Embora o esquema explícto que nós utlzamos acma seja acurado, ele é lento se você programou e rodou dfusao1d-exp.py, deve ter notado alguma demora para o programa rodar. Embora nossos computadores estejam fcando a cada da mas rápdos, sso não é desculpa para utlzar mal nossos recursos computaconas (é claro que, ao utlzarmos uma lnguagem nterpretada Python para programar, nós já estamos utlzando muto mal nossos recursos; no entanto, nosso argumento é ddátco: com uma lnguagem mas smples, podemos aprender mas rápdo e errar menos. Além dsso, todos os ganhos relatvos que obtvermos se manterão em qualquer outra lnguagem) Vamos portanto fazer uma mudança fundamental nos nossos esquemas de dferenças fntas: vamos calcular a dervada espacal no nstante n + 1: u n+1 u n = D un+1 +1 un+1 + u n+1 1, x t u n+1 u n = Fo(u n+1 +1 un+1 + u n+1 ), 1 Fou n+1 + (1 + Fo)un+1 Fou n+1 = 1 +1 un. (13.39) Reveja a dscretzação (13.5) (13.9): para = 1,..., N x 1, (13.39) acopla 3 valores das ncógntas u n+1 no nstante n + 1. Quando = 0, e quando = N x, não

Matemátca Aplcada 5 podemos utlzar (13.39), porque não exstem os índces = 1, e = N x +1. Quando = 1 e = N x 1, (13.39) precsa ser modfcada, para a ntrodução das condções de contorno: como u n 0 = 0 e un N x = 0 para qualquer n, teremos (1 + Fo)u n+1 Fou n+1 = u n, (13.40) 1 1 Fou n+1 N x + (1 + Fo)un+1 N x 1 = un N x 1. (13.41) Em resumo, nossas ncógntas são u n+1, u n+1,... u n+1 (N 1 N x 1 x 1 ncógntas), e seu cálculo envolve a solução do sstema de equações 1 + Fo Fo 0... 0 0 Fo 1 + Fo Fo 0... 0.. 0... 0 Fo 1 + Fo Fo 0 0... 0 Fo 1 + Fo u n+1 1 u n+1. u n+1 N x u n+1 N x 1 = u n 1 u n. u n N x u n N x 1 A análse de establdade de von Neumann procede agora da manera usual: ε n+1 = ε n + Fo(ε n+1 +1 εn+1 + ε n+1 1 ) ξ l e a(t n+ t) e k l x = ξ l e at n e k l x (13.4) + Fo ξ l e a(t n+ t) e k l(+1) x ξ l e a (t n + t)e k l x +ξ l e a(t n+ t) e k l( 1) x, e a t = 1 + e a t Fo e k l x + e k l x, e a t = 1 + e a t Fo cos(k l x) 1, kl x e a t = 1 e a t 4Fo sn, kl x e a t 1 + 4Fo sn = 1, 1 e a t = 1 + 4Fo sn 1 sempre. (13.43) k l x Portanto, o esquema mplícto (13.39) é ncondconalmente estável, e temos confança de que o programa correspondente não se nstablzará. Exstem váras cosas atraentes para um programador em (13.4). Em prmero lugar, a matrz do sstema é uma matrz banda trdagonal; sstemas lneares com este tpo de matrz são partcularmente smples de resolver, e estão dsponíves na lteratura (por exemplo: Press et al., 199, seção.4, subrotna trdag). Em segundo lugar, a matrz do sstema é constante: ela só precsa ser montada uma vez no programa, o que torna a solução numérca potencalmente muto rápda. Nós vamos começar, então, construndo um pequeno módulo, convenentemente denomnado algln.py, que exporta a função trdag, que resolve um sstema trdagonal, mostrado na lstagem 13.9. Em seguda, o programa dfusao1d-mp.py resolve o problema com o método mplícto. Ele está mostrado na lstagem 13.10. A prncpal novdade está nas lnhas 4 46, e depos novamente na lnha 56. Em Python e Numpy, é possível especfcar sub-lstas, e sub-arrays, com um dspostvo denomnado slcng, que torna a

53 13. Dfusão pura Lstagem 13.9: algln.py Exporta uma rotna que resolve um sstema trdagonal, baseado em Press et al. (199) 1 # -*- codng: so-8859-1 -*- # ------------------------------------------------------------------------------ 3 # algln.py mplementa uma solução de um sstema lnear com matrz trdagonal 4 # ------------------------------------------------------------------------------ 5 from numpy mport zeros 6 def trdag(a,y): # A,y têm que ser arrays! 7 m = A.shape[0] # garante que A representa uma 8 n = A.shape[1] # matrz trdagonal 9 assert(m == 3) # garante que todos os tamanhos estão OK 10 o = y.shape[0] 11 assert (n == o) 1 x = zeros(n,float) # vetor de trabalho: va retornar a solução 13 gam = zeros(n,float) # vetor de trabalho: va fcar por aqu 14 f A[1,0] == 0.0 : 15 ext("erro 1 em trdag") 16 bet = A[1,0] 17 x[0] = y[0]/bet 18 for j n range(1,n): 19 gam[j] = A[,j-1]/bet 0 bet = A[1,j] - A[0,j]*gam[j] 1 f (bet == 0.0): ext("erro em trdag") 3 x[j] = (y[j] - A[0,j]*x[j-1])/bet 4 for j n range(n-,-1,-1): 5 x[j] -= gam[j+1]*x[j+1] 6 return x programação mas compacta e clara. Por exemplo, na lnha 43, todos os elementos A[0,1]... A[0,nx-1] recebem o valor -Fon. Exste um programa dvsao1d-mp.py, mas ele não precsa ser mostrado aqu, porque as modfcações, por exemplo a partr de dvsao1d-exp.py, são demasadamente trvas para justfcarem o gasto adconal de papel. Para t = 0,001, e x = 0,01, o resultado do método mplícto está mostrado na fgura 13.7 Nada mal, para uma economa de 100 vezes (em relação ao método explícto) em passos de tempo! (Note entretanto que a solução, em cada passo de tempo, é um pouco mas custosa, por envolver a solução de um sstema de equações acopladas, anda que trdagonal.) Crank Ncholson A dervada espacal em (13.8) é aproxmada, no esquema mplícto (13.39), por um esquema de O( x ). A dervada temporal, por sua vez, é apenas de O( t). Mas é possível consertar sso! A déa é substtur (13.39) por u n+1 u n = D u n +1 un + u n 1 + un+1 +1 un+1 + u n+1 1, t x x u n+1 = u n + Fo u n +1 un + u n + 1 un+1 +1 un+1 + u n+1 1. (13.44) Com esta mudança smples, a dervada espacal agora é uma méda das dervadas em n e n + 1, ou seja: ela está centrada em n + 1/. Com sto, a dervada temporal do lado esquerdo torna-se, na prátca, um esquema de ordem centrado em n + 1/! Como sempre, nosso trabalho agora é verfcar a establdade do esquema numérco. Para sto, fazemos ε n+1 Fo ε n+1 +1 εn+1 + ε n+1 1 = ε n + Fo ε n +1 εn + ε n 1,

Matemátca Aplcada 54 Lstagem 13.10: dfusao1d-mp.py Solução numérca da equação da dfusão: método mplícto. 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # dfusao1d-mp resolve uma equação de dfusão com um método 5 # mplícto 6 # 7 # uso:./dfusao1d-mp.py 8 # ---------------------------------------------------------- 9 from future mport prnt_functon 10 from future mport dvson 11 fou = open('dfusao1d-mp.dat','wb') 1 dx = 0.01 # defne a dscretzação em x 13 dt = 0.001 # defne a dscretzação em t 14 prnt('# dx = %9.4f' % dx) 15 prnt('# dy = %9.4f' % dt) 16 nx = nt(round(1.0/dx,0)) # número de pontos em x 17 nt = nt(round(1.0/dt,0)) # número de pontos em t 18 prnt('# nx = %9d' % nx) 19 prnt('# nt = %9d' % nt) 0 from numpy mport zeros 1 u = zeros((,nx+1),float) # apenas posções no tempo # são necessáras! 3 def CI(x): # defne a condção ncal 4 f 0 <= x <= 1.0: 5 return.0*x*(1.0-x) 6 else: 7 return 0.0 8 for n range(nx+1): # monta a condção ncal 9 x = *dx 30 u[0,] = CI(x) 31 u[0].tofle(fou) # mprme a condção ncal 3 old = False 33 new = True 34 D =.0 # dfusvdade 35 Fon = D*dt/((dx)**) # número de Fourer 36 prnt("fo = %10.6f" % Fon) 37 A = zeros((3,nx-1),float) # cra a matrz do sstema 38 # ------------------------------------------------------------------------------ 39 # cudado, "lnha" e "coluna" abaxo não sgnfcam as reas lnhas e colunas 40 # do sstema de equações, mas sm a forma de armazenar uma matrz trdagonal 41 # ------------------------------------------------------------------------------ 4 A[0,0] = 0.0 # zera A[0,0] 43 A[0,1:nx-1] = -Fon # preenche o fm da 1a lnha 44 A[1,0:nx-1] = 1.0 + *Fon # preenche a segunda lnha 45 A[,0:nx-] = -Fon # preenche o níco da a lnha 46 A[,nx-] = 0.0 # zera A[,nx-] 47 # ------------------------------------------------------------------------------ 48 # mporta uma tradução de trdag de Numercal Recpes para Python 49 # ------------------------------------------------------------------------------ 50 from algln mport trdag 51 for n n range(nt): # loop no tempo 5 prnt(n) 53 # ------------------------------------------------------------------------------ 54 # atenção: calcula apenas os pontos nternos de u! 55 # ------------------------------------------------------------------------------ 56 u[new,1:nx] = trdag(a,u[old,1:nx]) 57 u[new,0] = 0.0 # condção de contorno, x = 0 58 u[new,nx] = 0.0 # condção de contorno, x = 1 59 u[new].tofle(fou) # mprme uma lnha com os novos dados 60 (old,new) = (new,old) # troca os índces 61 fou.close() # fecha o arquvo de saída, e fm.

55 13. Dfusão pura 0.5 0.4 t = 0,00 u(x, t) 0.3 0. t = 0,05 0.1 0.0 t = 0,10 t = 0,15 0 0. 0.4 0.6 0.8 1 x Fgura 13.7: Solução numérca com o método mplícto (13.39) (círculos) versus a solução analítca (lnha chea) da equação de dfusão para t = 0, t = 0,05, t = 0,10 e t = 0,15. Apenas 1 a cada 5 pontos da grade numérca são mostrados, para facltar a comparação com a solução analítca. e substtuímos um modo de Fourer: ξ l e a(t n+ t) e k l x Fo e k l (+1) x e k l x + e k l( 1) x = ξ l e at n e k l x + Fo e k l (+1) x e k l x + e k l( 1) x e a t 1 Fo e k l x + e k l x = 1 + Fo e k l x + e k l x e a t 1 Fo cos(k l x) 1 = 1 + Fo cos(k l x) 1 kl x kl x e a t 1 + Fo sn = 1 Fo sn e a t = 1 Fo sn k l x 1 + Fo sn. k l x É fácl notar que e a t < 1, e o esquema numérco de Crank-Ncholson é ncondconalmente estável. O esquema numérco de Crank-Ncholson é smlar a (13.39): Fo un+1 + (1 + Fo)un+1 Fo 1 un+1 = Fo +1 un + (1 1 Fo)un + Fo un (13.45) +1 Para as condções de contorno de (13.30), as lnhas correspondentes a = 1 e = N x 1 são (1 + Fo)u n+1 1 Fo un+1 = (1 Fo)u n 1 + Fo un, (13.46) Fou un+1 N x + (1 + Fo)un+1 = Fo N x 1 un + (1 N x Fo)un N x (13.47) 1

Matemátca Aplcada 56 0.5 0.4 t = 0,00 u(x, t) 0.3 0. t = 0,05 0.1 0.0 t = 0,10 t = 0,15 0 0. 0.4 0.6 0.8 1 x Fgura 13.8: Solução numérca com o método de Crank-Ncholson ( (13.45)) (círculos) versus a solução analítca (lnha chea) da equação de dfusão para t = 0, t = 0,05, t = 0,10 e t = 0,15. Apenas 1 a cada 5 pontos da grade numérca são mostrados, para facltar a comparação com a solução analítca. As mudanças no códgo de dfusao-mp.py são relatvamente fáces de se dentfcar. O códgo do programa que mplementa o esquema numérco de Crank-Ncholson, dfusao1d-ckn.py, é mostrado na lstagem 13.11. A grande novdade computaconal de dfusao1d-ckn.py é a lnha 56: com os arrays proporconados por Numpy, é possível escrever (13.45) vetoralmente: note que não há necessdade de fazer um loop em x para calcular cada elemento b[] ndvdualmente. O mesmo tpo de facldade está dsponível em FORTRAN90, FOR- TRAN95, etc.. Com sso, a mplementação computaconal dos cálculos gerada por Numpy (ou pelo complador FORTRAN) também é potencalmente mas efcente. O método de Crank-Ncholson possu acuráca O( t), portanto ele deve ser capaz de dar passos anda mas largos no tempo que o método mplícto (13.39); no programa dfusao1d-ckn.py, nós especfcamos um passo de tempo 5 vezes maor do que em dfusao1d-mp.py. O resultado é uma solução cerca de 5 vezes mas rápda (embora, novamente, haja mas contas agora para calcular o vetor de carga b), e é mostrado na fgura 13.8. Exemplo 13.1 Dada a equação da dfusão undmensonal u t = D u x, 0 x L,

57 13. Dfusão pura Lstagem 13.11: dfusao1d-ckn.py Solução numérca da equação da dfusão: esquema de Crank-Ncholson. 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # dfusao1d-ckn resolve uma equação de dfusão com o método 5 # de Crank-Ncholson 6 # 7 # uso:./dfusao1d-ckn.py 8 # ---------------------------------------------------------- 9 from future mport prnt_functon 10 from future mport dvson 11 fou = open('dfusao1d-ckn.dat','wb') 1 dx = 0.01 # defne a dscretzação em x 13 dt = 0.005 # defne a dscretzação em t 14 prnt('# dx = %9.4f' % dx) 15 prnt('# dt = %9.4f' % dt) 16 nx = nt(round(1.0/dx,0)) # número de pontos em x 17 nt = nt(round(1.0/dt,0)) # número de pontos em t 18 prnt('# nx = %9d' % nx) 19 prnt('# nt = %9d' % nt) 0 from numpy mport zeros 1 u = zeros((,nx+1),float) # apenas posções no tempo # são necessáras! 3 def CI(x): # defne a condção ncal 4 f 0 <= x <= 1.0: 5 return.0*x*(1.0-x) 6 else: 7 return 0.0 8 for n range(nx+1): # monta a condção ncal 9 x = *dx 30 u[0,] = CI(x) 31 u[0].tofle(fou) # mprme a condção ncal 3 old = False 33 new = True 34 D =.0 # dfusvdade 35 Fon = D*dt/((dx)**) # número de Fourer 36 prnt("fo = %10.6f" % Fon) 37 A = zeros((3,nx-1),float) # cra a matrz do sstema 38 # ------------------------------------------------------------------------------ 39 # cudado, "lnha" e "coluna" abaxo não sgnfcam as reas lnhas e colunas 40 # do sstema de equações, mas sm a forma de armazenar uma matrz trdagonal 41 # ------------------------------------------------------------------------------ 4 A[0,0] = 0.0 # zera A[0,0] 43 A[0,1:nx-1] = -Fon/.0 # preenche o fm da 1a lnha 44 A[1,0:nx-1] = 1.0 + Fon # preenche a segunda lnha 45 A[,0:nx-] = -Fon/.0 # preenche o níco da a lnha 46 A[,nx-] = 0.0 # zera A[,nx-] 47 # ------------------------------------------------------------------------------ 48 # mporta uma tradução de trdag de Numercal Recpes para Python 49 # ------------------------------------------------------------------------------ 50 from algln mport trdag 51 for n n range(nt): # loop no tempo 5 prnt(n) 53 # ------------------------------------------------------------------------------ 54 # recalcula o vetor de carga vetoralmente 55 # ------------------------------------------------------------------------------ 56 b = (Fon/)*u[old,0:nx-1] + (1 - Fon)*u[old,1:nx] + (Fon/)*u[old,:nx+1] 57 # ------------------------------------------------------------------------------ 58 # atenção: calcula apenas os pontos nternos de u! 59 # ------------------------------------------------------------------------------ 60 u[new,1:nx] = trdag(a,b) 61 u[new,0] = 0.0 # condção de contorno, x = 0 6 u[new,nx] = 0.0 # condção de contorno, x = 1 63 u[new].tofle(fou) # mprme uma lnha com os novos dados 64 (old,new) = (new,old) # troca os índces 65 fou.close() # fecha o arquvo de saída, e fm.

Matemátca Aplcada 58 e o esquema de dscretzação 1 t x = L/N x, x = x, = 0,..., N x, t n = t t, u n = u(x, t n ), (u n+1 +1 un +1 ) + (un+1 1 un 1 ) = D un +1 un + u n 1 x, obtenha o crtéro de establdade por meo de uma análse de establdade de von Neumann. SOLUÇÃO Suponha que a equação dferencal se aplque ao erro: ε n = ξ l e at n e k l x Então 1 t l (ξl e a(t n+ t) e k l(+1) x ξ l e at n e k l(+1) x ) + (ξ l e a(t n+ t) e k l( 1) x ξ l e at n e k l( 1) x = 1 t D ξ l e at ne kl(+1) x ξ l e at ne k l x + ξ l e at ne k l( 1) x x ; (ξl e a t e kl(+1) x ξ l e kl(+1) x ) + (ξ l e a t e kl( 1) x ξ l e k l( 1) x = 1 t Segue-se que D ξ l e kl(+1) x ξ l e k l x + ξ l e k l( 1) x x ; ( e a t e kl(+1) x e kl(+1) x ) + ( e a t e kl( 1) x e k l( 1) x = D ek l(+1) x e k l x + e k l( 1) x x ; ( e a t e k l(+1) x e k l(+1) x ) + ( e a t e k l( 1) x e k l( 1) x = D t x e k l (+1) x e k l x + e k l( 1) x. e a t e k l(+1) x + e k l( 1) x = e k l(+1) x + e k l( 1) x + Fo e k l(+1) x e k l x + e k l( 1) x A função e a t e k l x + e k l x = e k l x + e k l x + Fo e k l x + e k l x e a t = 1 + Fo cos(k l x) cos(k l x) = 1 + Fo cos(k l x) 1 cos(k l x) = 1 4Fo sen (k l x/). cos(k l x) f (x) = sen (x/) cos(x) possu sngulardades em π/ + kπ, e muda de snal em torno destas sngulardades: não é possível garantr que e a t < 1 unformemente, e o esquema é ncondconalmente nstável.

59 13. Dfusão pura Exercícos Propostos 13.3 Consdere a equação dferencal parcal com condções ncas e de contorno u t = D u x, 0 x L, u(x, 0) = 0, u(0, t) = c, u (L, t) = 0, x onde c é uma constante. Dado o esquema de dscretzação mplícto clássco, u n+1 u n t = D un+1 +1 un+1 + u n+1 1 x para N x = 8, obtenha o sstema de equações lneares [A][u] n+1 = [b] onde os A,j s dependem do número de grade de Fourer, e os b s dependem dos u n s. Em outras palavras, escreva explctamente a matrz quadrada [A] e a matrz-coluna [b] para N x = 8. 13.4 Dada a equação dferencal não-lnear de Boussnesq, h t = h h, x x h(x, 0) = H, h(0, t) = H 0, h x = 0, x=1 obtenha uma dscretzação lnearzada da mesma em dferenças fntas do tpo da segunte forma: h(x, t n ) = h( x, n t) = h n dscretze a dervada parcal em relação ao tempo com um esquema progressvo no tempo entre n e n + 1; aproxme h dentro do colchete por h n (este é o truque que lnearza o esquema de dferenças fntas) e mantenha-o assm; utlze esquemas de dferenças fntas mplíctos centrados no espaço para as dervadas parcas em relação a x, exceto no termo h n do tem anteror. NÃO MEXA COM AS CONDIÇÕES DE CONTORNO.

Matemátca Aplcada 60 13.3 Dfusão em Dmensões: ADI, e equações elítcas Consdere a equação da dfusão em dmensões, u t = D u x + u. (13.48) y Como sempre, nós queremos ser muto concretos, e trabalhar com um problema que possua solução analítca. Consdere então a condção ncal a solução analítca é u(x, y, 0) = u 0 exp u(x, y, t) = u 0 1 + 4t D/L exp (x + y ) L (x + y ) L + 4Dt ; (13.49). (13.50) Na verdade esta solução se espalha por todo o plano x y, mas nós podemos trabalhar com um problema fnto em x e y, por exemplo, fazendo L x L, L y L, e mpondo condções de contorno que se ajustem exatamente à solução analítca: u 0 u( L, y, t) = 1 + 4t D/L exp (L + y ), (13.51) L + 4Dt u 0 u(l, y, t) = 1 + 4t D/L exp (L + y ), (13.5) L + 4Dt u 0 u(x, L, t) = 1 + 4t D/L exp (x + L ), (13.53) L + 4Dt u 0 u(x, L, t) = 1 + 4t D/L exp (x + L ). (13.54) L + 4Dt Agora, nós vamos fazer D = (como antes) e L = 1, e resolver o problema numercamente. Nossa escolha recará sobre um método smples, e de O( t), denomnado ADI (alternatng-drecton mplct). Este método nos proporconará um exemplo de uma técnca denomnada operator splttng ou tme splttng, que nós vamos traduzr como separação de operadores Esta técnca consste em marchar mplctamente em uma dmensão espacal de cada vez, mantendo a outra dmensão explícta. Portanto, nós vamos utlzar dos esquemas dferentes de dferenças fntas (na prátca), para resolver o problema! E-los u n+1, j u n, j t = D u n+ u n+1, j, j = D t u n+1 +1, j un+1, j + u n+1 1,j x u n+1 +1, j un+1 + u n+1, j 1,j + un+ x + un,j+1 un +,j un, j 1 y,j+1 un+,j + u n+ y, j 1 (13.55) (13.56) Examne cudadosamente (13.55) e (13.56): na prmera, note que o esquema é mplícto em x; na segunda, a stuação se reverte, e o esquema é mplícto em y. É claro

61 13.3 Dfusão em Dmensões: ADI, e equações elítcas que nós vamos precsar de duas análses de establdade de von Neumann, uma para cada equação. 011-09-4T17:07:04 Por enquanto, vou supor que os dos esquemas são ncondconalmente estáves, e mandar ver. Além dsto, por smplcdade vamos fazer x = y =, de manera que só haverá um número de Fourer de grade no problema, e então teremos, para x: u n+1,j u n,j = Fo u n+1,j Fo u n+1 1,j un+1 Fo = D t, (13.57) + u n+1 +,j +1, j un, j 1 un +, j un,,j+1 u n+1 1, j un+1, j + u n+1 +1,j = u n, j + Fo u n,j 1 un, j + un, j+1 Fou n+1 + (1 + Fo)un+1 Fou n+1 = 1,j,j +1,j Foun + (1, j 1 Fo)un +, j Foun (13.58), j+1 Na dmensão y, u n+ u n+1,j,j u n+, j Fo = Fo u n+1 1, j un+1 + u n+1, j u n+,j 1 un+ + u n+, j, j+1 + +1,j un+,j 1 un+ = u n+1, j + Fo, + u n+,, j, j+1 u n+1 1,j un+1 + u n+1,j +1, j Fou n+ + (1 + Fo)un+ Fou n+ =, j 1, j, j+1 Foun+1 + (1 Fo)un+1 + Fou n+1 (13.59) 1, j, j +1, j Se nós utlzarmos (novamente por smplcdade) o mesmo número de pontos N + 1 em x e em y, teremos o segunte mapeamento para a nossa grade: N = L ; (13.60) x = L +, = 0,..., N, (13.61) y j = L + j, j = 0,..., N, (13.6), e portanto L x L e L y j L. Lembrando que os valores de u 0,j, u N,j, u,0 e u,n estão especfcados, há (N 1) ncógntas para serem calculadas. A beleza de (13.58) e (13.59) é que em vez de resolver a cada passo (dgamos) t um sstema de (N 1) ncógntas, nós agora podemos resolver a cada passo t N 1 sstemas de (N 1) ncógntas, alternadamente para u 1,...,N 1; j e u ;1,...,N1. É claro que o céu é o lmte: poderíamos, por exemplo, em vez de usar um esquema totalmente mplícto, usar Crank-Ncholson em cada avanço t; sto nos dara medatamente um esquema com acuráca de ordem t. No entanto, assm como está o método ADI já é sufcentemente sofstcado para nosso prmero encontro com este tpo de problema. Devemos, portanto, programá-lo. Vamos, ncalmente, programar a solução analítca, na lstagem 13.1. A solução analítca do problema para os nstantes de tempo t = 0, t = 0,1, t = 0, e t = 0,3 está mostrada na fgura 13.9

Matemátca Aplcada 6 Lstagem 13.1: dfusaod-ana.py Solução analítca da equação da dfusão bdmensonal. 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ---------------------------------------------------------- 4 # dfusaod-ana: solução analítca de 5 # 6 # du/dt = D (du^/dx^ + du^/dy^) 7 # 8 # u(x,0) = T0 exp(-(x^ + y^)/l^) 9 # 10 # com T0 = 1, D =, L = 1, em um domíno (-L,-L) até (L,L) 11 # 1 # uso:./dfusaod-ana.py 13 # ---------------------------------------------------------- 14 from future mport prnt_functon 15 from future mport dvson 16 fou = open('dfusaod-ana.dat','wb') 17 dd = 0.01 18 dt = 0.001 19 prnt('# dd = %9.4f' % dd) 0 prnt('# dt = %9.4f' % dt) 1 nn = nt(.0/dd) # número de pontos em x e em y nt = nt(1.0/dt) # número de pontos em t 3 prnt('# nn = %9d' % nn) 4 prnt('# nt = %9d' % nt) 5 from math mport exp 6 def ana(x,y,t): 7 return (1.0/(1.0 + 8*t))*exp(-(x** + y**)) 8 from numpy mport zeros 9 u = zeros((nn+1,nn+1),float) # um array para conter a solução 30 for n n range(nt+1): # loop no tempo 31 t = n*dt 3 prnt(t) 33 for n range(nn+1): # loop no espaço 34 x = -1 + *dd 35 for j n range(nn+1): 36 yj = -1 + j*dd 37 u[,j] = ana(x,yj,t) 38 u.tofle(fou) # mprme uma matrz com os dados 39 fou.close()

63 13.3 Dfusão em Dmensões: ADI, e equações elítcas Fgura 13.9: Solução analítca da equação da dfusão bdmensonal, para t = 0, t = 0, t = 0,1, t = 0, e t = 0,3

Matemátca Aplcada 64 Em seguda, o esquema numérco ADI está mplementado na lstagem 13.13. O resultado é mostrado na fgura 13.10. Lstagem 13.13: dfusaod-ad.py Solução numérca da equação da dfusão bdmensonal, esquema ADI. 1 #!/usr/bn/python # -*- codng: so-8859-1 -*- 3 # ------------------------------------------------------------------------------ 4 # dfusaod-ad resolve uma equação de dfusão com um método mplícto 5 # 6 # uso:./dfusaod-ad.py 7 # ------------------------------------------------------------------------------ 8 from future mport prnt_functon 9 from future mport dvson 10 fou = open('dfusaod-ad.dat','wb') 11 dd = 0.0 # defne a dscretzação em x,y 1 dt = 0.001 # defne a dscretzação em t 13 prnt('# dd = %9.4f' % dd) 14 prnt('# dt = %9.4f' % dt) 15 nn = nt(round(.0/dd,0)) # número de pontos em x,y 16 nt = nt(round(1.0/dt,0)) # número de pontos em t 17 prnt('# nn = %9d' % nn) 18 prnt('# nt = %9d' % nt) 19 from numpy mport zeros 0 u = zeros((,nn+1,nn+1),float) # apenas posções no tempo 1 # são necessáras! from math mport exp 3 def CCy(y): 4 return (1.0/aux)*exp( - (1.0 + y*y)/aux) 5 def CCx(x): 6 return (1.0/aux)*exp( - (1.0 + x*x)/aux) 7 def CI(x, y): 8 return exp(-(x*x + y*y)) 9 for n range(nn+1): # monta a condção ncal 30 x = -1.0 + *dd # ntera, até as fronteras 31 for j n range(nn+1): # nclusve 3 yj = -1.0 + j*dd 33 u[0,,j] = CI(x,yj) 34 u[0].tofle(fou) # mprme a condção ncal 35 D =.0 # dfusvdade 36 Fon = D*dt/((dd)**) # número de Fourer 37 prnt("fo = %10.6f" % Fon) 38 A = zeros((3,nn-1),float) # cra a matrz do sstema 39 # ------------------------------------------------------------------------------ 40 # monta a matrz do sstema 41 # ------------------------------------------------------------------------------ 4 A[0,0] = 0.0 # zera A[0,0] 43 A[0,1:nn-1] = -Fon # preenche o fm da 1a lnha 44 A[1,0:nn-1] = 1.0 + *Fon # preenche a segunda lnha 45 A[,0:nn-] = -Fon # preenche o níco da a lnha 46 A[,nn-] = 0.0 # zera A[,nn-] 47 # ------------------------------------------------------------------------------ 48 # mporta uma tradução de trdag de Numercal Recpes para Python 49 # ------------------------------------------------------------------------------ 50 from algln mport trdag 51 old = False # o velho truque! 5 new = True 53 n = 0 54 b = zeros(nn-1,float) 55 whle (n < nt+1): # loop no tempo 56 n += 1 57 prnt(n) 58 # ------------------------------------------------------------------------------ 59 # varre na dreção x 60 # ------------------------------------------------------------------------------ 61 t = n*dt 6 aux = 1.0 + 8.0*t 63 for j n range(nn+1): # CC ao longo de x 64 yj = -1.0 + j*dd 65 u[new,0,j] = CCy(yj) 66 u[new,nn,j] = CCy(yj)