# Learning Airfoil Parameters¶

This is a tutorial to determine the aerodynamic coefficients of a given airfoil using GENN in SMT (other models could be used as well). The obtained surrogate model can be used to give predictions for certain Mach numbers, angles of attack and the aerodynamic coefficients. These calculations can be really useful in case of an airfoil shape optimization. The input parameters uses the airfoil Camber and Thickness mode shapes.

Inputs: Airfoil Camber and Thickness mode shapes, Mach, alpha

Outputs (options): cd, cl, cm

In this test case, we will be predicting only the Cd coefficient. However, the other databases for the prediction of the other terms are available in the same repository. Bouhlels mSANN uses the information contained in the paper [1] to determine the airfoil’s mode shapes. Moreover, in mSANN a deep neural network is used to predict the Cd parameter of a given parametrized airfoil. Therefore, in this tutorial, we reproduce the paper [2] using the Gradient-Enhanced Neural Networks (GENN) from SMT.

Briefly explaining how mSANN generates the mode shapes of a given airfoil:

Using inverse distance weighting (IDW) to interpolate the surface function of each airfoil.

Then applying singular value decomposition (SVD) to reduce the number of variables that define the airfoil geometry. It includes a total of 14 airfoil modes (seven for camber and seven for thickness).

Totally 16 input variables, two flow conditions of Mach number (0.3 to 0.6) and the angle of attack (2 degrees to 6 degrees) plus 14 shape coefficients.

The output airfoil aerodynamic force coefficients and their respective gradients are computed using ADflow, which solves the RANS equations with a Spalart-Allmaras turbulence model.

See also [3], [4], [5], [6] for more information.

## References¶

## Implementation¶

### Utilities¶

```
import csv
import os
import numpy as np
WORKDIR = os.path.dirname(os.path.abspath(__file__))
def load_NACA4412_modeshapes():
return np.loadtxt(open(os.path.join(WORKDIR, "modes_NACA4412_ct.txt")))
def load_cd_training_data():
with open(os.path.join(WORKDIR, "cd_x_y.csv")) as file:
reader = csv.reader(file, delimiter=";")
values = np.array(list(reader), dtype=np.float32)
dim_values = values.shape
x = values[:, : dim_values[1] - 1]
y = values[:, -1]
with open(os.path.join(WORKDIR, "cd_dy.csv")) as file:
reader = csv.reader(file, delimiter=";")
dy = np.array(list(reader), dtype=np.float32)
return x, y, dy
def plot_predictions(airfoil_modeshapes, Ma, cd_model):
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
# alpha is linearily distributed over the range of -1 to 7 degrees
# while Ma is kept constant
inputs = np.zeros(shape=(1, 15))
inputs[0, :14] = airfoil_modeshapes
inputs[0, -1] = Ma
inputs = np.tile(inputs, (50, 1))
alpha = np.atleast_2d([-1 + 0.16 * i for i in range(50)]).T
inputs = np.concatenate((inputs, alpha), axis=1)
# Predict Cd
cd_pred = cd_model.predict_values(inputs)
# Load ADflow Cd reference
with open(os.path.join(WORKDIR, "NACA4412-ADflow-alpha-cd.csv")) as file:
reader = csv.reader(file, delimiter=" ")
cd_adflow = np.array(list(reader)[1:], dtype=np.float32)
plt.plot(alpha, cd_pred)
plt.plot(cd_adflow[:, 0], cd_adflow[:, 1])
plt.grid(True)
plt.legend(["Surrogate", "ADflow"])
plt.title("Drag coefficient")
plt.xlabel("Alpha")
plt.ylabel("Cd")
plt.show()
```

### Main¶

- ::
Drag coefficient prediction (cd): 0.009881152860141375