Для пользователя неудобно указывать каждый аспект алгоритма. Если алгоритм допускает вложенные компоненты, то конечного числа опций будет недостаточно. Поэтому очень важно, чтобы опции не обязательно «всплыли» на верхний уровень, как в случае явных аргументов или параметров шаблона. Это иногда называют "проблемой конфигурации" в разработке программного обеспечения. Я считаю, что PETSc обладает уникально мощной системой управления конфигурациями. Это похоже на шаблон Service Locator в эссе Мартина Фаулера об инверсии управления .
Система конфигурации PETSc работает через комбинацию заданной пользователем конфигурации, управляемой объектами решателя (с запросами get и set) и базой данных параметров. Любой компонент симуляции может объявить опцию конфигурации, значение по умолчанию и место для размещения результата. Вложенные объекты имеют префиксы, которые можно составлять, так что каждый объект, который нуждается в настройке, может быть адресован независимо. Сами параметры можно прочитать из командной строки, среды, файлов конфигурации или из кода. Когда опция объявлена, указывается строка справки и справочная страница, чтобы -help
опция была понятной и чтобы можно было написать правильно связанный графический интерфейс.
Пользователь вызывает SetFromOptions
метод для настройки объекта на основе параметров командной строки. Вызов этой функции не является обязательным и не может быть вызван, если пользователь (человек, пишущий код, который вызывает PETSc) раскрывает параметры через какой-то другой интерфейс. Мы настоятельно рекомендуем пользователю предоставить базу данных опций, поскольку она дает конечному пользователю (человеку, выполняющему приложение) большую мощность, но это не требуется.
Типичная конфигурация, вызываемая через
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();
Примечания:
PetscOptionsList()
предоставляет пользователю выбор из динамического списка. Существует архитектура плагинов, которую новые реализации могут использовать, чтобы представить себя первоклассным для вызывающих. (Эти реализации могут быть размещены в общих библиотеках и использованы как первоклассные без перекомпиляции программ.)
SNESSetFromOptions()
рекурсивно конфигурирует линейные решатели, предобусловливатели и любые другие компоненты, требующие настройки.