• Nenhum resultado encontrado

Instituto de Física Armando Dias Tavares Departamento de Física Aplicada e Termodinâmica

N/A
N/A
Protected

Academic year: 2019

Share "Instituto de Física Armando Dias Tavares Departamento de Física Aplicada e Termodinâmica"

Copied!
44
0
0

Texto

(1)

Departamento de Física Aplicada e Termodinâmica

Física Computacional A

DFAT/

FiscompFA

Equações Diferenciais Ordinárias

Professor: Anibal Leonardo Pereira

última atualização: junho 2011

Estagiários:

2004/1 a 2005/2

Luciana Conceição Iecker Lima

2010/1

Magali dos Santos Leodato

2009/1 a 2010/2

Filipe da Fonseca Cordovil

Monitores:

2001/1

Diego Chagas Garcia

2002/2

Erick Azevedo Meirelles

2003/1 a 2003/2

Luciana Maria dos Santos Azevedo

2003/1 a 2003/2

Tatiana Gonçalves Martins

2003/1 a 2005/2

Renato Nascente Júnior

2004/1 a 2005/2

Públio Martins Romano M. Carreiro

2006/1 a 2007/2

Luiz Fernando Rosalba Telles Souza

2006/1 a 2007/2

Paulo Henrique Pfitzner

2008/1 a 2008/2

Filipe da Fonseca Cordovil

2008/1 a 2009/2

Magali dos Santos Leodato

2011/1 a

Filipe da Fonseca Cordovil

1. Introdução

O método de Euler é o método numérico mais simples que pode ser usado para resolver uma equação

diferencial ordinária de primeira ordem (

Equação Diferencial Ordinária

– EDO).

Uma equação diferencial ordinária é uma equação que envolve só uma variável independente. Por exemplo, a

equação diferencial que descreve o movimento de um pêndulo simples de massa m e comprimento l é

d

2

dt

2

g

l

sen

=

0

ou

d

2

dt

2

=−

g

l

sen



que é uma equação diferencial ordinária de primeira ordem pois a única variável independente é o tempo.

As equações

dy

dx

=

x

8

d

2

y

dx

2

3

dy

dx

2y

=

0

d

3

y

dx

3

2

d

2

y

dx

2

2

dy

dx

=

cos

x

x

dy

dx

y

=

3

d

2

y

dx

2

2

dy

dx

3

(2)

enquanto as equações

z

x

z

x

z

y

=

0

2

z

x

2

2

z

y

2

=

x

2

y

não são, pois possuem duas variáveis independentes x e y.

As equações diferenciais podem ser classificadas quanto ao tipo, a ordem e a linearidade:

Tipo

podem ser ordinárias ou parciais. Ordinárias quando as funções forem somente funções de uma

variável, por exemplo:

y

=

f

x

. Parciais quando as funções forem funções de mais de uma

variável independente:

z

=

f

x , y

Ordem

pode ser de 1

a

, 2

a

, 3

a

, …, enésima ordem, dependendo da derivada de maior ordem presente na

equação. A equação

d

2

dt

2

=−

g

l

sen



é uma equação diferencial ordinária de segunda ordem

Linearidade

Será linear quando as incógnitas e suas derivadas aparecem de forma linear na equação e não

linear caso contrário. A equação

x

dy

dx

y

=

3

é uma equação diferencial ordinária de primeira

ordem linear

Equações diferenciais ordinárias de primeira ordem são equações que podem ser escritas assim:

F

t , y , y '

=

0

ou

dy

dt

=

f

t , y

ou então

F

x , y , y '

=

0

ou

dy

dx

=

f

x , y

2. Método de Euler

Vários problemas encontrados na física envolvem equações diferenciais ordinárias de primeira ordem, por

exemplo:

movimento de projétil

movimento harmônico

são exemplos clássicos.

O método de Euler (

método de Euler padrão; método de Euler progressivo; Forward Euler method

) para uma

equação

diferencial ordinária de primeira ordem

pode ser apresentado assim:

Considere a equação diferencial

dy

dx

=

f

x , y

onde x e y são as variáveis independentes e dependentes e

f

x , y

é a função derivada.

A função derivada pode ser determinada usando-se as diferenças finitas, então:

dy

dx

=

lim

x0

y

x

=

lim

x0

y

i1

y

i

x

i1

x

i

=

lim

h0

y

i1

y

i

h

dy

dx

y

i1

y

i

h

onde se fez

x

=

h

=

x

i1

x

i

(

geralmente h é chamado de passo e feito constante

)

(3)

f

x , y

=

y

i1

y

i

h

o que nos leva a

y

i1

=

y

i

h f

x

i

, y

i

.

Esta forma de chegar ao novo valor de y, o valor

y

i1

, conhecido o valor anterior,

y

i

, é chamada de

método de Euler (

Euler padrão ou Euler progressivo

).

No problema do valor inicial (Problema do Valor Inicial – PVI)

{

dy

dx

=

f

x , y

y

x

0

=

y

0

valores iniciais: x0, y0

os pares de valores (x, y) são encontrados utilizando-se recursivamente a equação

y

i1

=

y

i

h f

x

i

, y

i

.

Esta Folha contém

03 Atividades

00 atividades exemplos

03 atividade exemplo com ajustes e/ou acréscimos

00 atividades para serem feitas

00 atividades para serem ajustadas e/ou acrescidas

Seu professor de laboratório (e/ou teoria) poderá alterar esta relação !

Código da folha de atividades

Acesse a Home Page da disciplina, entre no link Datas-e-Atividades, para obter o código da folha de atividades. Toda atividade tem que ter o "xx" substituído pelo código indicado. Exemplos: código 02 ► fxxa3.f03

f02a3.f03

Atividade 01

Entregar em meio magnético:

1. programa: euler1_prog fxxa1.f03

2. módulos: fc_constantes.f03 m_rotinas.f03 m1func.f03

3. scripts: euler1.plt

4. arquivos: euler1-h05.dados euler1-h02.dados euler1-h005.dados euler.gif

Exemplo/Acréscimo/Ajuste:

Exemplifica o uso do método de Euler progressivo para a solução de equação diferencial ordinária com valor inicial especificado

Observação:

As soluções, exata e as numéricas são colocadas num mesmo gráfico para evidenciar o erro nos valores da solução, conforme h vai aumentando

Fazer:

(4)

do valor inicial:

dy

dx

=

cos

4x



x

2

y

x

0

=

y

0

=

2

no intervalo [0,1] com h=0.5, h=0.2 e h=0.05. Construa o

gráfico (arquivo euler.gif) contendo a solução exata

y

=

2

1

3

x

3

1

4

sin

4x

e as três soluções encontradas pelo

método de Euler progressivo.

a1.2) A velocidade de queda de um corpo é descrita pela equação

