Sélection du solveur : NonlinearBlockGS vs NewtonSolver
J'ai deux groupes openmdao avec une dépendance cyclique entre les groupes. Je calcule les dérivées en utilisant l'étape complexe. J'ai un solveur non linéaire pour la dépendance et j'utilise SLSQP pour optimiser ma fonction objectif. Le problème réside dans le choix du solveur non linéaire. Lorsque j'utilise NonlinearBlockGSl'optimisation est réussie en 12 itérations. Mais lorsque j'utilise NewtonSolveravec Directsolverou ScipyKrylovl'optimisation échoue (limite d'itération dépassée), même avec maxiter=2000. Les connexions cycliques convergent, mais c'est juste que les variables de conception n'atteignent pas les valeurs optimales. La différence entre les variables de conception dans les itérations consécutives est de l'ordre 1e-5. Et cela augmente les itérations nécessaires. De plus, lorsque je change la supposition initiale en une valeur plus proche de la valeur optimale, cela fonctionne.
Pour vérifier davantage, j'ai converti le modèle en IDF (en créant des copies des variables de couplage et des contraintes de cohérence), supprimant ainsi le besoin d'un solveur. Maintenant, l'optimisation est réussie en 5 itérations et les résultats sont similaires aux résultats lorsqu'il NonlinearBlockGSest utilisé.
Pourquoi cela arrive-t-il? Est-ce que je manque quelque chose? Quand dois-je utiliser NewtonSolverplutôt que d'autres ? Je sais qu'il est difficile de répondre sans voir le code. Mais c'est juste que mon code est long avec plusieurs composants et je n'ai pas pu recréer le problème avec un modèle de jouet. Donc, toute idée générale est très appréciée.
Réponses
Sans voir le code, vous avez raison de dire qu'il est difficile de donner des détails.
De manière très générale, Newton peut parfois avoir beaucoup plus de mal à converger que NLBGS (Remarque : ce n'est pas absolument vrai, mais c'est une bonne règle empirique). Donc, ce que je suppose qu'il se passe, c'est que lors de votre première ou deuxième itération, le solveur de newton ne converge pas réellement. Vous pouvez vérifier cela en définissant newton.options['iprint']=2et en consultant l'historique des itérations pendant l'itération de l'optimiseur.
Lorsque vous avez un solveur dans votre optimisation, il est essentiel que vous vous assuriez également de le configurer pour générer une erreur en cas de non-convergence. Certains optimiseurs peuvent gérer cette erreur et revenir en arrière sur la recherche de ligne. D'autres mourront tout simplement. De toute façon, c'est important. Sinon, vous finissez par donner à l'optimiseur un cas non convergé dont il ne sait pas qu'il n'est pas convergé.
C'est mauvais pour deux raisons. Tout d'abord, les valeurs d'objectif et de contraintes qu'il obtient seront fausses ! Deuxièmement, et peut-être plus important encore, les dérivées qu'il calcule vont être fausses ! Vous pouvez lire les détails [dans le manuel théorique], mais en résumé, les méthodes dérivées analytiques utilisées par OpenMDAO supposent que les résidus sont passés à 0. Si ce n'est pas le cas, les calculs échouent. Même si vous faisiez un modèle complet de différences finies, les modèles non convergents sont un problème. Vous n'obtiendrez que des déchets bruyants lorsque vous essayez de le FD. 2
Donc, en supposant que vous avez correctement configuré votre modèle et que les solveurs linéaires ont configuré les problèmes (cela ressemble à vous puisque cela fonctionne avec NLBGS), il est fort probable que le solveur de newton ne converge pas. Utilisez iprint, éventuellement combiné avec l'impression de débogage du pilote , pour vérifier cela par vous-même. Si c'est le cas, vous devez comprendre comment faire en sorte que Newton se comporte mieux.
Il y a quelques conseils ici qui sont assez généraux. Vous pouvez également essayer d'utiliser la recherche de ligne armijo , qui peut souvent stabiliser une résolution de newton au prix d'une certaine vitesse.
Enfin... Newton n'est pas la meilleure réponse dans toutes les situations. Si NLBGS est plus stable et moins coûteux en termes de calcul, vous devriez l'utiliser. J'applaudis votre désir de le faire fonctionner avec Newton. Vous devriez certainement rechercher pourquoi ce n'est pas le cas, mais s'il s'avère que Newton ne peut tout simplement pas résoudre votre problème couplé de manière fiable, c'est bien aussi !