POLITECNICO DI MILANO DIPARTIMENTO DI MATEMATICA Corsi di Analisi Numerica delle EDP2 e Programmazione Avanzata per il Calcolo Scientifico TECNICA DI RICOSTRUZIONE DELLE DERIVATE PRIME E SECONDE IN 2D. Prof. Alfio Quarteroni Prof. Luca Formaggia Benedetta Franzelli Matr. 680481 ANNO ACCADEMICO 2006-2007 Contents 1 Introduzione 2 2 Teoria della ricostruzione 2.1 Un esempio 1d . . . . . . . . . . . . . . . . . . 2.2 Proprietà dell’operatore di ricostruzione . . . . 2.2.1 Condizione di consistenza . . . . . . . . 2.2.2 Condizione di località . . . . . . . . . . 2.2.3 Condizione di linearità e limitatezza . . 2.2.4 Ipotesi di superconvergenza . . . . . . . 2.3 Possibili tecniche di ricostruzione del gradiente 2.3.1 Procedure di ricostruzione globale . . . 2.3.2 Procedure di ricostruzione locale . . . . 2.3.3 Operatore di ricostruzione dell’Hessiana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 4 5 5 6 6 7 7 7 8 12 3 Analisi dei risultati numerici 3.1 Esempio 1: comportamento uniforme . . 3.2 Esempio 2: concentrazione centrale . . . 3.3 Esempio 3: concentrazione in un angolo 3.4 Esempio 4: infittimento su 2 lati . . . . 3.5 Esempio 5: infittimento su un lato . . . 3.6 Esempio 6: diffusione e trasporto . . . . 3.7 Conclusioni sui metodi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 13 19 23 26 29 32 35 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Codice C++ per i metodi ricostruttivi 4.1 Geometria del problema: file SHAPE.HPP . . . . . . . . . . 4.2 Generazione e gestione della mesh: MESH.HPP . . . . . . . . 4.3 Polinomio interpolante e gradiente esatto: POLINOMI.HPP . 4.4 Metodi per la risoluzione di un sistema lineari: METODI.HPP 4.5 Metodi di ricostruzione: RICOSTRUZIONE.HPP . . . . . . . 4.6 Il calcolo dell’errore: ERRORE.HPP . . . . . . . . . . . . . . 4.7 Inserimento dei dati da parte dell’utente: UTENTE.HPP . . 4.8 Come funziona il programma: MAIN.CPP . . . . . . . . . . . 36 38 40 41 43 44 44 45 45 5 Conclusioni 47 1 Chapter 1 Introduzione Il calcolo del gradiente di una approssimazione ad elementi finiti risulta spesso necessario da un punto di vista applicativo. Numerose quantità macroscopiche (quali gli sforzi e le deformazioni nell’elasticità, il campo elettrico in elettrostatica e la corrente nei semiconduttori) sono infatti descritte in termini del gradiente. Le derivate prime (e seconde), inoltre, vengono spesso usate nella costruzione di stime a posteriori dell’errore di discretizzazione. D’altra parte la componente normale del gradiente di un’approssimazione FEM risulta generalmente discontinua attraverso i lati degli elementi della mesh. La quantità di interesse risulta cosı̀ discontinua. Stesso risultato si ottiene quando si sceglie di lavorare con polinomi P1 nella costruzione della soluzione approssimata: il gradiente calcolato sarà dato da funzioni costanti a tratti. Si rende quindi necessaria l’introduzione di opportune procedure di postprocessing dei gradienti all’interno dei codici di calcolo, al fine di fornire approssimazioni più regolari. Queste procedure prendono il nome di tecniche di ricostruzione del gradiente della soluzione discreta. Sotto opportune ipotesi forniscono soluzioni più accurate rispetto ai gradienti veri della soluzione approssimata. Obbiettivo di questo lavoro quindi è descrivere l’idea generale alla base delle tecniche ricostruttive, concentrandosi poi sulla descrizione di quattro metodi (capitolo 2). Nel capitolo 4 si descriverà il codice scritto in C++ che calcola il gradiente e l’ Hessiana con i metodi presentati. I risultati ottenuti per diverse funzioni verranno analizzati, nel capitolo 3, in termini di accuratezza e tempo di calcolo al fine di ricercare un qualche criterio su quale e quando un metodo risulti vincente piuttosto che un altro. 2 Chapter 2 Teoria della ricostruzione Dato un poligono Ω ⊂ R2 , si considera una famiglia di triangolazioni {Th } di Ω tale che ogni coppia di triangoli in Th abbia in comune al massimo un vertice o un lato. Si definisce lo spazio ad elementi finiti lineari a tratti: Xh1 = {v ∈ H 1 (Ω) : v |T ∈ P1 (T )} dove P1 (T ) indica lo spazio dei polinomi di grado non superiore a 1 ristretto al triangolo T : P1 (T ) = {v(x, y) = v00 + v10 x + v01 y, (x, y) ∈ T }. La soluzione EF di grado 1 sarà data da: uh (x, y) = 1 X i X uij Li (x)Lj (y) i=0 j=0 dove uij = u(xi , yj ), L à i (x) e L à j (y) sono i polinomi di Lagrange: Y x − xk . L à i (x) = xi − xk k6=i Figure 2.1: La figura di sinistra mostra triangolazioni ammissibili (sopra) e non ammissibili(sotto). A destra invece si mostra la mappa affine dal triangolo di riferimento T̂ al triangolo T ∈ Th . 3 CHAPTER 2. TEORIA DELLA RICOSTRUZIONE 4 Figure 2.2: Polinomio di Lagrange caratteristico in due dimensioni di grado 0 e 1. Si ricorda che i calcoli verranno effettuati su un triangolo di riferimento. Ogni elemento T ∈ Th , di area uguale a |T |, è l’immagine attraverso la mappa affine x = FT (x̂) = BT (x̂) + bT del triangolo di riferimento T̂ di vertici (0,0), (1,0) e (0,1) nel piano x̂ = (x̂, ŷ), dove la matrice invertibile BT e il vettore bT sono dati da: ¯ ¯ ¯x2 − x1 x3 − x1 ¯ ¯ ¯ BT = ¯ y2 − y1 y3 − y1 ¯ bT = (x1 , y1 )T , (i) mentre le coordinate dei vertici di T sono dati da aT = (xi , yi )T . Tramite la mappa affine è possibile lavorare sul triangolo di riferimento e in seguito rapportare i risultati al triangolo T ∈ Th . Per ulteriori approfondimenti si veda [1]. Ad ogni nodo Ni , 1 ≤ i ≤ M , si associa una patch Ki , costituita da tutti i triangoli T ∈ Th che hanno il nodo Ni come vertice. L’area della patch Ki coincide con il supporto della funzione base nel nodo Ni . 2.1 Un esempio 1d In questa sezione proponiamo un caso monodimensionale di ricostruzione della derivata prima per facilitare la comprensione del problema e dell’idea di base per la sua risoluzione. Chiamiamo uh la soluzione ad elementi finiti lineari. Il suo gradiente esatto ∇uh fornisce un’approssimazione discontinua per il gradiente esatto ∇u. Si ricostruisce allora il gradiente tramite elementi finiti lineari, facendo riferimento alla figura (2.1). Si calcolano i valori • che ∇uh assume nei punti medi degli intervalli. Ad ogni nodo ◦ si associa il valore ? calcolando la media tra i due valori • che lo circondano. La nuova approssimazione di ∇u si ottiene interpolando i nuovi valori ? utilizzando le stesse funzioni base di uh . Risulterà quindi essere anch’essa lineare a pezzi e continua su tutto il CHAPTER 2. TEORIA DELLA RICOSTRUZIONE 5 Figure 2.3: Ricostruzione del gradiente nel caso monodimensionale Figure 2.4: Ricostruzione del gradiente nel caso bidimensionale dominio. OSS 1. Per mediare i valori di ∇uh nei nodi ◦ esistono differenti tecniche e di conseguenza diverse approssimazioni ? per ∇u, caratterizzate da costi computazionali e accuratezza differenti. OSS 2. E’ possibile estendere la tecnica al caso bidimensionale sia nel caso di elementi della mesh triangolari che quadrati (nel seguito si considereranno solo elementi triangolari). Il valore assunto dal gradiente ∇u in corrispondenza del centro della patch ◦ sarà dato come combinazione dei valori del gradiente ∇uh assunti nei baricentri • degli elementi che compongono la patch. I nuovi valori ? calcolati per il centro di ogni patch verrano interpolati usando le funzioni di base di uh per ottenere il gradiente ricostruito. 2.2 Proprietà dell’operatore di ricostruzione Prima di descrivere alcune tecniche di ricostruzione e di valutarne l’efficacia numerica, è importante formalizzare le condizioni sufficienti dell’operatore di ricostruzione GR (uh ), affinchè lo stesso sia una buona approssimazione di ∇u. Per una trattazione rigorosa si faccia riferimento a [3]. 2.2.1 Condizione di consistenza Come in tutte le tecniche numeriche, si richiede per un operatore di postprocessing che in circostanze favorevoli questo riproduca il risultato esatto. CHAPTER 2. TEORIA DELLA RICOSTRUZIONE 6 Si richiede allora che valga la seguente condizione: COND 1: Sia u un polinomio di grado p + 1 sulla patch K (cioè u ∈ Pp+1 (K) ). Allora: GR (Πh (u)) = Πh (∇u) su K. E’ possibile dimostrare che questa proprietà è vera quando u è un polinomio quadratico e uh coincide con l’interpolato Πh (u) lineare a pezzi di u. Quindi è garantita la consistenza sui P2 , cioè GR (Πh (v)) = ∇v per ogni v ∈ P2 . Per la dimostrazione si veda [2]. 2.2.2 Condizione di località Una richiesta pratica importante è che il calcolo di GR sia poco costoso. Idealmente dovrebbe essere possibile calcolare il gradiente ricostruito senza rifarsi al problema globale, altrimenti risulterebbe più semplice risolvere il problema originale di partenza su una mesh più fine. Gli schemi più convenienti ricostruiscono il gradiente in un punto x0 come una combinazione lineare dei valori del gradiente dell’approssimazione campionati nei punti vicini a x0 . Questa condizione può essere scritta come: COND 2: Se x0 ∈ K, allora il valore del gradiente ricostruito GR (u)(x0 ) dipende solo dai valori di ∇uh campionato sulla patch K. 2.2.3 Condizione di linearità e limitatezza La forma del gradiente ricostruito dovrebbe idealmente poter essere maneggiata in maniera efficiente dalle strutture dati preesistenti all’interno del codice. In particolare GR dovrebbe essere una funzione semplice, che possa essere valutata e integrata agevolmente. La scelta per questo lavoro è quella dei polinomi Xh1 , cioè di polinomi lineare a tratti: COND 3: GR : X → X × X è un operatore lineare e esiste una costante C, indipendente da h, tale che: kGR (uh )kL∞ (K) ≤ C|uh |W 1,∞ (K) per ogni approssimazione ad elementi finiti uh ∈ X. Si osservi che è stata inoltre aggiunta l’ipotesi di linearità e limitatezza. CHAPTER 2. TEORIA DELLA RICOSTRUZIONE 2.2.4 7 Ipotesi di superconvergenza Quest’ultima condizione unita alla consistenza, alla località, alla limitatezza e alla linearità rendono GR (uh ) un’approssimazione di ∇u migliore di quanto lo sia ∇uh . COND 4: Se u ∈ H 3 (Ω) e la partizione è uniforme, allora esiste una costante C tale che: |uh − Πh (u)|H 1 (Ω) ≤ Ch2 |u|H 3 (Ω) , ovvero uh è superconvergente all’interpolato Πh (u). Ricordando che |u − uh |H 1 (Ω) ≤ Ch|u|H 3 (Ω) , ne segue che uh è un’approssimazione di Πh (u) migliore di quanto non lo sia per u. Si osservi che la superconvergenza non dipende dalla scelta fatta per l’operatore GR (.). 2.3 2.3.1 Possibili tecniche di ricostruzione del gradiente Procedure di ricostruzione globale Una prima famiglia di tecniche di ricostruzione comprende le procedure di ricostruzioni globali. Queste tecniche però presentano un costo computazionale molto elevato, poichè calcolare GR (uh ) costa circa il doppio di quanto costi calcolare l’approssimazione uh . Come già detto precedentemente è conveniente richiedere al ricostruttore di lavorare patchwise, cioè sulle singole patch. Solo per completezza riportiamo quindi un metodo di ricostruzione globale ( proposto da O.C.Zienkiewicz e J.Z.Zhu in [4] ), che però non affronteremo dal punto di vista numerico. Proiezione L2 (Ω) del gradiente ∇uh su [Xh1 ]2 : Il gradiente ricostruito GR (uh ) è soluzione dell’equazione Z Z GR (uh ) · vdΩ = ∇uh · vdΩ Ω Ω per ogni v ∈ [Xh1 ]2 . Sia Nh l’insieme dei nodi della griglia Th e ϕi la funzione base dello spazio Xh1 associata al nodo Ni ∈ Nh . Si riscrive il gradiente ricostruito in funzione delle basi dello spazio studiato: GR (uh )(x) = CHAPTER 2. TEORIA DELLA RICOSTRUZIONE 8 P Ni ∈Nh GR (uh )(Ni )ϕi (x), dove i valori nodali GR (uh )(Ni ) sono soluzioni del sistema: ¶ Z X µZ X |T | ϕi ϕj dΩ GR (uh )(Ni ) = ∇uh · ϕj dΩ = ∇(uh |T ) 3 Ω Ω Ni ∈Nh T 3Nj per ogni Nj ∈ Nh ed essendo |T | l’area del triangolo T. 2.3.2 Procedure di ricostruzione locale La seconda famiglia di tecniche di ricostruzioni è composta da procedure di ricostruzione locale. Lavorando con funzioni non necessariamente continue, anzichè usare l’operatore di interpolazione di Lagrange si preferisce lavorare con l’interpolato di Clément ΠC . Data una funzione v ∈ L2 (Ω), sia Pi v la proiezione di una funzione v|Ki ∈ L2 (Ki ) sul sottospazio Pk (Ki ), cioè: Pi v ∈ P1 (Ki ) (v − Pi v, p)Ki = 0 (2.1) per ogni p ∈ Pk (Ki ),dove (., .)Ki rappresenta il prodotto scalare L2 in Ki . L’operatore di Clément è definito come: Πc v = M X Pi v(Ni )ϕi , i=1 dove M è il numero dei nodi della mesh. L’operatore di ricostruzione del gradiente GR : Xh1 → (Xh1 )2 è allora dato da: · µ ¶ µ ¶¸ ∂uh ∂uh GR uh = ΠC (∇uh ) := ΠC , ΠC . ∂x ∂y E’ ora possibile sostituire il prodotto scalare L2 dell’equazione (2.1) con un prodotto scalare pesato, ad esempio: Z (v, w)Ki = v(x)w(x)gi (x)dx Ki dove gi (x)|T è il peso. Risolvendo l’integrale con grado k = 0 si ottengono i metodi che appartengono alla classe delle tecniche della media pesata (weighted average techniques). I valori nodali sono ricavati esplicitamente come: 1 X GR (uh )(Ni ) = gi |T ∇(uh |T ) W T 3Ni CHAPTER 2. TEORIA DELLA RICOSTRUZIONE dove W = P T 3Ni 9 gi |T . Usando invece i punti di Gauss e/o i punti di ottimo d’ integrazione nel calcolo dell’integrale dell’equazione (2.1) si ottengono i metodi che appartengono alla classe delle tecniche di ricostruzione sulla patch (patch recovery techniques). Per maggiori dettagli si veda [5]. WEIGHTED AVERAGE TECHNIQUES Una classe tra le tecniche locali più importanti è la famiglia dei metodi di media pesata. Il gradiente dell’ approssimazione ad elementi finiti fornisce un’approssimazione discontinua del gradiente esatto. Questa può essere usata per costruire un’approssimazione in ogni nodo mediando i contributi pesati di tutti gli elementi che circondano il nodo. Questi nuovi valori vengono poi interpolati per ottenere un’approssimazione continua sull’intero dominio. All’interno di questa classe descriviamo due metodi che verranno in seguito analizzati anche dal punto di vista numerico. Lumping della matrice di massa (Metodo MEDIA): Zienkiewicz e Zhu nel 1987 presentarono questo metodo al fine di ridurre il costo computazionale dell’approccio globale (si veda [4]). Scegliendo in (2.1) di lavorare con k=0, i valori nodali GR (uh )(Ni ) possono essere ricavati esplicitamente come: GR (uh )(Ni ) = X |T | ∇(uh |T ) |Ki | T 3Ni S dove Ki = T 3Ni T ∈ Th . Risulta corrispondere a un metodo della media pesata una volta scelto gi (x)|T = |T |. Il valore della derivata nei triangoli di una patch di area più grande contribuirà maggiormente rispetto al valore della derivata dei triangoli di area inferiore. Media pesata con l’inverso della distanza (Metodo ID): Nell’equazione GR (uh )(Ni ) = 1 X gi |T ∇(uh |T ) W T 3Ni si sceglie gi (x) = kNi − bKT k, dove bKT è il baricentro del triangolo T . In questo modo si privilegia il valore che la derivata assume nei nodi che fanno parte della patch e che sono maggiormente vicini al nodo di interesse. CHAPTER 2. TEORIA DELLA RICOSTRUZIONE 10 Figure 2.5: Ricostruzione del gradiente col metodo SPR PATCH RECOVERY TECNIQUES Su ogni patch locale è possibile ottenere delle soluzioni GR (uh ) sotto forma di espansione polinomiale, cioè: [GR uh (x)]j = P (x)aj dove [GR uh (x)]j è la componente j-esima del gradiente definita sulla patch e aj è il vettore colonna dei coefficienti del polinomio da determinare. I monomi presenti in ogni colonna della matrice P (x) sono quelli presenti nelle funzioni base degli elementi utilizzati. Nel caso di triangoli lineari P (x) = [1, x, y]. I coefficienti non noti aj possono essere calcolati tramite metodi diversi. Di seguito ne vengono riportati due. Superconvergent Patch Recovery technique (Metodo SPR) Si cerca GR (.) ∈ [Xh1 ]2 come soluzione di un problema locale discreto ai minimi quadrati. Si generalizza al caso bidimensionale il modello proposto in [6]. Partendo da un campionamento di ∇uh nei baricentri bKi = (xKi , yKi ) • dei triangoli costituenti la patch Kp viene ricostruito il valore di GR (uh ) in corrispondenza del centro della patch Np . Le componenti del gradiente nel nodo Np GR (uh )(Np ) = (G1R (uh )(Np ), G2R (uh )(Np )) vengono determinate nella forma: GjR (uh )(Np ) = P (Np )T aj per j = 1, 2, dove P (x) = [1, x, y]T è il vettore dei polinomi P1 utilizzati per la costruzione di Xh1 , mentre gli aj sono i vettori delle incognite determinati mediante un’approssimazione ai minimi quadrati basata sui valori discreti ∇uh (bKi ). Il problema diviene allora: si cerca aj tale che I(aj ) = P ³ ∂uh i ´2 T aj ) (b − P (b ) sia minimo K K i i ∂xj per j=1,2. Tale condizione è verificata se aj è soluzione del sistema M aj = bj CHAPTER 2. TEORIA DELLA RICOSTRUZIONE 11 Pelp Pelp h per j=1,2 con M = i=1 P (bKi )P (bKi )T e bj = i=1 P (bKi ) ∂u ∂xj (bKi ), dove elp indica il numero di elementi che costituiscono la patch p-esima. Il problema può essere riscritto nella seguente forma matriciale: GGT aj = Gbj dove: ¯ ¯ 1 ¯ ¯xK G = ¯¯ 1 ¯ yK1 ¯ ¯ 1 ¯ ¯ xK2 xKelp ¯¯ yK2 yKelp ¯¯ ¯ ¯ ¯ ∂uh ¯ ¯ ¯ ∂xj (bK1 ) ¯ ¯ ∂uh (b ) ¯ ¯ ∂xj K2 ¯ ¯ bj = ¯¯ .. ¯ ¯ ¯ . ¯ ¯ ∂uh ¯ ∂x (bKelp )¯ j 1 ··· ··· ··· Minimizzazione di un funzionale (Metodo ZZ): Per questo metodo si veda [7]. Si cerca GR (.) ∈ [Xh1 ]2 come soluzione di un problema locale continuo ai minimi quadrati. I vettori delle incognite aj vengono cercati minimizzando il funzionale ¶2 Z µ ∂uh (x) − P (x)T aj dx I(aj ) = ∂xj Ki con j=1,2. Questo comporta la risoluzione di un sistema lineare di equazioni: Pi aj = bi dove Pi = eli µZ X n=1 bi = ¶ P (x)P (x)dx T Tn eli µZ X n=1 ¶ ∂uh P (x) dx ∂xj Tn T dove eli è il numero di elementi nella patch e Ωn è l’area legata al triangolo n-esimo che compone la patch. Si osservi che il valore del gradiente ricostruito dipende esclusivamente dal campionamento di ∇uh sulla patch. Per il calcolo dell’integrale, lavorando con polinomi P1 si utilizza la formula composita dei trapezi (si veda [1]): Z 3 |Tn | X c 1 I1 (f ) = Πh f (x)dx = f (aT (j) ) 3 Tn j=1 CHAPTER 2. TEORIA DELLA RICOSTRUZIONE 12 Figure 2.6: Nodi di interpolazione. Il calcolo dell’integrale con la formula composita dei trapezi viene effettuata coi nodi del triangolo di mezzo che ha grado di esattezza pari a 1 ed il cui ordine di infinitesimo rispetto a h è uguale a 2. OSS 1: La matrice Pi è simmetrica e definita positiva. OSS 2: Il numero di equazioni che devono essere risolte simultaneamente è piccolo (tre se si lavora con triangoli lineari) ed il costo della valutazione della ricostruzione è proporzionale al numero di nodi della griglia. OSS 3: Una volta che i vettori dei parametri a sono calcolati, il gradiente in un nodo è facilmente determinato. OSS 4: La ricostruzione del gradiente funziona meglio per nodi interni piuttosto che sulle patches vicino ai bordi. L’esistenza di nodi di bordo comporta dei risultati poco accurati finchè la patch è costituita da pochi elementi. Per risolvere questo inconveniente è possibile ricostruire il gradiente con le tecniche Patch recovery per i nodi interni ed applicare invece i metodi weighted average per i nodi di bordo. 2.3.3 Operatore di ricostruzione dell’Hessiana E’ possibile studiare l’operatore di ricostruzione anche per la matrice Hessiana HR (uh ) ∈ [Xh1 ]2×2 data da: HR (uh ) = H ∗ (uh ) + (H ∗ (uh ))T 2 dove H ∗ (uh ) è la matrice definita come: H ∗ (uh ) = µ ¶¶ ¶¶¶T µ µ µ µ ∂uh ∂uh GR Πc GR Πc . ∂x ∂y Ovviamente esistono anche differenti approcci, ed è anche possibile combinare tra di loro le diverse tecniche ricostruttive per il calcolo delle derivate seconde. In questo lavoro, ci limitiamo a ricostruire l’Hessiana basandoci sulle quattro tecniche presentate sopra prese singolarmente. Chapter 3 Analisi dei risultati numerici L’obbiettivo di questo lavoro è la descrizione di alcuni metodi di ricostruzione e un’analisi di tipo numerico per comprendere se e sotto quali ipotesi una tecnica sia da prediligere piuttosto che un’altra. Per fare questo si considereranno diverse funzioni (sufficientemente regolari), di cui si ricostruirà il gradiente e l’Hessiana tramite le 4 tecniche illustrate lavorando su mesh uniformi e mesh adattate fornite dal programma di calcolo Freefem++. Le stime degli errori nel calcolo del gradiente e dell’Hessiana: µZ ¶2 2 kG(u) − GR (uh )kL = (∇u − GR (uh )) · (∇u − GR (uh ))dΩ Ω µZ kH(u) − HR (uh )k2L = Ω ¶2 (H(u) − HR (uh )) · (H(u) − HR (uh ))dΩ saranno utilizzati come indici della bontà della tecnica di ricostruzione. 3.1 Esempio 1: comportamento uniforme Si considera la funzione u(x, y) = exp(−(x − 0.5)2 − (y − 0.5)2 ) sul dominio Ω = (0, 1)2 . Mesh uniforme: Tramite Freefem si costruisce la mesh uniforme di partenza costituita da 50 elementi (la lunghezza degli elementi è quindi di h = 0.2). Ad ogni iterazione si dimezza la dimensione h fino ad arrivare a una mesh costituita da 51200 elementi. Si studia il comportamento delle quattro tecniche ricostruendo le derivate e calcolando le due stime di errore. Si presta particolare attenzione al calcolo delle derivate nei nodi di bordo nei due metodi di patch recovery. Nei nodi di bordo si applicherà o il metodo in esame o il metodo della media inversa (nel secondo caso li chiameremo metodi SPR+INV e ZZ+INV). Si 13 CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 14 Figure 3.1: a) Soluzione esatta b) Componente x del gradiente della soluzione esatta c) Componente xx dell’hessiana della soluzione esatta osservi che il comportamento dei 4 metodi è qualitativamente lo stesso. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 0.072752 0.0816795 1.183319 0.0698597 0.073927 0.073927 100 0.023396 0.0247928 0.121435 0.0221542 0.0234452 0.0234452 400 0.0077647 0.00796322 0.259151 0.00727214 0.00775759 0.00775759 3200 0.00264629 0.00267602 0.0148015 0.00246074 0.00264313 0.00264313 12800 0.000917238 0.000921919 0.00702885 0.000849407 0.000916374 0.000916374 Figure 3.2: Componente del gradiente e dell’Hessiana ricostruita con il metodo SPR. Si osservi l’esistenza di valori sul bordo distanti dal valore esatto. Il grafico dell’Hessiana è schiacciato per effetto di un valore sbagliato molto grande nel nodo (1,0) Si osservi che i valori calcolati con la tecnica SPR sia per il gradiente che per l’Hessiana risultano decisamente maggiori rispetto a quelli ottenuti con gli altri metodi. Questo perchè il metodo SPR calcola dei valori poco accurati nei nodi di bordo. Il problema sembra risolversi applicando il metodo della media inversa nei nodi esterni (metodo SPR+INV). CHAPTER 3. ANALISI DEI RISULTATI NUMERICI HESS Media INV SPR ZZ SPR+INV ZZ+INV 50 0.375431 0.425249 332.282 0.3516 0.380524 0.380524 100 0.211518 0.224706 2.95069 0.196105 0.211826 0.211826 400 0.149454 0.151765 37.5316 0.14135 0.149154 0.149154 3200 0.109394 0.109741 1.24149 0.104662 0.109207 0.109207 15 12800 0.0792117 0.0792429 1.67497 0.0761731 0.0791185 0.0791185 Figure 3.3: Andamento qualitativo del tempo di calcolo per i vari metodi Il metodo INV, sebbene mostri risultati simili agli altri metodi, risulta in tutte le iterazioni peggiore rispetto a ZZ e a quello di media. Interessante è il confronto tra MEDIA e ZZ, studiato sia col metodo di media inversa per i nodi esterni che nella versione standard. In questo caso la versione standard risulta sempre vincente, mentre il metodo di media risulta migliore rispetto alllo ZZ+INV solo nelle prime iterazioni. Prime conclusioni da verificare negli altri esempi per griglie uniformi: 1. Il metodo di media presenta un buon rapporto accuratezza costo computazionale 2. il metodo standard ZZ ha l’accuratezza maggiore, ma anche il costo computazionale più elevato. 3. Il metodo SPR fornisce errori significativamente peggiori degli altri metodi, il problema viene risolto introducendo un controllo sui nodi di bordo. CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 16 Si osservi inoltre che: • il calcolo col metodo ZZ, sebbene offra risultati migliori, è computazionalmente più complesso e comporta un tempo di calcolo notevolmente maggiore rispetto al metodo MEDIA (e al metodo ZZ+INV) • il metodo ZZ+INV e il metodo SPR+INV forniscono risultati pressocchè identici • il metodo ZZ+INV supera il metodo MEDIA una volta che il numero di nodi interni è di molto superiore al numero di nodi esterni (sperimentalmente per ogni nodo esterno si hanno quattro nodi interni) • il metodo SPR+INV corregge gli errori del metodo SPR sui nodi esterni MESH ADATTATA Tramite Freefem è possibile costruire una mesh adattata per il problema in esame tramite la funzione adaptmesh(). Questa funzione prende in ingresso Figure 3.4: Griglia adattata alla prima e all’ultima iterazione. In questo caso non vi è molta differenza. la griglia di partenza da adattare e la funzione su cui basare l’adattazione. Vi sono poi dei parametri ulteriori che si possono scegliere per caratterizzare l’adattazione di griglia. E’ possibile ad esempio fissare la lunghezza minima e massima per ogni elemento, cercare di mantenere il più possibile i vertici di partenza, fissare l’errore o la metrica da usare. In questo lavoro si sfrutteranno due parametri per analizzare la robustezza dei vari metodi dalle caratteristiche della griglia. Innanzittutto si costruisce a partire dalla griglia di 50 elementi uniforme tramite 5 iterazioni successive la griglia adattata con CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 17 Figure 3.5: Risultati ottenuti sulla griglia adattata all’ultima iterazione. a) Componente x del gradiente ricostruito col metodo della Media b) Componente xx del gradiente ricostruito col metodo della Media i parametri standard della funzione adaptmesh(). Vengono riportati i risultati ottenuti per la prima griglia adattata e l’ultima griglia trovata. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 0.072752 0.0816795 1.183319 0.0698597 0.073927 0.073927 1 iter 0.00639991 0.00742848 0.0273363 0.00550232 0.00659395 0.00659395 ultima iter 0.00666939 0.0075084 0.124705 0.00585982 0.00694518 0.00664568 Il comportamento qualitativo per il gradiente e per l’Hessiana non è di molto dissimile, sebbene l’errore per l’Hessiana sia di molto maggiore. Per calcolare l’Hessiana si applica due volte il metodo, di conseguenza gli errori commessi saranno amplificati. HESS Media INV SPR ZZ SPR+INV ZZ+INV 50 0.375431 0.425249 332.282 0.3516 0.380524 0.380524 1 iter 0.116627 0.135441 2.02289 0.0935778 0.111993 0.111993 ultima iter 0.121143 0.125721 12.3486 0.0945305 0.0997407 0.109269 Con la prima iterazione di adattazione il valore ottenuto per tutti i metodi si abbassa, raggiungendo con 900 elementi un ordine di grandezza che corrisponde a una griglia uniforme con più di 1000 elementi. Questo comporta innanzittutto un costo computazionale minore. Si osservi che alla fine del CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 18 processo iterativo l’errore cresce anche se di poco, poichè diminuisce il numero di elementi in esame a 880. Ancora una volta il metodo SPR funziona male a causa del mal funzionamento nei punti di bordo . Poichè la mesh adattata non è molto diversa da una mesh uniforme il comportamento qualitativo dei vari metodi non cambia. ADATTAZIONE CON NUMERO DI ELEMENTI COSTANTI Tramite un altro parametro della funzione adaptmesh() (nbvx = numero massimo di nodi) è possibile fissare il numero massimo di nodi della griglia. Di conseguenza è possibile esercitare un controllo sul numero di elementi della griglia. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 0.072752 0.0816795 1.83319 0.0698597 0.073927 0.073927 1 iter 0.0431438 0.0296571 1.20583 0.0348511 0.0294463 0.0345911 ultima iter 0.0296775 0.0210865 3.56302 0.0240998 0.0214811 0.0239924 Figure 3.6: Griglia adattata alla prima e all’ultima iterazione. In questo caso non vi è molta differenza. In questo caso si è imposto un numero massimo di nodi pari a 200, che hanno portato alla costruzione di mesh composte da circa 320 elementi. Si è quindi deciso di partire con una griglia iniziale composta da 50 elementi e di adattarla con 6 iterazioni di griglie con al massimo 200 nodi. CHAPTER 3. ANALISI DEI RISULTATI NUMERICI HESS Media INV SPR ZZ SPR+INV ZZ+INV 50 0.375431 0.425249 332.282 0.3516 0.380524 0.380524 1 iter 0.356509 0.256426 20031.17 0.273017 0.203776 0.277427 19 ultima iter 0.284378 0.205775 7808.65 0.214554 0.170251 0.217568 Si riportano i risultati sulla griglia di partenza, sulla mesh della prima iterazione di adattazione e sull’ultima mesh calcolata. In questo caso non si ottiene il risultato sperato. Il motivo può essere ricercato nella costrizione forte sul numero dei nodi, che comporta una perdita di informazioni in alcune iterazioni. Questo comportamento era in effetti intuibile già a partire dalle mesh prodotte via Freefem. Quest’ultime, infatti, al procedere dell’iterazione non andavano verso una configurazione finale, ma cambiavano notevolmente, indicando il fatto che difficilmente si sarebbe raggiunta una configurazione ottimale per la mesh adattata. Si osservi che in questo caso il metodo INVERSA e il metodo SPR+INV battono il metodo MEDIA e il metodo ZZ+INV e perfino il metodo ZZ. Da questa prima analisi si può iniziare a supporre che: 1. il metodo MEDIA e il metodo ZZ (e ZZ+INV) forniscono delle stime migliori se si lavora con griglie strutturate o su griglie adattate ad hoc. 2. il metodo SPR+INV e il metodo INV funzionano in maniera peggiore su griglie ben adattate, ma lavorano meglio su griglie non strutturate o costruite appositamente. 3.2 Esempio 2: concentrazione centrale Si considera la funzione u(x, y) = exp(−100(x − 0.5)2 − 0.1(y − 0.5)2 ) sul dominio Ω = (0, 1)2 . Si procede in maniera del tutto analoga per questa nuova funzione. Se la funzione precedente era caratterizzata da una forte simmetria, questa funzione invece porterà alla generazione di griglie infittite in una striscia verticale centrale. D’ora in poi riporteremo solo i risultati ottenuti per il gradiente. Le conclusioni ricavate sul gradiente si potranno poi applicare anche all’Hessiana. MESH UNIFORME Il comportamento è del tutto analogo al caso precedente. CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 20 Figure 3.7: a) Soluzione esatta b) Componente x del gradiente della soluzione esatta c) Componente xx dell’hessiana della soluzione esatta GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 4.07784 4.11136 4.09433 4.07689 4.07928 4.07928 100 1.21446 1.23455 1.38035 1.20054 1.21307 1.21307 400 0.529852 0.532658 0.602807 0.523703 0.529576 0.529576 3200 0.143846 0.144532 0.180559 0.140532 0.143779 0.143779 12800 0.037848 0.0380098 0.0545226 0.0361933 0.0378322 0.0378322 Il metodo SPR e il metodo INVERSO sono i due meno accurati, mentre il metodo ZZ risulta sempre il migliore. Il metodo SPR commette un errore che rispetto all’errore commesso dagli altri metodi cresce al crescere del numero degli elementi. Figure 3.8: Risultati ottenuti sulla griglia adattata all’ultima iterazione. a) Componente x del gradiente ricostruito col metodo della Media b) Componente xx del gradiente ricostruito col metodo della Media MESH ADATTATA Si propongono i risultati per la prima mesh del ciclo (380 elementi) e la mesh finale ottimale (345 elementi). CHAPTER 3. ANALISI DEI RISULTATI NUMERICI GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 4.07784 4.11136 4.09433 4.07689 4.07928 4.07928 1 iter 0.0912201 0.126089 0.191808 0.0809992 0.110929 0.100837 21 ultima iter 0.0385979 0.0489994 2.98803 0.0326069 0.0445527 0.0353608 Figure 3.9: Griglia adattata alla prima e all’ultima iterazione. Si osservi ancora una volta il buon funzionamento dell’adattazione di griglia: si ottiene un errore corrispondente a quello di una mesh uniforme con più di 12000 elementi. Qualitativamente il risultato ottenuto è come sopra: il metodo MEDIA e ZZ battono il metodo SPR e il metodo INV. MESH ISOTROPICA Visto la scarsità degli elementi nella griglia adattata, sembra abbastanza inutile un’analisi sui metodi fissando il numero di nodi della griglia. Per mesh caratterizzata da triangoli cosı̀ schiacciati, sembra invece più interessante studiare il comportamento delle varie tecniche di ricostruzione, richiedendo tramite il parametro iso=true della funzione adaptmesh() di lavorare con mesh isotropiche. Questo comando porterà alla creazione di mesh composte da triangoli pressocchè equilateri. Per riuscire a descrivere l’infittimento nella zona centrale della mesh con triangoli equilateri, la triangolazione sarà composta da 5132 (mesh alla prima iterazione) e 8162 elementi (mesh all’ultima iterazione), implicando quindi un costo computazionale maggiore rispetto alle matrici adattate. CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 22 Figure 3.10: Griglia adattata alla prima e all’ultima iterazione. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 4.07784 4.11136 4.09433 4.07689 4.07928 4.07928 1 iter 0.0796898 0.0821293 3.7865 0.0809992 0.075385 0.075385 ultima iter 0.0328687 0.053522 2.93954 0.0302428 0.0410212 0.0306863 Si sperava che i metodi della media e della media inversa fossero avvantaggiate dall’utilizzo di triangoli equilateri. Questi metodi infatti sono sensibili alla forma degli elementi della mesh. Sebbene i metodi MEDIA e ZZ forniscano risultati migliori, si è propensi a pensare che questo miglioramento sia dovuto all’utilizzo di molti più elementi rispetto all’adattazione standard piuttosto che all’utilizzo di triangoli equilateri. Per quanto riguarda questi due metodi, si è portati a pensare che non convenga il passaggio a elementi di tipo equilatero, poichè il costo computazionale è notevolmente aumentato rispetto a quello relativo alla mesh adattata standard. Il metodo della media inversa, che a priori avrebbe dovuto ricavare dei vantaggi da questa scelta, ne risente invece in maniera negativa. Questo perchè per descrivere l’infittimento centrale si useranno, come già detto, molti più elementi, che saranno di conseguenza molto più piccoli. L’inverso delle distanze tra baricentro e vertici del triangolo su cui si basa questo metodo tenderà a crescere notevolmente portando a un peggioramento del risultato finale. Per quanto riguarda la dipendenza dell’accuratezza dei metodi dalla forma dei triangoli si può dedurre che: 1. il metodo ZZ non richiede di lavorare con triangoli equilateri 2. i metodi MEDIA e INV probabilmente risentono della forma dell’elemento, ma il primo metodo guadagna in accuratezza in virtù di un numero CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 23 maggiore di elementi piuttosto che per l’equilaterità degli elementi, mentre il secondo metodo perde più in accuratezza per l’utilizzo di elementi molto piccoli piuttosto che guadagnarne per la loro equilaterità 3.3 Esempio 3: concentrazione in un angolo 1 sul dominio Ω = (0, 1)2 . Questa Si considera la funzione u(x, y) = (x+y+0.1) funzione porterà un’infittimento della mesh in un angolo del dominio. Figure 3.11: a) Soluzione esatta b) Componente x del gradiente della soluzione esatta c) Componente xx dell’hessiana della soluzione esatta MESH UNIFORME Il comportamento qualitativo questa volta è leggermente diverso nelle mesh con un numero di elementi piccolo. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 13.2136 13.1755 18.8802 13.2483 13.2168 13.2168 100 5.65883 5.6588 6.77946 5.68023 5.69694 5.69694 400 2.30514 2.35221 4.42616 2.30955 2.36109 2.36109 3200 0.907759 0.966755 1.66836 0.904174 0.947978 0.947978 12800 0.346463 0.384122 0.881725 0.342686 0.363962 0.363962 Nelle prime due mesh, infatti, il metodo della media inversa presenta un errore minore, seguita dal metodo ZZ+INV (e ZZ+SPR) e dal metodo della MEDIA. Si osservi che finchè il metodo della media inversa presenta l’errore minore il metodo ZZ+INV è migliore rispetto alla sua versione standard. Al crescere del numero degli elementi il comportamento qualitativo ritorna a essere quello simile. MESH ADATTATA Si procede ancora una volta con l’adattamento standard della mesh. Anche in questo caso la sua applicazione risulta vincente, raggiungendo alla CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 24 Figure 3.12: Risultati ottenuti sulla griglia adattata all’ultima iterazione. a) Componente x del gradiente ricostruito col metodo della Media b) Componente xx del gradiente ricostruito col metodo della Media prima iterazione con 256 elementi un errore che sulla griglia adattata veniva raggiunto con più di 3500 elementi, mentre all’ultima iterazione con soli 141 elementi si raggiunge una precisione ottenibile solo con più di 12800 elementi su griglia uniforme. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 13.2136 13.1755 18.8802 13.2483 13.2168 13.2168 1 iter 0.632171 0.630064 3.00312 0.601562 0.635798 0.617642 ultima iter 0.113059 0.0985932 0.497515 0.0623844 0.0956929 0.09087 Figure 3.13: Griglia adattata alla prima e all’ultima iterazione. Questo è un chiaro esempio di quanto una buona griglia riesca a migliorare le prestazioni dei metodi di ricostruzione. E’ possibile supporre che: CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 25 1. quando si lavora con pochi elementi tutti concentrati su un angolo il metodo della media inversa ottiene la migliore prestazione e il metodo ZZ+INV batte il metodo della media 2. quando la concentrazione dei nodi si verifica al centro della mesh oppure se si lavora con tanti elementi il metodo della media funziona meglio rispetto al metodo della media inversa 3. il metodo SPR lavora particolarmente male poichè c’è la possibilità di perdere le informazioni nei nodi di bordo, che in questo caso sono particolarmente importanti. MESH ISOTROPICHE Visto che la triangolazione della griglia finale presenta dei triangoli molto schiacciati sembra interessante studiare come si comportano i metodi di ricostruzione qualora si lavori con triangoli equilateri. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 13.2136 13.1755 18.8802 13.2483 13.2168 13.2168 1 iter 0.811751 0.847777 2.7782 0.780098 0.816532 0.804249 ultima iter 0.162307 0.161427 3.81638 0.129827 0.151351 0.14311 Figure 3.14: Griglia adattata alla prima e all’ultima iterazione. La prima mesh sarà composta da circa 200 elementi e raggiunge un’accuratezza che veniva offerta da una mesh uniforme di circa 3000 elementi. Si osservi che il comportamento è lo stesso di quello su una mesh uniforme con appunto 3000 elementi. L’ultima iterazione offre una mesh di 405 elementi con CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 26 una precisione che riferita alla griglia uniforme si ottiene con più di 12800 elementi. Lavorare comunque con triangoli equilateri in questo caso non è conveniente poichè i risultati ottenuti con l’adattazione standard risultano migliori. Qui i due metodi ZZ sono i migliori (a causa del numero elevato di elementi), ma il metodo della media inversa si conferma ancora una volta capace di lavorare bene in un problema in cui si ha una concetrazione in un angolo. ADATTAZIONE CON NUMERO DI ELEMENTI COSTANTI Per questa funzione particolare, i cui valori elevati sono concentrati in un angolo della mesh, può essere interessante cercare di costruire una mesh che dia buoni risultati con pochi elementi. Si osservi però che il metodo d’adattazione standard in questo caso crea una mesh con un numero di elementi minore di 200. 3.4 Esempio 4: infittimento su 2 lati Si studia ora la funzione u(x, y) = (1 − x40 )(1 − y 40 ). Questa funzione porta a un infittimento della griglia in prossimità di due lati. Figure 3.15: a) Soluzione esatta b) Componente x del gradiente della soluzione esatta c) Componente xx dell’hessiana della soluzione esatta MESH UNIFORME Per matrici con un numero di elementi inferiore a 10000 il metodo INV risulta vincente rispetto a tutti gli altri metodi, seguito dal metodo ZZ. CHAPTER 3. ANALISI DEI RISULTATI NUMERICI GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 14.6509 14.6386 22.8822 14.648 14.6504 14.6504 100 9.39145 9.37398 9.68395 9.38725 9.39106 9.39106 400 5.12069 5.10763 5.07641 5.11597 5.12048 5.12048 3200 2.32789 2.32296 2.33577 2.32444 2.32783 2.32783 27 12800 0.936967 0.935713 0.949168 0.93511 0.936955 0.936955 Si ha ancora una volta la conferma che il metodo della media inversa funziona meglio nel caso di gradienti forti in prossimità dei lati della mesh, migliore perfino del metodo ZZ anche se computazionalmente è molto meno complesso. Figure 3.16: Risultati ottenuti sulla griglia adattata all’ultima iterazione. a) Componente x del gradiente ricostruito col metodo della Media b) Componente xx del gradiente ricostruito col metodo della Media MESH ADATTATA Figure 3.17: Griglia adattata alla prima e all’ultima iterazione. La prima matrice adattata è composta da 570 elementi ed ha un ordine CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 28 di precisione che si raggiungeva con griglie uniformi con più di 3200 elementi. Media INV SPR ZZ SPR+INV ZZ+INV 50 14.6509 14.6386 22.8822 14.648 14.6504 14.6504 1 iter. 0.61688 0.635729 1.7152 0.605296 0.616698 0.619846 ultima iter. 0.109409 0.12082 35.7527 0.106398 0.112644 0.110654 Nell’ultima griglia si lavora con oltre 1000 elementi ma con una precisione raggiungibile con griglia uniforme solo con più di 13000 elementi. Al contrario dell’esempio precedente, lavorando sulla mesh adattata il metodo MEDIA è più accurato del metodo INV. Si osservi però che il numero degli elementi per le mesh adattate è più elevato rispetto al caso precedente. Si ricorda che il metodo della media inversa funziona meglio di MEDIA soprattutto nel caso di griglia di pochi elementi. MESH ISOTROPICA Anche in questo caso adattando la mesh si ottengono dei triangoli molto schiacciati. Si cerca di vedere ancora una volta se lavorare con triangoli equilateri possa portare dei benefici o meno ai metodi ricostruttivi. Con la Figure 3.18: Griglia adattata alla prima e all’ultima iterazione. prima iterata si ottiene una mesh di 2000 elementi ma con una precisione per mesh di oltre 3000 elementi, come capitava con la mesh adattata. L’ultima mesh è 16000 elementi, con una precisione superiore a quella ottenuta con la mesh uniforme. CHAPTER 3. ANALISI DEI RISULTATI NUMERICI Media INV SPR ZZ SPR+INV ZZ+INV 50 14.6509 14.6386 22.8822 14.648 14.6504 14.6504 1 iter. 0.647879 0.653547 2.92849 0.641105 0.643693 0.644508 29 ultima iter. 0.101862 0.120678 0.273793 0.0960087 0.0993348 0.0971036 Ancora una volta il metodo della media funzione meglio di INV (come sempre riteniamo che questo sia causato dall’elevato numero di elementi della griglia). Le osservazioni fatte in merito al miglioramento dei metodi con l’utilizzo di triangoli equilateri restano le stesse. 3.5 Esempio 5: infittimento su un lato Si studia ora la funzione u(x, y) = (1 − x40 ). Questa funzione porta a un infittimento della griglia in prossimità di un lato. Figure 3.19: a) Soluzione esatta b) Componente x del gradiente della soluzione esatta c) Componente xx dell’hessiana della soluzione esatta MESH UNIFORME Ancora una volta, il metodo della media inversa risulta migliore rispetto al metodo della media a causa del forte gradiente in prossimità del lato destro della griglia. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 11.1255 11.1108 16.6841 11.1247 11.1245 11.1245 100 6.88163 6.86321 7.16503 6.88041 6.88105 6.88105 400 3.70903 3.69588 3.71015 3.70763 3.70883 3.70883 3200 1.68255 1.67768 1.70628 1.68156 1.68252 1.68252 12800 0.677094 0.675864 0.687295 0.676594 0.677091 0.677091 CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 30 Per una mesh di 50 elementi i metodi ZZ+INV e SPR+INV sono superiori alla loro versione standard. A partire però da una mesh di 100 elementi, i risultati per ZZ sono migliori rispetto alla versione modificata. Troviamo quindi un’ulteriore conferma di quanto detto finora: 1. il metodo INV funziona meglio del metodo della media finchè il gradiente è concentrato lungo un lato o vertice della mesh 2. i metodi corretti ZZ+INV e SPR+INV forniscono dei risultati migliori della versione standard (con un costo computazionale molto ridotto) finchè la mesh è composto da un numero relativamente piccolo di elementi e il metodo della media inversa funziona bene. MESH ADATTATA Figure 3.20: Griglia adattata alla prima e all’ultima iterazione. Lavorando con una griglia di soli 127 elementi si recupera un errore che si aveva solo su una griglia uniforme con più di 3200 elementi e con 153 elementi si raggiunge un’accuratezza ancora maggiore. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 11.1255 11.1108 16.6841 11.1247 11.1245 11.1245 1 iter. 1.01814 1.02612 1.35683 1.0305 1.03042 1.02451 ultima iter. 0.0697682 0.0737744 14.7326 0.0657949 0.07177 0.070284 Ancora una volta il metodo della media batte il metodo INV su una mesh adattata anche se composta da pochi elementi. Si può dedurre allora che generalmente su una griglia adattata funziona meglio MEDIA piuttosto che il metodo della media inversa. Il metodo ZZ resta sempre il metodo migliore, anche se il tempo di calcolo è elevato. CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 31 Figure 3.21: Risultati ottenuti sulla griglia adattata all’ultima iterazione. a) Componente x del gradiente ricostruito col metodo della Media b) Componente xx del gradiente ricostruito col metodo della Media MESH ISOTROPICA Figure 3.22: Griglia adattata alla prima e all’ultima iterazione. L’analisi su una mesh isotropica non risulta conveniente rispetto a lavorare su una mesh adattata standard poichè si ottengono due matrici di oltre 1100 e circa 8900 elementi che portano comunque dei risultati meno accurati delle matrici adattate standard. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 11.1255 11.1108 16.6841 11.1247 11.1245 11.1245 1 iter. 1.46087 1.45803 1.45533 1.4536 1.46062 1.46004 ultima iter. 0.0756749 0.0989536 4.38856 0.0731755 0.0759857 0.0741438 Come già osservato in precedenza il fatto di utilizzare elementi isotropici non migliora i risultati del metodo inverso perchè si utilizzano triangoli troppo piccoli. Un’eventuale soluzione potrebbe essere imporre una dimensione CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 32 minima degli elementi, ma questo potrebbe portare a delle mesh che non riescono a descrivere il forte gradiente nel lato destro della mesh. 3.6 Esempio 6: diffusione e trasporto Si affronta ora un problema di diffusione e trasporto: −∆u + u = 0 in Ω = (0, 1)2 ∂n u = sin(πx) su Γup ≡ {y = 1, 0 < x < 1} u = 0 su ∂Ω\Γup la cui soluzione esatta è data da: u(x, y) = con λ = sinh λy sin(πx) λ cosh(λ) √ 1 + π2. Figure 3.23: a) Soluzione esatta b) Componente x del gradiente della soluzione esatta c) Componente xx dell’hessiana della soluzione esatta MESH UNIFORME La soluzione esatta è una funzione regolare e non presenta gradienti elevati in prossimità dei lati della mesh. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 0.101345 0.101622 0.182811 0.0999169 0.101705 0.101705 100 0.0381634 0.0382113 0.134237 0.0371527 0.0382869 0.0382869 400 0.0138859 0.0138961 0.159535 0.0134263 0.0139151 0.0139151 3200 0.00497636 0.00497847 0.0115107 0.00479414 0.00498224 0.00498224 12800 0.00177098 0.0017714 0.00510333 0.0017029 0.00177208 0.00177208 CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 33 Di conseguenza il metodo della media funziona meglio del metodo della media inversa, anche se di poco. In generale la differenza dei risultati tra ZZ e la sua versione modificata è piccola quando la derivata esatta della soluzione non presenta gradienti elevati. E’ allora conveniente utilizzare il metodo modificato perchè presenta un costo computazionale inferiore. MESH ADATTATA Figure 3.24: Griglia adattata alla prima e all’ultima iterazione. Si procede all’adattamento della mesh tramite il metodo standard. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 0.101345 0.101622 0.182811 0.0999169 0.101705 0.101705 1 iter. 0.0106351 0.0110155 0.0212598 0.0100074 0.0104462 0.0105636 ultima iter. 0.00820553 0.00881764 0.0182514 0.00754251 0.00801394 0.0081214 Si ottiene una prima mesh di 650 elementi che saranno addossati al lato superiore della mesh restando comunque dei triangoli pressochè equilateri. La precisione della prima mesh è uguale a quella di una mesh uniforme con più di 800 elementi. La matrice finale è composta da 683 elementi e migliora leggermente l’accuratezza dei metodi. Studiando la mesh stessa è possibile intuire quale metodo utilizzare: non esistendo un forte raffinamento della mesh in prossimità di un lato, ma presentando solo una concentrazione di triangoli equilateri nella parte superiore della mesh, è consigliabile utilizzare il metodo della media piuttosto che la media inversa. Sebbene il metodo ZZ funzioni meglio è altresı̀ consigliabile utilizzare il metodo ZZ+INV che con un piccolo errore aggiuntivo permette di ridurre notevolmente il costo computazionale. CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 34 Figure 3.25: Risultati ottenuti sulla griglia adattata all’ultima iterazione. a) Componente x del gradiente ricostruito col metodo della Media b) Componente xx del gradiente ricostruito col metodo della Media ADATTAZIONE CON NUMERO DI ELEMENTI COSTANTI Figure 3.26: Griglia adattata alla prima e all’ultima iterazione. Dato che la mesh adattata è composta da un numero di triangoli equilateri relativamente grande, risulta più interessante studiare il caso di adattazione con numero di elementi costanti(< 350) piuttosto che procedere cercando una mesh isotropica. GRAD Media INV SPR ZZ SPR+INV ZZ+INV 50 0.101345 0.101622 0.182811 0.0999169 0.101705 0.101705 1 iter. 0.0245699 0.0166213 0.248997 0.0169474 0.0149849 0.0171639 ultima iter. 0.0249425 0.0154337 0.933958 0.0160973 0.0133383 0.0160952 Si osserva che dalla prima iterazione all’ultima iterazione il risultato non cambia molto. Questo perchè come già accaduto nell’esempio 1, la mesh CHAPTER 3. ANALISI DEI RISULTATI NUMERICI 35 costruita ad ogni iterazione è sottoposta ad un restrizione sui nodi troppo forte per cui ad ogni passo si rischia la perdita di informazioni importanti. I risultati seguono comunque l’andamento generale. 3.7 Conclusioni sui metodi In questo capitolo abbiamo analizzato 4 metodi di ricostruzione locale su diversi tipi di funzioni. In merito ai risultati ottenuti si possono fare alcune osservazioni interessanti: 1. il metodo SPR nella sua versione standard commette troppi errori di valutazione del gradiente nei nodi di bordo, soltanto la versione modificata può dare dei risultati accurati (esempio 1); 2. il metodo INV risulta il più accurato quando si lavora con griglie uniformi di piccole dimensioni e il gradiente della funzione presenta valori elevati in prossimità dei vertici o dei lati della griglia (esempi 3,4,5); 3. il metodo INV e il metodo SPR+INV funzionano meglio su griglie non uniformi e non costruite appositamente, mentre su griglie uniformi, costruite ad hoc o con un numero elevato di elementi è consigliabile utilizzare il metodo MEDIA e ZZ+INV (esempio 1,2,6); 4. il metodo ZZ è generalmente il metodo con una miglior precisione di ricostruzione, ma il tempo di calcolo richiesto è molto più elevato. La scelta del metodo dovrà allora essere fatta in funzione della griglia su cui si effettuano i calcoli al fine di ottimizzare il rapporto accuratezza-tempo di calcolo. Abbiamo infatti illustrato l’esistenza di casi in cui il metodo della media offre risultati più accurati o di poco dissimili da quelli dello ZZ, sebbene sia computazionalemnte meno complicato. Allo stesso modo il metodo INV risulta a volte più accurato del metodo SPR+INV. Al fine di scegliere il metodo in maniera adeguata è consigliabile analizzare l’aspetto della mesh. Chapter 4 Codice C++ per i metodi ricostruttivi Il codice proposto permette di calcolare il gradiente ricostruito con i quattro metodi presentati. Nella scrittura del codice si è cercato di curare contemporaneamente tre aspetti: l’ottimizzazione delle operazioni, la chiarezza e la semplicità del programma, la possibilità di generalizzarlo e estenderlo facilmente. E’ infatti importante poter riutilizzare il programma su mesh con elementi quadrangolari o nel caso di elementi finiti quadratici tramite semplici modifiche del codice. In questo lavoro ci concentreremo maggiormente su questi aspetti, mentre per una descrizione più particolareggiate del codice si rimanda ai commenti del codice stesso (e all’output di Doxygen). Obbiettivo del programma è valutare l’errore di ricostruzione per varie Figure 4.1: Grafico dei file costituienti il programma 36 CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 37 funzioni. Ma può anche essere leggermente modificato al fine di ottenere a partire da un vettore di valori nodali della soluzione approssimata (prodotta ad esempio da FREEFEM), il suo gradiente e l’hessiana. In questo lavoro descriveremo il codice per il calcolo dell’errore di ricostruzione. Prima di poter compilare il programma, l’utente dovrà modificare il contenuto del file utente.hpp. All’interno di questo file sarà possibile innanzitutto scegliere la precisione del programma modificando la riga: typedef double real. In secondo luogo l’utente dovrà inserire la funzione esatta, le componenti del gradiente e dell’Hessiana. La prima operazione di main.cpp permette all’utente di inserire il nome della mesh (specificandone il percorso completo). Questa mesh non è altro che un file con estensione .msh generato da Freefem. Il file si occupa anche della costruzione della struttura dati mesh. La definizione di questa classe è contenuta in mesh.hpp, mentre la definizione dei suoi elementi (punti, triangoli e patches) è contenuta nell’header file shape.hpp. All’utente viene inoltre richiesto di inserire un indice per la forma degli elementi della mesh. Sebbene il codice funzioni solo per il valore 0 (che corrisponde ai triangoli), questa richiesta dà la possibilità di introdurre anche mesh con elementi quadrangolari una volta aggiunti alcuni metodi specifici all’approssimazione su quadrati. Con lo stesso intento all’utente viene richiesto di scegliere il grado del polinomio con cui si lavora. Anche in questo caso solo una scelta pari a 1 permette il corretto utilizzo del codice, ma all’utente è data la possibilità di estendere il programma modificando pochi punti. Si osserva però che i metodi proposti in letteratura sono costruiti specificatamente su elementi triangolari con elementi finiti di grado 1. Il programma prosegue con il calcolo dei valori nodali della soluzione u, del gradiente e dell’Hessiana tramite la funzione sol_uh(). Verrà inoltre costruito il polinomio interpolante uh , tramite la funzione Lagrange() (che costruisce i polinomi di lagrange per ogni elemento della mesh) e interpole() (che fornisce il valore nodale del polinomio interpolante su ogni vertice della griglia). Si calcola in seguito il gradiente di uh , cioè il gradiente che si otterrebbe derivando la soluzione agli EF in maniera esatta. Per far ciò si utilizzano le funzioni deriv_x() e deriv_y(). Tutte queste funzioni sono contenute nel file polinomi.hpp. A questo punto il programma chiede all’utente quale metodo di ricostruzione preferisce usare. La ricostruzione del gradiente avviene richiamando le funzioni contenute in ricostruzione.hpp. Alcune di queste utilizzano i metodi implementati all’interno della libreria LAPACK di Fortran. All’interno del file metodi.hpp è possibile trovare l’importazione della libreria e con quale CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 38 metodo risolvere il sistema a seconda della precisione. Si osservi che al momento della compilazione bisognerà allora importare la libreria col seguente comando: g++ -o main main.cpp -L/usr/local/lib/ -llapack. Per la ricostruzione dell’Hessiana invece si dovrà costruire il polinomio interpolante per il gradiente ricostruito e applicarvi i metodi per il gradiente. A questo punto il programma calcola i due errori tramite le funzioni definite in errore.hpp, visualizzandoli a schermo insieme al tempo di calcolo della ricostruzione per i vari metodi. In ultimo si salvano su file i valori nodali delle varie funzioni calcolate. Questi file .dat permettono la rappresentazione grafica tramite gnuplot seguendo le istruzioni contenute nel file plot.gnu. Nel seguito illustreremo gli header file in dettaglio. 4.1 Geometria del problema: file SHAPE.HPP Nel header file shape.hpp sono definite le classi Point, Shape, Triangle e Patch che servono a contenere le informazioni sulla griglia del problema. CLASS POINT : La classe Point descrive i nodi della mesh. I suoi metodi privati sono: • x : ascissa del nodo (default 0) • y : ordinata del nodo (default 0) • Pid : numero che identifica il nodo (default 0) • Pb : 0-nodo interno, 1-nodo di bordo, 2-non si conosce se il nodo è interno o esterno (default 2). La classe è fornita di costruttore, di metodi che restituiscono i metodi privati, il metodo norma, l’overloading dell’operatore << di visualizzazione a schermo e dell’operatore − che restituisce la differenza tra due punti. CLASS SHAPE : La classe Shape è la classe base per le figure geometriche. I suoi metodi privati sono: • SnP : numero di punti della figura (default=0) • Spoints : vettore dei punti della figura • SnE : numero di lati CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 39 • Sid : numero che identifica la figura (default=0). La classe è dotata di costruttore, distruttore (dichiarato virtual per evitare conflitti con i distruttori delle classi derivate), metodi che restituiscono i metodi privati e di visualizzazione. Esiste inoltre il metodo baricentro() che restituisce il suo baricentro. Si osservi la creazione di un membro virtual measure() dichiarato nullo. Questo fa in modo che la classe Shape sia in realtà una classe astratta. OSSERVAZIONE: La costruzione di questa classe può essere vista come un primo tentativo di generalizzazione. A partire da questa, infatti, è possibile costruire delle classi derivate che descrivano la geometria degli elementi della mesh. Nel nostro caso triangoli (cui ricordiamo è stato associato il numero 0) ma è possibile introdurre anche quadrangoli e altre figure (ricordando sempre di associarvi un numero, di modo che l’utente possa passare la forma degli elementi come parametro del programma). CLASS TRIANGLE : La classe Triangle è una classe derivata della classe Shape. Erediterà quindi i suoi metodi privati. Presenta due diversi costruttori a partire da 3 punti o da 3 punti e il valore dell’identificatore. Il metodo measure() restituisce l’area del triangolo, dist_inversa() restituisce l’inverso della distanza del baricentro da un punto (questo servirà nel metodo della media inversa dove si calcolerà l’inverso della distanza per i vari nodi del triangolo). CLASS PATCH : La class Patch descrive l’unione di triangoli che condividono uno stesso nodo. I suoi metodi privati sono: • P tchid : numero che identifica la Patch, coincide con l’identificatore del nodo centrale • P tchtriangles : vettore contenente l’identificatore dei triangoli che costituiscono la Patch • P tchb : il nodo centrale della Patch è di bordo? 0-nodo interno, 1-nodo di bordo, 2-non si conosce se il nodo è interno o esterno . La classe è fornita dei metodi di restituzione dei metodi privati e dell’overloading dell’operatore <<. OSSERVAZIONE 2: La creazione della classe Patches è di fondamentale importanza. In tutte le tecniche di ricostruzione, infatti, il valore del gradiente in un punto viene calcolato in funzione del valore assunto nei punti vicini. E’ quindi possibile immaginare che in diverse circostanze si voglia richiamare l’insieme dei nodi vicini a un dato vertice. Questa operazione CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 40 è gestibile con qualche ciclo for, ma durante la scrittura di tutto il codice si è sempre preferito aumentare i costi in termine di spazio di memoria a beneficio dei costi in termine di tempo. 4.2 Generazione e gestione della mesh: MESH.HPP La classe Mesh permette di gestire i dati contenuti in un file .msh prodotta da Freefem. Il file .msh presenta sulla prima riga il numero di nodi, di elementi e di lati del bordo della mesh. Dalla seconda riga in poi fornisce per ogni nodo ascissa, ordinata e il lato della mesh cui appartiene (0 se nodo interno). Si osservi che nel nosto caso non importa a quale lato della mesh un nodo di bordo appartenga, quindi si assegnerà valore 1 all’identificatore di tutti quei nodi che non sono interni. Finita la descrizione dei nodi, si trovano le informazioni per ogni elemento. Su ogni riga si ha l’ID dei nodi che formano l’elemento e un numero che identifica la forma dell’elemento (se triangolo=0, se quadrato=1). In ultimo ci sono le informazioni sui lati che costituiscono il bordo della mesh. I primi due elementi indicano i nodi che ogni lato dei triangoli unisce, il terzo elemento indica il lato della mesh cui appartengono. OSSERVAZIONE: il fatto che il file .msh abbia l’informazione della forma dell’elemento come ultimo numero della riga relativa all’elemento può creare qualche difficoltà. E’ infatti di più difficile gestione l’informazione sulla natura di un elemento e la sua costruzione rispetto all’averla come primo valore della riga. Per ogni riga relativa all’elemento si prelevano sempre almeno quattro valori (la natura dell’elemento e almeno tre suoi vertici) e se l’ultimo elemento è pari a zero allora è un triangolo, altrimenti si memorizza anche il valore successivo perchè è il valore di un vertice per un quadrato. Questo ragionamento casca nel caso in cui un quadrato abbia proprio come terzo vertice il nodo di indice 0. Per evitare che si presenti questo tipo di errore supponiamo di lavorare con griglie composte da elementi dello stesso tipo, di modo che questa informazione possa essere inserita dall’utente a schermo. Un’altra soluzione potrebbe essere richiedere al codice di leggere la lunghezza di ogni riga e da questa dedurre la forma dell’ elemento. Questo tipo di operazione, seppur semplice, comporterebbe un aumento del costo computazionale. CLASS MESH: I suoi metodi privati sono: • Mpoints : array di punti che costituiscono la mesh • Melements : vettore contenente i puntatori ad elementi di tipo shape che costituiscono la mesh; l’utilizzo di un vettore di puntatori è indispensabile poichè non è possibile inizializzare un vettore di elementi di cui non si conosce la natura CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 41 • Mpatches : vettore contenente le patches. La classe è dotata di un costruttore che legge i dati dal file .msh, genera i punti, i triangoli e le patches costituenti la griglia.E’ presenta anche l’operatore di visualizzazione a schermo della mesh. OSSERVAZIONE 2: il vettore relativo alle patches viene costruito in maniera immediata durante la lettura e la generazione della mesh. Con poche accortezze è stato possibile memorizzare le informazioni sulle patches alla prima lettura del file .msh. Si risparmia cosı̀ almeno un ciclo for che sarebbe stato necessario nel caso in cui, una volta costruita la matrice mesh, si avesse voluto costruire le patches su ogni nodo. OSSERVAZIONE 3: in questo caso la struttura dati per il vettore è quella della standard library. Solo nel caso di un vettore di reali si preferirà il vettore presente nella libreria UBLAS. Questo perchè, mentre negli altri casi i vettori sono solo dei ”contenitori” di informazioni, i vettori di reali verranno utilizzati per risolvere il sistema. La libreria UBLAS contiene qualche funzione per le operazioni tra vettori e matrici (nel nostro caso le matrici saranno tutte di reali, quindi descritte tramite libreria UBLAS) che risultano comode qualora si vada a risolvere il sistema lineare (per i dettagli si veda [12]). Negli altri casi si preferisce fare riferimento alla standard library (si veda [10]) . 4.3 Polinomio interpolante e gradiente esatto: POLINOMI.HPP All’interno di questo file si trovano le funzioni e le classi che servono alla costruzione del polinomio interpolante e del gradiente esatto. FUNZIONE SOL UH: La funzione sol_uh() fornisce i valori nodali di una funzione. In ingresso la funzione riceve un puntatore a funzione u, un vettore di Point per il quale si vuole calcolare il valore della funzione. Ovviamente il numero di punti per elemento deve essere coerente con la scelta degli elementi e del grado. Nel nostro caso è sufficiente passare il vettore contenente le informazioni dei punti della matrice. Nel caso di un grado diverso da uno, sarà necessario costruire il vettore dei punti necessari per una giusta interpolazione. In uscita fornisce il vettore dei valori nodali. A partire da questi valori è possibile costruire il polinomio interpolante, nella forma: uh (x, y) = i 1 X X i=0 j=0 uij Li (x)Lj (y) CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 42 dove uij = u(xi , yj ), Li (x) e Lj (y) sono i polinomi di Lagrange: n Y x − xk . Li (x) = xi − xk k6=i CLASS LAGRANGE elem: Si osserva che, lavorando con il grado uno, su ogni elemento l’unico contributo non nullo delle funzioni base è quello relativo ai nodi dell’elemento. Questa classe presenta due costruttori. Il primo, generico, avvisa l’utente di aver scelto una combinazione di forma e grado non contemplata dal codice. Il secondo costruttore è una specializzazione del costruttore nel caso di triangoli e polinomi di grado 1. Si lavora sul triangolo di riferimento T̂ e traduce quanto trovato sul triangolo T tramite una mappa affine. I metodi privati di questa classe forniscono un vettore dei coefficienti per P (x) = (1, x, y) in ogni nodo. Il costruttore prende in ingresso un elemento della classe Triangle e il grado dei polinomi. Per ogni nodo del triangolo T si ottiene il contributo della funzione base calcolata sul nodo sul triangolo stesso. La classe contiene inoltre i metodi che ritornano i valori dei metodi privati. CLASS LAGRANGE: La classe Lagrange() fornisce come metodo privato l’insieme dei polinomi di Lagrange per tutti gli elementi. Il costruttore quindi prende come input il vettore degli elementi della mesh. CLASS INTERPOLE elem: Il metodo privato di questa classe fornisce i coefficienti del polinomio interpolante sull’elemento T. E’ sufficiente sommare sui nodi in esame il contributo di ogni funzione base moltiplicata per il valore nodale. Il costruttore prende in ingresso un elemento della classe Lagrange_elem e il vettore dei valori nodali della funzione di cui si sta calcolando il polinomio interpolante. CLASS INTERPOLE: La classe fornisce i polinomi interpolanti su ogni triangolo. Prende in ingresso il vettore dei triangoli, il vettore dei valori nodali della funzione e un elemento della class Lagrange. Bisogna prestare particolare attenzione affinchè i dati in ingresso siano coerenti tra di loro e che ci sia la giusta corrispondenza tra nodo in esame e valore della funzione. FUNZIONI DERIV X / DERIV Y: Sono definite le due funzioni deriv_x e deriv_y che a partire da un elemento della classe interpole() restituisce il valore della derivata rispetto a x e a y ( lavorando con EF del primo grado si ottiene un valore costante su ogni triangolo). Anche loro per semplicità sono state specializzate al caso in esame. CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 43 OSSERVAZIONE: ancora una volta ci teniamo a dire che si è cercato di generalizzare al massimo le funzioni. Una soluzione alternativa poteva essere quella di lavorare con le Class Template. Questa scelta sarebbe stata ottimale nel caso in cui si fosse potuto riscontrare qualche elemento comune ad esempio, nella costruzione tra polinomi di Lagrange su triangoli e quadrati per diversi gradi. In realtà il polinomio su quadrato è di più facile descrizione e in questo caso aumentare il grado non comporta particolari difficoltà. Al contrario aumentare il grado su triangolo è più complicato. Si poteva pensare di far ricorso alle funzioni gerarchiche (si veda [11]) ma in realtà la scelta del grado avviene all’inizio del programma e non si modifica più. E’ quindi sufficiente definire diversi costruttori a seconda del grado con cui si vuole lavorare. 4.4 Metodi per la risoluzione di un sistema lineari: METODI.HPP All’interno di questo header file sono presenti tutti quei metodi che servono per la risoluzione del sistema lineare. Sono inoltre presenti delle funzioni che non dipendono nè dal metodo ricostruttivo scelto, nè dalla forma degli elementi o del grado. Queste non sono che una serie di operazioni che si ripetono all’interno del codice e che sono state raggruppate per una miglior chiarezza. Vengono quindi definite le funzioni: twonorm() che restituisce la norma di un vettore, dot() che restituisce il prodotto scalare tra due vettori, area() che restituisce un vettore contenente le aree degli elementi della griglia, baricen() che restituisce un vettore contenente i baricentri degli elementi. OSSERVAZIONE: Le ultime due funzioni vengono richiamate all’interno dei metodi ricostruttivi. Ancora una volta si è preferito occupare memoria, risparmiando però del tempo. Infatti, durante la ricostruzione si procede per patches. Questo significa che ogni elemento viene richiamato tante volte quanti sono i suoi vertici e se non si costruissero questi due vettori aggiuntivi si rifarebbe la stessa operazione troppe volte. La parte più interessante di questo file resta comunque quella dedicata alla risoluzione di un qualsiasi sistema lineare. Sebbene la risoluzione dei sistemi non sia di particolare difficoltà (sono comunque matrici 3*3) si è preferito utilizzare delle funzioni presenti nella libreria LAPACK scritta in Fortran (per i dettagli si veda [9]). Si è quindi scelto di costruire una function template che utilizzi metodi diversi a seconda del grado di precisione del programma. Di default la precisione è double. Si è poi specializzata la funzione nel caso si stia lavorando con precisione di tipo float. Si ricorda CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 44 ancora una volta che al momento della compilazione sarà opportuno caricare anche la libreria in questione. 4.5 Metodi di ricostruzione: RICOSTRUZIONE.HPP In questo header file sono presenti la definzione dei 4 metodi ricostruttivi presentati. Lo schema è sempre lo stesso: ogni metodo è stato diviso in due parti. La prima parte permette il calcolo del gradiente ristretto a un solo elemento (funzioni seguite da patch). La seconda parte poi applica queste funzioni a tutti gli elementi della mesh. E’ stato utile, inoltre, introdurre due ulteriori funzioni per il metodo ZZ e SPR (matrix _ SPR e matrix _ ZZ) che costruiscono la matrice su una singola patch che serve al calcolo del gradiente in un nodo. Le funzioni sulla mesh restituiscono un vettore contenente il valore nodale della grandezza cercata. OSSERVAZIONE: E’ utile sottolineare il fatto che si è cercato di descrivere i passaggi comuni ai vari metodi (magari raggruppati a due a due) tramite un’unica funzione. In questo modo il codice risulta più chiaro e comprensibile. Si osservi inoltre che questo procedimento aiuta a evidenziare quali sono i tratti in comune e quali specifici di ogni metodo. Questo diviene evidente quando si vuole vedere la differenza,ad esempio, tra metodo ZZ e ZZ+INV. Ciò che cambia sono poche righe di codice, cosa che non si sarebbe colto altrettanto facilmente se non si fossero definite le funzioni sulle singole patches. OSSERVAZIONE 2: Si ricorda che questo file è specifico per il caso di elementi di grado uno su triangoli. In letteratura, infatti, la maggior parte dei metodi viene costruito per questo caso. Si ricorda che una delle qualità di un buon metodo ricostruttivo era quello di ottenere un gradiente tramite elementi finiti dello stesso grado della soluzione di partenza. Seguendo questa idea l’utente che desidera utilizzare elementi finiti del secondo ordine non potrà utilizzare i metodi ricostruttivi descritti in questo file, ma dovrà cercare una loro generalizzazione. Per quanto riguarda invece l’utilizzo di elementi quadrangolari abbiamo già detto che l’applicazione dei metodi qui illustrati a questo caso è pressochè immediata. 4.6 Il calcolo dell’errore: ERRORE.HPP All’interno di questo file è possibile trovare quanto è necessario per calcolare l’errore per il calcolo del gradiente e dell’Hessiana. FUNZIONE SCALAR(): La funzione viene definita in maniera diversa a seconda che abbia come CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 45 parametro di input un vettore o una matrice. Nel caso in cui riceva un vettore restituisce la somma del quadrato delle componenti del vettore. Se riceve in ingresso una matrice restituisce il valore della traccia della matrice trasposta per la matrice stessa. REAL ERROR(): La funzione calcola l’errore effettuato dal gradiente ricostruito. Riceve in ingresso il vettore delle componenti del gradiente esatto ∇u e del gradiente ricostruito GR uh oltre che il vettore di Triangle. REAL ERROR2(): La funzione calcola l’errore effettuato dall’Hessiana ricostruita. Oltre che alle componenti dell’Hessiana esatta Hu e dell’Hessiana ricostruita HR uh riceve in ingresso un vettore di Triangle. 4.7 Inserimento dei dati da parte dell’utente: UTENTE.HPP Il programma effettua i conti a partire dalla soluzione esatta u, dalle componenti di ∇u e di Hu. Questi dati vengono inseriti dall’utente nel file main.hpp dove: • f : puntatore a funzione che definisce la soluzione esatta u • dfx : puntatore a funzione che definisce ∂u ∂x • dfy : puntatore a funzione che definisce ∂u ∂y • dfxx : puntatore a funzione che definisce ∂2u ∂x2 • dfxy : puntatore a funzione che definisce ∂2u ∂x∂y • dfyy : puntatore a funzione che definisce ∂2u . ∂y 2 L’utente può inoltre modificare la precisione dell’ intero programma tramite il comando: typedef double real. 4.8 Come funziona il programma: MAIN.CPP Nel file main.cpp vengono richiamati i file di cui si è parlato finora. All’inizio della funzione main() vengono costruiti la classe Mesh, il valore nodale della soluzione esatta, del gradiente e dell’Hessiana. Si costruisce poi la base di Lagrange per tutti i nodi e il polinomio d’interpolazione uh . Si costruisce il gradiente ∇uh . All’utente sarà allora richiesto di scegliere quale metodo di ricostruzione usare e, nel caso dei metodi Patch recovery, se utilizzare la versione modificata per i nodi di bordo. A questo punto verranno ricostruiti CHAPTER 4. CODICE C++ PER I METODI RICOSTRUTTIVI 46 il gradiente e l’Hessiana. I risultati saranno salvati in un file di tipo .dat che può essere usato per una rappresentazione grafica via gnuplot. A video verranno visualizzati l’errore di ricostruzione e il tempo di calcolo per la ricostruzione della derivata e del gradiente. OSSERVAZIONE: I risultati ottenuti saranno contenuti in una cartella creata appositamente, se non già preesistente, chiamata ”results” al fine di rendere più chiara e gestibile la cartella in cui è stato memorizzato il programma. Chapter 5 Conclusioni I metodi descritti e i risultati ottenuti permettono la ricostruzione del gradiente in maniera accurata. La forma del gradiente e dell’Hessiana calcolata risulta simili alla forma esatta. Per quanto riguarda il codice di calcolo si ritiene di aver scritto un programma sufficientemente efficiente: i calcolati effettuati anche su griglie composte da numerosi elementi vengono risolti in tempi ragionevoli (per griglie di 51200 elementi si ottengono tempi di circa 11 secondi). E’ comunque possibile migliorare i tempi di calcolo e l’occupazione di memoria modificando le strutture dati e la loro gestione (creazione e gestione mesh, patches, basi lagrange, matrici). Anche per la risoluzione dei sistemi lineari è possibile utilizzare dei metodi diversi, anche se la ridotta dimensione del sistema non necessita di metodi particolarmente più veloci. Numerose sono le possibili estensioni del progetto. Innanzittutto è possibile migliorare le prestazioni dei metodi, soprattutto per i weighted average traducendo ogni patch tramite delle trasformazioni in una patch di riferimento su cui verranno effettuati i calcoli. Si può inoltre approfondire l’analisi dei metodi attraverso la loro applicazione ad altri tipi di funzioni e di domini. E’ inoltre possibile studiare anche altri metodi di ricostruzione e qualche loro applicazione ad esempio nell’ambito della costruzione di stime a posteriori dell’errore o di griglie adattate. 47 Bibliography [1] A.Quarteroni, A.Sacco, F.Saleri, Numerical Mathematics, SpringerVerlag, 2000, New York [2] S.Perotto Ricostruzione del gradiente di una soluzione discreta e stimatori a posteriori recovery-based , http://mox.polimi.it/it/progetti/adattivita.php3 [3] ??? [4] O.C. Zienkiewick, J.Z. Zhu, A simple error estiamtor and adaptive procedure for pratical engineering analysis, Int.J.Numer.Methods Eng. 24, 337-357 (1987) [5] R.C. Almeida, R.A. Feijòo, A.C.Galeao, C.Padra, R.S. Silva, Adaptive finite element computational fluid dynamics using an anisotropic error estimator, Comput. Methods Appl. Mech. Engrg. 182,379-400 (2000) [6] O.C. Zienkiewick, J.Z. Zhu, The superconvergent patch recovery and a posteriori error estimates. Part 1: the recovery technique, Int.J.Numer.Methods Eng. 33, 1331-1364 (1992) [7] L.Borges, R.Feijòo, C.Padra, N. Zouain, A directional error estiamtor for adaptive finite element analysis, Computational Mechanics, New trends and Applications, Barcelona ,Spain (1998) [8] V.Comincioli, Analisi numerica: McGraw-Hill, 1995, Italy [9] Sito internet ufficiale Boost www.boost.org/libs/numeric/ublas/ metodi, Basic modelli,applicazioni, Linear Algebra: [10] The C++ Standard Library: A tutorial and reference, AWL Publiesher,1999 [11] A.Quarteroni, Modellistica Numerica per Problemi Differenziali, Springer-Verlag Italia, 2003, Milano 48 BIBLIOGRAPHY [12] Sito internet ufficiale www.netlib.org/lapack/ 49 Linear Algebra PACKage: