• Non ci sono risultati.

Appendice B B.1. function analisi_aste_sumt.m

N/A
N/A
Protected

Academic year: 2021

Condividi "Appendice B B.1. function analisi_aste_sumt.m"

Copied!
30
0
0

Testo completo

(1)

Appendice B

B.1. function analisi_aste_sumt.m

% ANALISI STRUTTURALE DELLA VELA AL GENERICO PASSO DEL LOOP DI CALCOLO

% Il seguente file esegue varie operazioni: % 1) lettura dei nodi della griglia strutturale % 2) richiamo della function loads2.m

% 2.1 - lettura dei nodi della griglia aerodinamica

% 2.2 - costruzione della corrispondenza tra le coordinate dei punti di vela e vela_shadow

% 2.3 - calcolo delle forze nei nodi strutturali % 3) routine per il calcolo della deformata della vela % 4) salvataggio dati in un file dat

% 5) rappresentazione dello spostamento dei nodi della griglia strutturale

function analisi_aste_sumt % dichiarazioni: global choice_m global ind_vele global ind_loop global fid_loop global punto_scotta global choice_cc % introduzione scelte:

load scelte_folder; % input path_loop e path_folder

load(['scelte_opzioni_strutt',num2str(ind_vele)]); % INPUT: 'nlhs','nlvs',... % 'TolFun','TolSol','TolCon','TolGrad','Nitermax',... % 'TolAlfa','alfa_min','alfa_max','MaxFunEval','value_vedi',... % 'Nstar','Nrestart','rp0','rpmax','cgamma','choice_cc','choice_scotta','psc otta','limite'); gamma=cgamma; load(['scelte_Sinterp',num2str(ind_vele)]); % INPUT= 'k','path_out_igs','nLH_igs','nLV_igs'); load('scelte_start_loop'); % 'max_iter_loop','toll_def','toll_energia','toll_iso');

% lettura dei punti noti della vela:

load(['scelte_vela',num2str(ind_vele)]); % sigla_vela

path_load=[path_folder,'\ITER',num2str(ind_loop)];

% 1) ---DESIGNAZIONE DELLA GRIGLIA STRUTTURALE ---

% si crea una griglia strutturale con un numero di nodi qualunque. % La suddivisione della superficie in tratti equidistanti avviene % con la metodologia di interpolazione già vista.

(2)

ordineBS=k; nlv=nlvs; nlh=nlhs;

if ind_loop==1

% si genera la griglia strutturale dalla matrice della vela importata

xgriglia=load([path_load,'\x_',sigla_vela,'_it',num2str(ind_loop),'.dat']) ; ygriglia=load([path_load,'\y_',sigla_vela,'_it',num2str(ind_loop),'.dat']) ; zgriglia=load([path_load,'\z_',sigla_vela,'_it',num2str(ind_loop),'.dat']) ;

% griglia strutturale isou/isov

%[xgrigliaS,ygrigliaS,zgrigliaS]=crea_griglia_strutt(xgriglia,... % ygriglia,zgriglia,ordineBS,nlv,nlh); [xgrigliaS,ygrigliaS,zgrigliaS,message]=elabora_griglia_new(xgriglia,... ygriglia,zgriglia,toll_iso,nlv,nlh,k); elseif ind_loop>1

% si carica la griglia strutturale di partenza per la iterazione partendo

% dalla griglia deformata non iso-u/iso-v della iterazione precedente. % Questa e' trasformata nel file elabora2.m e salvata in iter(ind_loop) xgrigliaS=load([path_load,'\x_',sigla_vela,'_it',num2str(ind_loop),'_GSiso .dat']); ygrigliaS=load([path_load,'\y_',sigla_vela,'_it',num2str(ind_loop),'_GSiso .dat']); zgrigliaS=load([path_load,'\z_',sigla_vela,'_it',num2str(ind_loop),'_GSiso .dat']); end

% Tutti i nodi strutturali vengono salvati in x0:

% x0(:,:,ind linea verticale)=[xgriglia(indlv,:).' ygriglia(indlv,:).' zgriglia(indlv,:).'];

% NB: le matrici x-y-z-grigliaS sono state trasposte.

% Come si vede si ottengono tante matrici x0 quante sono le linee verticali. Esse sono

% ordinate dalla ralinga alla balumina, mentre al loro interno, ogni riga corrisponde

% alle coordinate (x,y,z) di un punto. I punti sono ordinati dalla base alla penna

for indlv=1:nlv % tutti i nodi strutturali

x0(:,:,indlv)=[xgrigliaS(indlv,:).' ygrigliaS(indlv,:).' zgrigliaS(indlv,:).'];

end

% 2) coordinate dei nodi interni (esclusione di quelli su base, ralinga, penna):

xx0 = x0(2:nlh-1,1:3,2:nlv); % xx0 è la matrice posizione iniziale nodi interni

(3)

% serve al calcolo delle lunghezze a riposo

% 3) punto di scotta: centro della sfera su cui si muove l'angolo di scotta

if choice_scotta==1

