L'inizializzazione del sistema prevede, ora, che l'assemblaggio del descrittore e quello della matrice possano essere eseguiti indipendentemente. Durante la sua vita, il descrittore può trovarsi in due differenti stati: 1. bld: stato di build. in questo stato è possibile aggiornare il contenuto del descrittore attraverso la routine psb_dscins. 2. asb: stato assembled. questo è lo stato della rappresentazione finale del descrittore ed è raggiunto a valle di una chiamata alla routine psb_dscasb. Durante la sua vita, la matrice può trovarsi in tre differenti stati: 1. bld: stato di build. in questo stato è possibile aggiornare il contenuto dela matrice attraverso la routine psb_spins. 2. asb: stato assembled. questo è lo stato della rappresentazione finale della matrice ed è raggiunto a valle di una chiamata alla routine psb_spasb. 3. upd: stato di update. è lo stato in cui è possibile (attraverso una chiamata alla routine psb_spasb) rigenerare la matrice. - Assemblaggio contestuale di matrice e descrittore Il procedimento da seguire prevede il seguente ordine di chiamate: 1. psb_dscall: allocazione del descrittore. Alla fine di questo step lo stato del descrittore sarà bld 2. psb_spall: allocazione della matrice. Alla fine di questo step lo stato della matrice sarà bld 3. psb_spins: in questo caso sia il descrittore che la matrice saranno nello stato bld. Quindi la psb_spins invoca la psb_dscins per portare il descrittore in uno stato pre-asb e poi effettivamente inserisce i coefficienti nella matrice (che quindi sarà anch'essa in uno stato pre-asb). Dunque, nel caso di costruzione/assemblaggio contestuale di matrise e descrittore, il contenuto del descrittore è implicitamente aggiornato da questa chiamata. (nel caso separato bisognerà esplicitamente prevedere questa fase attraverso una chiamata alla psb_dscins) 4. psb_dscasb: il descrittore viene assemblato e quindi portato allo stato asb. 5. psb_spasb: la matrice viene assemblata e quindi portata allo stato asb. - Assemblaggio di descrittore e matrice indipendenti Il procedimento da seguire per costruire/assemblare il descrittore prevede il seguente ordine di chiamate: 1. psb_dscall: allocazione del descrittore. Alla fine di questo step lo stato del descrittore sarà bld 2. psb_dscins: il descrittore viene inizializzato a partire dal pattern di sparsità della matrice e dal partizionamento. Alla fine di questo step sarà in uno stato pre-asb 3. psb_dscasb: il descrittore viene assemblato e quindi portato allo stato asb. Il procedimento da seguire per costruire/assemblare la matrice prevede il seguente ordine di chiamate: 1. psb_spall: allocazione della matrice. Alla fine di questo step lo stato della matrice sarà bld 2. psb_spins: i coefficienti vengono effettivamente inseriti nella matrice che sarà portata ad uno stato pre-asb. 3. psb_spasb: la matrice viene assemblata e quindi portata allo stato asb. - Aggiornamento della matrice Se il pattern di sparsità della matrice non cambia, la matrice può essere aggiornata attraverso il seguente procedimento: 1. psb_sprn: reinizializza la matrice. Alla fine di questo step la matrice sarà nello stato upd 2. psb_spins: i coefficienti della matrice vengono reinseriti 3. psb_spasb: la matrice viene assemblata e riportata nello stato asb. La gestione degli errori La nuova gestione degli errori prevede la creazione di uno stack di messaggi di errore che possa consentire di seguire a ritroso la sequenza di chiamate di routine fino ad arrivare a quella in cui l'errore è stato rilevato. Tutte le nuove interfacce prevedono un argomento "info" il quale ritorna un valore > 0 se all'interno della routine chiamata è stato rilevato un errore. Dunque ogni volta che si rileva una condizione di errore (o per verifica diretta o perchè una routine chiamata ha ritornato info>0) occorre mettere l'errore in cima allo stack per mezzo della routine psb_errpush(info,name,i_err,a_err) in cui: info: codice di errore (si veda SRC/F90/errormod.f90 per una corrispondenza codice-messaggiodierrore) name: stringa di lunghezza 20 contenente il nome della routine che invoca la psb_errpush() i_err: opzionale. E' un array di 5 interi contenente informazioni aggiuntive per il messaggio di errore (si veda errormod.f90) a_err: opzionale. E' una stringa di 20 contenente informazioni aggiuntive per il messaggio di errore (si veda errormod.f90) attraverso la routine psb_seterrverbosity si può impostare la verbosità del messaggio d'errore (se =1 viene stampato solo l'errore in cima allo stack; se >1 vengono stampati tutti) la routine psb_error(ictxt) provoca la stampa degli (dell') errori (errore) sullo stack ed, eventualmente, stronca il set di processi. l'argomento ictxt è opzionale: se è assente viene semplicemente stampato il messaggio d'errore altrimenti viene anche abortita l'esecuzione di tutti i processi. la routine psb_seterraction(action) determina quale azione deve essere intrapresa a fronte del rilevamento di un errore: action =0 : la routine in cui è stato rilevato un errore (e quindi dopo che l'errore stesso sia stato inserito sullo stack) semplicemente ritorna al chiamante un codice di errore action =1 : la routine in cui è stato rilevato un errore (e quindi dopo che l'errore stesso sia stato inserito sullo stack) prima di ritornare invoca la psb_error (e quindi, può, eventualmente stroncare l'esecuzione di tutti i processi).