dv

dt

=−

g

onde v é a velocidade e a aceleração da gravidade vale g=9.8067 m/s2. Calcule v como função da velocidade para um corpo com (a) saindo do repouso e (b) com velocidade inicial diferente de zero, no intervalo de t=o até t=10s. Construa o gráfico com a solução numérica e a solução analítica.

a1.3) um corpo move-se segundo a equação

dx

dt

=

v

x . Se a velocidade é constante e igual a 40 m/s uma tabela com as

posições x como função do tempo. Entregue o gráfico correspondente.

a1.4) A equação

dI

dt

=

aI

bI

2

descreve o crescimento populacional, sendo I o número de indivíduos. O termo aI

corresponde ao número de nascimentos e -bI2 o número de mortes. Solucione o problema (a) com b=0 e (b) com a=10 e b=3

Não deixe de substituir os

xx

pelo código adequado.

Escreva o programa

euler1_prog

e salve-o no arquivo

fxxa1.f03

Escreva os módulos e os scripts

Gere os arquivos de dados e os gráficos solicitados

Não deixe de atualizar o cabeçalho de forma adequada.

________________________________________________________________________________________

arquivo: fxxa1.f03

◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

program euler1_prog !

!---! Propósito: Constrói tabela de valores (x,y) solução da equação

! diferencial ordinária de 1a ordem com valor inicial y0 ! utilizando o método de Euler (Euler progressivo)

!---! Arquivo:fxxa1.f03

! Autor: Anibal L. Pereira 14/02/2009 !Revisões:

!---use fc_constantes

use fc_rotinas use fc_m1func implicit none

integer::i, & !contador

npassos ! número de passos inteiros real::x0,y0, & ! valor inicial

a,b, & ! intervalo - ponto inicial e ponto final h, & ! incremento h

delta ! incremento mais próximo de h

real,allocatable,dimension(:)::xt,yt !pontos da tabela

!---! Entrada pontos da tabela

!---print*, "====================================" print*, "Entre com o valor inicial x(0) e y(0)" print*, "====================================" read*, x0,y0

(5)

print*, "====================================" print*, "Entre com o incremento h "

print*, "====================================" read*, h

!---número de passos inteiros no intervalo a-b call incremento(a,b,h,npassos,delta)

print*,"npassos,delta",npassos,delta

!---cria vetores x e y da tabela allocate(xt(npassos+1),yt(npassos+1)) xt=0.0

yt=0.0

!---! cálculo da tabela solução da EDO

!---!---função derivada: fun6=f(x)=cos(4*x)+x*x

call euler_tab(fun6,x0,y0,a,b,delta,xt,yt)

!---! preserva resultado num arquivo

!---open(unit=10, file="euler-h05.dados", status="replace",action="readwrite") !open(unit=20, file="euler-h02.dados", status="replace",action="readwrite") !open(unit=30, file="euler-h005.dados", status="replace",action="readwrite")

do i=1,size(xt)

write(unit=10,fmt=*) xt(i),yt(i) end do

close(unit=10)

program euler1_prog

_______________________________________________________________________________________

arquivo: fc_constantes.f03

◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄

Utilize os módulos existentes:

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

_______________________________________________________________________________________

arquivo: fc_rotinas.f03

◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄►◄

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

module fc_rotinas

!--- !Propósito:

! Guarda funções e sub-rotinas

!--- !USO:

! Coloque no seu programa fonte as declarações ! use fc_constantes

! use fc_rotinas !

!COMPILAÇÃO:

! (1) deste módulo fiscomp_rotinas

! f03 -c fc_constantes.o fc_rotinas !

! (2) para usar o módulo com o programa <prog.f03>

! f03 -o <prog> fc_constantes.o fc_rotinas.o <prog.f03>

!--- ! Arquivo: fc_rotinas.f03

! Autor: Anibal L. Pereira 23/01/2009 !Revisões: Anibal L. Pereira 11/02/2009

!Revisões: Anibal L. Pereira 16/04/2010 !

!--- use fc_constantes

implicit none

!--- ! Interfaçes (funções e sub-rotinas sobrecarregadas)

(6)

interface copia_matriz

module procedure copia_matriz_i, copia_matriz_r, copia_matriz_d end interface

interface swap

module procedure swap_i, swap_r, swap_rv, swap_c, swap_cv end interface

interface incremento

module procedure incr_r, incr1_rv, incr2_rv end interface

interface entra_linha_matriz

module procedure entra_linha_matriz_t, entra_linha_matriz_a end interface

!--- ! Funções

!--- public:: derivada

!--- ! Sub-rotinas

!---

public:: gauss, & !gauss elimination AX=B !ok entra_linha_matriz, & !entra linha de uma matriz !ok !rotina sobrecarregada

!1)entra_linha_matriz_t(mat)

! entra linha da matriz pelo teclado !2)entra_linha_matriz_a(mat,arq)

! entra linha da matriz via arquivo

inversa_matriz, & !inversa matriz - método eliminação Gauss !ok copia_matriz, & !copia matriz em outra matriz !ok !rotina sobrecarregada

!1)copia_matriz(src,dest,n_cop,n_ncop) ! copia matriz de valores inteiros !2)copia_matriz(src,dest,n_cop,n_ncop) ! copia matriz de valores reais, sp !3)copia_matriz(src,dest,n_cop,n_ncop) ! copia matriz de valores reais, dp

swap, & !troca valores !ok !rotina sobrecarregada

!1)swap(a,b)

! troca valores inteiros !2)swap(a,b)

! troca valores reais, sp !3)swap(a,b)

! troca valores de vetor reais, sp !4)swap(a,b)

! troca valores complexos, sp !5)swap(a,b)

! troca valores de vetor complexo, sp

incremento, & !calcula incremento e gera vetor de pontos !ok !rotina sobrecarregada

!1)incremento(a,b,incr,ninterv,incrp)

! retorna número de intervalos inteiro para a-b e incremento !(ou incremento próximo)

!2)incremento(a,b,vet)

! Retorna um vetor com 100 pontos no intervalo a-b !3)incremento(a,b,incrp,vet)

! Retorna um vetor com os N pontos gerados pelo incremento em a-b

interp_lagrange, & !interpolação polinomial de Lagrange !ok interp_newton, & !interpolação polinomial diferenças divididas !ok interp_polinomial, & !interpolação polinomial diferenças divididas

! similar ao (Numerical Recipes) !ok dif_finita_asc, & !constrói tabela de diferenças finitas ascendente !ok dif_divididas_asc, & !constrói tabela de diferenças divididas ascendente

(7)