punto_scotta=[x0(1,:,nlv).';0]; % coincide con la bugna, che resta fissa

else % Lscotta=0

punto_scotta=pscotta; % Lscotta effettiva end

%--- % apertura file con storia di calcolo

fprintf(1,'\n ANALISI STRUTTURALE NEL FILE:

%s\\storia_calcolo_%s.txt\n\n',path_load,sigla_vela); fprintf(fid_loop,'\n ANALISI STRUTTURALE NEL FILE: %s\\storia_calcolo_%s.txt\n\n',path_load,sigla_vela);

fid_sc=fopen([path_load,'\storia_calcolo_',sigla_vela,'.txt'],'wt'); fprintf(fid_sc,' \t --- STORIA DI CALCOLO ---\n');

fprintf(fid_sc,'\n ITERAZIONE DEL LOOP DI CALCOLO PRINCIPALE: %2s\n\n',num2str(ind_loop));

fprintf(fid_sc,' griglia per il calcolo della deformata:\n'); fprintf(fid_sc,' linee orizzontali: %3d\n',nlh);

fprintf(fid_sc,' linee verticali : %3d\n',nlv);

fprintf(fid_sc,'\n VINCOLO GEOMETRICO DELLA VELA:\n'); if choice_cc==1

fprintf(fid_sc,' VELA TRIANGOLARE: RALINGA, BASE VINCOLATE:\n'); elseif choice_cc==2

fprintf(fid_sc,' VELA NON TRIANGOLARE: RALINGA, BASE VINCOLATE:\n'); elseif choice_cc==3

fprintf(fid_sc,' VELA TRIANGOLARE: RALINGA ED ANGOLO DI SCOTTA VINCOLATI:\n');

elseif choice_cc==4

fprintf(fid_sc,' VELA TRIANGOLARE: ANGOLI DI PENNA, MURA E SCOTTA VINCOLATI:\n');

end

fprintf(fid_sc,'\n VINCOLO GEOMETRICO PER L''ANGOLO DI SCOTTA:\n'); if choice_scotta==1

fprintf(fid_sc,' ANGOLO DI SCOTTA FISSO\n'); else

fprintf(fid_sc,' ANGOLO DI SCOTTA VINCOLATO A MUOVERSI SULLA SFERA CENTRATA NEL PUNTO DI SCOTTA\n');

fprintf(fid_sc,' COORDINATE DEL PUNTO DI SCOTTA IN ASSI BARCA E LUNGHEZZA SCOTTA:\n'); fprintf(fid_sc,' x= %5.3f (mm) y= %5.3f (mm) z= %5.3f (mm) Lscotta= %5.3f\n',... pscotta(1),pscotta(2),pscotta(3),pscotta(4)); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% -- RICHIAMO DELLA FUNCTION PER IL CALCOLO DEI CARICHI NODALI --

%si applica la funzione loads2.m per il calcolo delle forze nei nodi:

P=loads2(x0,nlh,nlv,limite); % function acquisizione carichi nodali % P= forze (N) nei nodi

% stampa dei carichi su file:

(4)

[rP,cP]=size(P);

fprintf(fid_sc,' CARICHI NEI NODI (N): \n'); fprintf(fid_sc,'\n'); stringaP=[]; for indc=1:cP stringaP=[stringaP,' %5.2f']; end stringaP=[stringaP,'\n']; for indrP=1:rP fprintf(fid_sc,stringaP,P(indrP,:)); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%---- CALCOLO COMPONENTI DEI VERSORI NORMALI ALLA SUPERF. NEI NODI ----

% calcolo e plot delle normali rispetto allo stato iniziale

[Nx,Ny,Nz]=surfnorm(xgrigliaS,ygrigliaS,zgrigliaS);

% significato Nx,Ny,Nz: componenti x delle normali alla vela nei nodi. % organizzazione Nx,Ny,Nz: colonna i-esima per linea orizz. i-esima

% organizzazione diversa delle componenti delle normali for ilv=1:nlv for ilh=1:nlh versnorm(ilh,1,ilv)=Nx(ilv,ilh); versnorm(ilh,2,ilv)=Ny(ilv,ilh); versnorm(ilh,3,ilv)=Nz(ilv,ilh); end end

% se la penna ha molteplicita' nlv si annullano le componenti della normale

if choice_cc~=2

versnorm(nlh,:,:)=0; end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% --- CALCOLO DELLA DEFORMATA ---

% blocco delle inizializzazioni

xold = x0; lancio =x0;

tempo_ini=cputime; % istante di inizio calcolo deformata

% TolFun :massima variazione funzione obiettivo originale (-1*lavoro)N*mm

% TolCon :massima violazione dei vincoli (mm)

% TolGrad :tolleranza sul gradiente della f_pseudo_obiettivo in xxnew finale (N)

% TolSol :tolleranza sulla soluzione xxnew finale (mm) % TolAlfa :tolleranza su alfa (vedi soluzione ricerca minimo monodimensonale)

% Nitermax :numero massimo iterazioni cicli 'for' interni

% Nstar :numero di volte consecutive, in cui accade che almeno un criterio

% di convergenza sia soddisfatto, mentre gli altri non lo sono.

% se Nstar>Nitermax equivale ad escluderlo

% Nrestart :num. iterazioni tra due RIAVVII del metodo per il calcolo del minimo

(5)

% stampa tolleranze su file

fprintf(fid_sc,'\n');

fprintf(fid_sc,' TOLLERANZE SCELTE:\n\n');

matrix_toll=str2mat([' TolFun = ',num2str(TolFun),' (N*mm)'],[' TolCon = ',num2str(TolCon),' (mm)'],...

[' TolGrad = ',num2str(TolGrad),' (N)'],[' TolSol = ',num2str(TolSol),' (mm)'],...

[' TolAlfa = ',num2str(TolAlfa)],[' max iter.= ',num2str(Nitermax)],...

[' NStar = ',num2str(Nstar)], [' Nrestart= ',num2str(Nrestart)]);

for indmt=1:8

fprintf(fid_sc,'%s\n',matrix_toll(indmt,:)); end

%--- % coeff. per l'aggiornamento della funzione Lagrangiana

% rpo : valore iniziale del coeff. per aggiornare i coeff. di Lagrange % rpmax : valore max di rp

% gamma : fattore per aggiornare rp con rp(i)=gamma*rp(i-1)

if isempty(rp0) % se non si fa nessuna scelta per errore rp0=0.4; % se pressione di INVIO senza scelta

end

%--- % stampa di rp su file

fprintf(fid_sc,' \n');

fprintf(fid_sc,' INITIAL PENALTY PARAMETER RP = %4.1f\n',rp0);

fprintf(fid_sc,' RP MASSIMO = %4.1g\n',rpmax);

fprintf(fid_sc,' COEFF. GAMMA PER L''AGGIORNAMENTO DI RP E LAMBDA = %4.1f\n',gamma);

% --- % --- RICERCA DEL MINIMO CONDIZIONATO ---

[xnew,lavoro_fe]=cerca_min_cond_sumt(lancio,x0,P,versnorm,nlh,nlv,TolFun,. .. TolCon,TolSol,TolGrad,TolAlfa,alfa_min,alfa_max,MaxFunEval,value_vedi,... Nitermax,rp0,rpmax,gamma,choice_m,Nstar,Nrestart,fid_sc); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for j=1:nlv for i= 1:nlh XNEW(i,j) = xnew(i,1,j); YNEW(i,j) = xnew(i,2,j); ZNEW(i,j) = xnew(i,3,j); end end

% matrici per l'interpolazione e la generazione del file IGES:

xgriglianew=XNEW.'; % nuova griglia per loop successivo ygriglianew=YNEW.'; % ogni riga è una linea verticale zgriglianew=ZNEW.'; % ogni colonna è una linea orizz.

(6)

% SPOSTAMENTI SECONDO X,Y,Z DEI SINGOLI NODI

delta_X=xgriglianew-xgrigliaS; delta_Y=ygriglianew-ygrigliaS; delta_Z=zgriglianew-zgrigliaS;

% matrice degli spostamenti dei nodi

spost=(delta_X.^2+delta_Y.^2+delta_Z.^2).^0.5; % massimo spostamento tra tutti i nodi

spost_max=max(max(spost)); % indice nodo

[nlv_nodo,nlh_nodo]=find(spost==spost_max);

% salvataggio matrici della nuova configurazione in file.dat path_save=[path_folder,'\ITER',num2str(ind_loop)];

nome_gsnew=[sigla_vela,'_it',num2str(ind_loop),'_GSnewnoiso.dat']; nome_delta=[sigla_vela,'_it',num2str(ind_loop),'.dat'];

if ind_loop==1

nome_gs=[sigla_vela,'_it',num2str(ind_loop),'_GSiso.dat']; % si salva la griglia strutturale isou/isov creata prima della deformazione

% alla iterazione 1 del loop

save([path_save,'\x_',nome_gs],'xgrigliaS','-ASCII','-DOUBLE'); save([path_save,'\y_',nome_gs],'ygrigliaS','-ASCII','-DOUBLE'); save([path_save,'\z_',nome_gs],'zgrigliaS','-ASCII','-DOUBLE'); end

% griglia strutturale dopo la deformazione e non iso-u/iso-v

save([path_save,'\x_',nome_gsnew],'xgriglianew','-ASCII','-DOUBLE'); save([path_save,'\y_',nome_gsnew],'ygriglianew','-ASCII','-DOUBLE'); save([path_save,'\z_',nome_gsnew],'zgriglianew','-ASCII','-DOUBLE');

% spostamenti dei nodi

save([path_save,'\deltaX_',nome_delta],'delta_X','-ASCII','-DOUBLE'); save([path_save,'\deltaY_',nome_delta],'delta_Y','-ASCII','-DOUBLE'); save([path_save,'\deltaZ_',nome_delta],'delta_Z','-ASCII','-DOUBLE');

% valori criteri di convergenza di loop energia=lavoro_fe;

save([path_save,'\criterio_',sigla_vela],'spost_max','energia');

% tangente al bordo di uscita.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% --- rappresentazione grafica ---

% SPOSTAMENTI SECONDO X,Y,Z DEI SINGOLI NODI

for ifigds=1:nlh figure

plot([1:nlv],delta_X(:,ifigds),'*r-',... [1:nlv],delta_Y(:,ifigds),'ob-',... [1:nlv],delta_Z(:,ifigds),'dg-');

strtitle=['Spostamenti dei nodi della linea orizzontale n°: ',... num2str(ifigds)];

title(strtitle);

legend('deltaX','deltaY','deltaZ'); xlabel('nodi');

(7)

end

% SEZIONI NEL PIANO (X,Y) -- prima e dopo la deformazione--

for ifigsez=1:nlh-1 % un grafico per ogni linea orizzontale, esclusa la penna

figure

plot(xgriglianew(:,ifigsez),ygriglianew(:,ifigsez),'*r-',... xgrigliaS(:,ifigsez),ygrigliaS(:,ifigsez),'ob-');

axis('equal');

strtitle=['Posizione dei nodi della linea orizzontale n°: ',... num2str(ifigsez)];

title(strtitle);

xlabel('ascissa X (mm)'); ylabel('ascissa Y (mm)');

legend('curva deformata','curva di partenza'); end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% --- PARTE FINALE DEL FILE STORIA_CALCOLO.TXT ---

fprintf(fid_sc,'\n SOLUZIONE X,Y,Z PER OGNI LINEA VERTICALE:\n\n');

for k = 1:nlv for i = 1:nlh fprintf(fid_sc,' %10.6f\t%10.6f\t%10.6f\n',xnew(i,1,k),... xnew(i,2,k),xnew(i,3,k)); end fprintf(fid_sc,'\n'); end

fprintf(fid_sc,'energia potenziale raggiunta (N*mm) = %6.2f\n\n',lavoro_fe);

fprintf(fid_sc,'spostamento massimo = %s (mm) per il nodo [linea vert.,linea orizz.]=[%s,%s]\n',...

num2str(spost_max),num2str(nlv_nodo),num2str(nlh_nodo)); tempo = tempo_fin - tempo_ini; % tempo di calcolo

fprintf(fid_sc,'tempo per la simulazione strutturale (min)= %6.2f\n',tempo/60);

status_sc = fclose(fid_sc); % chiusura file con risultati finali

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% ---- SCRITTURA FILE OUTPUT.TXT ---

% stampa su output.txt i risultati

% e le condizioni al contorno della simulazione

% apro in write per scrivere i ris.finali

fwri = fopen([path_load,'\output_',sigla_vela,'.txt'],'wt'); fprintf(fwri,'\n ITERAZIONE DEL LOOP DI CALCOLO PRINCIPALE: %2s\n\n',num2str(ind_loop));

fprintf(fwri,'MaxFunEval %6.2e TolSol %6.2e TolFun %6.2e TolCon %6.2e\n',...

Nitermax,TolSol,TolFun,TolCon);

fprintf(fwri,'\nrisultati simulazione(x,y,z per ogni linea verticale)\n');

for k = 1:nlv for i = 1:nlh

fprintf(fwri,'%10.6f\t%10.6f\t%10.6f\n',xnew(i,1,k),... xnew(i,2,k),xnew(i,3,k));

(8)

end

fprintf(fwri,'\n'); end

fprintf(fwri,'energia potenziale raggiunta = %20.3f\n\n',lavoro_fe);

% tempo = tempo_fin - tempo_ini; % tempo di calcolo fprintf(fwri,'tempo per la simulazione strutturale(min)= %20.3f\n',tempo/60);

status = fclose(fwri); % chiusura file con risultati finali %--- fprintf(1,'\n tempo per la simulazione strutturale (min): %4.1f\n',tempo/60); %su video

fprintf(fid_loop,' tempo per la simulazione strutturale (min): %4.1f\n',tempo/60); %su video

(9)

B.2. function loads2.m

% subroutine per l'acquisizione dei risultati CFD

% e per il calcolo del campo di forze nodali equivalenti

% COORDINATE DEI NODI DELLA MESH DI FLUENT PER VELA E VELA_SHADOW:

% Precedentemente si e' calcolata la pressione nei nodi delle % superfici VELA e VELA_SHADOW. I valori sono stati salvati in due % file di testo: tabella_vela.dat e tabella_velashad.dat.

% In essi compaiono:

% 1) una intestazione con il significato delle colonne di dati

% ( id nodo, x-nodo (m), y-nodo (m), z-nodo (m), pressione statica (Pa))

% 2) una linea vuota

