su2code / SU2

SU2: An Open-Source Suite for Multiphysics Simulation and Design
https://su2code.github.io
Other
1.35k stars 842 forks source link

Turbomachinery adjoint objective functions #889

Closed auzbaig closed 4 years ago

auzbaig commented 4 years ago

What are the objective functions that are available with Turbomachinery for the adjoint solver? The test case "disk_adj_turbomachinery/transonic_stator_2D" does not work with the python script:

$ shape_optimization.py -g DISCRETE_ADJOINT -f transonic_stator_2D.cfg

and shows the following error:

  File "/home/baigan/SU2/bin/SU2/opt/project.py", line 129, in __init__
    group = historyOutFields[this_obj]['GROUP']
KeyError: 'ENTROPY_GENERATION'

If I change the objective function to DRAG then this error disappears but then it won't support the constraint for FLOW_ANGLE_OUT. Is ENTROPY_GENERATION supported for Turbomachinery or not?

I generated the FFD mesh using DV_KIND=FFD_SETTING and then changed to FFD_CONTROL_POINT_2D with the new mesh.

A discrete adjoint run of SU2_CFD_AD seems to converge nicely. But how can I manually go through the process of generating config files for SU2_DOT / SU2_DEF to get the next deformed shape and what is the sequence they must be run if the python script is not working?

auzbaig commented 4 years ago

Hi , @economon @talbring , @pcarruscag , have any of you tried running this case before? I also face similar problems for 3D cases. I don't know whether this is a bug or I am doing something wrong.

economon commented 4 years ago

@auzbaig : sorry that this has been giving you issues. I think there are a couple of things happening here. First, there were important changes when all of the output was rewritten for v7, including a change in how the output fields are recognized by the python framework. In this commit (https://github.com/su2code/SU2/commit/39dbebc574a0886fa7c165d342dce8490947dbbe), a new history mapping capability was added, so that, rather than hard-coding the possible types of output/objective fields, the list can be updated automatically using updateHistoryMap.py, which parses the C++ files for available fields. You can see the available output fields for your problem by executing the dry run mode.

The second thing is that updateHistoryMap.py only parses a set list of files (you can find the list at the top of the file), and at the moment, the turbomachinery-specific outputs are not included. The turbomachinery features are being restructured currently in #866, which includes connecting it to the new output classes.

@talbring @salvovitale : please correct me if I am missing anything

auzbaig commented 4 years ago

@economon Thanks for your response. This issue is not Turbomachinery specific as I discovered later. The script is not working for the Tutorial Multi Objective Shape Design. Even if I exclude the turbomachinery markers and use generic inlet and outlets with periodic boundaries the same issue still remains.

What does it mean when it says: KeyError: 'ENTROPY_GENERATION'? This issue is with almost any other objective function other than lift, drag or efficiency.

economon commented 4 years ago

In short, it means that the particular objective that you are requesting is not available in the python framework at this time. You can run

$ SU2_CFD your_config.cfg -d

to see the list of possible outputs that can be used as objectives for your particular problem currently. There are some objectives that have not been moved to the new output structure yet (but they are coming). In the meantime, you can add new custom history outputs for the flow solver (see CFlowCompOutput.cpp for instance) and then use them for objectives during shape optimization (you will likely need to run updateHistoryMap.py to register the new outputs with python).

auzbaig commented 4 years ago

@economon Thanks for your answer. I have a couple more queries if you won't mind. When you say that the objective functions are not defined for the problem do you mean that I cannot solve the adjoint equations with that objective or just not yet use it with the shape optimization script as that data is not in the history output?

Secondly, how would I see how an objective function is defined? I have tried to see definitions for ENTROPY_GENERATION, TOTAL_PRESSURE_LOSS, KINETIC_ENERGY_LOSS, etc but couldn't find through a keyword search. Although it is solving the adjoint equations with these objectives, I don't know what they really mean.

Third, I see there is an obj function: CUSTOM_OBJFUNC. How do I define a custom objective function in SU2?

Thanks, Aman

economon commented 4 years ago

The discrete adjoint may still run with the chosen objective, since that is entirely defined within the C++, but some additional steps may be needed to run your objective with the Python framework. First, I recommend that you verify in your primal solve that you can compute one of your chosen objectives such as ENTROPY_GENERATION, and that it appears in the history file, since this is a prerequisite for running shape optimization with the Python framework.

You should be able to follow details of the old ENTROPY_GENERATION objective if you look in the COutputLegacy::SpecialOutput_Turbo() routine in the legacy output. Note that you may need to do some work to connect this for your particular problem, since as mentioned, the turbomachinery related features are currently being brought into line with the most recent version of the software, and the routine may not be called by default.

Once you have your desired objectives being computed and printed to the history file, give the updateHistoryMap.py script a look so that you can update the fields that the python framework can handle.

As for custom objectives, there is a variable within the fluid solvers named Total_Custom_ObjFunc that will be differentiated for you if you use it compute a custom expression within the solver class (you can do this in multiple places within the solver class, but make sure it is called). Same suggestions apply for making sure that you can compute the custom objective, it appears in the history file, and that the python script is updated to read that particular field during optimization.

auzbaig commented 4 years ago

@economon Thanks for your answer. Till when do you expect the Turbomachinery output structure will be in line with the rest of the code?

economon commented 4 years ago

That is dependent on #866, which is still in progress

xiapxiaoyu1981 commented 2 months ago

Hi Economon,

I encountered an issue very similar to what Auzbaig reported: the error message "OBJECTIVE_FUNCTION: invalid option value EntropyGeneration" during optimization with SU2. (I am using SU2 version 8.0.1 "Harrier.")

After thoroughly examining the existing Python optimization framework, I found that one of the steps in the optimization chain is generating different config.cfg files, with a focus on DV_VALUE and OBJECTIVE_FUNCTION.

DV_VALUE controls the geometry deformation; OBJECTIVE_FUNCTION determines the type of objective/constraints. Then the framework calls SU2_CFD and SU2_DOT to obtain performance metrics or gradient information. As you mentioned, "You might need to run updateHistoryMap.py to register new outputs with Python." Initially, I thought it meant simply providing a new input for OBJECTIVE_FUNCTION in the Python optimization framework. However, it seems that this may not work at the C++ level.

To verify this, I ran $ SU2_CFD your_config.cfg -d and observed all available history outputs. However, I suspect that OBJECTIVE_FUNCTION cannot use every history output, meaning that the adjoint solver might not recognize some objective functions. Does this imply that additional modifications in the C++ code are required?

Additionally, I would appreciate more information regarding CUSTOM_OBJFUNC. From TestCases/user_defined_functions/lam_flatplate.cfg, I understand that CUSTOM_OBJFUNC allows combinations of existing OBJECTIVE_FUNCTIONs and can also utilize CUSTOM_OUTPUTS. The flexibility of CUSTOM_OUTPUTS seems to enable the construction of various desired variables.

However, I am unsure whether using OBJECTIVE_FUNCTION= CUSTOM_OBJFUNC along with CUSTOM_OUTPUTS can entirely replace the need for additional modifications in the C++ code. Since I’m not very proficient in C++, I would greatly appreciate your guidance.

Sincerely, Tongtong