Es ist für den Benutzer umständlich, jeden Aspekt eines Algorithmus anzugeben. Wenn der Algorithmus verschachtelte Komponenten zulässt, ist keine endliche Anzahl von Optionen ausreichend. Daher ist es wichtig, dass Optionen nicht unbedingt auf die oberste Ebene "aufsprudeln", wie dies bei expliziten Argumenten oder Vorlagenparametern der Fall ist. Dies wird in der Softwareentwicklung manchmal als "Konfigurationsproblem" bezeichnet. Ich glaube, PETSc verfügt über ein einzigartig leistungsfähiges System für das Konfigurationsmanagement. Es ähnelt dem Service Locator-Muster in Martin Fowlers Aufsatz über die Umkehrung der Kontrolle .
Das Konfigurationssystem von PETSc basiert auf einer Kombination aus benutzerdefinierten Konfigurationen, die von den Solver-Objekten (mit Abfragen zum Abrufen und Festlegen) und der Optionsdatenbank verwaltet werden. Jede Komponente der Simulation kann eine Konfigurationsoption, einen Standardwert und einen Ort für das Ergebnis deklarieren. Verschachtelte Objekte haben Präfixe, die zusammengesetzt werden können, sodass jedes Objekt, das konfiguriert werden muss, unabhängig adressiert werden kann. Die Optionen selbst können über die Befehlszeile, die Umgebung, die Konfigurationsdateien oder über Code gelesen werden. Wenn eine Option deklariert wird, werden eine Hilfezeichenfolge und eine Manpage angegeben, damit die -help
Option verständlich ist und eine ordnungsgemäß verknüpfte GUI geschrieben werden kann.
Der Benutzer ruft eine SetFromOptions
Methode auf, mit der sich ein Objekt anhand der Befehlszeilenoptionen selbst konfigurieren kann. Der Aufruf dieser Funktion ist optional und kann möglicherweise nicht aufgerufen werden, wenn der Benutzer (der Code schreibt, der PETSc aufruft) die Optionen über eine andere Schnittstelle bereitstellt. Es wird dringend empfohlen, dass der Benutzer die Optionsdatenbank verfügbar macht, da dies dem Endbenutzer (der die Anwendung ausführt) viel Macht verleiht, dies ist jedoch nicht erforderlich.
Eine typische Konfiguration, die über aufgerufen wird
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();
Anmerkungen:
PetscOptionsList()
präsentiert dem Benutzer eine Auswahl aus einer dynamischen Liste. Es gibt eine Plugin-Architektur, mit der sich neue Implementierungen als erstklassig für Aufrufer ausgeben können. (Diese Implementierungen können in gemeinsam genutzten Bibliotheken abgelegt und als erstklassig verwendet werden, ohne dass Programme neu kompiliert werden müssen.)
SNESSetFromOptions()
Konfiguriert rekursiv die linearen Löser, Vorkonditionierer und alle anderen Komponenten, die konfiguriert werden müssen.