! 3-pontos !ok der2, & !derivada segunda da função usando diferença central ! 3-pontos !ok fit_poli, & !ajuste mínimos quadrados !ok euler1_tab, & !tabela com solução EDO 1a ordem

! PVI - Euler progressivo !ok euler2_tab, & !tabela com solução EDO 2a ordem

! PVI - Euler progressivo !ok euler_mod_tab !tabela com solução EDO 1a ordem

! PVI - Euler modificado !ok

contains

!!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !!@@@@@@@@@@@@@@@@@@@@ SUB-ROTINAS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

!@@@@@@@@@

!--- subroutine copia_matriz_i(src,dest,n_cop,n_ncop)

!--- !Propósito:

! Copia matriz do tipo inteiro de qualquer tamanho ! Adaptação de sub-rotina do numerical recipes

!--- !Autor: Anibal L. Pereira 26/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! copia_matriz_i(src,dest,n_cop,n_ncop) !

! src

! (in) matriz inteira ! matriz original ! dest

! (out) matriz inteira ! matriz copiada ! n_cop

! (out) inteiro

! número de elementos copiados ! n_ncop

! (out) inteiro

! número de elementos não copiados

!--- integer,intent(in) ,dimension(:)::src ! fonte

integer,intent(out),dimension(:)::dest ! copia

integer,intent(out)::n_cop, & ! número de dados copiados n_ncop ! número de dados não copiados

n_cop = min(size(src),size(dest)) ! menor valor entre os tamanhos n_ncop = size(src)- n_cop ! diferença entre os valores dest(1:n_cop) = src(1:n_cop) ! copia a matriz

end subroutine copia_matriz_i

!@@@@@@@@@

!--- subroutine copia_matriz_r(src,dest,n_cop,n_ncop)

!--- !Propósito:

! Copia matriz do tipo real de precisão simples de qualquer tamanho ! Adaptação de sub-rotina do numerical recipes

!--- !Autor: Anibal L. Pereira 26/01/2009

!Revisões:

(8)

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! copia_matriz_r(src,dest,n_cop,n_ncop) !

! src

! (in) matriz real ! matriz original ! dest

! (out) matriz real ! matriz copiada ! n_cop

! (out) inteiro

! número de elementos copiados ! n_ncop

! (out) inteiro

! número de elementos não copiados

!--- real,intent(in) ,dimension(:)::src ! fonte

real,intent(out),dimension(:)::dest ! copia

integer,intent(out)::n_cop, & ! número de dados copiados n_ncop ! número de dados não copiados

n_cop = min(size(src),size(dest)) ! menor valor entre os tamanhos n_ncop = size(src)- n_cop ! diferença entre os valores dest(1:n_cop) = src(1:n_cop) ! copia a matriz

end subroutine copia_matriz_r

!@@@@@@@@@

!--- subroutine copia_matriz_d(src,dest,n_cop,n_ncop)

!--- !Propósito:

! Copia matriz do tipo real de precisão dupla de qualquer tamanho ! Adaptação de sub-rotina do numerical recipes

!--- !Autor: Anibal L. Pereira 26/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! copia_matriz_d(src,dest,n_cop,n_ncop) !

! src

! (in) matriz real,dp ! matriz original ! dest

! (out) matriz real,dp ! matriz copiada ! n_cop

! (out) inteiro,I4B

! número de elementos copiados ! n_ncop

! (out) inteiro

! número de elementos não copiados

!--- real(kind=dp),intent(in) ,dimension(:)::src ! fonte

real(kind=dp),intent(out),dimension(:)::dest ! copia

integer,intent(out)::n_cop, & ! número de dados copiados n_ncop ! número de dados não copiados

n_cop = min(size(src),size(dest)) ! menor valor entre os tamanhos n_ncop = size(src)- n_cop ! diferença entre os valores dest(1:n_cop) = src(1:n_cop) ! copia a matriz

end subroutine copia_matriz_d

(9)

!--- subroutine swap_i(a,b)

!--- !Propósito:

! Troca posição de dois inteiros

!--- !Autor: Anibal L. Pereira 26/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! swap_i(a, b) !

! a

! (inout) inteiro ! primeiro valor ! b

! (inout) inteiro ! segundo valor

!--- integer,intent(inout):: a, &! primeiro valor

b ! segundo valor integer:: temp ! valor temporário

temp = a a = b b = temp

end subroutine swap_i

!@@@@@@@@@

!--- subroutine swap_r(a,b)

!--- !Propósito:

! Troca posição de dois reais, precisão simples ! Adaptação de sub-rotina do numerical recipes

!--- !Autor: Anibal L. Pereira 26/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! swap_r(a, b) !

! a

! (inout) real ! primeiro valor ! b

! (inout) real ! segundo valor

!--- real,intent(inout):: a, &! primeiro valor

b ! segundo valor real:: temp ! valor temporário

temp = a a = b b = temp

end subroutine swap_r

!@@@@@@@@@

!--- subroutine swap_rv(a,b)

(10)

! Troca conteúdo de dois vetores reais, precisão simples, tamanho qualquer ! Adaptação de sub-rotina do numerical recipes

!--- !Autor: Anibal L. Pereira 26/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! swap_rv(a, b) !

! a

! (inout) vetor real ! vetor primeiro valor ! b

! (inout) vetor real ! vetor segundo valor

!--- real,intent(inout),dimension(:):: a, &! vetor primeiro valor

b ! vetor segundo valor real,dimension(size(a))::temp ! vetor temporário

temp = a a = b b = temp

end subroutine swap_rv

!@@@@@@@@@

!--- subroutine swap_c(a,b)

!--- !Propósito:

! Troca posição de dois números complexos, precisão simples ! Adaptação de sub-rotina do numerical recipes

!--- !Autor: Anibal L. Pereira 26/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! swap_c(a, b) !

! a

! (inout) complex ! primeiro valor ! b

! (inout) complex ! segundo valor

!--- complex,intent(inout):: a, &! primeiro valor

b ! segundo valor complex:: temp ! valor temporário

temp = a a = b b = temp

end subroutine swap_c

!@@@@@@@@@

!--- subroutine swap_cv(a,b)

!--- !Propósito:

! Troca conteúdo de dois vetores complexos, precisão simples, tamanho qualquer ! Adaptação de sub-rotina do numerical recipes

(11)

!Autor: Anibal L. Pereira 26/01/2009 !Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! swap_cv(a, b) !

! a

! (inout) vetor complex ! vetor primeiro valor ! b

! (inout) vetor complexo ! vetor segundo valor

!--- complex,intent(inout),dimension(:):: a, &! vetor primeiro valor

b ! vetor segundo valor complex,dimension(size(a))::temp ! vetor temporário