% 3) 4 colonne di dati, separati dalla virgola o spazio (il carattere % di separazione si puo' scegliere durante la sessione di fluent % ed e' stato salvato nel file journal).

%

% Dopo aver letto i dati ed avere creato le rispettive matrici in matlab, % e' necessario ordinarli, perche' non sono scritti con lo stesso id e lo % lo stesso ordine. Questo rende non immediato assegnare allo stesso nodo % il valore di pressione relativo alla faccia sopravento e a quella

sottovento.

% Naturalmente ci interessa la differenza di pressione tra le due facce nei

% singoli nodi della mesh aerodinamica. %

% CRITERIO : anziche' integrare la pressione sull'area di influenza assegnata

% ad ogni nodo strutturale, si associa al pannellino un valore di pressione

% uniforme ed uguale a quello relativo al nodo della griglia di Fluent % piu' vicino al nodo della griglia strutturale.

%

% CRITERIO: il calcolo dell'area di influenza del nodo strutturale % e' sviluppato nel file "calcolo_area.m".

% NB: NELLA SIMULAZIONE CON FLUENT, la superficie vela_shadow viene creata % automaticamente. Fluent assegna a vela la superficie sottovento, a % vela_shadow quella sopravento.

% INPUT: x0 = matrice a 3 livelli di tutti i nodi e divisi per linea verticale

% nlh= numero linee orizzontali (iso-v) della vela % nlv= numero linee verticali (iso-u) della vela

% limite= numero massimo di righe dei file originali da conservare % OUTPUT

% forze_nodi = tabella delle FORZE dei nodi (nlh,nlv) in Newton % le righe sono relative a linee orizz. della griglia,

% le colonne a linee verticali

% NB: NON sono escluse la base e la penna % NON e' esclusa la ralinga

% nel caso della penna si rappresentano i contributi dei singoli spicchi % Il prodotto tra pressione ed area di influenza associati allo

% stesso nodo viene assunta come stima della forza agente sul nodo

function [forze_nodi]=loads2(x0,nlh,nlv,limite) global ind_loop

(10)

load scelte_folder; % % contiene path_loop e path_folder

load(['scelte_vela',num2str(ind_vele)]);% contiene le variabili: %('path_out_griglia','sigla_vela','corda_rif', %'altezza_rif','angolo_scotta','origine'); path_load=[path_folder,'\ITER',num2str(ind_loop)]; path_save=[path_folder,'\ITER',num2str(ind_loop)]; %--- % lettura dei dati di tabella_vela.dat ( faccia sottovento):

path_tabella=[path_load,'\tabella_',sigla_vela,'_it',num2str(ind_loop),'.d at'];

[datitab_vela]=limita_dati(path_tabella,limite); fprintf(1,'\n ACQUISIZIONE PRESSIONI SOTTOVENTO %s CONCLUSA\n',sigla_vela);

%--- nodes=length(datitab_vela(:,1)); % numero nodi

XYZ1=zeros(nodes,3);

% conversione da metri a mm

XYZ1 = 1000*[datitab_vela(:,2) datitab_vela(:,3) datitab_vela(:,4)]; press1=datitab_vela(:,5); % pressioni in 'Pa'

clear datitab_vela; % necessario per liberare memoria

%--- %--- % lettura dei dati di tabella_velashd.dat (faccia sopravento):

path_tabella_shad=[path_load,'\tabella_',sigla_vela,'_shad_it',num2str(ind _loop),'.dat'];

[datitab_velashd]=limita_dati(path_tabella_shad,limite); fprintf(1,'\n ACQUISIZIONE PRESSIONI SOPRAVENTO %s

CONCLUSA\n',sigla_vela);

%--- XYZ2=zeros(nodes,3);

% conversione da metri a mm

XYZ2 = 1000*[datitab_velashd(:,2) datitab_velashd(:,3) datitab_velashd(:,4)];

press2=datitab_velashd(:,5); % dati in Pa

clear datitab_velashd; % necessario per liberare memoria

%--- % si ordinano i dati di vela_shadow come quelli di vela:

for jc=1:(nodes-1) ind=jc; for inodo=ind:nodes if XYZ1(inodo,:) == XYZ2(ind,:) tempxyz=XYZ2(ind,:); temppress=press2(ind); XYZ2(ind,:)=XYZ2(inodo,:); press2(ind)=press2(inodo); XYZ2(inodo,:)=tempxyz; press2(inodo)=temppress; end end end %--- clear tempxyz temppress %---

% PRESSIONE sopravento - PRESSIONE sottovento press=(press2)-(press1);

% conteggio dei nodi CFD scarichi count=0;

for indp=1:nodes if press(indp)==0

count=count+1; % numero nodi scarichi end

(11)

%--- clear XYZ2 press1 press2

%--- XYZ=zeros((nodes-count),3); LOAD=zeros(nodes-count,1); index=0; for i=1:nodes if press(i)~=0 % modificato > in ~= index=index+1; XYZ(index,:)=XYZ1(i,:); LOAD(index)=press(i); end end %--- clear XYZ1 %--- disp(' ');

disp('acquisizione dati CFD completata'); disp(' ');

%--- % si acquisiscono i nodi del reticolo strutturale

% associando a ciascuno il nodo CFD più vicino % con il suo carico

for i=1:nlh for k=1:nlv

minima=norm(x0(i,:,k)-XYZ(1,:)); pos_min=1;

for m=2:index % per analizzare tutti e soli i nodi caricati dist=norm(x0(i,:,k)-XYZ(m,:)); if dist<minima pos_min=m; minima=dist; end end P(i,k)=LOAD(pos_min); end end %--- clear XYZ LOAD

%--- disp('tabella pressioni (Pa)'); disp(P); %--- % AREE DI INFLUENZA [D1,D2,D3]=size(x0); for ind=1:D3 xgriglia(ind,:)=x0(:,1,ind).'; ygriglia(ind,:)=x0(:,2,ind).'; zgriglia(ind,:)=x0(:,3,ind).'; end [area_vela,aree]=calcolo_area(xgriglia,ygriglia,zgriglia); %---

% FORZE NEI NODI for indh=1:nlh for indv=1:nlv

%(indh,indv) posizione del nodo nella griglia strutturale forze_nodi(indh,indv)=P(indh,indv).*aree(indh,indv);

end end

%--- % stampa dei risultati su schermo

disp('tabella aree di influenza (m^2)');

(12)

B.3. function calcolo_area.m

% 1) Si stima l'area della superficie della vela nel caso che % non sia nota. Questo dato interviene in fluent per la stima % dei coefficienti CL,CD,CM;

