%---------------------------------------------------- % Calcoli di Processo dell'Ingegneria Chimica % Davide Manca % 01-Dec-2003 22:32:12 % 29-Nov-2004 11:25:52 %----------------------------------------------------
La banca dati DIPPR riporta i seguenti dati per la pressione di vapore dell'acqua: For WATER The Vapor Pressure can be calculated as follows: VP in Pa = exp(A + B/T + C*ln(T) + D*T^E) Where: T = Temperature in Kelvin A = 7.3649E+01 B = -7.2582E+03 C = -7.3037E+00 D = 4.1653E-06 E = 2.0000E+00 In the range: 273.16 K to 647.13 K Range is experimental Quality code: 1Determinare, tramite metodo dicotomico, a quale temperatura si raggiunge una tensione di vapore pari a mezza atmosfera. Confrontare il risultato ottenuto con quello prodotto dalla funzione "fsolve" di Matlab dedicata alla risoluzione di sistemi di equazioni non lineari. Esempio di sintassi: [x,fval,exitFlag] = fsolve(@f,x0); Dove: f è la funzione da azzerare, x0 il valore di primo tentativo, x la soluzione, fval il valore della funzione in corrispondenza di x ed exitFlag l'indice di stato all'uscita di fsolve: > 0 se ha raggiunto la convergenza, = 0 se è stato raggiunto il numero massimo di iterazioni, < 0 se non è stata individuata la soluzione. N.B.: il simbolo @ prima del nome della funzione da azzerare rappresenta il puntatore a tale funzione.
clear all
clc
Le grandezze AA BB ... vengono contemporaneamente utilizzate nel presente script e nella funzione "funz" da azzerare. Il costrutto GLOBAL permette di NON passare via lista le costanti/variabili ad altre porzioni di codice. Si noti che le variabili/costanti sono separate da uno spazio. Le costanti/variabili presenti nel costrutto GLOBAL hanno lo stesso ordine nelle varie porzioni di codice in cui tale costrutto compare.
global AA BB CC DD EE PRESSIONE
Le costanti AA BB ... verranno utilizzate dalla funzione "funz"
AA = 7.3649E+01;
BB = -7.2582E+03;
CC = -7.3037E+00;
DD = 4.1653E-06;
EE = 2.0000E+00;
PRESSIONE = 0.5 * 101325.; % [Pa]
a = 283.15; % Estremo inferiore b = 373.15; % Estremo superiore epsi = 1.e-5; % Massimo intervallo di incertezza MAX_ITER = 30; % Fondamentale: per evitare loop infiniti iConto = 0; % Contatore iterazioni effettive fa = funz(a); fb = funz(b);
if sign(fa) * sign(fb) > 0 disp('Estremi del metodo dicotomico NON consistenti. Impossibile continuare...'); return end
while abs(b-a) > epsi & iConto < MAX_ITER iConto = iConto + 1; c = a + 0.5 * (b-a); % formulazione robusta fc = funz(c); % FONDAMENTALE: si noti che ad ogni iterazione la funzione viene calcolata UNA SOLA volta if sign(fa) * sign(fc) < 0. b = c; fb = fc; % Si noti come venga usata una variabile ausiliaria evitando così un nuovo calcolo inutile della funzione else a = c; fa = fc; % Si noti come venga usata una variabile ausiliaria evitando così un nuovo calcolo inutile della funzione end disp([num2str(iConto),') c = ',num2str(c),' f(c) = ',num2str(fc),' delta = ',num2str(b-a)]); end
1) c = 328.15 f(c) = -34902.7672 delta = 45 2) c = 350.65 f(c) = -7886.3652 delta = 22.5 3) c = 361.9 f(c) = 16169.3852 delta = 11.25 4) c = 356.275 f(c) = 3021.643 delta = 5.625 5) c = 353.4625 f(c) = -2692.0573 delta = 2.8125 6) c = 354.8687 f(c) = 97.4146 delta = 1.4063 7) c = 354.1656 f(c) = -1313.8542 delta = 0.70313 8) c = 354.5172 f(c) = -612.3917 delta = 0.35156 9) c = 354.693 f(c) = -258.5364 delta = 0.17578 10) c = 354.7809 f(c) = -80.8235 delta = 0.087891 11) c = 354.8248 f(c) = 8.2298 delta = 0.043945 12) c = 354.8028 f(c) = -36.3133 delta = 0.021973 13) c = 354.8138 f(c) = -14.0458 delta = 0.010986 14) c = 354.8193 f(c) = -2.909 delta = 0.0054932 15) c = 354.8221 f(c) = 2.6601 delta = 0.0027466 16) c = 354.8207 f(c) = -0.12451 delta = 0.0013733 17) c = 354.8214 f(c) = 1.2678 delta = 0.00068665 18) c = 354.821 f(c) = 0.57164 delta = 0.00034332 19) c = 354.8209 f(c) = 0.22356 delta = 0.00017166 20) c = 354.8208 f(c) = 0.049523 delta = 8.5831e-005 21) c = 354.8207 f(c) = -0.037495 delta = 4.2915e-005 22) c = 354.8207 f(c) = 0.0060141 delta = 2.1458e-005 23) c = 354.8207 f(c) = -0.015741 delta = 1.0729e-005 24) c = 354.8207 f(c) = -0.0048632 delta = 5.3644e-006
disp(' '); disp(['Soluzione finale raggiunta dopo ',num2str(iConto),' iterazioni']); disp([' xSol = ',num2str(c),' = ',num2str(c-273.15),' ^C f(xSol) = ',num2str(fc)]); disp(' ');
Soluzione finale raggiunta dopo 24 iterazioni xSol = 354.8207 = 81.6707 ^C f(xSol) = -0.0048632
x0 = 50. + 273.15; [x,fval,exitFlag] = fsolve(@funz,x0); disp(['Soluzione con "fsolve" x = ',num2str(x),' f(x) = ',num2str(fval)]); disp(['Indice di uscita da fsolve: ',num2str(exitFlag),' (se maggiore di 0 vuol dire che ha raggiunto la convergenza !!!)']);
Optimization terminated: first-order optimality is less than options.TolFun. Soluzione con "fsolve" x = 354.8207 f(x) = 4.3656e-010 Indice di uscita da fsolve: 1 (se maggiore di 0 vuol dire che ha raggiunto la convergenza !!!)
Si noti la monotonia crescente di tale relazione
for i = 1: 100 T(i) = i + 273.15; P(i) = funz(T(i)) + PRESSIONE; % Dato che la funz(T) è pari alla differenza tra Pv(T) e PRESSIONE end plot(T,P,'r-o'),grid,xlabel('temperatura [K]'),ylabel('Pv(T) [Pa]'),title('Tensione di vapore dell''acqua');
Si noti l'utilizzo dei coefficienti necessari alla valutazione della tensione di vapore passati tramite istruzione GLOBAL
function f = funz(T) global AA BB CC DD EE PRESSIONE f = exp(AA + BB / T + CC * log(T) + DD * T ^ EE) - PRESSIONE;