temp = a a = b b = temp

end subroutine swap_cv

!@@@@@@@@@

!--- subroutine gauss(n,a)

!--- !Propósito:

! Solução numérica de sistema de equações lineares pelo método da eliminação ! de Gauss

!

! Atenção: pelo menos um dos coeficientes não homogêneos tem que ser diferente ! de zero. Caso contrário não há garantia de funcionamento correto !--- !Autor: Anibal L. Pereira 23/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! gauss(n, a ) !

! n

! (in) inteiro

! número de equações lineares ! a

! (in/out) matriz real,dp, shape(:,:)

! na entrada: matriz aumentada original Nx(N+1)

! na saída : matriz aumentada contendo soluções na coluna N+1

!--- real(kind=dp),dimension(:,:),intent(inout)::a

integer,intent(in)::n ! número de equações lineares integer:: i, & !

j, & ! contador

jc, & ! contador, anda pela coluna jr, &

k, & kc, & nv, &

pv !número da coluna com maior valor absoluto do coeficiente integer::i9

real(kind=dp):: det=1.0, & ! determinante eps, & ! epsilon da máquina eps2, & ! dobro de epsilon r, & !

(12)

tm, & ! valor temporário para troca va

!--- !---

! Determina épsilon da máquina !--- eps=epsilon(det)

eps2 = eps*2

!--- ! gera a matriz triagonal

!---

do i=1,n-1 ! anda nas colunas, 1,2,...,N-1 (até penúltima) pv=i ! identifica o pivot

!---

do j=i+1,n !na coluna i anda da linha 2 até última para achar o maior valor absoluto

if(abs(a(pv,i)) < abs(a(j,i))) pv=j !pv = número da linha que contém maior valor absoluto end do

!---

if(pv /= i) then ! coloca linha com maior valor nesta posição do jc=1,n+1 ! anda pelas colunas

tm=a(i,jc) ! guarda temporariamente valor da linha i a(i,jc)=a(pv,jc) ! escreve valor da linha pv na linha i a(pv,jc)=tm ! escreve valor da linha i na linhas pv end do

det=-det ! valor do determinante end if

!---

if(a(i,i) == 0) then ! matriz singular - primeiro pivot igual a zero --> para o processo print*,"a(",i,i,") = 0 Matriz singular! "

stop end if

!---

do jr=i+1,n !eliminação dos coeficientes abaixo do pivot da linha i if(a(jr,i) /= 0) then

r = a(jr,i)/a(i,i)

do kc=i,n+1 ! anda na linha coluna a coluna ate a última temp=a(jr,kc)

a(jr,kc)=a(jr,kc)-r*a(i,kc)

! se o valor for menor que 2*epsilon ele é zerado if(abs(a(jr,kc))<eps2*temp) a(jr,kc)=0.0 end do

end if end do end do

!--- ! calcula o determinante

!--- do i=1,n

det = det*a(i,i) end do

if(det == 0) then

print*,"Determinante = 0 Matriz é singular" stop

else

! solução das equações a(n,n+1)=a(n,n+1)/a(n,n) do nv= (n-1),1,-1

va = a(nv,n+1) do k=(nv+1),n

va = va - a(nv,k)*a(k,n+1) end do

a(nv,n+1)=va/a(nv,nv) end do

return end if

end subroutine gauss

!@@@@@@@@@

!--- subroutine entra_linha_matriz_t(mat)

!--- !Propósito:

(13)

!--- !Autor: Anibal L. Pereira 23/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! entra_linha_matriz_t(mat) !

! mat

! (out) real, shape(:,:)

! matriz com dados obtidos via teclado

!--- real,dimension(:,:),intent(out)::mat

integer::i,n,m

n = size(mat,dim=1) ! número de linhas m = size(mat,dim=2) ! número de colunas

do i=1,n

read*, mat(i,1:m) end do

end subroutine entra_linha_matriz_t

!@@@@@@@@@

!--- subroutine entra_linha_matriz_a(mat,arq)

!--- !Propósito:

! Entra valores da linha de uma matriz via arquivo

!--- !Autor: Anibal L. Pereira 23/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! entra_linha_matriz_a(mat,arq) !

! mat

! (out) real, shape(:,:)

! matriz com dados obtidos do arquivo ! arq

! (in) caractere

! nome do arquivo de dados

!--- real,dimension(:,:),intent(out)::mat

character(len=*),intent(in)::arq integer::i,n,m

n = size(mat,dim=1) ! número de linhas m = size(mat,dim=2) ! número de colunas

open(unit=20, file=arq, status="old", action="read")

do i=1,n

read(unit=20,fmt=*) mat(i,1:m) end do

close(unit=20)

end subroutine entra_linha_matriz_a

!@@@@@@@@@

!--- subroutine inversa_matriz(n,mat,inv)

!--- !Propósito:

(14)

!--- !Autor: Anibal L. Pereira 24/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! inversa_matriz(n,mat,inv) !

! n

! (in) inteiro

! número de linhas da matriz quadrada NxN ! mat

! (in) matriz quadrada real, shape(:,:) ! matriz a ser invertida

! inv

! (out) matriz quadrada real,shape(:,:) ! matriz inversa

!--- real,dimension(:,:),intent(in) ::mat ! matriz

real,dimension(:,:),intent(out)::inv ! matriz inversa integer,intent(in)::n ! número de linhas na matriz original real,allocatable,dimension(:,:)::mat_aum ! matriz aumentada N x M integer::m ! número de colunas na matriz aumentada => m=2*n

integer:: cci,ccj! contadores

integer:: i, & ! contador, anda pelas colunas de 1 até n-1 j, & ! contador, anda pelas linhas de i+1 até n jc, & ! contador, anda pelas colunas de 1 até m jr, & ! contador, anda pelas linhas de i+1 até n k, &

kc, & ! contador, anda pelas colunas de 1 até m ma, & ! contador, indo de n+1 até m --> n elementos nv, &

pv ! número da linha que tem o maior valor absoluto real:: det=1.0, & ! inicialização do determinante

eps, & ! epsilon da máquina eps2, & ! dobro de epsilon r, & !

temp, & ! valor temporário para troca tm, & ! valor temporário para troca va

!--- m = 2*n

allocate(mat_aum(n,m)) mat_aum = 0

!--- ! copia a matriz e agrega matriz unitária na matriz aumentada !--- do cci=1,n

mat_aum(cci,1:n) = mat(cci,1:n) end do

do cci=1,n do ccj=n+1,m

if ((cci+n) == ccj)then mat_aum(cci,ccj) = 1.0 end if

end do end do

!--- ! Determina épsilon da máquina !--- eps=epsilon(det)

eps2 = eps*2

!---