% 2) si calcolano le aree di influenza dei singoli nodi. Per il

% loro uso vedi il file loads2.m che legge le tabelle di pressione % esportate da fluent.

% INPUT : griglia X,Y,Z rappresentativa della vela % OUTPUT: area_vela = scalare in m^2

% aree = tabella (nlh,nlv) delle aree di influenza % ** prima riga : aree dei nodi della base

% ** ultima riga: area della penna esplosa in nlv % contributi

function [area_vela,aree]=calcolo_area(xgriglia,ygriglia,zgriglia)

%---

% matrice trasposta: prima riga = linea orizz. 1, ultima riga = penna % prima colonna = ralinga , ultima col. = balumina XT=xgriglia.';YT=ygriglia.';ZT=zgriglia.';

[nlh,nlv]=size(XT);

%--- % si inseriscono nlv-1 colonne con solo zeri

MVX=[];MVY=[];MVZ=[]; for ind=1:nlv-1 % MATRICE DELLE X MX1=[XT(:,ind),zeros(nlh,1)]; MVX=[MVX,MX1]; % MATRICE DELLE Y MY1=[YT(:,ind),zeros(nlh,1)]; MVY=[MVY,MY1]; % MATRICE DELLE Z MZ1=[ZT(:,ind),zeros(nlh,1)]; MVZ=[MVZ,MZ1]; end % ultima colonna MVX=[MVX,XT(:,nlv)]; MVY=[MVY,YT(:,nlv)]; MVZ=[MVZ,ZT(:,nlv)]; [nhparz,nvparz]=size(MVX);

% si inseriscono nlh-1 righe con solo zeri

MHX=[];MHY=[];MHZ=[]; for ind=1:nlh-1 % MATRICE DELLE X MX2=[MVX(ind,:);zeros(1,nvparz)]; MHX=[MHX;MX2]; % MATRICE DELLE Y MY2=[MVY(ind,:);zeros(1,nvparz)]; MHY=[MHY;MY2]; % MATRICE DELLE Z MZ2=[MVZ(ind,:);zeros(1,nvparz)]; MHZ=[MHZ;MZ2]; end % ultima riga MHX=[MHX;MVX(nlh,:)];

(13)

MHY=[MHY;MVY(nlh,:)]; MHZ=[MHZ;MVZ(nlh,:)];

%--- % MATRICE UNICA DELLE CORDINATE DI TUTTI I NODI X0(:,:,1)=MHX;

X0(:,:,2)=MHY; X0(:,:,3)=MHZ;

% passaggio da mm a metri:

X0=X0.*10^-3; % coordinate di tutti i punti della griglia % la matrice X0 ha 2*nlv-1 colonne, sempre dispari,

% e (2*nlh-1) righe, ancora sempre dispari %---

% STIMA DELL'AREA APPROSSIMATA CON I PANNELLI GENERATI DALLA GRIGLIA

% fase 1:

% si genera il nodo intermedio tra un nodo originale generico e quello % originale e ad esso superiore (stessa linea verticale, una riga orizz. più alto,

% nella griglia originale x/y/z/griglia)).

%(indh,indv) posizione nella matrice allargata X0 del nodo che si calcola

for indv=[1:2:2*nlv-1] for indh=[2:2:2*nlh-2] X0(indh,indv,:)=(X0(indh+1,indv,:)+X0(indh-1,indv,:))./2; end end %--- % fase 2:

% si genera il nodo intermedio tra due nodi originali successivi ed appartenenti

% alla stessa linea orizzontale

for indv=[2:2:2*nlv-2] for indh=[1:2:2*nlh-1] X0(indh,indv,:)=(X0(indh,indv+1,:)+X0(indh,indv-1,:))./2; end end %--- % fase 3:

% si genera il nodo intermedio tra i nodi appartenenti a due linee % verticali consecutive ed ottenuti nella fase 1:

for indv=[2:2:2*nlv-2] for indh=[2:2:2*nlh-2] X0(indh,indv,:)=(X0(indh,indv+1,:)+X0(indh,indv-1,:))./2; end end %--- % aree di influenza aree=zeros(nlh,nlv); % inizializzazione %---

% AREE DI INFLUENZA RELATIVE AI NODI INTERNI DELLA GRIGLIA ORIGINALE

% NOTA: si scrive tutto in funzione della posizione (indh,indv) dei nodi % della griglia originale nella griglia allargata X0.

for indv=[3:2:2*nlv-3]

for indh=[3:2:2*nlh-3];

%( indh,indv, % indici dei nodi della griglia originale nella griglia allargata)

for indcc=1:3

A(indcc)=X0(indh,indv-1,indcc)-X0(indh,indv,indcc); B(indcc)=X0(indh-1,indv-1,indcc)-X0(indh,indv,indcc);

(14)

C(indcc)=X0(indh-1,indv,indcc)-X0(indh,indv,indcc); D(indcc)=X0(indh-1,indv+1,indcc)-X0(indh,indv,indcc); E(indcc)=X0(indh,indv+1,indcc)-X0(indh,indv,indcc); F(indcc)=X0(indh+1,indv+1,indcc)-X0(indh,indv,indcc); G(indcc)=X0(indh+1,indv,indcc)-X0(indh,indv,indcc); H(indcc)=X0(indh+1,indv-1,indcc)-X0(indh,indv,indcc); end aree((indh+1)/2,(indv+1)/2) = 0.5*(norm(cross(A,B))+norm(cross(B,C))+... norm(cross(C,D))+norm(cross(D,E))+norm(cross(E,F))+... norm(cross(F,G))+norm(cross(G,H))+norm(cross(H,A))); end end %--- % AREE DI INFLUENZA RELATIVE AI NODI DELLA RALINGA

for indv=1

for indh=[3:2:2*nlh-3]; % si escludono base e penna

%( indh,indv, % indici dei nodi della griglia originale nella griglia allargata) for indcc=1:3 A(indcc)=0; B(indcc)=0; C(indcc)=X0(indh-1,indv,indcc)-X0(indh,indv,indcc); D(indcc)=X0(indh-1,indv+1,indcc)-X0(indh,indv,indcc); E(indcc)=X0(indh,indv+1,indcc)-X0(indh,indv,indcc); F(indcc)=X0(indh+1,indv+1,indcc)-X0(indh,indv,indcc); G(indcc)=X0(indh+1,indv,indcc)-X0(indh,indv,indcc); H(indcc)=0; end aree((indh+1)/2,(indv+1)/2) = 0.5*(norm(cross(A,B))+norm(cross(B,C))+... norm(cross(C,D))+norm(cross(D,E))+norm(cross(E,F))+... norm(cross(F,G))+norm(cross(G,H))+norm(cross(H,A))); end end %---

% AREE DI INFLUENZA RELATIVE AI NODI DELLA BALUMINA

for indv=2*nlv-1

for indh=[3:2:2*nlh-3]; % si escludono base e penna

%( indh,indv, % indici dei nodi della griglia originale nella griglia allargata) for indcc=1:3 A(indcc)=X0(indh,indv-1,indcc)-X0(indh,indv,indcc); B(indcc)=X0(indh-1,indv-1,indcc)-X0(indh,indv,indcc); C(indcc)=X0(indh-1,indv,indcc)-X0(indh,indv,indcc); D(indcc)=0; E(indcc)=0; F(indcc)=0; G(indcc)=X0(indh+1,indv,indcc)-X0(indh,indv,indcc); H(indcc)=X0(indh+1,indv-1,indcc)-X0(indh,indv,indcc); end

(15)

aree((indh+1)/2,(indv+1)/2) = 0.5*(norm(cross(A,B))+norm(cross(B,C))+... norm(cross(C,D))+norm(cross(D,E))+norm(cross(E,F))+... norm(cross(F,G))+norm(cross(G,H))+norm(cross(H,A))); end end %---

% AREE DI INFLUENZA RELATIVE AI NODI DELLA BASE

for indv=[1:2:2*nlv-1] for indh=1;

