-
Notifications
You must be signed in to change notification settings - Fork 913
Description
Hey everyone,
I have been taking a deep dive into the shape optimization features in SU2 and have resurfaced with some observations, suggestions, and questions.
First, the bug:
Even though the config_template, and option structure have changed the numbering of the DEFINITION_DV (for example, FFD_CONTROL_POINT went from being 7 to 11), this has not been reflected in the SU2_PY/SU2/io/tools.py, or any of the tutorials. Therefore, there is a mismatch in what the C++ code uses, and what the python code uses. This is an easy problem to fix and is being fixed in the branch fix_set_ffd_script.
Next, I want to have a discussion about the shape optimization options and scalings. Currently there are the following options in the config template to control scaling:
% Optimization objective function with scaling factor, separated by semicolons.
% To include quadratic penalty function: use OPT_CONSTRAINT option syntax within the OPT_OBJECTIVE list.
% ex= Objective * Scale
OPT_OBJECTIVE= DRAG * 10
% Optimization constraint functions with pushing factors (affects its value, not the gradient in the python scripts), separated by semicolons
% ex= (Objective = Value ) * Scale, use '>','<','='
OPT_CONSTRAINT= ( LIFT > 0.328188 ) * 0.001; ( MOMENT_Z > 0.034068 ) * 0.001; ( AIRFOIL_THICKNESS > 0.11 ) * 0.001
%
% Factor to reduce the norm of the gradient (affects the objective function and gradient in the python scripts)
% In general, a norm of the gradient ~1E-6 is desired.
OPT_GRADIENT_FACTOR= 1E-6
%
% Factor to relax or accelerate the optimizer convergence (affects the line search in SU2_DEF)
% In general, surface deformations of 0.01'' or 0.0001m are desirable
OPT_RELAX_FACTOR= 1E3
%
% Optimization bound (bounds the line search in SU2_DEF)
OPT_LINE_SEARCH_BOUND= 0.1
%
% Upper bound for each design variable (bound in the python optimizer)
OPT_BOUND_UPPER= 1E10
%
% Lower bound for each design variable (bound in the python optimizer)
OPT_BOUND_LOWER= -1E10
%
% Optimization design variables, separated by semicolons
DEFINITION_DV= ( 19, 1.0 | airfoil | AIRFOIL, 0, 0, 0, 1.0 ); ...
Now this provides a lot of flexibility in scaling the inputs to the optimizer, which is great because these optimizers aren't very robust with scaling. But the way they behave is sometimes a little odd. I am going to go through each option and talk about how it affects things (to the best of my knowledge). I am hoping someone can shed some light on the choices that were made and correct me if I am wrong in any of my assessment.
-
OPT_OBJECTIVE Scaling: It scales the objective function with the factor that you multiply it with. In the case above, the DRAG is being scaled by 10. This scaling is also applied to the gradient of the objective function.
-
OPT_CONSTRAINT Scaling: Same as the OPT_OBJECTIVE scaling, but for the constraints
-
OPT_GRADIENT_FACTOR: This is a misleading name and I propose changing it. Even though the name has gradient in it, this scaling is applied to both, the objective/constraint, and its gradient. I would like to change the name to OPT_GLOBAL_FACTOR. The reason why this is global and different from the objective/constraint scaling is because it's applied uniformly to all objectives and constraints.
-
OPT_RELAX_FACTOR: This is a scaling factor that purely multiplies the DV_VALUES from a config file, before applying the deformation to the mesh. For example, if you are performing a 2D optimization using a FFD and the optimizer spits out a suggested DV_VALUE of 0.001, the mesh deformation routine will move the FFD control point by 1 (according to the scaling given above)
-
OPT_LINE_SEARCH_BOUND: This is an interesting one and the one I am least sure off. This option limits the maximum final movement of the FFD control points in the cartesian coordinate system. So, DV_VALUE * OPT_RELAX_FACTOR results in a movement of the FFD_CONTROL_POINT. If the the maximum movement of any of the control points is greater than OPT_LINE_SEARCH_BOUND, then all the control point movements are scaled such that the maximum movement = OPT_LINE_SEARCH_BOUND.
-
OPT_UPPER/LOWER_BOUND: This value is divided by the OPT_RELAX_FACTOR to give the optimizer the maximum/minimum values for the design variables.
-
DEFINITION_DV Scaling: This one I am really confused about. The only place that I can find this being used, is to scale the gradient of the objectives/constraints. It doesn't seem to actually scale the DVs anywhere in the python code, except for in the initialization, where the DVs are zeroed out anyway. Am I missing something here? Is it correct to think that scaling the gradients is one way to ensure that the DVs that the optimizer outputs scaled DVs?
In general, I think it'd be useful to have more information in the config template so that the scalings don't seem to be a dark art. The template does have some suggestions, like the gradient norm should order 10^-6. I have found this suggestion to be super useful, and it does work well. But I am not sure why the gradients need to be so small for the optimizer to work well. Any insight into this value?
In the end I am hoping to de-mystify some of the scalings, and how best to go about them. Ideally at the end of this discussion I can document some best practices (at least for the case of 3D shape optimization with FFD_CONTROL_POINTS). Any comments, suggestions, corrections, and/or insight would be super helpful.