do i=1,n-1 ! i=número da coluna -- (forward elimination) (n-1)passos pv=i ! pv=número da linha com maior valor absoluto

do j=i+1,n ! j=número da linha, sempre começando 1 unidade a mais que a coluna if(abs(mat_aum(pv,i)) < abs(mat_aum(j,i))) pv=j

end do

(15)

! se esta linha não contém o maior valor troca as linhas de posição pivota a linha do jc=1,m !jc=coluna

tm = mat_aum(i,jc)

mat_aum(i,jc)= mat_aum(pv,jc) mat_aum(pv,jc)= tm

end do

det = - det ! cada mudança de linha muda o sinal de det end if

do jr=i+1,n ! anda pela linhas debaixo do pivot ! zera os valores abaixo do pivot

if(mat_aum(jr,i) /= 0) then r = mat_aum(jr,i)/mat_aum(i,i)

do kc=i,m ! anda pelas colunas ! escreve novos valores na linha

temp= mat_aum(jr,kc)

mat_aum(jr,kc)= mat_aum(jr,kc)-r*mat_aum(i,kc) ! se o valor for menor que 2*epsilon ele é zerado

if(abs(mat_aum(jr,kc))< eps2*temp) mat_aum(jr,kc)=0.0 end do

end if end do end do

!--- ! calcula o terminante da matriz NxN pivotada !--- do i=1,n

det = det*mat_aum(i,i) end do

if(mat_aum(n,n) /= 0) then !backward elimination

do ma=n+1, m !coloca a matriz I à esquerda da matriz aumentada mat_aum(n,ma)= mat_aum(n,ma)/mat_aum(n,n)

do nv=n-1,1,-1

va = mat_aum(nv,ma) do k=nv+1,n

va = va - mat_aum(nv,k)* mat_aum(k,ma) end do

mat_aum(nv,ma)=va/mat_aum(nv,nv) end do

end do end if

!--- ! copia inversa para matriz inv !--- do i=1,n

inv(i,:)=mat_aum(i,n+1:m) end do

deallocate(mat_aum)

end subroutine inversa_matriz

!@@@@@@@@@

!--- subroutine interp_lagrange(np,xt,yt,x,yans)

!--- !Propósito:

! Interpola e extrapola usando a fórmula de Lagrange (polinômio de Lagrange) !--- !Autor: Anibal L. Pereira 26/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! lagrange_interp(n,xt,yt,x,yans) !

! np

! (in) inteiro

! número de pontos da tabela ! xt

! (in) vetor real

(16)

! yt

! (in) vetor real

! vetor com pontos y da tabela ! x

! (in) real

! ponto x para o qual a interpolação será calculada ! yans

! (out) real

! ponto y interpolado

!--- integer,intent(in)::np ! número de pontos da tabela

real,dimension(0:np-1),intent(in)::xt ! ponto x da tabela real,dimension(0:np-1),intent(in)::yt ! ponto y da tabela real,intent(in)::x ! ponto x para interpolação real,intent(out)::yans ! ponto y interpolado !---

integer:: i, j ! contadores real::z ! produto dos fatores !--- yans=0.0

do i=0,np-1 z=1.0 do j=0,np-1

if(i /= j) z=z*(x-xt(j))/(xt(i)-xt(j)) end do

yans=yans+z*yt(i) end do

end subroutine interp_lagrange

!@@@@@@@@@

!--- subroutine incr_r(a,b,incr,ninterv,incrp)

!--- !Propósito:

! Retorna o próprio incremento ou o incremento mais próximo do incremento solicitado ! que gera um números inteiro de intervalos iniciando em a e terminando em b.

! Também retorna o número de incrementos

!--- !Autor: Anibal L. Pereira 27/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! incr_r(a,b,incr,ninterv,incrp) !

! a

! (in) real ! ponto inicial ! b

! (in) real ! ponto final ! incr

! (in) real

! increvento sugerido ! ninterv

! (out) inteiro

! número de intervalos ! incrp

! (out) real

! incremento igual ou próximo do desejado para gerar um números de intervalos ! inteiro em a-b

!--- real,intent(in):: a, &! ponto inicial

b, &! ponto final do intervalo incr ! incremento desejado

integer,intent(out)::ninterv ! números de intervalos em a-b real,intent(out):: incrp ! incremento mais próximo !---

(17)

integer::iN_pontos

!--- ! cálculo do incremento e número de intervalos !--- N_pontos=(b-a)/incr

iN_pontos=int(N_pontos) ninterv=iN_pontos

if(N_pontos /= iN_pontos) then !Incremento mais próximo incrp=(b-a)/iN_pontos else

!Mesmo incremento incrp=incr

end if

end subroutine incr_r

!@@@@@@@@@

!--- subroutine incr1_rv(a,b,vet)

!--- !Propósito:

! Retorna um vetor com 100 pontos no intervalo a-b

!--- !Autor: Anibal L. Pereira 27/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! incr1_rv(a,b,vet) !

! a

! (in) real ! ponto inicial ! b

! (in) real ! ponto final ! vet

! (out) vetor real, shape(:)

! vetor com 100 pontos no intervalo a,b

!--- real,intent(in):: a, & ! ponto inicial

b ! ponto final do intervalo

real,intent(out),dimension(100):: vet ! vetor de pontos no intervalo a-b !---

real(sp)::delta integer:: i

delta=(b-a)/100

vet=[ a,((a+i*delta),i=2,100) ] end subroutine incr1_rv

!@@@@@@@@@

!--- subroutine incr2_rv(a,b,incrp,vet)

!--- !Propósito:

! Retorna um vetor com os N pontos gerados com o incremento especificado ! iniciando em a e terminando em b

! !

!ATENÇÃO: porque o tamanho do vetor tem que ser conhecido pelo programa que chama ! esta sub-rotina, esta sub-rotina só possa ser camada depois do vetor ! ter sido alocado com o tamanho certo, então:

!

! primeiro: call incremento(a,b,incr,ninterv,incrp) !

(18)

!--- !Autor: Anibal L. Pereira 27/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! incr2_rv(a,b,incrp,vet) !

! a

! (in) real ! ponto inicial ! b

! (in) real ! ponto final ! incrp

! (in) real

! tamanho dos intervalos em a-b ! vet

! (out) vetor real

! vetor com N posições gerado com incrp no intervalo a-b

!--- real,intent(in):: a, &! ponto inicial

b, &! ponto final do intervalo incrp ! incremento

real,intent(out),dimension(:)::vet ! vetor com pontos de a até b !---

integer:: i,n

n=size(vet)

vet=[ a,((a+i*incrp),i=1,n-1) ] end subroutine incr2_rv

!@@@@@@@@@