%( indh,indv, % indici dei nodi della griglia originale nella griglia allargata) for indcc=1:3 B(indcc)=0; C(indcc)=0; D(indcc)=0; if indv==1 A(indcc)=0; H(indcc)=0; E(indcc)=X0(indh,indv+1,indcc)-X0(indh,indv,indcc); F(indcc)=X0(indh+1,indv+1,indcc)-X0(indh,indv,indcc); G(indcc)=X0(indh+1,indv,indcc)-X0(indh,indv,indcc); elseif indv==2*nlv-1 A(indcc)=X0(indh,indv-1,indcc)-X0(indh,indv,indcc); H(indcc)=X0(indh+1,indv-1,indcc)-X0(indh,indv,indcc); E(indcc)=0; F(indcc)=0; G(indcc)=X0(indh+1,indv,indcc)-X0(indh,indv,indcc); else A(indcc)=X0(indh,indv-1,indcc)-X0(indh,indv,indcc); E(indcc)=X0(indh,indv+1,indcc)-X0(indh,indv,indcc); F(indcc)=X0(indh+1,indv+1,indcc)-X0(indh,indv,indcc); G(indcc)=X0(indh+1,indv,indcc)-X0(indh,indv,indcc); H(indcc)=X0(indh+1,indv-1,indcc)-X0(indh,indv,indcc); end end aree((indh+1)/2,(indv+1)/2) = 0.5*(norm(cross(A,B))+norm(cross(B,C))+... norm(cross(C,D))+norm(cross(D,E))+norm(cross(E,F))+... norm(cross(F,G))+norm(cross(G,H))+norm(cross(H,A))); end end %---

% AREE DI INFLUENZA RELATIVE AI NODI DELLA PENNA

% (la penna e' supposta esplosa in nlv punti distinti come posizione % nella matrice X0 ma geometricamente coincidenti);

for indv=[1:2:2*nlv-1] for indh=2*nlh-1;

%( indh,indv, % indici dei nodi della griglia originale nella griglia allargata) for indcc=1:3 A(indcc)=0; E(indcc)=0; F(indcc)=0;

(16)

G(indcc)=0; H(indcc)=0; if indv==1 B(indcc)=0; C(indcc)=X0(indh-1,indv,indcc)-X0(indh,indv,indcc); D(indcc)=X0(indh-1,indv+1,indcc)-X0(indh,indv,indcc); elseif indv==2*nlv-1 B(indcc)=X0(indh-1,indv-1,indcc)-X0(indh,indv,indcc); C(indcc)=X0(indh-1,indv,indcc)-X0(indh,indv,indcc); D(indcc)=0; else B(indcc)=X0(indh-1,indv-1,indcc)-X0(indh,indv,indcc); C(indcc)=X0(indh-1,indv,indcc)-X0(indh,indv,indcc); D(indcc)=X0(indh-1,indv+1,indcc)-X0(indh,indv,indcc); end end aree((indh+1)/2,(indv+1)/2) = 0.5*(norm(cross(A,B))+norm(cross(B,C))+... norm(cross(C,D))+norm(cross(D,E))+norm(cross(E,F))+... norm(cross(F,G))+norm(cross(G,H))+norm(cross(H,A))); end end %--- %AREA TOTALE area_vela=sum(sum(aree)); %---

(17)

B.4. function cerca_min_cond_sumt.m

% file per risolvere il problema della ricerca di un minimo condizionato % OUTPUT: NUOVA CONFIGURAZIONE VELA

function [xnew,lavoro_new]=cerca_min_cond_sumt(lancio,x0,P,... versnorm,nlh,nlv,TolFun,TolCon,TolSol,TolGrad,... TolAlfa,alfa_min,alfa_max,MaxFunEval,value_vedi,... Nitermax,rp0,rpmax,gamma,choice_m,Nstar,Nrestart,fid_sc); global teta global choice_cc global punto_scotta rp=rp0; %

% lancio: posizione di partenza per i nodi interni. Può essere diversa % da xx0 se abbiamo già svolto più iterazioni del loop

aeroelastico.

% Il nostro problema prevede il calcolo di un vettore lambda, con tante % componenti quante sono le equazioni di vincolo. Le equazioni di vincolo % prevedono allungamento nullo per le aste, escludendo quelle solidali % alla base ed alla ralinga

% valori iniziali delle function

lavoro_old=f_work(lancio,x0,P,versnorm,nlh,nlv); vincoli_old=vincoli_miei(lancio,x0,nlh,nlv);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% --- STIMA DEL GRADIENTE DELLE FUNZIONI VINCOLO --- %

gradv=grad_vincoli_def(lancio,x0,nlh,nlv);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%--STIMA DEL GRADIENTE DELLA FUNZIONE OBIETTIVO ORIGINALE (-LAVORO)-- %

gradfobj=grad_f_work_def(P,versnorm,nlh,nlv);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% inizializzazione posizione e vettore lambda

xnew=lancio; % posizioni di partenza per i nodi interni

for nvinc=1:length(vincoli_old)% numero di vincoli

if dot(gradv(nvinc,:),gradfobj)<0 % ogni vettore ha tante % componenti quante sono % le variabili

lambda(nvinc,1)=1; % moltiplicatori di Lagrange elseif dot(gradv(nvinc,:),gradfobj)>0 lambda(nvinc,1)=-1; else

(18)

lambda(nvinc,1)=0; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% ---- SEQUENTIAL UNCONSTRAINED MINIMIZATION TECHNIQUES ----

% Si è definita una funzione pseudo-obiettivo, secondo la tecnica

% nota come AUGMENTED LAGRANGE MOLTIPLIER METHOD (cfr. par. 5-8 pag. 141 Vanderplaats).

% La funzione obiettivo originale è il lavoro (cambiato di segno)

% delle forze esterne applicate ai nodi interni della griglia strutturale. % L'obiettivo è quello di trasformare un problema di minimo

% condizionato nel calcolo di una sequenza di problemi di minimo % non condizionato.

% Si deve costruire perciò una nuova funzione obiettivo,

% da minimizzare al posto di quella originale.Ciò avviene in due step: %

% 1) si scrive la funzione di lagrange %

% L(X,lambda)= F(X)+ sommatoria(lambda(1:k)*vincolo(X) k-esimo) %

% 2) si applica ad essa l'approccio cosiddetto 'exterior penalty function' %

% A(X,lambda,rp)=L(X,lambda)+rp*sommatoria([vincolo(X) k-esimo]^2) %

% questa è la nuova funzione obiettivo (o pseudo-obiettivo), % dove k=1:numero equazioni di vincolo

% NB: i vincoli sono solo equazioni (no disequazioni), dal significato % allungamento asta k-esima =0.

% Al generico passo del ciclo di calcolo si considerano note: % la configurazione di partenza (posizione nodi della griglia),i

moltiplicatori % di Lagrange, il coefficiente di penalizzazione rp. La nuova funzione

% obiettivo A(X,lambda,rp) viene minimizzata secondo X e si calcola % la posizione parziale dei nodi della griglia.

% Successivamente si aggiornano sia il vettore lambda che il coeff. rp, % procedendo alla soluzione di un altro problema di minimo non

condizionato.

% La tecnica di soluzione per la ricerca del minimo non vincolato è % affrontata con una tecnica a scelta tra quelle note come

% METODO DELLE DIREZIONI CONIUGATE (di Fletcher & Reeves) e % VARIABLE METRIC METHOD.

% (cfr. par. 3-3.2/fig.3-12 pag. 89-90 e par. 3-3.3 pag. 92 % di Vanderplaats).

%

% stampa su video del titolo per i risultati

fprintf(1,' \n');

fprintf(1,' SEQUENTIAL UNCONSTRAINED MINIMIZATION TECHNIQUES ----\n\n');

% apertura file con storia di calcolo

fprintf(fid_sc,' \n');

fprintf(fid_sc,' SEQUENTIAL UNCONSTRAINED MINIMIZATION TECHNIQUES ----\n\n');

(19)

N1=0;N2=0; % coefficienti per criterio di uscita associati a Nstar, % max. iteraz. successive in cui uno dei criteri

