Elementi di Informatica e Applicazioni Numeriche T
Controllo degli Errori (Accenni)
Un Esempio
Un serbatoio a pressione atmosferica contiene un reagente chimico
Il reagente ha ρ=1.189×103 e μ=2.10×10−3
Il livello del serbatoio è di 2m di reagente
Il serbatoio scarica il reagente attraverso una condotta
La condotta è lunga 30m e scende di 1m complessivamente
La condotta ha un diametro di 5cm e scabrezza 2mm
Il serbatoio viene riempito di reagente nel tempo, secondo la legge:
Qin=0.002(1+sin(2πt240))
Un Esempio
In pratica, la portata in ingresso varia con un periodo di 240s
La portata massima in ingresso è di 2L/s
La portata mininima è nulla
Un Esempio
I dati del problema in sintesi:
Si determini il livello del serbatoio nel tempo
Soluzione
Si tratta di un sistema dinamico tempo continuo
Quindi possiamo modellarlo con una EDO...
...E per prime cosa dobbiamo scegliere come modellare lo stato
Una possibilità: H= volume del reagente
Con questa scelta, la derivata è data da:
dH=Qin−Qout
Dove Qout è la portata in uscita lungo la condotta
Soluzione
Per calcolare Qout, codifichiamo l'equazione di Bernoulli...
functionz = bernoulli(Q, h1)
...
v = hspeed(Q, D);
H12 = z1 + h1 - v.^2 ./ (2.*g);
nu = mu ./ rho;
Re = Reynolds(v, D, nu);
f = churchill(Re, es ./ D);
WD = loss_l(f, D, L, v, g);
WC = loss_k(k, v, g);
z = H12 - WD - WC;
end
Il codice intero è disponibile sul sito del corso
Soluzione
...Poi determiniamo il valore della portata con il metodo di Newton:
functionQ = Qout_computation(h1)% Definisco una funzione da usare con fsolve
f = @(Q) ( bernoulli(Q, h1) );
% Determino la portata
Q = fsolve(f, 0.001);
end
ATTENZIONE: non è detto che il metodo di Newton converga!
Quando possibile, è bene controllare che non ci siano errori...
Controllo degli Errori in Octave
In Octave possiamo indicare la presenza di errori con:
error(MSG)
MSG è una stringa (un messaggio di errore)
La funzione:
Interrompe l'esecuzione
Stampa il messaggio di errore
Indica la riga in cui error è stata chiamata
Soluzione
Nel nostro caso, possiamo controllare il risultato con:
functionQ = Qout_computation(h1, tol = 1e-5)% Definisco la funzione da usare con fsolve
f = @(Q) ( bernoulli(Q, h1) );
% Determino la portata[Q, FVAL] = fsolve(f, 0.001);
ifabs(FVAL) > tol % Vero in caso di errori
error('Errore nel calcolo della portata')
endend
Se fsolve ha prolemi a convergere (e.g. h1 negativo)...
...Il nuovo codice segnala che c'è stato un problema!
Soluzione
Adesso che abbiamo Qout, possiamo calcolare dH
functiondH = dH_computation(H, t)
...
% Calcolo l'altezza del serbatoio
h1 = H ./ (pi .* r.^2);
% Calcolo Qout
Qout = Qout_computation(h1);
% Calcolo Qin
Qin = 0.002.*(1 + sin(2.* pi .* (t ./ 240)));
% Calcolo la derivata del volume di reagente
dH = -Qout + Qin;
end
Soluzione
Sempre per evitare errori, gestiamo il caso h1=0
functiondH = dH_computation(H, t, tol = 1e-5)
...
Qout = 0;
if h1 > tol
Qout = Qout_computation(h1);
end
...
end
Se non lo facciamo ed il serbatoio si svuota...
...l'equazione di Bernoulli fornisce ancora una portata non nulla!
Questo succede perché il serbatoio è rialzato
Soluzione
Per terminare l'esercizio dobbiamo solo risolvere una EDO
t = linspace(0, 480); % Intervallo di tempo
H0 = 2 .* (pi .* r.^2); % Volume iniziale
H = lsode(@dH_computation, H0, t);
% Trasformo il volume in livello
Hl = H ./ (pi .* r.^2);
% Disegno l'andamento
plot(t, Hl)
Soluzione
Ecco l'andamento per i primo 480 secondi:
Elementi di Informatica e Applicazioni Numeriche T
Inversione del Tempo e Stato Stazionario
Un Esempio
Supponiamo che il serbatoio dell'esercizio visto non sia alimentato
Quale deve essere il livello iniziale perché si svuoti in 300s?
Soluzione
È sufficiente invertire la direzione della variabile tempo
Quindi dobbiamo negare le derivate:
dH = +Q; % Era: dH = -Q (+ Qin)
Poi sostituire le occorrenze di t con tf−t
Nel nostro caso dH non dipende dal tempo
Quindi dobbiamo risolvere l'EDO:
t = linspace(0, 300);
H0 = 0;
H = lsode(@dH_computation, H0, t);
Soluzione
Se lo facciamo, otteniamo questo risultato:
Inversione del Tempo e Stato Stazionario
Perché il livello è piatto?
Perché siamo partiti da uno stato stazionario valido!
Allo stato stazionario la derivata è nulla
Soluzione:
Basta partire da un serbatoio "leggermente pieno":
t = linspace(0, 300);
H0 = tol; % Es. tol = 1e-4
H = lsode(@dH_computation, H0, t);
Soluzione
Ecco la nuova soluzione:
Elementi di Informatica e Applicazioni Numeriche T
Equazioni Non Lineari e Problemi di Progettazione
Un Esempio
Consideriamo il serbatoio del caso precedente...
...Ma assumiamo che il serbatoio non sia alimentato
Supponiamo che il reagente sia pericoloso:
La condotta è normalmente chiusa (alla bocca)...
...In caso di problemi, viene aperta e deve svuotare il serbatoio
HP: il serbatoio si considera vuoto anche se la condotta non lo è
Problema:
Quale deve essere il diametro della condotta...
...Per svuotare il serbatoio in 60 secondi?
Problemi di Progettazione
Questo tipo di problema si può ridurre ad una equazione
Supponiamo di avere una funzione F(D) che:
Dato un valore per il diametro D...
...Denota il livello del serbatoio dopo 60s
Allora, il nostro problema si riduce a risolvere:
F(D)=0
F(D) non può essere espressa con una formula analitica...
...Ma non importa! Ci basta saperla calcolare
Soluzione
La nostra funzione dovrà avere più o meno questa struttura:
functionH60 = H_in_60_sec(D)
...
t = linspace(0, 60); % 60 secondi bastano
H0 = 2 .* (pi .* r.^2);
f = @(H, t) (...); % Funzione per calcolare dH
H = lsode(f, H0, t);
% Restituisco il volume dopo 60 secondi
H60 = H(end);
end
Internamente, risolviamo una equazione differenziale!
È semplicemente il nostro modo per calcolare il livello dopo 60m
Dobbiamo capire come calcolare dH, però...
Soluzione
Per calcolare dH, modifichiamo la funzione dell'esercizio 1:
functiondH = dH_computation(H, t, D)
...
h1 = H ./ (pi .* r.^2);
Qout = ... % Qout dipende anche da D!
Qin = 0.002.*(1 + sin(2.* pi .* (t ./ 240)));
dH = Qout + Qin;
end
E nella funzione H_in_60_sec, avremo:
f = @(H, t) dH_computation(H, t, D);
Adesso dobbiamo solo poter calcolare Qout...
Soluzione
Per calcolare Qout, modifichiamo la funzione dell'esercizio 1:
functionQ = Qout_computation(h1, D, tol=1e-5)
f = @(Q) ( ... ); % Questa dipenderà da D![Q, FVAL] = fsolve(f, 0.001);
ifabs(FVAL) > tol
error('Errore nel calcolo della portata')
endend
E nella funzione dH_computation, avremo:
Qout = Qout_computation(h1, D);
A questo punto ci manca solo l'equazione di Bernoulli...
Soluzione
Ora dobbiamo solo modificare un'ultima funzione dell'esercizio 1:
functionz = bernoulli(Q, h1, D)% Il codice è invariato!end
Nella funzione Qout_computation, avremo:
f = @(Q) bernoulli(Q, h1, D);
A questo punto possiamo risolvere il problema con:
D = fsolve(H_in_60_sec, 0.05)
Ma non funziona. Perché?
Soluzione
Vediamo come varia il livello a 60s in funzione di D
Soluzione
Il metodo di Newton non può procedere...
...Se visita un valore di D dove F′(D)=0
Nel nostro caso ci sono molti punti in cui F(D) è "piatta"
Soluzione:
Facciamo sì che quando il livello è 0, H60 sia leggermente negativo:
H60 = H(end) - 1e-5;
E poi usiamo un metodo "tipo bisezione"!
D = fzero(H_in_60_sec, [0.05, 0.30])
Elementi di Informatica e Applicazioni Numeriche T
Interpolazione con Vincoli
Un Esempio
Nostro nipote ci ha chiesto di costruire una pista per le macchinine:
La pista deve essere lineare, ma può andare in salita e discesa
La quota iniziale deve essere di 50cm
Dopo 40cm, la quota deve essere di 40cm
La pista termina dopo 1m ad una quota di 45cm
La pendenza iniziale deve essere di −2cm per cm
La pendenza finale deve essere di +1cm per cm
Determinare la forma della pista utilizzando una curva polinomiale
Evidentemente si tratta di un nipotino esigente :-)
Un Esempio
Ecco i dati del problema in sintesi:
Problemi di Interpolazione Vincolati
Si tratta di un problema di interpolazione "vincolato"...
...E si risolve più o meno nello stesso modo!
Proviamo a formalizzare cosa sappiamo del problema:
Quindi per ottenere la lunghezza, ci basta calcolare:
L_{a,b} = \int_{a}^{b} \sqrt{1 + f'(x)^2} dx
Nel nostro esempio:
p = % coefficienti del polinomio
pp = polyder(p);
phip = @(x) polyval(pp, x); % derivata della curva% Definisco la funzione da integrare
ddist = @(x) sqrt(1 + phip(x).^2);
% Integro tra i due estremi
L = quadv(ddist, x0, x2)
Elementi di Informatica e Applicazioni Numeriche T
Controllo degli Errori (Accenni)