È ingombrante per l'utente specificare ogni aspetto di un algoritmo. Se l'algoritmo consente componenti nidificati, non sarebbe sufficiente un numero finito di opzioni. Pertanto, è fondamentale che le opzioni non si "appagino" al massimo livello, come nel caso di argomenti espliciti o parametri del modello. Questo è talvolta chiamato "problema di configurazione" nell'ingegneria del software. Credo che PETSc abbia un sistema straordinariamente potente per la gestione della configurazione. È simile al modello di Service Locator nel saggio di Martin Fowler sull'inversione del controllo .
Il sistema di configurazione di PETSc funziona attraverso una combinazione di configurazione specificata dall'utente gestita dagli oggetti del risolutore (con query get e set) e dal database delle opzioni. Qualsiasi componente della simulazione può dichiarare un'opzione di configurazione, un valore predefinito e un luogo in cui inserire il risultato. Gli oggetti nidificati hanno prefissi che possono essere composti, in modo tale che ogni oggetto che necessita di configurazione possa essere indirizzato in modo indipendente. Le opzioni stesse possono essere lette dalla riga di comando, dall'ambiente, dai file di configurazione o dal codice. Quando viene dichiarata un'opzione, vengono specificate una stringa di aiuto e una pagina man, in modo che l' -help
opzione sia comprensibile e che sia possibile scrivere una GUI correttamente collegata.
L'utente chiama un SetFromOptions
metodo per configurare un oggetto in base alle opzioni della riga di comando. La chiamata a questa funzione è facoltativa e non può essere chiamata se l'utente (persona che scrive codice che chiama PETSc) sta esponendo le opzioni attraverso un'altra interfaccia. Raccomandiamo vivamente che l'utente esponga il database delle opzioni perché fornisce all'utente finale (persona che esegue l'applicazione) una grande potenza, ma non è necessario.
Una configurazione tipica, chiamata via
PetscObjectOptionsBegin(object); /* object has prefix and descriptive string */
PetscOptionsReal("-ts_atol", /* options database key */
"Absolute tolerance for local truncation error", /* long description */
"TSSetTolerances", /* function and man page on topic */
ts->atol, /* current/default value *?
&ts->atol, /* place to store value */
&option_set); /* TRUE if the option was set */
PetscOptionsList("-ts_type","Time stepping method","TSSetType",TSList,
defaultType,typeName,sizeof typeName,&option_set);
TSAdaptSetFromOptions(ts->adapt); /* configures adaptive controller method */
/* ... many others */
/* ... the following is only called from implicit implementations */
SNESSetFromOptions(ts->snes); /* configure nonlinear solver. */
PetscOptionsEnd();
Appunti:
PetscOptionsList()
presenta all'utente una scelta da un elenco dinamico. Esiste un'architettura plug-in che le nuove implementazioni possono utilizzare per esporsi come chiamanti di prima classe. (Queste implementazioni possono essere inserite in librerie condivise e utilizzate come prima classe senza ricompilare i programmi.)
SNESSetFromOptions()
configura in modo ricorsivo i solutori lineari, i precondizionatori e qualsiasi altro componente che necessita di configurazione.