Skip to content

Aero-Structural Discrete Adjoint Sensitivities and Python Wrapper Developments #1750

Open
patelha57 wants to merge 172 commits intodevelopfrom
feature_pysu2_fsi_adjoint
Open

Aero-Structural Discrete Adjoint Sensitivities and Python Wrapper Developments #1750
patelha57 wants to merge 172 commits intodevelopfrom
feature_pysu2_fsi_adjoint

Conversation

@patelha57
Copy link
Copy Markdown
Contributor

@patelha57 patelha57 commented Sep 5, 2022

Motivation

Fundamental bottlenecks exist for industrial adoption of high-fidelity physics codes with fully coupled discrete adjoint sensitivity analysis. These bottlenecks include a lack of flexibility, modularity, and robustness of the computational tools, as well as the potential startup development costs needed to implement and verify the MDAO features. The purpose of this work is to facilitate the coupling of SU2 with external structural codes (e.g. NASTRAN, TACS, Airbus structural suite Lagrange) for gradient-based aerodynamic shape and structural sizing optimization using dedicated frameworks (e.g. OpenMDAO).

Startup development costs include the creation of modular tools that are designed to be driven by another framework like OpenMDAO, rather than to drive execution themselves. However, leveraging those MDAO frameworks assumes that software codes and modules to be coupled exist, have appropriate data structures, execution and query APIs, and are wrapped in Python for flexibility and ease of use. The proposed changes were motivated with the goal of making SU2 more modular and flexible, particularly to facilitate its integration into large-scale MDAO frameworks. For more details on the motivation, methodology, and verification & validation results, please refer to our paper from AIAA Aviation 2022.

Proposed Changes

@aa-g and I propose the following code updates:

  1. Implementation of residual-based discrete adjoint solver as CDiscAdjResidualSolver
    a. New config option: KIND_DISC_ADJ

  2. Enhancements and standardization of SU2 Python API
    a. Add pysu2/pysu2ad methods
    b. Standardize Python API and function names
    c. Overloaded getter/setter methods to make data handling more flexible

Related Work

These efforts are related to Issue #1262, Pull Request #1300, and Discussion #1325.

PR Checklist

  • I am submitting my contribution to the develop branch.
  • My contribution generates no new compiler warnings (try with --warnlevel=3 when using meson).
  • My contribution is commented and consistent with SU2 style (https://su2code.github.io/docs_v7/Style-Guide/).
  • I used the pre-commit hook to prevent dirty commits and used pre-commit run --all to format old commits.
  • I have added a test case that demonstrates my contribution, if necessary.
  • I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary.

WallyMaier and others added 30 commits May 7, 2020 14:20
@bigfooted
Copy link
Copy Markdown
Contributor

Hi @patelha57 what is the current status? Would be nice to see a couple of older PR's get merged into develop, especially this one.

@patelha57
Copy link
Copy Markdown
Contributor Author

Hi @patelha57 what is the current status? Would be nice to see a couple of older PR's get merged into develop, especially this one.

No additional code development needed from my POV (please correct me if I'm wrong!). Just need to fix these regression tests failures, add example for the residual solver adjoint, and add documentation.

Comment on lines +62 to +101
/*!
* \brief Get total sensitivity of the objective function w.r.t. surface coordinates or displacements at mesh
* vertices. \return Total sensitivity of the objective function w.r.t. the un-deformed coordinates.
*/
vector<vector<passivedouble>> GetObjectiveCoordinatesTotalSensitivities() const;

/*!
* \brief Get total sensitivity of the objective function w.r.t. surface coordinates or displacements at a mesh
* vertex. \param[in] iPoint - Mesh vertex index. \return Total sensitivity of the objective function w.r.t. the
* un-deformed coordinates.
*/
vector<passivedouble> GetObjectiveCoordinatesTotalSensitivities(unsigned long iPoint) const;

/*!
* \brief Get total sensitivity of the objective function w.r.t. surface coordinates or displacements at marker
* vertices. \param[in] iMarker - Marker identifier. \return Total sensitivity of the objective function w.r.t. the
* surface coordinates.
*/
vector<vector<passivedouble>> GetMarkerObjectiveCoordinatesTotalSensitivities(unsigned short iMarker) const;

/*!
* \brief Get total sensitivity of the objective function w.r.t. surface coordinates or displacements at a marker
* vertex. \param[in] iMarker - Marker identifier. \param[in] iVertex - Marker vertex index. \return Total sensitivity
* of the objective function w.r.t. the surface coordinates.
*/
vector<passivedouble> GetMarkerObjectiveCoordinatesTotalSensitivities(unsigned short iMarker,
unsigned long iVertex) const;

/*!
* \brief Get total sensitivity of the objective function w.r.t. the design variables.
* \return Total sensitivity of the objective function w.r.t. the design variables.
*/
vector<vector<passivedouble>> GetObjectiveDesignVariablesTotalSensitivities() const;

/*!
* \brief Get total sensitivity of the objective function w.r.t. a design variable.
* \param[in] iDV - Design Variable index.
* \return Total sensitivity of the objective function w.r.t. a design variable.
*/
vector<passivedouble> GetObjectiveDesignVariablesTotalSensitivities(unsigned short iDV) const;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This interface is not adequate, there is a better alternative as I've explained before.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are talking about the matrix view implementation, correct?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, there is a recent example of doing that for another type of container here https://github.com/su2code/SU2/pull/2388/changes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much, I started converting them. Would appreciate a review and any additional comments when you get a chance!

Copy link
Copy Markdown
Member

@pcarruscag pcarruscag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, looks good to me, mostly just comments about naming conventions.

* \param[in] alpha - Angle (degree).
*/
void SetFarFieldAoA(passivedouble alpha);
void SetAngleOfAttack(passivedouble alpha);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void SetAngleOfAttack(passivedouble alpha);
void SetFarFieldAoA(passivedouble alpha);

* \param[in] beta - Angle (degree).
*/
void SetFarFieldAoS(passivedouble beta);
void SetAngleOfSideslip(passivedouble beta);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void SetAngleOfSideslip(passivedouble beta);
void SetFarFieldAoS(passivedouble beta);

Comment on lines +577 to +587
/*!
* \brief Get the number of conservative state variables.
* \return Number of conservative state variables.
*/
unsigned long GetNumberStateVariables() const;

/*!
* \brief Get the number of primitive state variables.
* \return Number of primitive state variables.
*/
unsigned long GetNumberPrimitiveVariables() const;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this known from the primitive indices return? If not, this info belongs there, or at least together with the corresponding functions.

Comment on lines +615 to +621
/*!
* \brief Get sensitivity of flow residuals with respect to farfield design variables as a matrix-vector product with
* the adjoint variable.
* \return Partial derivative of aerodynamic residuals with respect to farfield design variable.
*/
vector<passivedouble> GetResidualsFarfieldVariablesSensitivities() const;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a matrix/vector view?

Comment on lines +609 to +613
/*!
* \brief Get sensitivity of objective function with respect to farfield design variables as a partial derivative.
* \return Partial derivative of aerodynamic function with respect to farfield design variable.
*/
vector<passivedouble> GetObjectiveFarfieldVariablesSensitivities() const;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the farfield design variables? can you document the expected size of the vector?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now the only supported farfield design variables are 1) angle of attack and 2) mach number.

