4.3 Problemas
Exemplo 4.3.1. Resolva numericamente o problema de valor de contorno
usando a fórmula de diferenças finitas central de ordem 2 para discretizar a
derivada. Compute o erro absoluto médio definido por
|
|
onde é o
-ésimo ponto
da malha, e
é o número de
pontos da mesma, é a
solução aproximada e
é a solução analítica, dada por
|
|
Solução: Primeiro, vamos montar a discretização do problema que está definido
no domínio .
A malha é dada por:
|
|
com .
Aplicando na equação diferencial o método de diferenças finitas central
de ordem 2 para aproximar a derivada segunda, obtemos as seguintes
equações:
|
|
As equações de contorno levam as condições:
Ou seja, obtemos o seguinte sistema linear
:
Observamos que este é um sistema linear
, o qual pode ser escrito
na forma matricial ,
cujos matriz de coeficientes é
|
|
o vetor das incógnitas e o vetor dos termos constantes são
|
|
Vamos aplicar o método de Jacobi para resolver esse problema. Partimos do
exemplo 4.2.2 e introduzimos a matriz oriunda da discretização:
#include <stdio.h>
#include <math.h>
#define N 101 /* dimensão do sistema*/
double norma_2(double x[N])
{
int i;
double norma2=x[0]*x[0]/(2*(N-1));
for (i=1;i<N-1;i++)
{
norma2+=x[i]*x[i]/(N-1);
}
norma2+=x[N-1]*x[N-1]/(2*(N-1));
return sqrt(norma2);
}
void Iteracao(double u_antigo[N],double u_atual[N],double matriz[N][N], double vetor[N])
{
double aux;
int i,j;
for (i=0;i<N;i++)
{
aux=0;
for (j=0;j<i;j++)
aux+=matriz[i][j]*u_antigo[j];
for (j=i+1;j<N;j++)
aux+=matriz[i][j]*u_antigo[j];
u_atual[i]=(vetor[i]-aux)/matriz[i][i];
}
}
void Jacobi(double tolerancia,double u_atual[N],double vetor[N],double matriz[N][N],double malha[N])
{
double u_antigo[N],dif[N];
int i,controle=3;
//chute inicial
for (i=0;i<N;i++)u_antigo[i]=0;
//iteração
while (controle)
{
Iteracao(u_antigo,u_atual,matriz,vetor);
for (i=0;i<N;i++) dif[i]=u_atual[i]-u_antigo[i];
if (norma_2(dif)<tolerancia) controle--;
else controle=3;
for (i=0;i<N;i++) u_antigo[i]=u_atual[i];
}
return;
}
double solucao_analitica(double x)
{
return -25.*(x-1.)*(x-1.)*(x-1.)*(x-1.)/3-25.*x/3+25./3.;
}
main (void)
{
int i,j;
double tolerancia=1e-5,solucao[N];
double matriz[N][N];
double vetor[N],x[N];
//malha
double h=1./(N-1);
for (i=0;i<N;i++) x[i]=i*h;
//matriz e vetor
for (i=0;i<N;i++) for (j=0;j<N;j++) matriz[i][j]=0;
matriz[0][0]=1;
vetor[0]=0;
for (i=1;i<N-1;i++)
{
matriz[i][i]=-2;
matriz[i][i+1]=1;
matriz[i][i-1]=1;
vetor[i]=-100*h*h*(x[i]-1)*(x[i]-1);
}
matriz[N-1][N-1]=1;
vetor[N-1]=0;
Jacobi(tolerancia,solucao,vetor,matriz,x);
//erro médio
double erro=0;
for (i=0;i<N;i++) erro+=fabs(solucao[i]-solucao_analitica(x[i]));
erro/=N;
printf("erro médio = %f\n",erro);
//for (i=0;i<N;i++) printf("u_%d=%f, u(x[%d]) = %f\n",i,solucao[i],i,
solucao_analitica(x[i]));
}