Casi todos los paquetes de solución directa dispersa dividen la factorización en dos etapas:
-
La factorización simbólica calcula una ordenación, a menudo utilizando la disección anidada o un algoritmo de grado mínimo aproximado, de forma que los factores sean lo más dispersos posible y asigna espacio para mantener el resultado. El valor de las entradas de la matriz no se utiliza o sólo se utiliza para hacer estimaciones sobre el pivote.
-
La factorización numérica calcula la factorización dada la ordenación y la dispersión calculada por la factorización simbólica.
En la mayoría de las circunstancias, la factorización simbólica es mucho menos costosa que la factorización numérica, por lo que SAME_NONZERO_PATTERN
ofrece un beneficio limitado. Esto cambia cuando se ejecuta en paralelo con muchos procesos, ya que la factorización simbólica no escala tan bien (y algunos paquetes populares, incluyendo MUMPS, la calculan en serie).
Es muy poco probable que su factor de 100 provenga de la etapa de factorización simbólica. ¿Quizás estés reutilizando los factores de la iteración anterior? Para cuestiones de rendimiento como ésta, suele ser útil ejecutar con -log_summary
y comparar los tiempos y el equilibrio de carga para el Mat*FactorSym
y Mat*FactorNum
eventos. Envíe la salida a petsc-users@mcs.anl.gov o petsc-maint@mcs.anl.gov si desea ayuda para interpretar la salida.
En cuanto a la "actualización" de los factores tras pequeños cambios en las entradas de la matriz, los intentos de hacerlo han sido normalmente infructuosos. Una alternativa que recomiendo es utilizar la antigua factorización como precondicionador de la nueva matriz. Para los problemas no lineales usando SNES, se puede experimentar usando -snes_lag_preconditioner
o -snes_lag_jacobian
. Si utiliza KSP directamente, entonces pase SAME_PRECONDITIONER
a KSPSetOperators()
.