% di convergenza è soddisfatto e gli altri non lo sono. % --- % --- CICLO FOR --- %--- for indext=1:Nitermax %stampa su video fprintf(1,' \n'); fprintf(1,'\t\t ---\n'); fprintf(1,'\t\t ITERAZIONE SUMT N°: %-10s \n',... num2str(indext)); fprintf(1,'\t\t ---\n'); %stampa su file fprintf(fid_sc,' \n'); fprintf(fid_sc,'\t\t ---\n'); fprintf(fid_sc,'\t\t ITERAZIONE SUMT N°: %-10s \n',... num2str(indext)); fprintf(fid_sc,'\t\t ---\n'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if choice_m==1

% METODO DELLE DIREZIONI CONIUGATE PER MINIMO NON VINCOLATO % DELLA FUNZIONE PSEUDO-OBIETTIVO:

[xnew,f_pseudo_obj_new,delta_xx,max_abs_grad]=MDC_sumt(xnew,x0,... P,versnorm,nlh,nlv,lambda,rp,Nitermax,... TolFun,TolSol,TolGrad,TolAlfa,alfa_min,alfa_max,MaxFunEval,value_vedi,... indext,Nstar,Nrestart,fid_sc); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% else

% VARIABLE METRIC METHODS PER MINIMO NON VINCOLATO % DELLA FUNZIONE PSEUDO-OBIETTIVO:

[xnew,f_pseudo_obj_new,delta_xx,max_abs_grad]=VMM_sumt(xnew,... x0,P,versnorm,nlh,nlv,lambda,rp,Nitermax,... TolFun,TolSol,TolGrad,TolAlfa,alfa_min,alfa_max,MaxFunEval,value_vedi,... indext,Nstar,Nrestart,teta,fid_sc); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% lavoro_new=f_work(xnew,x0,P,versnorm,nlh,nlv); vincoli_new=vincoli_miei(xnew,x0,nlh,nlv);

% differenza tra i valori successivi del lavoro delle forze esterne < toll criterio1=(lavoro_new-lavoro_old);

% massimo valore assoluto delle componenti del vettore vincoli < toll, ovvero

% max(|allungamenti aste|) < toll prefissata

(20)

% rappresentazione su video di alcuni valori calcolati

str1=[' numero iterazione = ',num2str(indext)];

str2=[' lavoro_new = ',num2str(lavoro_new),' (N*mm)']; str3=[' (lavoro_new - lavoro_old) = ',num2str(criterio1),' (N*mm)']; str4=[' massima violazione vincoli = ',num2str(criterio2),' (mm)']; str5=[' max(abs(xxnew-xxold)) = ',num2str(delta_xx),' (mm)']; str6=[' max(|grad_F_lagrangiana|) = ',num2str(max_abs_grad),' (N)'];

disp(' ');

disp('---'); disp(' RISULTATI PARZIALI SUMT '); disp('---'); disp(' '); disp(str1); disp(str2); disp(str3); disp(str4); disp(str5); disp(str6); disp('---'); % stampa su file fprintf(fid_sc,' \n'); fprintf(fid_sc,'---\n'); fprintf(fid_sc,' RISULTATI PARZIALI SUMT \n'); fprintf(fid_sc,'---\n'); fprintf(fid_sc,' \n'); fprintf(fid_sc,'%s\n',str1); fprintf(fid_sc,'%s\n',str2); fprintf(fid_sc,'%s\n',str3); fprintf(fid_sc,'%s\n',str4); fprintf(fid_sc,'%s\n',str5); fprintf(fid_sc,'%s\n',str6); fprintf(fid_sc,'---\n'); %--- %%%%%%%%%% CRITERI DI CONVERGENZA %%%%%%%%%

% 1) Se la funzione obiettivo originale differisce da quella % calcolata alla iterazione precedente per una toll. fissata % 2) se i vincoli sono anch'essi all'interno

% di una toll. scelta

%--- % Può accadere che un criterio sia soddisfatto, mentre % l'altro no. Se questa situazione non si modifica, si % può scegliere di uscire:

% la function 'decidi_break distingue tra i due casi di cui sopra

[stringa,codice,N1,N2]=decidi_break(Nstar,N1,N2,...

abs(criterio1),criterio2,TolFun,TolCon,Nitermax,indext); [rstr,cstr]=size(stringa);

if (codice==0)&(N1>0)&(N2>0) % TUTTI i criteri soddisfatti % < Nstar volte