!--- subroutine interp_newton(xt,yt,x,y)

!--- !Propósito:

! Interpolação progressiva de Newton - intervalos iguais, aceita tabela de ! dados com tamanho N (qualquer, maior que 2)

!--- !Autor: Anibal L. Pereira 24/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! interp_newton(xt,yt,x,y) !

! xt

! (in) vetor real ! X - pontos da tabela ! yt

! (in) vetor real ! Y - pontos da tabela ! x

! (in) real ! ponto desejado ! y

! (out) real

! ponto interpolado

!--- real,intent(in),dimension(:)::xt,yt ! tabela original

real,intent(in) :: x ! ponto

real,intent(out):: y ! ponto interpolado !---

(19)

real,allocatable,dimension(:)::xti,yti ! tabela para interpolação real,allocatable,dimension(:,:)::dd ! diferenças finitas real,dimension(1)::po !posição da menor diferença

real,dimension(0:9)::pr ! produtos real::s, & ! variável local fator ! fatorial integer:: i,i1,j , &! contador

ipo, &! posição do ponto mais próximo de x tam, &! tamanho do vetor

k ! posição de x0 para criar a tabela de interpolação !---

!--- cria os vetores com tamanho certo tam=size(xt)

if(tam < 2) stop "tabela necessita de pelo menos 2 pontos" if(tam >= 10) then

allocate(xti(0:9),yti(0:9),hi(tam),dd(0:9,0:9)) xti=0.0

yti=0.0

hi=0.0 dd=0.0

else

!---tamanho maior que 2 e menor que 10

allocate(xti(tam),yti(tam),hi(tam),dd(tam,tam)) xti=0.0

yti=0.0

hi=0.0 dd=0.0

end if

!--- cria vetor com diferenças hi=abs(x-xt)

!--- ! tabela original com 10 ou mais pontos

!--- !

!---localiza a posição mais próxima do ponto x po=minloc(hi)

ipo=po(1)

if (x == xt(ipo)) then

y=yt(ipo) ! ponto-base não necessita interpolação return

end if

!--- gera tabela de interpolação com 10 pontos, iniciando em x0 if(ipo-4 >= 0) then

!--- tem 4 elementos anteriores if(size(xt)-ipo >=5) then

!--- tem 5 elementos posteriores k=ipo-4

!---cria tabela de interpolação do i=0,9

xti(i)=xt(k+i) yti(i)=yt(k+i) end do

else

!--- não tem 5 elementos depois k=ipo-(9-(size(xt)-ipo))

do i=0,9

xti(i)=xt(k+i) yti(i)=yt(k+i) end do

end if else

!--- não tem 4 elementos anteriores k=1

!---cria tabela de interpolação do i=0,9

xti(i)=xt(k+i) yti(i)=yt(k+i) end do

end if

(20)

!--- !

!---cálculos das diferenças finitas dd(0:9,0)=yti

do i=1,9 ! completando a tabela de diferença finita iniciando k=9-i

do j=0,k

dd(j,i)=dd(j+1,i-1)-dd(j,i-1) end do

end do

!--- variável local

s=(x-xti(0))/(xti(1)-xti(0)) !--- gera os produtos

pr(0)=1.0 pr(1)=s pr(9)=0.0 do j=2,8

pr(j)=pr(j-1)*(s-(j-1)) end do

!--- ponto interpolado y=dd(0,0)

fator=1.0 do i=1,9

fator=fator*i

y=y+(pr(i)/fator)*dd(0,i) end do

end subroutine interp_newton

!@@@@@@@@@

!--- subroutine interp_polinomial(xt,yt,x,y)

!--- !Propósito:

! Interpolação polinomial - intervalos não necessitam ser iguais, tamanho da ! tabela é N (com N qualquer)

!

! Adaptação da sub-rotina polint do numerical recipes

!--- !Autor: Anibal L. Pereira 24/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! interp_polinomial(xt,yt,x,y) !

! xt

! (in) vetor real

! X - pontos da tabela - máximo de 10 ! yt

! (in) vetor real

! Y - pontos da tabela - máximo de 10 ! x

! (in) real ! ponto desejado ! y

! (out) real

! ponto interpolado

!--- real,intent(in),dimension(:):: xt,yt ! pontos x,y da tabela

real,intent(in):: x ! ponto para interpolação real,intent(out):: y ! valor interpolado !---

integer:: i, & ! contador do loop tn, & ! tamanho dos vetores

ipvmp ! posição na tabela do menor valor de x-xt

integer,dimension(1):: pvmp ! posição do menor valor de x-xt real,dimension(size(xt)):: copy1, & ! vetor

(21)

den, & ! vetor

d1, & ! vetor com diferença obtida por xt-x vdax ! vetor diferença absoluta para x real::dy ! flutuação no valor y

!--- tn=size(xt) ! tamanho do vetor xt

if(tn /= size(yt)) stop "<== Programa terminou porque vetores tem tamanhos diferentes" copy1=yt ! copia o vetor yt nos vetores copy1 e

copy2=yt ! copy2

d1=xt-x ! subtrai x de todos os pontos x da tabela

vdax=abs(x-xt) ! vetor com diferenças absolutas entre x e os pontos xt pvmp=minloc(vdax)

ipvmp=pvmp(1) ! índice do valor tabelado mais perto de x y=yt(ipvmp) ! valor inicial da interpolação

ipvmp=ipvmp-1 !

do i=1,tn-1 ! den(1:tn-i)=d1(1:tn-i)- d1(1+i:tn)

if (any(den(1:tn-i) == 0.0)) stop "<== Calculo falhou" den(1:tn-i)=(copy1(2:tn-i+1)-copy2(1:tn-i))/den(1:tn-i) copy2(1:tn-i)=d1(1+i:tn)*den(1:tn-i) copy1(1:tn-i)=d1(1:tn-i)*den(1:tn-i)

if (2*ipvmp < tn-i) then dy=copy1(ipvmp+1)

else

dy=copy2(ipvmp) ipvmp=ipvmp-1 end if

y=y+dy end do

end subroutine interp_polinomial

!@@@@@@@@@

!--- subroutine dif_finita_asc(xt,yt,dif)

!--- !Propósito:

! Constrói a tabela de diferenças finitas ascendente - incrementos equidistantes !--- !Autor: Anibal L. Pereira 30/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! dif_finita_asc(xt,yt,dif) !

! xt

! (in) vetor real, shape(:) ! valores X da tabela ! yt

! (in) vetor real, shape(:) ! valores Y da tabela ! dif

! (out) matriz, shape(:,:)

! contém x e as diferenças finitas: y,Dy,D^2y,...

!--- real,dimension(:),intent(in)::xt, yt

