Update use_custom authored by Adrien Crovato's avatar Adrien Crovato
......@@ -23,12 +23,21 @@ pbl.setFreestream(aoa, aos, minf)
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.
Lifting bodies are then added using
Bodies are then added using
```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)
```
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
```python
wing.addMotion()
......@@ -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)
```
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
```python
grd = sdpm.Gradient(sol)
......@@ -104,7 +115,7 @@ grd.run()
grd.computePartialsGafRe(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
```python
sens = adj.compute(of, seeds, wrt)
......
......