| ... | @@ -23,12 +23,21 @@ pbl.setFreestream(aoa, aos, minf) |
... | @@ -23,12 +23,21 @@ pbl.setFreestream(aoa, aos, minf) |
|
|
pbl.setUnsteady(n_modes, kred)
|
|
pbl.setUnsteady(n_modes, kred)
|
|
|
```
|
|
```
|
|
|
where `sref` is the reference surface area, `cref` is the reference chord length, `xref`, `yref` and `zref` are the coordinates of the reference center around which aerodynamic moments are computed, `ysym` indicates whether only a half model is provided and y-symmetry boundary condition should be applied, `aoa` and `aos` are the angles of attack and of side slip, `minf` is the freestream Mach number, `n_modes` is the number of unsteady motions and `kred` is an array of reduced frequencies. Note that the last line can be ignored for steady problems.
|
|
where `sref` is the reference surface area, `cref` is the reference chord length, `xref`, `yref` and `zref` are the coordinates of the reference center around which aerodynamic moments are computed, `ysym` indicates whether only a half model is provided and y-symmetry boundary condition should be applied, `aoa` and `aos` are the angles of attack and of side slip, `minf` is the freestream Mach number, `n_modes` is the number of unsteady motions and `kred` is an array of reduced frequencies. Note that the last line can be ignored for steady problems.
|
|
|
Lifting bodies are then added using
|
|
Bodies are then added using
|
|
|
```python
|
|
```python
|
|
|
wing = sdpm.Body(msh, body_name, te_name, cref, n_div, n_modes, n_kred)
|
|
wing = sdpm.Body(msh, body_name)
|
|
|
pbl.addBody(wing)
|
|
pbl.addBody(wing)
|
|
|
```
|
|
```
|
|
|
where `body_name` and `te_name` are the names of the lifting body to be added and of its trailing edge in the Gmsh model, `n_div` is the number of chordwise panels, and `n_kred` is the number of reduced frequencies. For steady problems, the last two arguments default to 0 and `n_div` can be set to 1.
|
|
where `body_name` is the name in the Gmsh model of the lifting body to be added. For a body to produce meaningful aerodynamic loads, one or more wakes must be added using
|
|
|
|
```python
|
|
|
|
wing.addWake(te_name, cref, n_div)
|
|
|
|
```
|
|
|
|
where `te_name` is the name in the Gmsh model of the trailing edge to which the wake is attached and `n_div` is the number of chordwise panels. For steady problems, the latter defaults to 1. Once the wakes have been added, the initialization of the body can be completed using
|
|
|
|
```python
|
|
|
|
wing.initialize(n_modes, n_kred)
|
|
|
|
```
|
|
|
|
where `n_kred` is the number of reduced frequencies. For steady problems, the two arguments default to 0.
|
|
|
|
|
|
|
Unsteady rigid body motions can be added using
|
|
Unsteady rigid body motions can be added using
|
|
|
```python
|
|
```python
|
|
|
wing.addMotion()
|
|
wing.addMotion()
|
| ... | @@ -97,6 +106,8 @@ Additionally, chordwise pressure distributions can be extracted along the wing s |
... | @@ -97,6 +106,8 @@ Additionally, chordwise pressure distributions can be extracted along the wing s |
|
|
sdpm.utils.create_slices(wing, vars, model_name, y_sec)
|
|
sdpm.utils.create_slices(wing, vars, model_name, y_sec)
|
|
|
```
|
|
```
|
|
|
where `vars` is a dictionary containing the name and its corresponding data array (e.g. `{'cp': sol.getPressure()}`), `model_name` is the name of the model (inherited from the model file) and `y_sec` is an array of y coordinates.
|
|
where `vars` is a dictionary containing the name and its corresponding data array (e.g. `{'cp': sol.getPressure()}`), `model_name` is the name of the model (inherited from the model file) and `y_sec` is an array of y coordinates.
|
|
|
|
|
|
|
|
### Calculating the gradients
|
|
|
The derivatives of the Generalized Aerodynamic Force (GAF) matrices can be calculated and accessed using
|
|
The derivatives of the Generalized Aerodynamic Force (GAF) matrices can be calculated and accessed using
|
|
|
```python
|
|
```python
|
|
|
grd = sdpm.Gradient(sol)
|
|
grd = sdpm.Gradient(sol)
|
| ... | @@ -104,7 +115,7 @@ grd.run() |
... | @@ -104,7 +115,7 @@ grd.run() |
|
|
grd.computePartialsGafRe(i_freq, i_mode, i_row, j_col, wrt)
|
|
grd.computePartialsGafRe(i_freq, i_mode, i_row, j_col, wrt)
|
|
|
grd.computePartialsGafIm(i_freq, i_mode, i_row, j_col, wrt)
|
|
grd.computePartialsGafIm(i_freq, i_mode, i_row, j_col, wrt)
|
|
|
```
|
|
```
|
|
|
The last two lines will return the derivative of the real and imaginary parts of the GAF matrix entry at row `i_row` and column `j_col` with respect to the component `wrt` of mode number `i_mode` at frequency `i_freq` for all body nodes. `wrt` can either be `'a'` (rigid pitch), `'h'` (rigid plunge), `'dz'` (modal displacements along z), `'rx'` (modal rotations about x) or `'ry'` (modal rotations about y).
|
|
The last two lines will return the derivative of the real and imaginary parts of the GAF matrix entry at row `i_row` and column `j_col` with respect to the component `wrt` of mode number `i_mode` at frequency `i_freq` for all body nodes. `wrt` can either be `'a'` (rigid pitch), `'h'` (rigid plunge), `'dx'` (modal displacements along x), `'dy'` (modal displacements along y), `'dz'` (modal displacements along z), `'rx'` (modal rotations about x), `'ry'` (modal rotations about y) or `'rz'` (modal rotations about z). Note that the gradients are only implemented for the subsonic solver and not the transonic one.
|
|
|
If automatic differentiation has been enabled, the sensitivities of the solution can be computed using
|
|
If automatic differentiation has been enabled, the sensitivities of the solution can be computed using
|
|
|
```python
|
|
```python
|
|
|
sens = adj.compute(of, seeds, wrt)
|
|
sens = adj.compute(of, seeds, wrt)
|
| ... | |
... | |
| ... | | ... | |