fprintf(1,'\n DA CERCA_MIN:CRITERI DI CONVERGENZA SODDISFATTI\n'); fprintf(fid_sc,'\n DA CERCA_MIN:CRITERI DI CONVERGENZA

SODDISFATTI\n');

(21)

elseif codice==1; % superato il numero massimo ammesso % di applicazioni del ciclo SUMT e la % convergenza non è stata raggiunta.

for indrstr=1:rstr % stampa su video e file fprintf(1,' %s\n',stringa(indrstr,:)); fprintf(fid_sc,' %s\n',stringa(indrstr,:)); end

break % si esce ma convergenza non raggiunta

elseif codice==2; % almeno un criterio soddisfatto Nstar volte % consecutive, gli altri non tutti soddisfatti

for indrstr=1:rstr % stampa su video e file fprintf(1,' %s\n',stringa(indrstr,:)); fprintf(fid_sc,' %s\n',stringa(indrstr,:)); end

break % si esce ma convergenza non raggiunta end

%%%%%%%%%%% FINE CRITERI DI CONVERGENZA %%%%%%%%%%%

% Il ciclo prosegue con la iterazione successiva se i % criteri non sono stati soddisfatti:

% aggiornamento dei moltiplicatori di Lagrange

lambda=lambda+2*rp.*vincoli_new;

% aggiornamento del fattore rp

rp=gamma*rp;

if rp>rpmax

rp=rpmax; % non deve superare il valore max. end

% aggiornamento della configurazione di partenza

lavoro_old=lavoro_new; vincoli_old=vincoli_new;

% adesso si e' in grado di risolvere un'altra ricerca di minimo per la funzione

% pseudo-obiettivo, con parametri rp e landa aggiornati

(22)

B.5 function VMM_sumt.m

% VARIABLE METRIC METHODS -MINIMO R^n NON VINCOLATO

% OUTPUT: MATRICE XXNEW,ovvero configurazione di minimo per % la funzione pseudo-obiettivo relativa alla tecnica % Augmented Lagrange Multiplier Method (cfr. pag 140 di % Vanderplaats).Il minimo non vincolato si ottiene con % il metodo del primo ordine 'VARIABLE METRIC METHODS ' % (cfr. pag. 93 del Vanderplaats)

%

% f_obj_new: valore della funzione pseudo-obiettivo %

% lo schema di calcolo ripete la fig. 3-12 di pag. 90; esso % costituisce un adattamento del metodo delle DIREZIONI % CONIUGATE, modificando la direzione di ricerca al nuovo % passo iterativo con una matrice che approssimi l'inversa % della HESSIANA, matrice delle derivate seconde della % funzione pseudo-obiettivo (ovvero obiettivo del problema % intermedio non vincolato).

function [xnew,f_pseudo_obj_new,criterio2,criterio3]=VMM_sumt(xnew,... x0,P,versnorm,nlh,nlv,lambda,rp,Nitermax,... TolFun,TolSol,TolGrad,TolAlfa,alfa_min,alfa_max,MaxFunEval,value_vedi,... indext,Nstar,Nrestart,teta,fid_sc); %--- DIM_x0=size(x0); N1=0;N2=0;N3=0;

% vettore punto iniziale

xnew_vect=vettorizza(xnew);

criterio2=0; % max(abs(xxnew-xxold))

% valore iniziale della f_pseudo_obiettivo

f_pseudo_obj_new=aug_lagrange(xnew,x0,P,versnorm,nlh,nlv,lambda,rp); delta_fpobj=0;

%criterio2=0;

% gradiente della funzione pseudo_obiettivo,

[grad_fpseudo_new,grad_come_x0_new]=grad_auglm(xnew,x0,... P,versnorm,nlh,nlv,lambda,rp); criterio3=max(abs(grad_fpseudo_new));

% la prima forma del gradiente è un vettore, la seconda una % matrice con la struttura di x0.

% prima forma della matrice approssimante l'HESSIANA^-1

Hess_new=eye(length(grad_fpseudo_new)); % matrice identità % direzione di ricerca %S_search_new_vect=(-1).*Hess_new*grad_fpseudo_new; %S_search_new=vect2matrix(S_search_new_vect,DIM_x0); max_value=max(criterio3,10^-10);

(23)

S_search_new_vect=(-1./max_value).*Hess_new*grad_fpseudo_new; S_search_new=vect2matrix(S_search_new_vect,DIM_x0);

% parametro per l'HESSIANA

%--- % se teta=0 metodo DFP

% se teta=1 metodo BFGS

%---

% contatore per rappresentazione risultati parziali: cont_ris=0;

% inizializzazione coeff. sensibile al RESTART restart=0;

%--- % opzioni per la function 'fminbnd'

options=optimset; % opzioni di default

if value_vedi==0

options.Display=['off']; % non visibilità dei calcoli se =0 else

options.Display=['iter']; % visibilità dei calcoli se =1 end

options.MaxfunEvals=MaxFunEval;% numero max valutazioni della funzione obiettivo da minimizzare

options.MaxIter=Nitermax; % num. max. iterazioni options.TolFun=TolFun; % toll funzione obiettivo

options.TolX=TolAlfa; % tolleranza sulla soluzione 'alfa' %---

% titolo per risultati parziali su video

str_titolo1=[' ---- VARIABLE METRIC METHOD CON TETA = ',num2str(teta),' AL PASSO SUMT N°: ',num2str(indext),' ----'];

str_titolo2=[' iter min_alfa F_pseudo_ob. c1=F_new-F_old c2=delta_x c3=|max(grad(F))| SLOPE'];

fprintf(1,' \n');

fprintf(1,'\t%-50s\n\n',str_titolo1); fprintf(1,'%-50s\n\n',str_titolo2); fprintf(1,' \n');

fprintf(1,' %-6d %10s %12.2f %12.2e %12.2e %12.2f\t\t\t DATI INIZIALI\n',...

cont_ris,' *****',f_pseudo_obj_new,delta_fpobj,criterio2,criterio3);

% titolo per risultati parziali su file fprintf(fid_sc,' \n');

fprintf(fid_sc,'\t%-50s\n\n',str_titolo1); fprintf(fid_sc,'%-50s\n\n',str_titolo2); fprintf(fid_sc,' \n');

fprintf(fid_sc,' %-6d %10s %12.2f %12.2e %12.2e %12.2f\t\t\t DATI INIZIALI\n',...

cont_ris,' *****',f_pseudo_obj_new,delta_fpobj,criterio2,criterio3); % ---

%%%%%%%--- CICLO FOR ESTERNO --- %%%%%%%% % --- for ind_ext_MDC=1:Nitermax esci=0;

%%%%%%% SOTTO-PROBLEMA DI MINIMO MONODIMENSIONALE %%%%%%%%%

% stabilita la configurazione di partenza (posizione nodi della griglia) % e scelta la direzione di ricerca S_search=-H*grad(F), determiniamo

(24)

% il valore di alfa per cui esiste un minimo della funzione % pseudo_obiettivo nella direzione scelta. Il problema diventa: %

% trovare 'alfa' tale che: min(F_pseudo_obiettivo(X0+alfa*S_search)) %

% Questo sottoproblema si risolve definendo una nuova function per % la funzione pseudo-obiettivo ed esplicitando la dipendenza da alfa, % nel senso di X(alfa)=X0+alfa*S_search

min_alfa=fminbnd('aug_lagrange_di_alfa',alfa_min,alfa_max,options,... S_search_new,xnew,x0,P,versnorm,nlh,nlv,lambda,rp);

%%%%%%%%%%%%% FINE SOTTOPROBLEMA %%%%%%%%%%%%%

%---

% salvo il valore di alfa precedente: alfa_old=min_alfa;

% salvo la direzione di ricerca precedente: S_search_old=S_search_new;

S_search_old_vect=S_search_new_vect; % si salva la soluzione XX precedente: xold=xnew;

xold_vect=xnew_vect;

% si salva la stima precedente della f pseudo-obiettivo f_pseudo_obj_old=f_pseudo_obj_new;

% si salva il gradiente della f pseudo-obiettivo: grad_fpseudo_old=grad_fpseudo_new;

% si salva la approssimazione all'Hessiana Hess_old=Hess_new;

%---

% si aggiorna il punto di partenza della ricerca xnew=xold+alfa_old*S_search_old; xnew_vect=xold_vect+alfa_old*S_search_old_vect; delta_x=max(abs(xnew_vect-xold_vect)); criterio2=delta_x; % si aggiorna la f_pseudo_obiettivo f_pseudo_obj_new=aug_lagrange(xnew,x0,P,versnorm,nlh,nlv,lambda,rp); delta_fpobj=f_pseudo_obj_new-f_pseudo_obj_old; %criterio2=delta_fpobj./f_pseudo_obj_new;

% si aggiorna il gradiente della f_pseudo_obiettivo

[grad_fpseudo_new,grad_come_x0_new]=grad_auglm(xnew,x0,... P,versnorm,nlh,nlv,lambda,rp); criterio3=max(abs(grad_fpseudo_new)); %--- cont_ris=cont_ris+1; if restart==0

fprintf(1,' %6d %10.5f %12.2f %12.2e %12.2e %12.2f\t\t\t S = -grad(F)\n',...

cont_ris,min_alfa,f_pseudo_obj_new,delta_fpobj,criterio2,criterio3); fprintf(fid_sc,' %6d %10.5f %12.2f %12.2e %12.2e %12.2f\t\t\t S = -grad(F)\n',...

cont_ris,min_alfa,f_pseudo_obj_new,delta_fpobj,criterio2,criterio3);

elseif restart==1

fprintf(1,' %-6d %10.5f %12.2f %12.2e %12.2e %12.2f\t\t\t S = -grad(F) RESTART PERIODICO\n',...

(25)

cont_ris,min_alfa,f_pseudo_obj_new,delta_fpobj,criterio2,criterio3); fprintf(fid_sc,' %6d %10.5f %12.2f %12.2e %12.2e %12.2f\t\t\t S = -grad(F) RESTART PERIODICO\n',...

cont_ris,min_alfa,f_pseudo_obj_new,delta_fpobj,criterio2,criterio3);

restart=0; end

if abs(min_alfa)<TolAlfa % se alfa=0 è la soluzione cercata esci=1;

break % esco dal ciclo 'for' e dalla function, esportando % XNEW che minimizza la funzione pseudo-obiettivo ed % il valore della funzione obiettivo originale

else

% procedura per aggiornare la direzione di ricerca % da utilizzare alla prossima ricerca di minimo % vettore p: p_vect=xnew_vect-xold_vect; % vettore y: y_vect=grad_fpseudo_new-grad_fpseudo_old; % scalare sigma: sigma=dot(p_vect,y_vect); % scalare tau: tau=y_vect.'*Hess_old*y_vect; % matrice D: if teta==0 D1_matrix=(1./(sigma)).*(p_vect*p_vect.'); D2_matrix=((-1)/tau).*Hess_old*y_vect*(Hess_old*y_vect).'; D3_matrix=0; elseif teta==1 D1_matrix=((sigma+teta.*tau)/(sigma.^2)).*(p_vect*p_vect.'); D2_matrix=0; D3_matrix=-(teta/sigma).*(Hess_old*y_vect*p_vect.'+p_vect*(Hess_old*y_vect).'); else D1_matrix=((sigma+teta.*tau)/(sigma.^2)).*(p_vect*p_vect.'); D2_matrix=((teta-1)/tau).*Hess_old*y_vect*(Hess_old*y_vect).'; D3_matrix=-(teta/sigma).*(Hess_old*y_vect*p_vect.'+p_vect*(Hess_old*y_vect).'); end D_matrix=D1_matrix+D2_matrix+D3_matrix;

% aggiornamento della Hessiana:

Hess_new=Hess_old+D_matrix;

(26)

%S_search_new_vect=(-1).*Hess_new*grad_fpseudo_new; %S_search_new=vect2matrix(S_search_new_vect,DIM_x0); S_search_new_vect=(-1).*Hess_new*grad_fpseudo_new; max_value=max(max(abs(S_search_new_vect)),10^-10); S_search_new_vect=(-1./max_value).*Hess_new*grad_fpseudo_new; S_search_new=vect2matrix(S_search_new_vect,DIM_x0); % --- % --- %%%%%%% CICLO FOR INTERNO %%%%%%% --- % ---

for ind_int_MDC=1:Nitermax

xold=xnew; % conservo la soluzione per la iter. successiva xold_vect=xnew_vect; grad_fpseudo_old=grad_fpseudo_new; Hess_old=Hess_new; f_pseudo_obj_old=f_pseudo_obj_new; %---

% pendenza di F(alfa) in alfa=0:

slope=dot(S_search_new_vect,grad_fpseudo_new);

if slope>=0 % si fa ripartire il metodo

max_value=max(criterio3,10^-10);

Hess_new=eye(length(grad_fpseudo_new)); % matrice identità

S_search_new_vect=(-1/max_value).*grad_fpseudo_new; S_search_new=vect2matrix(S_search_new_vect,DIM_x0); restart=0; esci=0.5; break else %--- %%%%%% SOTTOPROBLEMA DI MINIMO MONODIMENSIONALE %%%%% min_alfa=fminbnd('aug_lagrange_di_alfa',alfa_min,alfa_max,options,... S_search_new,xnew,x0,P,versnorm,nlh,nlv,lambda,rp); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %--- end %--- % risultati parziali xnew=xold+min_alfa*S_search_new; xnew_vect=xold_vect+min_alfa*S_search_new_vect; f_pseudo_obj_new = aug_lagrange(xnew,x0,P,... versnorm,nlh,nlv,lambda,rp); [grad_fpseudo_new,grad_come_x0_new]=grad_auglm(xnew,x0,... P,versnorm,nlh,nlv,lambda,rp);

(27)

%--- % differenza tra due iterazioni successive:

delta_fpobj=(f_pseudo_obj_new-f_pseudo_obj_old); delta_x=max(abs(xnew_vect-xold_vect));

%--- % Se la F_pseudo-obiettivo decresce si applicano % i criteri di convergenza:

%--- %%%%%%--- CRITERIO DI CONVERGENZA ---%%%%%%%

% si adottano i criteri seguenti:

% 1) |variazione della f. pseudo-obiettivo| < TolFun; % 2) max(|XNEW-XOLD|)< TolSol;

