Es engorroso para el usuario especificar cada aspecto de un algoritmo. Si el algoritmo permite componentes anidados, entonces no sería suficiente un número finito de opciones. Por lo tanto, es crítico que las opciones no necesariamente "suban" al nivel superior, como en el caso de argumentos explícitos o parámetros de plantilla. Esto a veces se llama el "problema de configuración" en ingeniería de software. Creo que PETSc tiene un sistema único y poderoso para la gestión de la configuración. Es similar al patrón del Localizador de servicios en el ensayo de Martin Fowler sobre inversión de control .
El sistema de configuración de PETSc funciona a través de una combinación de configuración especificada por el usuario administrada por los objetos solucionadores (con consultas get y set) y la base de datos de opciones. Cualquier componente de la simulación puede declarar una opción de configuración, un valor predeterminado y un lugar para colocar el resultado. Los objetos anidados tienen prefijos que se pueden componer, de modo que cada objeto que necesita configuración se puede abordar de forma independiente. Las opciones en sí pueden leerse desde la línea de comandos, el entorno, los archivos de configuración o desde el código. Cuando se declara una opción, se especifican una cadena de ayuda y una página de manual, de modo que la -help
opción sea comprensible y se pueda escribir una GUI correctamente vinculada.
El usuario llama a un SetFromOptions
método para hacer que un objeto se configure según las opciones de la línea de comandos. Llamar a esta función es opcional y no se puede llamar si el usuario (persona que escribe el código que llama a PETSc) está exponiendo las opciones a través de alguna otra interfaz. Recomendamos encarecidamente que el usuario exponga la base de datos de opciones porque le da al usuario final (persona que ejecuta la aplicación) una gran cantidad de poder, pero no es obligatorio.
Una configuración típica, llamada vía
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()
presenta al usuario una opción de una lista dinámica. Existe una arquitectura de complementos que las nuevas implementaciones pueden usar para exponerse como de primera clase a las personas que llaman. (Estas implementaciones pueden colocarse en bibliotecas compartidas y usarse como de primera clase sin volver a compilar programas).
SNESSetFromOptions()
configura recursivamente los solucionadores lineales, preacondicionadores y cualquier otro componente que necesite configuración.