real,dimension(:,:),intent(out)::dif !---

integer:: i,j,k, & ! contadores n_pontos ! número de pontos !--- ! copia xt e yt para a matriz dif

n_pontos=size(xt)

if(n_pontos > 10) stop "Maximo 10 pontos" do i=1,n_pontos

(22)

end do

!print*,"--- matriz dif ---"

!print"(8f12.5)",((dif(i,j),j=1,n_pontos+1),i=1,n_pontos) !stop

do k=3,n_pontos+1 ! anda pelas colunas j=n_pontos - (k-2)

do i=1,j

dif(i,k)=dif(i+1,k-1)-dif(i,k-1) end do

end do

end subroutine dif_finita_asc

!@@@@@@@@@

!--- subroutine dif_divididas_asc(xt,yt,dif)

!--- !Propósito:

! Constrói a tabela de diferenças divididas ascendente - incrementos podem ser ! desiguais

!--- !Autor: Anibal L. Pereira 30/01/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: nenhum ![ funções]: nenhuma ![sub-rotinas]: nenhuma

!--- !Argumentos:

! dif_divididas_asc(xt,yt,dif) !

! xt

! (in) vetor real, shape(:) ! valores X da tabela ! yt

! (in) vetor real, shape(:) ! valores Y da tabela ! dif

! (out) matriz, shape(:,:)

! contém x e as diferenças divididas

!--- real,dimension(:),intent(in)::xt, yt

real,dimension(:,:),intent(out)::dif !---

integer:: i,j,k, & ! contadores n_pontos ! número de pontos !--- ! copia xt e yt para a matriz dif

n_pontos=size(xt)

if(n_pontos > 10) stop "Maximo 10 pontos" do i=1,n_pontos

dif(i,1)=xt(i) dif(i,2)=yt(i) end do

do k=3,n_pontos+1 ! anda pelas colunas j=n_pontos - (k-2) ! anda dentro da coluna do i=1,j

! diferença dividida

dif(i,k)=(dif(i+1,k-1)-dif(i,k-1))/(dif(i+(k-2),1)-dif(i,1)) end do

end do

end subroutine dif_divididas_asc

!@@@@@@@@@

!--- subroutine bissecao(func,a,b,tol,zero,ifail)

!--- !Propósito:

! Calcula a integral da função usando o método da bisseção

!--- !Autor: Anibal L. Pereira 30/01/2009

!Revisões:

(23)

!DEPENDÊNCIA:

![ módulos]: <<<<<< especificado pelo usuário >>>>>> ![ funções]: <<<<<< especificada pelo usuário >>>>>> ![sub-rotinas]: nenhuma

!--- !Argumentos:

! bissecao(func,a,b,tol,zero,ifail) !

! func

! (in) função, real, dp

! funçãoespecidicada pelo usuário ! a

! (in) real, dp

! valores inicial da integral definida ! b

! (in) real, dp

! valores final da integral definida ! zero

! (out) real, dp

! valores da integral definida ! ifail

! (out) inteiro

! valores indicando o status

!--- real(kind=dp),external::func

real(kind=dp),intent(in)::a,b,tol real(kind=dp),intent(out)::zero

integer,intent(out)::ifail ! indicador de erro !---

real(kind=dp)::a1,b1 ! copia local dos limites iniciais integer:: i, & ! contador

num_int ! número de iterações real(kind=dp)::meio_intr ! meio do intervalo !--- ! status e causas de erro

ifail=0

if(func(a)*func(b)>0) then

! 0 raiz pode ser encontrada

ifail=1 ! 1 raiz não está dentro do intervalo a-b return

endif

if(tol < 0) then

ifail=2 ! 2 tolerância inválida tolerância<0 return

endif

if(a > b) then

ifail=3 ! 3 intervalo inválido a>b return

endif a1=a b1=b

num_int=ceiling(log(tol/(b1-a1))/log(0.5_dp)) do i=1,num_int

meio_intr=(a1+b1)/2

if(func(a1)*func(meio_intr)<0)then b1=meio_intr

else

a1=meio_intr end if

end do

zero=(a1+b1)/2

end subroutine bissecao

!@@@@@@@@@

!--- subroutine newton_raphson(func,x,tol,zero)

!--- !Propósito:

! Calcula zero da função pelo método de Newton-Raphson

!--- !Autor: Anibal L. Pereira 04/02/2009

!Revisões:

(24)

!DEPENDÊNCIA:

![ módulos]: <<<<<< especificado pelo usuário >>>>>> ![ funções]: <<<<<< especificada pelo usuário >>>>>> ![sub-rotinas]: nenhuma

!--- !Argumentos:

! newtom_raphson(func,x,tol,zero) !

! func

! (in) função real,dp

! função especificada pelo usuário ! x

! (in) real,dp

! valores x da abcissa ! tol

! (in) real,dp

! valor da tolerância - erro ! zero

! (out) real,dp ! zero da função

!--- real(kind=dp),external::func

real(kind=dp),intent(in)::x, tol real(kind=dp),intent(out)::zero

!--- real(kind=dp)::erro, & !erro

xb, & !valor prévio de x y_deriv, & !derivada no ponto x xt !raiz

integer:: n ! número de iterações !--- erro=1.0D10

xt=x xb=xt n=0

do while (erro > tol) n=n+1

y_deriv=derivada(func,xt) xt=xt-func(xt)/y_deriv erro=abs(xt-xb)

xb=xt end do zero=xt

end subroutine newton_raphson

!@@@@@@@@@

!--- subroutine integ_trapezio(func,a,b,n,it)

!--- !Propósito:

! Calcula a integral da função entre os pontos a e b utilizando n intervalos ! pelo método do trapézio

!--- !Autor: Anibal L. Pereira 04/02/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: <<<<<< especificado pelo usuário >>>>>> ![ funções]: <<<<<< especificada pelo usuário >>>>>> ![sub-rotinas]: nenhuma

!--- !Argumentos:

! integ_trapezio(func,a,b,n,it) !

! func

! (in) função real,dp

! função especificada pelo usuário ! a

! (in) real,dp

! valores inicial da integral definida ! b

! (in) real,dp

(25)

! n

! (in) inteiro

! número de intervalos ! it

! (out) real,dp

! valor da integral definida

!--- real(kind=dp),external::func

real(kind=dp),intent(in)::a, b integer,intent(in)::n

real(kind=dp),intent(out)::it

!--- real(kind=dp)::dx, & !incremento

s1, & !parte da soma s2, & !parte da soma p !ponto

integer:: i ! contador

!--- dx=(b-a)/n

s1=func(a)+func(b) p=a

s2=0.0_dp do i=1,n-1 p=p+dx