Comment on lines +596 to +607
/*!
* \brief Get a read-only view of dCoordinates/dCoordinates^T * psi for all mesh nodes.
* \return CPyWrapperMatrixView of shape (nPoint, nDim).
*/
CPyWrapperMatrixView CoordinatesCoordinatesSensitivities() const;

/*!
* \brief Get a read-only view of dCoordinates/dDisplacements^T * psi for a marker.
* \param[in] iMarker - Marker index.
* \return CPyWrapperMatrixView of shape (nVertex, nDim).
*/
CPyWrapperMatrixView MarkerCoordinatesDisplacementsSensitivities(unsigned short iMarker) const;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these derivatives of deformed coordinates with respect to original coordinates and boundary deformations, respectively? The comments or function names could reflect that deformed/original difference better

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CoordinatesCoordinatesSensitivities() is sensitivity of volume coordinate w.r.t deformed surface coordinates... so dxv/dxa. And MarkerCoordinatesDisplacementsSensitivities() is for deformed surface coordinates w.r.t surface displacements dxa/dua.

I will update function names and documentation accordingly.

Comment on lines +623 to +638
* \brief Get a read-only view of dObjective/dStates for all mesh nodes.
* \return CPyWrapperMatrixView of shape (nPoint, nVar).
*/
CPyWrapperMatrixView ObjectiveStatesSensitivities() const;

/*!
* \brief Get a read-only view of dResiduals/dStates^T * psi for all mesh nodes.
* \return CPyWrapperMatrixView of shape (nPoint, nVar).
*/
CPyWrapperMatrixView ResidualsStatesSensitivities() const;

/*!
* \brief Get a read-only view of dTractions/dStates^T * psi for all mesh nodes.
* \return CPyWrapperMatrixView of shape (nPoint, nVar).
*/
CPyWrapperMatrixView ForcesStatesSensitivities() const;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is meant by states here? The solution, i.e. conservative variables? If so, please make the term consistent.

Copy link
Copy Markdown
Contributor Author

@patelha57 patelha57 Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes states refers to conservative variables. I will make that explicit... ObjectiveSolutionSensitivities(), ResidualsSolutionSensitivities(), etc...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to add these? They don't seem used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just using this simple box example to debug and verify sens from residual-based solver match fixed-point. Will remove these configs after incorporating the check into the new example script

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants