Qu'est-ce qui peut mal tourner lors de l'utilisation de méthodes Krylov précondonifiées du KSP ( package de solveur linéaire de PETSc ) pour résoudre un système linéaire clairsemé tel que ceux obtenus en discrétisant et en linéarisant des équations différentielles partielles?
Quelles mesures puis-je prendre pour déterminer ce qui ne va pas pour mon problème?
Quels changements puis-je apporter pour résoudre avec succès et efficacité mon système linéaire?
petsc
balise. La méthodologie est générale, mais je pense que la réponse serait moins utile si chaque "essayez ceci" n'incluait pas également le "comment". Alternativement, le "comment" devrait être beaucoup plus long (et plus sujet aux erreurs pour le spectateur) s'il devait être expliqué de manière indépendante du logiciel. Si quelqu'un veut expliquer comment faire toutes ces choses en utilisant un package différent, je serai ravi de rendre la question indépendante du logiciel et de changer ma réponse pour indiquer qu'elle décrit ce qu'il faut faire dans PETSc. Remarque: J'ai ajouté ceci, qui est une version améliorée d'une FAQ, donc je pourrais aimer les gens sur ce site.Réponses:
Conseil initial
-ksp_converged_reason -ksp_monitor_true_residual
lorsque vous essayez de comprendre pourquoi une méthode ne converge pas.-ksp_view_binary
ouMatView()
pour enregistrer le système linéaire, puis utilisez le code à$PETSC_DIR/src/ksp/ksp/examples/tutorials/ex10.c
pour lire dans la matrice et le résoudre (éventuellement avec un nombre différent de processus). Cela nécessite une matrice assemblée, donc son utilité peut être quelque peu limitée.Raisons courantes pour lesquelles KSP ne converge pas
-pc_type svd -pc_svd_monitor
. Essayez également un solveur direct avec-pc_type lu
(via un package tiers en parallèle, par exemple-pc_type lu -pc_factor_mat_solver_package superlu_dist
).KSPSetNullSpace()
.KSPSetNullSpace()
été utilisées, mais le côté droit n'est pas cohérent. Vous devrez peut-être appelerMatNullSpaceRemove()
sur le côté droit avant d'appelerKSPSolve()
.-ksp_gmres_restart 1000 -pc_type none
. Pour les problèmes de point de selle simples, essayez-pc_type fieldsplit -pc_fieldsplit_type schur -pc_fieldsplit_detect_saddle_point
. Voir le manuel de l'utilisateur et la page de manuel PCFIELDSPLIT pour plus de détails. Pour les problèmes plus difficiles, lisez la littérature pour trouver des méthodes robustes et demandez ici (ou[email protected]
ou[email protected]
) si vous souhaitez des conseils sur la façon de les mettre en œuvre. Par exemple, voir cette question pour Helmholtz haute fréquence. Pour les tailles de problème modestes, voyez si vous pouvez vivre avec simplement en utilisant un solveur direct.-pc_type asm -sub_pc_type lu
améliore le taux de convergence. Si GMRES perd trop de progrès dans le redémarrage, voyez si un redémarrage plus long aide-ksp_gmres_restart 300
. Si une transposition est disponible, essayez d'-ksp_type bcgs
autres méthodes qui ne nécessitent pas de redémarrage. (Notez que la convergence avec ces méthodes est souvent erratique.)-pc_type lu
ou en parallèle en utilisant un package tiers (par exemple-pc_type lu -pc_factor_mat_solver_package superlu_dist
, oumumps
). La méthode doit converger en une seule itération si les matrices sont les mêmes, et en un "petit" nombre d'itérations sinon. Essayez-snes_type test
de vérifier les matrices si vous résolvez un problème non linéaire.-ksp_type fgmres or -ksp_type gcr
.-pc_mg_galerkin
de construire algébriquement un opérateur grossier correctement mis à l'échelle ou assurez-vous que toutes les équations sont mises à l'échelle de la même manière si vous souhaitez utiliser des niveaux grossiers rediscrétisés.-ksp_diagonal_scale -ksp_diagonal_scale_fix
. Peut-être changer la formulation du problème pour produire des équations algébriques plus amicales. Si vous ne pouvez pas corriger l'échelle, vous devrez peut-être utiliser un solveur direct.-mat_mffd_type ds
). Essayez d' utiliser une plus grande précision pour rendre la differentiation plus précise,./configure --with-precision=__float128 --download-f2cblaslapack
. Vérifiez s'il converge dans des régimes de paramètres "plus faciles".-ksp_gmres_modifiedgramschmidt
ou utilisez une méthode qui orthogonalise différemment, par exemple-ksp_type gcr
.la source
Mon conseil aux étudiants est d'essayer un solveur direct dans ces cas. La raison en est qu'il existe deux classes de raisons pour lesquelles un solveur peut ne pas converger: (i) la matrice est incorrecte, ou (ii) il y a un problème avec le solveur / préconditionneur. Les solveurs directs produisent presque toujours quelque chose que vous pouvez comparer à la solution que vous attendez, donc si la réponse du solveur direct semble correcte, alors vous savez que le problème vient du solveur / précondition itératif. D'un autre côté, si la réponse semble incorrecte, le problème est lié à l'assemblage de la matrice et du côté droit.
J'utilise généralement simplement UMFPACK comme solveur direct. Je suis sûr qu'il est simple d'essayer quelque chose de similaire avec PETSC.
la source
-pc_type lu -pc_factor_mat_solver_type umfpack
pour utiliser UMFPACK (ou-pc_type cholesky -pc_factor_mat_solver_package cholmod
pour des problèmes SPD) via PETSc, mais notez que UMFPACK et CHOLMOD sont en série. Pour parallèle, l' utilisation-pc_factor_mat_solver_package superlu_dist
oumumps
,pastix
,spooles
.superlu_dist
serait-ksp_type preonly -pc_type lu -pc_factor_mat_solver_package superlu_dist
. Est-ce correct?