Applicazione della Proper Orthogonal Decomposition (POD...

21
Applicazione della Proper Orthogonal Decomposition (POD) al Problema di Minima Compliance Pierluigi Colombo

Transcript of Applicazione della Proper Orthogonal Decomposition (POD...

Applicazione della Proper Orthogonal Decomposition (POD) al Problema di Minima

Compliance

Pierluigi Colombo

Abstract In molte applicazioni, le classiche procedure di discretizzazione possono portare ad alti

costi computazionali, a causa del grande numero di gradi di libertà che la

discretizzazione comporta. Un modo efficiente di ridurre la complessità del problema

discretizzato è la Proper Orthogonal Decomposition (POD). Questo metodo consiste

nel catturare la dinamica dominante del fenomeno fisico attraverso delle soluzioni già

calcolate, e la costruzione a partire da queste di un sottospazio di dimensione ridotta

con una base ortonormale. Come vedremo questa tecnica è in grado di ridurre in

maniera considerevole i costi computazionali del calcolo di una nuova soluzione. In

questo lavoro si tratterà della POD, del problema di ottimizzazione topologica di

minima compliance e di come la POD vi è stata implementata. L’algoritmo di

ottimizzazione topologica unito alla POD è stato poi applicato ad un problema concreto

ed i risultati sono stai poi comparati con quelli dell’algoritmo di ottimizzazione

topologica classico.

1 POD e relazione con SVD In questo capitolo si presenta l’obiettivo della POD e la sua relazione con la Singular

Value Decomposition (SVD). L’obiettivo è di trovare una base ortonormale dello

spazio generato da 𝑛 vettori 𝑦1, 𝑦2, …, 𝑦𝑛 con 𝑦𝑧 ∈ ℝ𝑚 con 𝑧 = 1, … , 𝑛.

Sia 𝑌 ∈ ℝ𝑚×𝑛 la matrice le cui colonne sono i vettori 𝑦1, 𝑦2,…, 𝑦𝑛. La SVD ci

garantisce che esistono due matrici ortogonali 𝑈 ∈ ℝ𝑚×𝑚 e 𝑉 ∈ ℝ𝑛×𝑛 ed una

matrice diagonale Σ ∈ ℝ𝑚×𝑛 tale che:

𝑌 = 𝑈Σ𝑉𝑇 (1)

In particolare esistono 𝑟 valori positivi 𝜎1 ≥ 𝜎2 ≥ ⋯ ≥ 𝜎𝑟 tale che:

Σ = (𝐷 00𝑇 𝑂

) (2)

Con 𝐷 = 𝑑𝑖𝑎𝑔(𝜎1, 𝜎2, … , 𝜎𝑟). Le colonne {ϕ𝑗}𝑗=1

𝑚 di 𝑈 e {ψ𝑖}𝑖=1

𝑛 di 𝑉 sono dette

rispettivamente vettori singolari sinistri e vettori singolari destri di 𝑌, ed i valori

{𝜎𝑘}𝑗=1𝑟 sono detti valori singolari di 𝑌

Per le matrici 𝑌𝑌𝑇 e 𝑌𝑇𝑌, simmetriche e definite positive, valgono le seguenti

relazioni:

𝑌𝑌𝑇 = (𝑈Σ𝑉𝑇)(𝑈Σ𝑉𝑇)𝑇 = 𝑈ΣΣT𝑈𝑇 (3)

𝑌𝑇𝑌 = (𝑈Σ𝑉𝑇)𝑇(𝑈Σ𝑉𝑇) = 𝑉ΣTΣ𝑉𝑇 (4)

quindi {(ϕ𝑗 , 𝜎𝑗2)}

𝑗=1

𝑟 e {(ψ𝑖 , 𝜎𝑖

2)}𝑖=1𝑟 sono coppie autovalore-autovettori per le matrici

𝑌𝑌𝑇 E 𝑌𝑇𝑌 rispettivamente. Le rimanti coppie {(ϕ𝑗 , 0)}𝑗=𝑟+1

𝑚(se 𝑚 > 𝑛) o

{(ψ𝑖 , 0)}𝑖=𝑟+1𝑛 (se 𝑛 > 𝑚) identificano una base per 𝐾𝑒𝑟(𝑌𝑌𝑇), 𝐾𝑒𝑟(𝑌𝑇𝑌).

Essendo in generale 𝑟 < min (𝑚, 𝑛), la SVD di 𝑌 può essere scritta in termini di matrici

ridotte:

𝑌 = 𝑈𝑟D𝑉𝑟𝑇 (5)

Con

𝑈𝑟 = [(ϕ1, ϕ2, … , 𝜙𝑟] ∈ ℝ𝑚×𝑟 (6)

𝑉𝑟 = [(ψ1, ψ2, … , ψ𝑟] ∈ ℝ𝑛×𝑟

(7)

Data una matrice 𝐴 ∈ ℝ𝑛×𝑛 simmetrica e positiva (𝐴 = 𝐴𝑇), e sia (𝜆, 𝑣𝜆) una coppia

autovalore-autovettore, Allora 𝐴𝑣𝜆 = 𝜆𝑣𝜆. Quindi moltiplicando per 𝐴𝑇 si ottiene

𝐴𝑇𝐴𝑣𝜆 = 𝜆𝐴𝑇𝑣𝜆 = 𝜆2𝑣𝜆. Quindi 𝜆2 è un autovalore della matrice 𝐴𝑇𝐴, che è a sua

volta il quadrato del valore singolare 𝜎𝜆 = 𝜆. Essendo per ipotesi la matrice singolare

𝐴 positiva si ottiene che gli autovalori di 𝐴 coincidono con suoi valori singolari.

Un’altra proprietà fondamentale della SVD è che le prime 𝑟 colonne della matrice

ortogonale 𝑈 sono una base per lo spazio delle colonne di 𝑌. Quindi le colonne

𝑦1, 𝑦2, … 𝑦𝑛 ammettono una espansione di Fourier (finita) rispetto agli autovalori

singolari {𝜙𝑗}𝑗=1

𝑟. Infatti sapendo che (𝑈𝑟)𝑇𝑈𝑟 = 𝐼𝑟 (𝑈𝑟 è ortogonale), si ha che:

𝑦𝑗 = ∑ (𝐷(𝑉𝑟)𝑇)𝑘𝑗𝑈∙,𝑘 =𝑟𝑘=1

∑ ((𝑈𝑟)𝑇𝑈𝑟𝐷(𝑉𝑟)𝑇)𝑘𝑗𝑈∙,𝑘 =𝑟𝑘=1 ∑ ((𝑈𝑟)𝑇𝑈𝑟𝐷(𝑉𝑟)𝑇)𝑘𝑗𝑈∙,𝑘 =𝑟

𝑘=1

∑ ((𝑈𝑟)𝑇𝑌)𝑘𝑗𝑈∙,𝑘 =𝑟𝑘=1 ∑ (𝑦𝑗 , 𝜙𝑘)

ℝ𝑚𝜙𝑘𝑟𝑘=1

Quindi

𝑦𝑗 = ∑(𝑦𝑗 , 𝜙𝑘)ℝ𝑚𝜙𝑘

𝑟

𝑘=1

(7)

Formuliamo ora il problema della POD. Si vuol trovare la base {𝜙𝑗}𝑗=1

𝑟 tale che l’errore

di approssimazione di ogni vettore 𝑦𝑖 ∈ ℝ𝑚 con la sua proiezione sui vettori

{𝜙𝑗}𝑗=1

𝑟sia minimizzato. Se consideriamo il caso di 𝑟 = 1 il problema è formulato nel

seguente modo:

𝑚𝑎𝑥 {∑|(𝑦𝑖 , �̃�)|2

, ϕ̃ ∈ ℝ𝑚: ‖�̃�‖ℝ𝑚

2𝑛

𝑖=1

= 1}

(P1)

𝑃1 è un problema di ottimizzazione vincolato che può essere risolto con il metodo dei

moltiplicatori di Lagrange. Qui (∙,∙) identifica il prodotto scalare in ℝ𝑚 e ‖∙‖ℝ𝑚 indica

la norma euclidea in ℝ𝑚. Introducendo la funzione 𝑒: ℝ𝑚 → ℝ definita

𝑒(𝜙) = 1 − ‖𝜙‖2, 𝜙 ∈ ℝ𝑚 (8)

il vincolo del problema 𝑃1 può essere espresso come 𝑒(𝜙) = 0. Da notare come

∇𝑒(𝜙) = −2𝜙, che è diverso da zero per ogni 𝜙 tale che 𝑒(𝜙) = 0, quindi la nostra

soluzione ottima è un punto regolare per il vincolo del problema 𝑃1. Sia ora

𝐿: ℝ𝑚 × ℝ → ℝ la lagrangiana associata al problema 𝑃1:

𝐿(𝜙, 𝜈) = ∑|(𝑦𝑖 , 𝜙)|2 +

𝑛

𝑖=1

𝜈(1 − ‖𝜙‖2)

(9)

Sia 𝜙 un ottimo locale del problema 𝑃1. Essendo 𝜙 un punto regolare per il vincolo

𝑒(𝜙) = 0 allora esiste un unico moltiplicare di Lagrange 𝜈 tale che ∇𝐿(𝜙, 𝜈) = 0.

Calcolando il gradiente di 𝐿 rispetto a 𝜙 si ottiene:

𝜕𝐿

𝜕𝜙𝑖

(𝜙, 𝜈) =𝜕

𝜕𝜙𝑖(∑ |∑ 𝑌𝑘𝑖𝜙𝑘

𝑚

𝑘=1

|

2

+ 𝜈(1 − ∑ 𝜙𝑘2)

𝑚

𝑘=1

𝑛

𝑗=1

) =

= 2 ∑ (∑ 𝑌𝑘𝑗𝜙𝑘𝑌𝑖𝑗

𝑚

𝑘=1

)

𝑛

𝑗=1

− 2𝜈𝜙𝑖 = 2(𝑌𝑌𝑇𝜙)𝑖 − 2𝜈𝜙𝑖

Quindi la soluzione 𝜙 del problema 𝑃1 risolve il problema agli autovalori

𝑌𝑌𝑇𝜙 = 𝜈𝜙

(10)

In più il valore della funzione obiettivo valutata in 𝜙 è uguale all’autovalore associato

in equazione 10. Prendendo il massimo degli autovalori della matrice 𝑌𝑌𝑇(che è

semidefinita positiva) si può dimostrare che questo è anche il massimo assunto dalla

funzione obiettivo del problema 𝑃1 e tale autovalore coincide con il valore singolare

più alto della matrice 𝑌. La soluzione quindi del problema 𝑃1 è il vettore singolare

sinistro associato al valore singolare più grande.

Questi ragionamenti possono essere estesi nel caso in cui non si cerchi un solo vettore

�̃� che massimizzi il problema 𝑃1 ma 𝑙 vettori 𝜙1, 𝜙2, … , 𝜙𝑙 tale che massimizzino il

problema 𝑃2 qui esposto:

𝑚𝑎𝑥 {∑ ∑|(𝑦𝑖 , 𝜙𝑘)|2

𝑛

𝑖=1

𝑙

𝑘=1

, (𝜙𝑝, 𝜙𝑞) = 𝛿𝑝𝑞 ∀𝑝, 𝑞: 1 ≤ 𝑝, 𝑞 ≤ 𝑙}

(P2)

La soluzione in questo caso è composta dai vettori che costituiscono le prime 𝑙 colonne

della matrice dei vettori singolari sinistri. In tale soluzione il valore del funzionale è

∑ 𝜎𝑖𝑙𝑖=1 . Un valore estremamente importante è la somma dei valori associati ai vettori

singolari sinistri che non sono usati nella creazione del sottospazio. Infatti tale valori

equivale all’errore commesso proiettando i vettori {𝑦𝑖}𝑖=1𝑛 nel sottospazio generato dai

vettori {𝜙𝑘}𝑘=1𝑙 . Quindi la POD consiste nel risolvere il problema agli autovalori della

matrice 𝑌𝑌𝑇 e troncare da un certo punto in poi i valori singolari della matrice 𝑌.

In genere però in molte applicazioni può succedere che il numero di gradi di liberta 𝑚

dei vettori 𝑦𝑖 sia di molto inferiore (diversi ordini di grandezza) del numero 𝑛 di vettori

𝑦𝑖 disponibili. In tal caso la matrice 𝑌𝑌𝑇 ∈ ℝ𝑚×𝑚 può essere estremamente grande.

Per poter risolvere il problema della POD però può essere sfruttata la matrice

𝑌𝑇𝑌 ∈ ℝ𝑛×𝑛, molto più piccola della precedente. L’idea è calcolare gli autovettori e

gli autovalori della matrice 𝑌𝑇𝑌. Infatti se 𝜓𝑖 è l’autovettore associato all’autovalore

𝜆𝑖, quindi

𝑌𝑇𝑌𝜓𝑖 = 𝜆𝑖𝜓𝑖

Allora

𝜙𝑖 =1

√𝜆𝑖

𝑌𝜓𝑖 , ∀ 𝑖: 1 ≤ 𝑖 ≤ 𝑙

Infatti se 𝜓𝑖 è un autovettore della matrice 𝑌𝑇𝑌 allora:

𝑌𝑇𝑌𝜓𝑖 = 𝜆𝑖𝜓𝑖 → (𝑌𝑌𝑇)𝑌𝜓𝑖 = 𝜆𝑖𝑌𝜓𝑖

Quindi 𝑌𝜓𝑖è autovettore della matrice 𝑌𝑌𝑇. Il fattore 1

√𝜆𝑖 è una normalizzazione.

2 Applicazione

La POD è stata sfruttata per risolvere un problema minima compliance, un problema

di ottimizzazione topologica, che ha l’obiettivo di costruire la più rigida struttura

utilizzando una quantità limitata di materiale. Per risolvere il problema di

ottimizzazione è stato utilizzato il S.I.M.P (Solid Isotropic Material with Penalization),

un metodo che introduce una appropriata funzione di densità per descrivere la

soluzione ottima.

In particolare, dato un corpo Ω ⊂ ℝdim (𝑑𝑖𝑚 = 2,3) con una forza 𝑓 applicata su Γ𝑁 ⊂

𝜕Ω, l’obiettivo è calcolare il sottoinsieme Ω𝑚𝑎𝑡 ⊂ Ω che minimizza il lavoro delle

forze esterne ∫ 𝑓 ∙ �⃗⃗�ΓN

𝑑𝛾 con �⃗⃗� il campo di spostamento.

2.1 Problema elastico

Qui è presentato il problema elastico per un materiale con coefficiente di Poisson 𝜇 e

modulo di Young 𝐸. Sia Ω un dominio, Γ𝐷 ⊂ 𝜕Ω la porzione del bordo in cui è fissato

uno spostamento, Γ𝑁 ⊂ 𝜕Ω la porzione del bordo in cui è imposto il carico 𝑓 e Γ𝐹 =

𝜕Ω\(Γ𝐷 ∪ Γ𝑁). Il problema dell’equilibrio elasto-statico consiste nel trovare il campo

di spostamento �⃗⃗� tale che:

{

−∇∙σ(�⃗⃗⃗�)=0 𝑖𝑛 Ω𝑢=0 𝑖𝑛 Γ𝐷

σ(�⃗⃗⃗�)�⃗⃗�=𝑓 𝑖𝑛 Γ𝑁

σ(�⃗⃗⃗�)�⃗⃗�=0 𝑖𝑛 Γ𝐹

(11)

Con �⃗⃗� il vettore unitario uscente ortogonale a 𝜕Ω e 𝜎 il tensore di stress. Con l’ipotesi

di piccoli spostamenti il tensore 𝜎 nella teoria elastica è:

𝜎(�⃗⃗�) = 2𝜇𝜖(�⃗⃗�) + 𝜆 𝑡𝑟(𝜖(�⃗⃗�))𝐼 (12)

con i coefficienti di Lamè definiti come:

𝜆 =𝐸𝜈

(1+𝜈)(1−𝜈) e 𝜇 =

𝐸

2(1+𝜈)

𝜖(�⃗⃗�) definito come:

𝜖(�⃗⃗�) =∇�⃗⃗� + ∇�⃗⃗�𝑇

2

ed 𝐼 il tensore identità. In accordo con la legge di Hook lo stress il tensore di stress può

essere scritto come

𝜎(�⃗⃗�) = 𝐸0𝜖(�⃗⃗�) (13)

𝐸0 è detto tensore di elasticità e dipende dalle proprietà del materiale 𝜆 e 𝜇.

2.2 Ottimizzazione topologica

Per inserire nel problema 11 le informazioni della struttura del dominio, oltre a quelle

del materiale, si definisce il tensore

𝐸𝑚𝑎𝑡 = 𝜒𝑚𝑎𝑡(𝑥)𝐸0 (14)

con 𝜒𝑚𝑎𝑡(𝑥) la funzione caratteristica del sottoinsieme Ω𝑚𝑎𝑡 ⊂ Ω definita:

𝜒𝑚𝑎𝑡(𝑥) = {1 𝑥 ∈ Ω𝑚𝑎𝑡

0 𝑥 ∉ Ω𝑚𝑎𝑡 (15)

in questo caso ogni dominio ottimo Ω𝑚𝑎𝑡sarà identificato univocamente dalla sua

funzione caratteristica 𝜒𝑚𝑎𝑡. Con l’introduzione del tensore 𝐸𝑚𝑎𝑡 è possibile ridefinire

il tensore 𝜎 come:

𝜎𝑚𝑎𝑡(�⃗⃗�) = 𝐸𝑚𝑎𝑡𝜖(�⃗⃗�) (16)

La formulazione debole quindi del problema (11), con all’interno anche la struttura del

dominio definita da (15) è: trovare �⃗⃗� ∈ 𝑈 tale che

𝑎(�⃗⃗�, �⃗�) = 𝑙(�⃗�) ∀�⃗� ∈ 𝑈 (17)

con

𝑎(�⃗⃗�, �⃗�) = ∫ 𝜎𝑚𝑎𝑡(�⃗⃗�): 𝜖(�⃗�)𝑑ΩΩ

(18)

𝑙(�⃗⃗�) = ∫ 𝑓 ∙ �⃗⃗�Γ𝑁

𝑑𝛾 (19)

con 𝑓definita come in (11), �⃗� funzione test e

𝑈 = {�⃗⃗� ∈ [𝐻1(Ω)]𝑑𝑖𝑚, 𝑑 = 2,3 ∶ �⃗⃗� = 0 𝑠𝑢 Γ𝐷} (20)

Il problema di minima compliance è quindi definito: trovare Ω𝑚𝑎𝑡 ⊂ Ω tale che

{

min(𝑙(�⃗⃗�)) 𝑐𝑜𝑛 �⃗⃗�(𝐸𝑚𝑎𝑡) ∈ 𝑈

𝑎(�⃗⃗�, �⃗�) = 𝑙(�⃗�) ∀�⃗� ∈ 𝑈

∫ 𝜒𝑚𝑎𝑡𝑑Ω = 𝑉𝑜𝑙(Ω𝑚𝑎𝑡) ≤ 𝛼𝑉0Ω

(21)

𝛼 è detto volume fraction ed è compreso nell’intervallo (0,1), 𝑉0 è il volume della

struttura iniziale. In genere la funzione binaria 𝜒𝑚𝑎𝑡 viene sostituita da una funzione

𝜌: Ω → [0,1]. Il tensore elastico quindi diventa

𝐸(𝑥) = ℎ(𝜌(𝑥))𝐸0 (22)

𝜌 è considerata una densità, nel senso che ∫ 𝜌𝑑ΩΩ

è uguale al volume della struttura.

Nel modello S.I.M.P si ha

ℎ(𝜌(𝑥)) = 𝜌𝑝 (23)

con 𝑝 > {2

1−𝜈,

4

1+𝜈}. In questo modo valori di 𝑝 ≠ {0,1} vengono penalizzati dal

modello poiché contribuiscono all’integrale ∫ 𝜌𝑑ΩΩ

non fornendo però rigidezza alla

struttura. Il problema (21) quindi diventa: trova 𝜌: Ω → [0,1] ∈ 𝐿∞ tale che

{

min(𝑙(�⃗⃗�)) 𝑐𝑜𝑛 �⃗⃗�(𝜌) ∈ 𝑈

𝑎𝜌(�⃗⃗�, �⃗�) = 𝑙(�⃗�) ∀�⃗� ∈ 𝑈

∫ 𝜌𝑑Ω = 𝑉𝑜𝑙(Ω𝑚𝑎𝑡) ≤ 𝛼𝑉0Ω 𝑐𝑜𝑛 𝜌min ≤ 𝜌 ≤ 𝜌

(24)

2.3 Algoritmo di ottimizzazione

Un approccio per risolvere il problema di ottimizzazione è:

Imposta una funzione di densità iniziale

While (criterio di converegenza non verificato)

Calcola lo spostamento con la densità in memoria;

Aggiorna la densità con un algoritmo di ottimizzazione;

end

L’ottimizzazione è stata svolta con la libreria NLopt (Versione 2.4.2). La proiezione

nel sottospazio costruito dalla POD viene utilizzata nel calcolo dello spostamento con

l’attuale funzione di densità. Definendo Ωℎ = {𝐾𝑗} una partizione del dominio Ω, si

definisce lo spazio 𝑋ℎ1 come:

𝑋ℎ1 = {𝑣ℎ ∈ 𝐶0(Ω̅): 𝑣ℎ|𝐾𝑗

∈ 𝑃1(𝐾𝑗) ∀ 𝐾𝑗 ∈ Ωℎ} (25)

e lo spazio 𝑉ℎ ⊂ 𝑉 lo spazio finito dimensionale degli spostamenti ammissibili come:

𝑉ℎ = {𝑣ℎ ∈ [𝑋ℎ1]𝑑𝑖𝑚: 𝑣ℎ = 0 𝑠𝑢 Γ𝐷} (26)

lo spostamento numerico all’iterazione 𝑖 del ciclo �⃗⃗�𝑛𝑢𝑚,𝑖 è soluzione del problema

𝐴�⃗⃗�𝑛𝑢𝑚,𝑖 = �⃗� (27)

con 𝐴 matrice il cui generico elemento (𝑖, 𝑗)è definito come

𝐴𝑖𝑗 = 𝑎(𝜙𝑖⃗⃗ ⃗⃗ , �⃗⃗�𝑗) (28)

e �⃗� vettore il cui generico elemento 𝑖 è definito

�⃗�𝑖 = 𝑙(�⃗⃗�𝑗) (29)

con �⃗⃗�𝑗 elemento della base 𝑉ℎ. Se la dimensione di 𝑋ℎ1 è 𝑁𝑒, la matrice

𝐴 ∈ ℝ𝑑𝑖𝑚∙𝑁𝑒×𝑑𝑖𝑚∙𝑁𝑒 ed �⃗� ∈ ℝ𝑑𝑖𝑚∙𝑁𝑒. Nella iterazione dell’algoritmo di ottimizzazione

non viene risolto il sistema (27), ma viene risolto una opportuna proiezione del sistema

(27) attraverso una matrice 𝑃 ∈ ℝ(𝑑𝑖𝑚∙𝑁𝑒)×𝑟, con 𝑟 ≪ 𝑑𝑖𝑚 ∙ 𝑁𝑒 ricavata dalla

decomposizione di Tucker in equazione (17). In questo caso viene risolto il sistema

𝑃𝑇𝐴𝑃�⃗⃗�𝑟𝑖𝑑,𝑖 = 𝑃𝑇�⃗� (30)

La matrice di cui viene svolta la SVD è la matrice 𝑼 i cui vettori sono gli spostamenti

ottimi 𝑢𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑜(𝑖)

della configurazione con volume fraction 𝛼𝑖. 𝑢𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑜(𝑖)

è il

campo di spostamento ottenuto con la densità ottima.

3 Implementazione

3.1 Librerie utilizzate e classe ElasticProblemSolver

Le librerie utilizzate sono 3:

• fenics/2016.1.0 per la discretizzazione del problema 17

• Eigen/3.2.8 per il calcolo dello spostamento 𝑢𝑛𝑢𝑚,𝑖 ad ogni iterazione di

ottimizzazione e per il calcolo della SVD (necessaria per la POD).

• NLopt/2.4.2 per l’ottimizzazione.

• Paraview versione 5.4.1 per la visualizzazione dei risultati.

A queste librerie si aggiunge una classe ElasticProblemSolver, creata da Leonardo

Locatelli e Francesco Clerici, e da me modificata per utilizzare le matrici sparse ed il

solver di Eigen e la POD. La classe contiene gli attributi necessari per la

discretizzazione del problema 28:

• Costanti fisiche: 𝜇 e 𝜆

• Vincoli: condizioni al bordo di Dirichlet e volume fraction imposta

• Discretizzazioni: spazi funzionali e mesh e vettori singolari sinistri per la POD

• Soluzioni: �⃗⃗�𝑛𝑢𝑚 e 𝜌𝑛𝑢𝑚

I principali metodi della classe sono:

• Un solver ElasticProblemSolver::Solve(). Il solver calcola lo spostamento �⃗⃗�𝑛𝑢𝑚

senza la POD usando:

1. Costanti fisiche: 𝜇 e 𝜆

2. Condizione al bordo di Dirichlet

3. Gli spazi funzionali

4. La densità 𝜌𝑛𝑢𝑚

Per il calcolo della soluzione �⃗⃗�𝑛𝑢𝑚 viene usato il solver di Fenics.

• Un metodo ElasticProblemSolver::get_compl() per il calcolo della compliance

usando:

1. Costanti fisiche: 𝜇 e 𝜆

2. Le soluzioni numeriche del problema 28 𝜌𝑛𝑢𝑚 e �⃗⃗�𝑛𝑢𝑚

• Un solver ElasticProblemSolver::Solve_eigen(). Il solver calcola lo spostamento

�⃗⃗�𝑛𝑢𝑚 senza la POD usando:

5. Costanti fisiche: 𝜇 e 𝜆

6. Condizione al bordo di Dirichlet

7. Gli spazi funzionali

8. La densità 𝜌𝑛𝑢𝑚

Per il calcolo della soluzione �⃗⃗�𝑛𝑢𝑚 viene usato il solver di Eigen. Il metodo

utilizza la funzione solver_eigen_sparso del file funzioni.cpp

• ElasticProblemSolver::Solve_proiettato(). Il solver calcola lo spostamento

�⃗⃗�𝑛𝑢𝑚 con la POD usando:

1. Costanti fisiche: 𝜇 e 𝜆

2. Condizione al bordo di Dirichlet

3. Gli spazi funzionali

4. La densità 𝜌𝑛𝑢𝑚

5. I vettori singolari sinistri.

Per il calcolo della soluzione �⃗⃗�𝑛𝑢𝑚 viene usato il solver di Eigen. Il metodo utilizza la

funzione solver_eigen_proiettato del file funzioni.cpp. Nel file funzioni.cpp vengono

definite altre funzioni utili al progetto quali

• void lettura(int (&dimensioni)[2],Eigen::Matrix<double, Eigen::Dynamic,

Eigen::Dynamic> &matrice_spostamenti_online). La funzione legge da file i

dati necessari per la POD

• void stampa_dati(const Eigen::Matrix<double, Eigen::Dynamic,

Eigen::Dynamic> &matrice). La funzione stampa su file i dati necessari per la

POD

• void dolfin2eigen(const dolfin::Vector &vector_dolfin, Eigen::Matrix<double,

Eigen::Dynamic, 1> &vettore_eigen,const dolfin::Matrix

&matrice_dolfin,Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>

&matrice_eigen). La funzione è utilizzata per trasferire i dati da una matrice di

Dolfin ad una matrice di Eigen

• void dolfin2eigen_sparsa(const dolfin::Vector &vector_dolfin,

Eigen::Matrix<double, Eigen::Dynamic, 1> &vettore_eigen,const

dolfin::Matrix &matrice_dolfin,Eigen::SparseMatrix<double>

&matrice_eigen). La funzione fa la stessa cosa della funzione precedente ma la

funzione eigen che riceve i dati è una matrice sparsa. È stata utilizzata questa

funzione per sfruttare la struttura sparsa delle matrice di Dolfin generate.

• 3 funzioni, utilizzate per i metodi solver della classe ElasticProblemSolver

precedentemente citata:

a) void solver_eigen(dolfin::Function &u, const Eigen::Matrix<double,

Eigen::Dynamic, Eigen::Dynamic> &matrice, const

Eigen::Matrix<double, Eigen::Dynamic, 1> &vettore_destro). Solver

che usa le matrici dense di Eigen

b) void solver_eigen_sparso(dolfin::Function &u, const

Eigen::SparseMatrix<double> &matrice, const Eigen::Matrix<double,

Eigen::Dynamic, 1> &vettore_destro, const Eigen::MatrixXd

&vettori_singolari_sinistri). Solver che usa le matrici sparse di Eigen

c) void solver_eigen_proiettato(dolfin::Function &u, const

Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> &matrice,

const Eigen::Matrix<double, Eigen::Dynamic, 1> &vettore_destro,

const Eigen::MatrixXd &vettori_singolari_sinistri). Solver che usa la

POD

A questo file si aggiunge un file myfun.hh con le funzioni obiettivo utilizzate

nell’ottimizzazione.

3.2 Fase Offline e Fase Online

Il Progetto comprende una fase Offline ed una fase Online separate. La fase Offline è

stata utilizzata per generare le 𝑆 soluzioni ottime {𝑢𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑒(𝑖)

}𝑖=1𝑆 associate al

problema 24 con la volume fraction{𝛼𝑖}𝑖=1𝑆 . Le soluzioni ottime sono state calcolate

senza l’utilizzo della POD. Le {𝑢𝑛𝑢𝑚(𝑖)

}𝑖=1𝑆 calcolate vengono quindi stampate su un file

txt di nome “soluzione_spostamento.txt”. La fase Online invece prevede la lettura del

file “soluzione_spostamento.txt” e il calcolo di una nuova soluzione 𝑢𝑛𝑢𝑚𝑃𝑂𝐷 e 𝜌𝑃𝑂𝐷 per

un valore di valume fraction 𝛼𝑃𝑂𝐷 diverso dagli 𝑆 valori di volume fraction {𝛼𝑖}𝑖=1𝑆

utilizzati per risolvere il problema della fase Offline. 𝑢𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑜𝑃𝑂𝐷 e 𝜌𝑜𝑡𝑡𝑖𝑚𝑜

𝑃𝑂𝐷 sono

calcolati sfruttando la proiezione nel sottospazio generato dalla SVD della matrice le

cui colonne sono le soluzioni {𝑢𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑜(𝑖)

}𝑖=1𝑆 ad ogni iterazione del ciclo di

iterazione.

3.2.1 Fase Offline

Avviata l’esecuzione del codice verrà chiesto se si vuole procedere con la fase Offline

(premendo 0) o con la fase Online (premendo un qualsiasi altro numero). Avviata la

fase Offline verrà chiesto di inserire la volume fraction 𝛼𝑚𝑖𝑛𝑖𝑚𝑎, la volume fraction

𝛼𝑚𝑎𝑠𝑠𝑖𝑚𝑎 e per quante volume fraction si vuole avere la soluzione (il programma

quindi calcolerà la soluzione per quel numero di volume fraction uniformemente

distribuite tra 𝛼𝑚𝑖𝑛𝑖𝑚𝑎 e 𝛼𝑚𝑎𝑠𝑠𝑖𝑚𝑎)La fase Offline è stata eseguita calcolando gli

spostamenti {𝑢𝑛𝑢𝑚(𝑖)

}𝑖=130 per 30 configurazioni ottime con 𝛼𝑚𝑖𝑛𝑖𝑚𝑎 = 0.25 e

𝛼𝑚𝑎𝑠𝑠𝑖𝑚𝑎 = 0.627. I valori di volume fraction usati sono illustrati in Figura 1

Figura 1: Volume fraction usate per la fase Offline

All’inizio della fase Offline viene definito:

• il dominio da ottimizzare (un Cantilever, Figura 2)

• Le costanti Fisiche 𝐸 e 𝜈, usati per calcolare i coefficienti di Lamè 𝜇 e 𝜆 come

𝜆 =𝐸𝜈

(1+𝜈)(1−𝜈) , 𝜇 =

𝐸

2(1+𝜈)

• Gli spazi funzionali

• Le condizioni al bordo

• I valori di volume fraction {𝛼𝑖}𝑖=130 per i quali viene risolto il problema 24

Figura 2: Cantilever ottimizzato

Una volta definito il problema viene creato un oggetto della classe

ElasticProblemSolver. Per risolvere il problema di ottimizzazione viene creato un

oggetto della classe nlopt::opt. Tramite il costruttore della classe nlopt::opt può essere

scelto l’algoritmo di ottimizzazione. L’algoritmo usato è il “local optimization,

derivative/gradient-based (Method of Moving Asymptotes)”. Tramite il metodo

set_min_objective della classe nlopt::opt si imposta la funzione obiettivo, che nel

nostro caso è la compliance, tramite la funzione myvfunc. myvfunc riceve in ingresso

in input una funzione di densità ed il vincolo di volume fraction per il quale si sta

calcolando la configurazione ottima, calcola il campo di spostamento associato alla

funzione di densità in ingresso tramite il solver ElasticProblemSolver::Solve() e la

direzione di discesa tramite il metodo ElasticProblemSolver::get_grad_compl(); fatto

questo calcola il valore di compliance tramite il metodo

ElasticProblemSolver::get_compl() e lo ritorna. Si impone il vincolo sulla volume

fraction tramite il metodo della classe nlopt::opt add_inequality_constraint. Il risultato

dell’ottimizzazione si ottiene infine attraverso il metodo optimize della classe

nlopt::opt. Da notare come nella fase Offline si calcoli il campo di spostamento ad ogni

iterazione di ottimizzazione tramite il metodo ElasticProblemSolver::Solve(), che non

prevede l’uso della POD. L’ottimizzazione quindi è svolta per ogni valore di volume

fraction {𝛼𝑖}𝑖=1𝑆 e calcola la distribuzione di densità ottima 𝜌𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑎

(𝑖) associata a 𝛼𝑖;

attraverso poi il solver della classe ElasticProblemSolver si ricavare il campo di

spostamento 𝑢𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑜(𝑖)

associato a 𝜌𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑜(𝑖)

. Il campo di spostamento 𝑢𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑜(𝑖)

viene quindi stampato sul file “soluzione_spostamento.txt”

3.2.2 Fase Online

Nella fase Online vengono usate le informazioni raccolte nel file

“soluzione_spostamento.txt” dalla fase Offline. Nella fase Online verrà chiesto il

valore di Volume fraction 𝛼 per il quale voler fare l’ottimizzazione, e poi si passerà

alla lettura della file “soluzione_spostamento.txt”, i cui dati verranno salvati nella

matrice matrice_spostamenti_online, un oggetto della classe:

Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>

La matrice matrice_spostamenti_online avrà nella colonna 𝑖 il campo di spostamento

𝑢𝑛𝑢𝑚,𝑜𝑡𝑡𝑖𝑚𝑜(𝑖)

associato alla densità ottima 𝜌𝑖 calcolato con il valore di volume fraction

𝛼𝑖.

Per fare la SVD viene creato un oggetto 𝑠𝑣𝑑 della classe:

Eigen::JacobiSVD<Eigen::MatrixXd>

nel cui costruttore viene passato la matrice matrice_spostamenti_online. Per estrarre

poi la matrice dei vettori singolari sinistri si usa il metodo matrixU() della classe

Eigen::JacobiSVD<Eigen::MatrixXd>. I vettori singolari sinistri sono salvati

nell’oggetto vettori_singolari_sinistri della classe Eigen::MatrixXd. Il prossimo

passaggio è scegliere la dimensione del sottospazio nel quale si proietterà il sistema in

equazione 27. Per decidere la dimensione verrà stampata una tabella a schermo del tipo

Nella prima colonna della tabella vengono mostrati i valori singolari in ordine

decrescente. Nella seconda colonna viene mostrata la 𝑑𝑒𝑠𝑐𝑟𝑖𝑧𝑖𝑜𝑛𝑒 𝑑𝑖 𝑣𝑎𝑟𝑖𝑎𝑛𝑧𝑎. La

descrizione di varianza in riga 𝑗 è uguale alla somma dei primi 𝑗 valori singolari fratto

la somma totale. 1 − 𝑑𝑒𝑠𝑐𝑟𝑖𝑧𝑖𝑜𝑛𝑒 𝑑𝑖 𝑣𝑎𝑟𝑖𝑎𝑛𝑧𝑎 è uguale all’errore di proiezione delle

soluzione storiche nel sottospazio di dimensione 𝑗. Il valore in riga 𝑗 della terza colonna

indica la grandezza della dimensione dello spazio di proiezione per avere la

𝑑𝑒𝑠𝑐𝑟𝑖𝑧𝑖𝑜𝑛𝑒 𝑑𝑖 𝑣𝑎𝑟𝑖𝑎𝑛𝑧𝑎 nela riga 𝑗. Grazie alla tabella si può scegliere la dimensione

più appropriata per lo spazio di proiezione.

I passaggi successivi definiscono il problema da risolvere, come nel caso Offline:

• il dominio da ottimizzare (un Cantilever, Figura x1)

• Le costanti Fisiche 𝐸 e 𝜈, usati per calcolare i coefficienti di Lamè 𝜇 e 𝜆 come

𝜆 =𝐸𝜈

(1+𝜈)(1−𝜈) , 𝜇 =

𝐸

2(1+𝜈)

• Gli spazi funzionali

• Le condizioni al bordo

• Il valore di volume fraction 𝛼𝑖 per il quale si vuole risolvere il problema 24.

E si passa quindi a definire il problema di ottimizzazione tramite la classe nlopt::opt.

La funzione obiettivo in questo caso però non è descritta dalla funzione myvfunc

utilizzata nella fase Offline, ma dalla funzione myvfunc_proiettata. myvfunc_proiettata

è analoga a myvfunc ma calcola il campo di spostamento associato ad una funzione di

densità (ad ogni iterazione del ciclo di ottimizzazione) tramite il solver

ElasticProblemSolver::Solve_proiettato(). La soluzione di densità calcolata dopo il

ciclo di ottimizzazione è salvata nel file 3DOpt_online.pvd

4 Risultati In questa sezione verranno mostrati i risultati dell’ottimizzazione topologica con la

POD e paragonati, in termini di tempo e soluzione, con l’algoritmo di ottimizzazione

classico. Nell’algoritmo classico ad ogni iterazione 𝑖 di ottimizzazione viene

calcolato il campo di spostamento 𝑢𝑛𝑢𝑚,𝑖 tramite la risoluzione di un sistema lineare

con una matrice con 126630009 valori, 11253 righe e 11253 colonne, con 450459

elementi non nulli. In Figura 3 è mostrato il risultato con l’algoritmo di

ottimizzazione classico con un valore di volume fraction pari a 0.57. Il tempo di

calcolo è 4 minuti e 38 secondi, la risoluzione del sistema lineare ad ogni ciclo è di

0.02 secondi, con una Compliance del risultato finale pari a 0.153855

Figura 3

In figura 4 invece è mostrata la soluzione con l’algoritmo di ottimizzazione usando la

POD. La dimensione del sottospazio usata è di 30 vettori, la dimensione massima

disponibile con 30 soluzioni storiche, ed ad ogni iterazione il tempo impiegato per la

soluzione del sistema lineare per il calcolo dello spostamento 𝑢 è di 0.0005 secondi,

40 volte di meno del precedente. Il tempo di calcolo di calcolo totale è di 2 minuti e 7

secondi, e la compliance finale è 0.120192

Figura 4

In Figura 5 viene mostrato invece il caso di una ottimizzazione topologica con POD

usando però con una base di dimensione 15. Con una base di questa dimensione

l’errore, riferito alla proiezione delle soluzioni storiche in questo sottospazio, è meno

dello 0.5%. Il tempo di calcolo dello spostamento 𝑢 ad ogni iterazione è di 0.0002

secondi, circa la metà del caso con una dimensione dello spazio di proiezione di 30. Il

tempo di calcolo totale è di 1 minuto e 39 secondi, meno del precedente.

Figura 5

Pur avendo scelto una dimensione dello spazio di proiezione metà del primo caso i

risultati sono molto simili. Questo è dovuto al fatto da una dimensione pari a 15 ad una

pari a 30 si passa da un errore dello 0.5% ad uno dello 0%.

Con una dimensione del sottospazio pari a 5 l’errore di proiezione delle soluzioni

storiche in tale sottospazio è del 2%. Il tempo per risolvere il sistema lineare è un terzo

del caso in cui il sottospazio abbia dimensione 15 e il tempo di calcolo globale è di 1

minuto e 35 secondi. Il risultato è mostrato in Figura 6.

Figura 6

In Figura 7 invece è mostrato il caso con una dimensione del sottospazio pari ad 1.

L’errore di proiezione delle soluzioni storiche in tale sottospazio è del 5%, il tempo di

risoluzione del sistema lineare (equazione) è di 3 10−5 secondi e il tempo totale

dell’algoritmo è di 1 minuto e 7 secondi.

Figura 6

5 Conclusioni Nel progetto è stata introdotto la POD e il problema di ottimizzazione topologica a minima

compliance, è stato introdotto l’algoritmo implementato per poter usare la POD nel ciclo di

ottimizzazione per il calcolo dello spostamento 𝑢 e sono stati presentati i risultati. I risultati

hanno mostrato un calo del tempo di calcolo dell’ottimizzazione con POD rispetto a quello

classico, è una buona scalabilità al variare della dimensione del sottospazio. In particolare al

diminuire della dimensione si aveva un guadagno in tempo con una soluzione praticamente

identica al caso di dimensioni del sottospazio più alte. Questo è dovuto alla distribuzione del

valori dei valori singolari sinistri.

6 Creazione ambiente, Compilazione ed avvio Il progetto è stato testato ed i risultati sono stati prodotti su una macchina virtuale

VirtualBox. L’installazione del sistema operativo è:

• Installazione di vagrant e git

• Con git nella cartella lanciare “vagrant init centos/7”

• Lanciare “vagrant up”

• Apri il file C:\Users\{username}\.vagrant.d\boxes\centos-VAGRANTSLASH-

7\1611.01\virtualbox\Vagrantfile e lo modifichi in modo che compaia

config.vm.synced_folder ".", "/vagrant", type: "virtualbox"

• Lanciare “vagrant plugin install vagrant-vbguest” nella cartella del punto 2

• Lanciare “vagrant up”

• Lanciare “vagrant ssh”

• Installazione dei moduli con “curl -O "http://www1.mate.polimi.it/PACS/gcc5-

glibc.tgz" ”

• sudo tar xvzf gcc5-glibc.tgz -C /

cat - >> ~/.bashrc <<EOF

export mkPrefix=/u/sw

source \$mkPrefix/etc/profile

module load gcc-glibc/5 octave

EOF

La macchina virtuale è pronta. Per avviarla bisogna lanciare:

• vagrant up

• vagrant ssh

• source /u/sw/etc/profile

• module load gcc-glibc/5 octave

• module load fenics

Al primo avvio bisogna scaricare ed installare NLopt-2.4.2.tar.gz dal sito:

http://nlopt.readthedocs.io/en/latest/

Di default, libnlopt.so sarà installato in usr/local/lib e nlopt.h in /usr/local/include. Se

le cartelle sono diverse bisogna correggere il cmake inserito del progetto, nelle righe

• set(NLOPTINC /usr/local/include)

• set(NLOPTLIB /usr/local/lib)

Per la compilazione ed esecuzione lanciare

• cmake .

• make

• ./3Delasticty

L’output del programma è 3DOpt_online.pvd, da aprire con paraview.

IMPORTANTE: Nella cartella ci sono due file: soluzioni_spostamento.txt

e dimensioni.txt . Questi file contengono le informazioni delle 30 simulazioni offline.

Se si lancia una nuova fase offline vengono sovrascritti. Per evitare che succeda basta

rinominarli prima che si lanci una nuova fase offline, in questo modo nel caso si voglia

lanciare una fase online con le stesse soluzioni storiche di questo paper è sufficiente

rinominarli con il nome giusto.

7 References S. Volkwein: Proper Orthogonal Decomposition: Theory and Reduced-Order

Modelling

M.P. Bendsoe, O. Sigmund: Topology optimization Theory, Methods and

Applications