É complicado para o usuário especificar todos os aspectos de um algoritmo. Se o algoritmo permitir componentes aninhados, nenhum número finito de opções seria suficiente. Portanto, é fundamental que as opções não necessariamente "subam" para o nível superior, como no caso de argumentos explícitos ou parâmetros de modelo. Às vezes, isso é chamado de "problema de configuração" na engenharia de software. Acredito que o PETSc tenha um sistema exclusivamente poderoso para gerenciamento de configurações. É semelhante ao padrão Service Locator no ensaio de Martin Fowler sobre inversão de controle .
O sistema de configuração do PETSc funciona através de uma combinação de configuração especificada pelo usuário, gerenciada pelos objetos solucionadores (com consultas get e set) e pelo banco de dados de opções. Qualquer componente da simulação pode declarar uma opção de configuração, um valor padrão e um local para colocar o resultado. Objetos aninhados têm prefixos que podem ser compostos, de modo que todos os objetos que precisam de configuração possam ser endereçados de forma independente. As opções em si podem ser lidas na linha de comando, ambiente, arquivos de configuração ou código. Quando uma opção é declarada, uma cadeia de ajuda e uma página de manual são especificadas, para que a -help
opção seja compreensível e para que uma GUI corretamente vinculada possa ser gravada.
O usuário chama um SetFromOptions
método para fazer com que um objeto se configure com base nas opções da linha de comando. Chamar esta função é opcional e pode não ser chamado se o usuário (pessoa que escreve o código que chama PETSc) estiver expondo as opções por meio de alguma outra interface. É altamente recomendável que o usuário exponha o banco de dados de opções, pois fornece ao usuário final (pessoa que executa o aplicativo) uma grande quantidade de energia, mas isso não é necessário.
Uma configuração típica, chamada 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();
Notas:
PetscOptionsList()
apresenta ao usuário uma opção em uma lista dinâmica. Existe uma arquitetura de plug-in que as novas implementações podem usar para se expor como de primeira classe aos chamadores. (Essas implementações podem ser colocadas em bibliotecas compartilhadas e usadas como primeira classe sem recompilar programas.)
SNESSetFromOptions()
configura recursivamente os solucionadores lineares, pré-condicionadores e outros componentes que precisam de configuração.