% 3) |variazione max del gradiente di f. pseudo-obiett.| < TolGrad % variazione: differenza tra valori relativi a due

% iterazioni successive criterio1=abs(delta_fpobj); criterio2=delta_x; %criterio2=delta_fpobj./f_pseudo_obj_new; criterio3=max(abs(grad_fpseudo_new));

% visione dei risultati parziali: cont_ris=cont_ris+1;

fprintf(1,' %-6d %10.5f %12.2f %12.2e %12.2e %12.2f %12.2f\n',cont_ris,...

min_alfa,f_pseudo_obj_new,delta_fpobj,criterio2,criterio3,slope); fprintf(fid_sc,' %-6d %10.5f %12.2f %12.2e %12.2e %12.2f

%12.2f\n',cont_ris,...

min_alfa,f_pseudo_obj_new,delta_fpobj,criterio2,criterio3,slope);

% applicazione dei criteri:

[stringa,codice,N1,N2,N3]=decidi_break_3cc(Nstar,N1,N2,N3,...

criterio1,criterio2,criterio3,TolFun,TolSol,TolGrad,cont_ris,Nitermax); [rstr,cstr]=size(stringa);

if (codice==1) % esaurite le iterazioni a disposizione % per calcolo al generico passo SUMT for indrstr=1:rstr fprintf(1,' %s\n',stringa(indrstr,:)); fprintf(fid_sc,' %s\n',stringa(indrstr,:)); end esci=1; break

elseif (codice==2) % almeno un criterio è soddisfatto Nstar % volte consecutive; gli altri non verificati for indrstr=1:rstr

fprintf(1,' %s\n',stringa(indrstr,:)); fprintf(fid_sc,' %s\n',stringa(indrstr,:)); end

esci=1; % si esce dal programma, ma convergenza % non raggiunta a questo passo SUMT break

elseif (codice==0)&(N1>0)&(N2>0)&(N3>0) % TUTTI i criteri % soddisfatti < Nstar volte

(28)

if min(min(N1,N2),N3)==1 % primo caso in cui

% tutti i criteri soddisfatti

% (uno una volta,gli altri una o più)

max_value=max(criterio3,10^-10);

Hess_new=eye(length(grad_fpseudo_new)); % matrice identità

S_search_new_vect=(-1/max_value).*grad_fpseudo_new; S_search_new=vect2matrix(S_search_new_vect,DIM_x0);

restart=0;

esci=0.5; % si esegue un ciclo for esterno % la prima volta che tutti i criteri % sono soddisfatti contemporaneamente break

elseif min(min(N1,N2),N3)>1 % tutti i criteri soddisfatti % anche più di una volta fprintf(1,' DA MIN_VAR_METRIC : CRITERI DI CONVERGENZA SODDISFATTI\n');

fprintf(fid_sc,' DA MIN_VAR_METRIC : CRITERI DI CONVERGENZA SODDISFATTI\n');

esci=1;

break % esci per convergenza raggiunta

end end

%%%%%%%%%---FINE CRITERIO CONVERGENZA---%%%%%%%% %---

% Può accadere che la funzione obiettivo non diminuisca, % ma aumenti a causa di errori accumulati. E' necessario % allora far ripartire il metodo, inizializzando la % direzione di ricerca con S= -grad(F) ed uscendo dal % ciclo FOR interno.

% Nei testi inoltre si consiglia di attivare periodicamente % il ciclo FOR ESTERNO, ricominciando il calcolo con

% S=- grad(F). Tale criterio dovrebbe limitare la propagazione % di errore nell'aggiornamento della direzione di ricerca S.

if ((ind_int_MDC>1)&(delta_fpobj>0))

max_value=max(criterio3,10^-10);

Hess_new=eye(length(grad_fpseudo_new)); % matrice identità S_search_new_vect=(-1./max_value).*grad_fpseudo_new;

S_search_new=vect2matrix(S_search_new_vect,DIM_x0);

restart=0; esci=0.5;

break % si fa ripartire il metodo

% se la f_pseudo _obj non decresce

elseif (ind_int_MDC>Nrestart)

max_value=max(criterio3,10^-10);

Hess_new=eye(length(grad_fpseudo_new)); % matrice identità S_search_new_vect=(-1./max_value).*grad_fpseudo_new;

(29)

restart=1; esci=0.5;

break % si esce da for interno

end

% Può accadere che si esaurisca il numero max. di % iterazioni disponibili per il ciclo FOR interno:

if ind_int_MDC>=Nitermax

fprintf(1,'\n iterazioni interne non sufficienti per soluzione minimo non vincolato\n');

fprintf(fid_sc,'\n iterazioni interne non sufficienti per soluzione minimo non vincolato\n');

esci=1;

break % esce da for interno e poi da quello esterno

end

%--- % procedura per aggiornare la direzione di ricerca % da utilizzare alla prossima ricerca di minimo % vettore p: p_vect=xnew_vect-xold_vect; % vettore y: y_vect=grad_fpseudo_new-grad_fpseudo_old; % scalare sigma: sigma=dot(p_vect,y_vect); % scalare tau: tau=y_vect.'*Hess_old*y_vect; % matrice D: if teta==0 D1_matrix=(1./(sigma)).*(p_vect*p_vect.'); D2_matrix=((-1)/tau).*Hess_old*y_vect*(Hess_old*y_vect).'; D3_matrix=0; elseif teta==1 D1_matrix=((sigma+teta.*tau)/(sigma.^2)).*(p_vect*p_vect.'); D2_matrix=0; D3_matrix=-(teta/sigma).*(Hess_old*y_vect*p_vect.'+p_vect*(Hess_old*y_vect).'); else D1_matrix=((sigma+teta.*tau)/(sigma.^2)).*(p_vect*p_vect.'); D2_matrix=((teta-1)/tau).*Hess_old*y_vect*(Hess_old*y_vect).'; D3_matrix=-(teta/sigma).*(Hess_old*y_vect*p_vect.'+p_vect*(Hess_old*y_vect).'); end D_matrix=D1_matrix+D2_matrix+D3_matrix;

(30)

% aggiornamento della Hessiana:

Hess_new=Hess_old+D_matrix;

% aggiornamento della direzione di ricerca: %S_search_new_vect=(-1).*Hess_new*grad_fpseudo_new; %S_search_new=vect2matrix(S_search_new_vect,DIM_x0); S_search_new_vect=(-1).*Hess_new*grad_fpseudo_new; max_value=max(max(abs(S_search_new_vect)),10^-10); S_search_new_vect=(-1./max_value).*Hess_new*grad_fpseudo_new; S_search_new=vect2matrix(S_search_new_vect,DIM_x0); % --- end %%%% FINE CICLO FOR INTERNO %%%% % --- end %%%% FINE CICLO IF %%%%

% ---

if (esci==1)

break % esce dal ciclo FOR ESTERNO elseif ind_ext_MDC>=Nitermax

fprintf(1,'\n iterazioni esterne non sufficienti per soluzione minimo non vincolato\n');

fprintf(fid_sc,'\n iterazioni esterne non sufficienti per soluzione minimo non vincolato\n');

break % esce dal ciclo FOR esterno end

% --- end %%%%% FINE CICLO FOR ESTERNO %%%%% % ---

Riferimenti

Documenti correlati

[r]

Premessa: supponiamo di aver seguito tutti i ragionamenti svolti dal libro di testo fino alla formula (4.43) a pagina 139 (quella che a lezione ` e stata chiamata Osservazione 1

Fissato, quindi, un tale valore si determini al variare di α il condizionamento di A con indice 1, 2,

Fissato, quindi, un tale valore si determini al variare di α il condizionamento di A con indice 1, 2,

Fissato un tale valore si determini al variare di α il numero di condizionamento di A con indici 1, 2,

Si prova che: (1) se una matrice `e invertibile, allora anche la sua inversa `e invertibile, con inversa la matrice data; (2) se due matrici dello stesso tipo sono invertibili,

Dalla dimostrazione di questo teorema possiamo dedurre anche il seguente Algoritmo di Gauss-Jordan per il calcolo della matrice inversa. Sia A una matrice quadrata di tipo n

[r]