Metodi FEM per problemi
ellittici
Gabriella Puppo
Principali argomenti
• Elementi finiti P2
• Velocità di convergenza
• Problema di convezione/diffusione
Filo elastico con elementi P2
•
•
•
•
Costruisco gli elementi della base
Calcolo la matrice di rigidità di elemento
Calcolo la matrice di rigidità globale
Costruisco una function che calcola il carico
e risolve il sistema
• Disegno la soluzione, come polinomio
quadratico a tratti
Costruzione delle funzioni di
base di elemento
Considero l’intervallo [0,1] e costruisco su questo intervallo le
3 funzioni della base.
E’ facile vedere che si ottiene:
l 1 (x) = (2x - 1) (x - 1)
l 2 (x) = - 4x (x - 1)
l 3 (x) = x (2x - 1)
Costruendo i grafici delle tre funzioni, si ottiene:
Costruzione della matrice di
rigidità di elemento
La costruzione della matrice di base di elemento è un’operazione
noiosissima, nella quale inoltre è facile commettere errori di
calcolo.
La situazione migliora tantissimo se si ha a disposizione un
pacchetto per il calcolo simbolico.
Poiché la Student edition di Matlab ha un pacchetto di calcolo
simbolico, nel seguito calcoliamo la matrice di rigidità, facendo
fare i conti a Matlab.
Fare i conti con il calcolo
simbolico
L’utilizzo del pacchetto di calcolo simbolico è molto semplice.
Innanzitutto, devo dire che x è una variabile simbolica:
>> syms x
A questo punto, ogni variabile alla quale venga assegnata una
espressione contenente x diventa a sua volta simbolica:
>> l1=(2*x-1)*(x-1)
l1 =
(2*x-1)*(x-1)
Per calcolare l’elemento di posto (1,1) della matrice di
rigidità, devo:
Calcolare la derivata del polinomio:
>> dl1=diff(l1)
dl1 =
4*x-3
Moltiplicare la derivata per se stessa e integrare fra 0 e 1:
>> a(1,1)=int(dl1*dl1,0,1)
a=
7/3
In realtà è più efficiente procedere in modo vettoriale:
Calcolo un vettore con i tre polinomi:
>> l=[(2*x-1)*(x-1), -4*x*(x-1), x*(2*x-1)]
Ne calcolo la derivata:
>> dl=diff(l)
dl =
[ 4*x-3, -8*x+4, 4*x-1]
Devo ora moltiplicare le derivate in tutti i modi possibili, cioè
devo calcolare dl’*dl.
Matlab però considera x una variabile complessa: devo
specificare che x è reale:
>> syms x real
A questo punto posso calcolare:
>> dl'*dl
ans =
[
(4*x-3)^2, (4*x-3)*(-8*x+4), (4*x-3)*(4*x-1)]
[ (4*x-3)*(-8*x+4),
(-8*x+4)^2, (-8*x+4)*(4*x-1)]
[ (4*x-3)*(4*x-1), (-8*x+4)*(4*x-1),
(4*x-1)^2]
Infine, calcolo l’integrale fra 0 e 1 di quello che ho ottenuto:
>> a=int(ans,0,1)
a=
[ 7/3, -8/3, 1/3]
[ -8/3, 16/3, -8/3]
[ 1/3, -8/3, 7/3]
Questa è la matrice di rigidità per un elemento di lunghezza 1.
Per riscalare su un elemento di lunghezza h devo dividere per h.
Notare che le frazioni sono rimaste indicate: questo risultato è
esatto
Costruisco ora la matrice di rigidità globale
La prima riga della matrice di rigidità è relativa alla funzione di
base a “bolla”, centrata sul primo nodo interno:
[16
-8
0
0
0
0
0 ...
La seconda riga della matrice di rigidità è relativa alla funzione
di base a “tenda”, centrata sul secondo nodo interno:
[ -8 14
-8
1
0
0
0 ...
Tutti gli elementi devono poi essere moltiplicati per 1/(3h)
Ottengo così la matrice di rigidità globale.
Per N intervalli ho 2N -1 nodi interni. Nel caso N = 5:
a=
16
-8
0
0
0
0
0
0
0
-8
14
-8
1
0
0
0
0
0
0
-8
16
-8
0
0
0
0
0
0
1
-8
14
-8
1
0
0
0
0
0
0
-8
16
-8
0
0
0
0
0
0
1
-8
14
-8
1
0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
-8 1 0
16 -8 0
-8 14 -8
0 -8 16
Devo infine
moltiplicare ogni
elemento per
1/(3h)
Esercizio
Scrivere una function che calcoli la matrice di rigidità globale,
assegnando in input il numero N di intervalli, supponendo che il
fattore 1/(3h) sia portato a destra del segno = .
Ottengo questo listato:
function a=penta(n)
% A=PENTA(N) costruisce la matrice di rigidita' per
%
il problema del filo elastico, trattato con
%
elementi P2, e condizioni di Dirichlet.
%
N e' il numero di intervalli
%
=> A e' (2N-1)*(2N-1)
%
Il fattore 1/(3h) e’ stato portato a destra
continua ...
… continua
m=2*n-1 % dimensioni della matrice
a=16*eye(m);
for i=2:2:m-1;
a(i,i)=14;
end
b=ones(m-1,1);
a=a+diag(-8*b,-1)+diag(-8*b,1);
% inserisce i +1 sulla diagonale +2
for i=2:2:m-3
a(i,i+2)=1;
end
% inserisce i +1 sulla diagonale -2
for i=4:2:m-1
a(i,i-2)=1;
end
Calcolo del vettore di carico
Il vettore b è dato da
L’indice i denota tutti i nodi.
Dobbiamo distinguere i nodi pari dai nodi dispari, perché le
funzioni di base hanno forma e supporto diversi.
Nodi pari e nodi dispari
Sui nodi dispari, la funzione della base è una funzione “a bolla”.
Il suo supporto è l’intervallo [x i - h/2, x i + h/2] .
Sui nodi pari, la funzione della base è una funzione “a tenda”.
Il suo supporto è l’intervallo [x i - h, x i + h] . Inoltre, poiché
queste funzioni hanno un punto angoloso in x i , l’integrale va
spezzato in due contributi, da [x i - h, x i ] a [x i , x i + h] .
Calcolo gli integrali usando la formula di Simpson
Questa formula ha un errore O(b-a) 5, ed ha quindi precisione
sufficiente per gli elementi P2.
Inoltre, (x)  0 su un solo nodo della formula di quadratura.
Il vettore di carico quindi è:
Questa grandezza deve poi essere moltiplicata per 3h.
Programma FEM P2
Posso ( finalmente!) scrivere il programma che risolve il problema
del filo elastico con condizioni di Dirichlet.
Questo programma chiama la function penta che costruisce la matrice
di rigidità per gli elementi P2.
function [x,u]=filo_p2(f,n)
% Risolve il problema del filo elastico su (0,1)
% per condizioni al bordo omogenee di
% Dirichlet in x=0 e in x=1,
% con carico definito dalla funzione
% F e N intervalli
a=penta(n);
h=1/n; % spaziatura di griglia
m=2*n-1 % numero dei nodi interni
% calcola la posizione dei nodi interni:
for i=1:m; x(i) = i*h/2; end % la spaziatura e' h/2
fx = feval(f,x);
for i=1:2:m
b(i) = 2*h/3 *fx(i); % nodi dispari
end
for i = 2:2:m-1
b(i) = h/3 *fx(i); % nodi pari
end
b=3*h*b';
% ho portato 3h a destra
u=a\b;
% Ora aggiungo le condizioni al contorno
u(2:m+1)=u; u(1)=0; u(m+2)=0;
x(2:m+1)=x; x(1)=0; x(m+2)=1;
Esempio
Risolvo il problema del filo elastico con carico uniforme
>>f=inline('-1+0*x');
>> [x,u]=filo_p2(f,10);
>> plot(x,u,'Linewidth',2)
Velocità di convergenza
Valutiamo la velocità di convergenza per il problema del filo
elastico, utilizzando sia gli elementi P1 che gli elementi P2
Considero un problema di cui conosco la soluzione esatta, per
esempio:
Valuto l’ errore su diverse griglie
Calcolo l’ errore
usando griglie via via
più fitte.
Per semplicità uso la
norma del massimo:
exa=inline('x.*(x-1).*exp(x)');
f=inline('-exp(x).*(x.^2+3*x)');
n=10;
fprintf(' n
P1
P2 \n')
for k=1:4
[x,u]=filo_dir(f,n);
err_p1(k)=norm(exa(x)-u',inf);
[x,u]=filo_p2(f,n);
err_p2(k)=norm(exa(x)-u',inf);
fprintf('%3.0f %12.5e %12.5e \n',n,...
err_p1(k),err_p2(k))
n=n*2;
end
Risultati
Ottengo questi risultati:
N
10
20
40
P1
1.784725544444921e-03
4.910462530513526e-04
1.288307737212224e-04
P2
2.082890535519071e-05
1.844384948512536e-06
1.630962657862395e-07
Qui N è il numero di intervalli. Il metodo agli elementi P2
usa circa il doppio delle incognite del metodo P1, ma l’ errore
è molto più piccolo
Esercizio
Costruire un programma che ricostruisca l’andamento
del numero di condizionamento della matrice di
rigidita’ del filo elastico al variare di N, con elementi
P1 e con elementi P2.
Chiamo:
CP1(N) = numero di condizionamento matrice P1 con N intervalli
CP2(N) = numero di condizionamento matrice P2 con N intervalli
Disegno il grafico di CP1 e CP2 in funzione di N, e provo ad
interpolare i dati con un polinomio di grado assegnato nel senso dei
minimi quadrati (cioe’ con polyfit)
Esercizio
Studiare il comportamento del problema del filo elastico con
elementi P2, nel caso di un carico puntiforme.
Esercizio
Considerare una funzione di carico molto oscillante, tipo
f(x)= -1 + 10*sin(10*pi*x).
Studiare la deformazione del filo, usando elementi P1 e elementi
P2.
Come posso sfruttare il fatto che la soluzione prodotta dagli
elementi P2 è quadratica a tratti per migliorare il grafico?
Problema di
convezione-diffusione
Vogliamo risolvere questo problema al contorno:
Che è equivalente alla formulazione variazionale:
Matrice di rigidità
La matrice di rigidità di questo problema è una matrice tridiagonale,
con:
N.B. Il fattore h che moltiplica la matrice di rigidità è stato portato
a destra dell’ uguale e quindi moltiplica il vettore di carico.
Questo è il listato di una function che costruisce la matrice di
convezione - diffusione.
function a=mat_cd1d(n,nu,beta)
% A=MAT_CD1D(N,NU,BETA) Crea la matrice N per N tridiagonale del
%
filo elastico per il problema di convezione-diffusione,
%
con campo di velocita' BETA sull'intervallo (0,1)
%
e diffusione NU
%
N e' il numero di nodi interni
a=2*eye(n); h=1/(n+1);
peclet = h*beta/2/nu;
for i=1:n-1
a(i,i+1)=-1 +peclet;
a(i+1,i)=-1 -peclet;
end
a=a*nu;
Il listato del programma principale è molto simile a quelli già
visti:
function [x,u]=c_d(f,n,nu,beta)
% [X,U]=C_D(F,N,NU,BETA)
% Risolve il problema del filo elastico su (0,1)
% per condizioni al bordo omogenee di
% Dirichlet, con carico definito dalla funzione
% F e N punti interni
% NU e' il coefficiente di diffusione
% BETA e' il campo di velocita'
a=mat_cd1d(n,nu,beta);
h=1/(n+1); % spaziatura di griglia
% calcola la posizione dei nodi interni:
for i=1:n; x(i) = i*h; end
b=h^2*feval(f,x); b=b'; % ho portato h a sinistra
u=a\b;
% Ora aggiungo le condizioni al contorno
u(2:n+1)=u; u(1)=0; u(n+2)=0;
x(2:n+1)=x; x(1)=0; x(n+2)=1;
Carico uniforme, =1, N=100
Carico puntiforme, =1, N=100
Negli esempi precedenti, il numero di Peclet era
sempre minore di 1:
Pe =  h / 2
Se aumentiamo il numero di Peclet, la soluzione
diventa oscillante
Convezione-diffusione, =100, N=100
Esercizio
Studiare il comportamento delle oscillazioni spurie per il
problema di convezione diffusione rispetto a variazioni nel
numero di Peclet.
Come si comporta l’ampiezza delle oscillazioni rispetto a Pe?
Esercizio
Risolvere il problema:
e verificare che anche in questo caso il comportamento
oscillatorio della soluzione e’ legato al numero di Peclet.
Esercizio
Il numero di Peclet deve essere minore di 1 dappertutto
o solo nello strato limite?
1) Scrivere una function che calcoli la matrice di convezione diffusione per un vettore x, che contenga le ascisse di nodi di
griglia assegnati (cioe’ non uniformi).
2) Modificare di conseguenza anche il vettore di carico.
3) Costruire una griglia ad-hoc che sia piu’ fitta all’interno dello
strato limite e risolvere il problema di convezione-diffusione su
quella griglia
Esercizio
Modificare il problema di convezione diffusione aggiungendo una
condizione di Neumann. Provare i due casi seguenti:
1) Condizione di Neumann in x=0, Dirichlet in x=1 con β >0;
2) Condizione di Neumann in x=0, Dirichlet in x=1 con β <0.
Ottengo comunque uno strato limite per valori di β/ν elevati?
Scarica

Metodi FEM in 1D