s2=s2+func(p) end do

it=(dx/2.0_dp)*(s1+2_dp*(s2)) end subroutine integ_trapezio

!@@@@@@@@@

!--- subroutine simpson_1_3(func,a,b,n,simp)

!--- !Propósito:

! Calcula a integral da função entre os pontos a e b utilizando n1 intervalos ! pelo método de simpson 1/3

!--- !Autor: Anibal L. Pereira 04/02/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: <<<<<< especificado pelo usuário >>>>>> ![ funções]: <<<<<< especificada pelo usuário >>>>>> ![sub-rotinas]: nenhuma

!--- !Argumentos:

! simpson_1_3(func,a,b,n,it) !

! func

! (in) função real,dp

! função especificada pelo usuário ! a

! (in) real,dp

! valores inicial da integral definida ! b

! (in) real,dp

! valor final da integral definida ! n

! (in) inteiro

! número de intervalos ! simp

! (out) real,dp

! valor da integral definida

!--- real(kind=dp),external::func

real(kind=dp),intent(in)::a, b ! ponto inicial e final

integer,intent(in)::n ! número sugerindo de intervalos real(kind=dp),intent(out)::simp ! valor da integral

!--- real(kind=dp)::h, & !tamanho do incremento x !ponto

(26)

!---

!--- ! garante que o número de intervalos é sempre par, o que garante ! numeros impares de pontos

! (n=par)===> n1=n (n=impar) ===> n1=n+1

!--- n1=max(n,2)

n1=n1+modulo(n1,2)

h=(b-a)/n1 x=a

simp=func(x) ! simp=f(a)

do i=1,n1-1

x=a+i*h ! anda por cada um dos pontos de x(2) até x(n-1) simp = simp + (3 -(-1)**i)*func(x) ! soma 4*f(x_impares) e 2*f(x_pares)

end do

x=b

simp = simp + func(x) ! soma último ponto f(b) simp = h*(simp/3)

end subroutine simpson_1_3

!@@@@@@@@@

!--- subroutine der1(func,x,tol,der)

!--- !Propósito:

! Calcula a derivada primeira da função fornecida no ponto x usando a ! aproximação da diferença central para 3-pontos

!--- !Autor: Anibal L. Pereira 07/02/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: <<<<<< especificado pelo usuário >>>>>> ![ funções]: <<<<<< especificada pelo usuário >>>>>> ![sub-rotinas]: nenhuma

!--- !Argumentos:

! der1(func,x,tol,der) !

! func

! (in) função real,dp

! função especificada pelo usuário ! x

! (in) real,dp

! valores do ponto no qual será calculada a derivada primeira ! tol

! (in) real,dp ! tolerância ! der

! (out) real,dp

! valor da derivada no ponto x

!--- real(kind=dp),external::func

real(kind=dp),intent(in)::x,tol real(kind=dp),intent(out)::der !---

real(kind=dp)::h ! incremento real(kind=dp),dimension(0:100)::d, & ! derivadas

e ! diferença entre as derivadas integer::i ! contador

!--- h=1.0

d(0) =0.5*(func(x+h)-func(x-h))/h do i=1,2

h=h/2

d(i)= 0.5*(func(x+h)-func(x-h))/h e(i)= abs(d(i))-abs(d(i-1)) end do

(27)

do while ( e(i) > tol .and. (i < 100) ) h=h/2

d(i+2) = 0.5*(func(x+h)-func(x-h))/h e(i+2) = abs(d(i+2) - d(i+1))

i=i+1 end do der=d(i+1)

end subroutine der1

!@@@@@@@@@

!--- subroutine der2(func,x,tol,der)

!--- !Propósito:

! Calcula a derivada segunda da função fornecida no ponto x usando a ! aproximação da diferença central para 3-pontos

!--- !Autor: Anibal L. Pereira 10/02/2009

!Revisões:

!--- !DEPENDÊNCIA:

![ módulos]: <<<<<< especificado pelo usuário >>>>>> ![ funções]: <<<<<< especificada pelo usuário >>>>>> ![sub-rotinas]: nenhuma

!--- !Argumentos:

! der2(func,x,tol,der) !

! func

! (in) função real,dp

! função especificada pelo usuário ! x

! (in) real,dp

! valores do ponto no qual será calculada a derivada primeira ! tol

! (in) real,dp ! tolerância ! der

! (out) real,dp

! valor da derivada no ponto x

!--- real(kind=dp),external::func

real(kind=dp),intent(in)::x,tol real(kind=dp),intent(out)::der !---

real(kind=dp)::h ! incremento real(kind=dp),dimension(0:100)::d2, & ! derivadas

e ! diferença entre as derivadas integer::i ! contador

!--- h=1.0

d2(0) = (func(x+h)-2*func(x)+func(x-h))/(h*h) do i=1,2

h=h/2

d2(i)= (func(x+h)-2*func(x)+func(x-h))/(h*h) e(i)= abs(d2(i))-abs(d2(i-1))

end do i=1

do while ( e(i) > tol .and. (i < 100) ) h=h/2

d2(i+2) = (func(x+h)-2*func(x)+func(x-h))/(h*h) e(i+2) = abs(d2(i+2) - d2(i+1))

i=i+1 end do der=d2(i+1)

end subroutine der2

!@@@@@@@@@

!--- subroutine fit_poli(n,xt,yt,coef)

!--- !Propósito:

Referências

Documentos relacionados

A Escola Estadual Médio Solimões (EEMS), objeto deste estudo, é considerada uma escola de médio porte, segundo a classificação estabelecida pela Secretaria de

Esta dissertação pretende explicar o processo de implementação da Diretoria de Pessoal (DIPE) na Superintendência Regional de Ensino de Ubá (SRE/Ubá) que

De acordo com o Consed (2011), o cursista deve ter em mente os pressupostos básicos que sustentam a formulação do Progestão, tanto do ponto de vista do gerenciamento

O construto estilo e qualidade de vida é explicado pelos seguintes indicadores: estilo de vida corrido realizando cada vez mais trabalho em menos tempo, realização

Propiciar um panorama geral da área de Física do Estado Sólido, com ênfase nas idéias fundamentais e conceitos gerais, e uma visão moderna da ciência dos materiais. Utilização

O objetivo do curso foi oportunizar aos participantes, um contato direto com as plantas nativas do Cerrado para identificação de espécies com potencial

A versão reduzida do Questionário de Conhecimentos da Diabetes (Sousa, McIntyre, Martins &amp; Silva. 2015), foi desenvolvido com o objectivo de avaliar o

Entende-se que os objetivos desta pesquisa foram alcançados, uma vez que a medida de polaridade conseguiu captar espaços com maiores potenciais de copresença (espaços