In this tutorial we show how to deform a blade using a parameter file. A BladeX parameter file is a file that contains information about the radial distribution of parameters `chord`

, `pitch`

, `rake`

, `skew`

, `camber`

at specific radial sections. In addition to that, it also contains information about the B-spline construction of each of the parametric curves as well as their control points deformations as a way to deform the whole blade.

The tutorial is divided into two sections: the first section deals with the `ParamFile`

class, where it shows how to handle a parameter file in terms of reading an initial file, perform some changes to the included parameters, and then writing out the manipulated data. The second section deals with the `Deformation`

class which is responsible for deforming the blade parametric curves based on the information given in a parameter file. The `Deformation`

class also allows us to export the parameter file of the deformed radial distribution of the parameters, so that we can read that deformed parameters of the exported file via the `ParamFile`

class, and also to generate the deformed blade via the `Blade`

class.

`ParamFile`

class for handling the parameter file, and we import the `Deformation`

class for the blade deformation.
We also import `numpy`

and we set `matplotlib`

for the notebook.

In [1]:

```
import matplotlib.pyplot as plt
import numpy as np
from bladex import ParamFile, Deformation
```

**param_file** of the `ParamFile`

class, then we read the parameter file through the `read_parameters`

method with passing a valid string for the parameter file name. In case the filename does not exist then the method creates a default parameter file then reads it. In this tutorial we generate a default parameter file using this procedure, then we operate on the file data using the `ParamFile`

module.

In [2]:

```
# In order to ensure that the method generates a reads a default parameter file,
# we have first to check and remove the parameter file if exists.
import os
if os.path.exists('data/parameters.prm'):
os.remove('data/parameters.prm')
# Instantiate the ParamFile object, generate a default parameter file then reads it
param_file = ParamFile()
param_file.read_parameters(filename='data/parameters.prm')
```

To show the associated data of the `ParamFile`

object we just need to print that object. The associated data are as follows:

Radii sections.

Radial distribution of the parameters

`chord lengths`

,`pitch`

,`rake`

,`skew`

,`camber`

BSpline curve constructing the radial distribution of the previous parameters. The specified information are:

- spline degree
- spline discrete points to be evaluated (npoints)
- spline control points (nbasis)
- Y deformation of the control points

In [3]:

```
print(param_file)
```

`chord`

, `pitch`

, `rake`

, `skew`

, `camber`

are all array of zeros (with length = 8). The default spline degree is 3, and the spline is constructed with 500 points for evaluating the B-spline. Finally each spline is associated with 10 control points by default, and the default deformations are array of zeros (with length = 10) for all the parameters. We also emphasize that all the arrays for the radial distribution of parameters `chord`

, `pitch`

, `rake`

, `skew`

, `camber`

must have the same length as the radial sections; which is 8 in this tutorial; otherwise an exception is raised.

Now suppose we want to change some values in the parameter file. We can do that either by opening the file and changing the values manually, or we can go the smarter way and change the values through the module itself.

Suppose we are interested in changing the following parameters:

First radial section, i.e.

`radii[0]`

= 0.31. (Default value was 0.3)Radial distribution of the chord = [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]. (Default was array of zeros)

Radial distribution of the pitch = [0.1, 0.14, 0.19, 0.25, 0.28, 0.26, 0.23, 0.15]. (Default was array of zeros)

Pitch deformations = [0.025, 0.025, 0.03, 0.01, -0.009, -0.01, -0.02, -0.03, -0.03, -0.05]. (Default was array of zeros)

Radial distribution of the rake = [0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08]. (Default was array of zeros)

Spline degree of the rake = 5. (Default was 3)

Spline number of points for the rake = 1000. (Default was 500)

Radial distribution of the skew = [0.3, 0.25, 0.21, 0.18, 0.19, 0.23, 0.28, 0.32]. (Default was array of zeros)

Number of control points for the skew = 5. (Default was 10) // Now we have to change the length of deformations array for the skew curve as well

Deformations array of the skew = [-0.01, -0.03, -0.06, -0.04, 0.07]. (Default was array of zeros with length=10)

We apply these changes to the **param_file** object as follows.

In [4]:

```
# Change radii first section
param_file.radii[0] = 0.31
# Change radial distribution of chord. Same procedure can be applied to other
# parameters by simply replacing the string 'chord' into any of the
# following: 'pitch', 'rake', 'skew', or 'camber'
param_file.parameters['chord'] = np.array([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
# Change radial distribution of pitch
param_file.parameters['pitch'] = np.array([0.1, 0.14, 0.19, 0.25, 0.28, 0.26, 0.23, 0.15])
# Change pitch deformations. Same procedure can be applied to other
# parameters by simply replacing the string 'pitch' into any of the
# following: 'chord', 'rake', 'skew', or 'camber'
param_file.deformations['pitch'] = np.array([0.025, 0.025, 0.03, 0.01, -0.009, -0.01, -0.02, -0.03, -0.03, -0.05])
# Change radial distribution of rake
param_file.parameters['rake'] = np.array([0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08])
# Change spline degree of rake. Same procedure can be applied to other
# parameters by simply replacing the string 'rake' into any of the
# following: 'chord', 'pitch', 'skew', or 'camber'
param_file.degree['rake'] = 5
# Change spline npoints of rake. Same procedure can be applied to other
# parameters by simply replacing the string 'rake' into any of the
# following: 'chord', 'pitch', 'skew', or 'camber'
param_file.npoints['rake'] = 1000
# Change radial distribution of skew angles
param_file.parameters['skew'] = np.array([0.3, 0.25, 0.21, 0.18, 0.19, 0.23, 0.28, 0.32])
# Change number of control points of skew spline curve. Same procedure can be applied to other
# parameters by simply replacing the string 'skew' into any of the
# following: 'chord', 'pitch', 'rake', or 'camber'
param_file.nbasis['skew'] = 5
# Change Y control points deformations of skew spline curve. Same procedure can be applied to other
# parameters by simply replacing the string 'skew' into any of the
# following: 'chord', 'pitch', 'rake', or 'camber'
param_file.deformations['skew'] = np.array([-0.01, -0.03, -0.06, -0.04, 0.07])
```

**param_file** object holds the updated data correctly, we print out the associated data of the object.

In [5]:

```
print(param_file)
```

In [6]:

```
param_file.write_parameters(filename='data/parameters.prm')
```

Now that we prepared the parameters file with the desired data, we wish to apply the deformations to the parametric curves. In this tutorial we deform only the pitch and skew curves by specifying their deformation arrays with non-zero values. After that we evaluate the radial distribution of the deformed curves at the same radial sections, i.e. radii = [0.31, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] and then export a new parameters file holding the deformed parameters while resetting the deformations back to zeros.

First of all We instantiate the deformation object **deform**

In [7]:

```
deform = Deformation(paramfile='data/parameters.prm')
```

`ParamFile`

attributes (e.g. `radii`

, `parameters`

, `degree`

, `nbasis`

, `npoints`

, `deformations`

) through the **deform** object, then we can do that through the `param`

attribute. An example is shown below.

In [8]:

```
# Radial distribution of chord
print(deform.param.parameters['chord'])
# Control points deformations of pitch
print(deform.param.deformations['pitch'])
# Spline degree of rake
print(deform.param.degree['rake'])
```

`param`

attribute, the **deform** object has also `paramfile`

, `deformed_parameters`

, `control_points`

, `spline`

. The last three attributes are Python dictionaries where the valid keys are the strings (`chord`

, `pitch`

, `rake`

, `skew`

, `camber`

). An example of how to access such attributes is shown below.

In [9]:

```
print('Parameter file name: ', deform.paramfile)
print('Initial values of chord deformed radial distribution (no computations performed yet): ', deform.deformed_parameters['chord'])
print('Initial control points coordinates of pitch: ', deform.control_points['pitch'])
print('Initial spline evaluations of camber: ', deform.spline['camber'])
```

Now we compute the control points of the pitch and skew curves.

In [10]:

```
deform.compute_control_points(param='pitch')
deform.compute_control_points(param='skew')
```

`update_control_points`

method.

In [11]:

```
deform.update_control_points(param='pitch')
deform.update_control_points(param='skew')
```

In [12]:

```
deform.generate_spline(param='pitch')
deform.generate_spline(param='skew')
deform.plot(param=['pitch', 'skew'], original=True, ctrl_points=True, spline=True, rbf=False, rbf_points=500, deformed=False, outfile=None)
```

`pitch`

and `rake`

, at the same radial sections, we run the `compute_deformed_parameters`

for both parameters. This method searches the spline npoints evaluations for those who lie at the radii sections within some tolerance. It is important to specify the tolerance carefully so that finding the deformed parameters is feasible.

In [13]:

```
deform.compute_deformed_parameters(param='pitch', tol=1e-3)
deform.compute_deformed_parameters(param='skew', tol=1e-3)
print('Pitch deformed parameters: ', deform.deformed_parameters['pitch'])
print('\nSkew deformed parameters: ', deform.deformed_parameters['skew'])
```

Finally we plot the `pitch`

and `skew`

curves including the following:

Original radial distribution of the parameter.

Radial Basis Function (RBF) interpolation of the radial distribution of the parameter.

Updated control points of the B-spline interpolation, after performing the deformation.

B-spline interpolation of the parametric curve, constructed using the control points.

Deformed radial distribution of the parameter.

We also export a new parameter file which contains now the radial sections of the deformed parameters, while the deformations array is reset to zeros, since we already applied the deformation.

In [14]:

```
deform.plot(param=['pitch', 'skew'], original=True, ctrl_points=True, spline=True, rbf=True, rbf_points=500, deformed=True, outfile=None)
deform.export_param_file(outfile='data/parameters_mod.prm')
```

Now that we have a new parameter file that includes the deformed parameters, we can read those parameters and use them to create a `Blade`

object, so that we can visualize the deformed blade sections using the `Blade`

class.

An example is shown in the following.

In [15]:

```
from bladex import Blade, NacaProfile
# Instantiate a `ParamFile` class object and read the parameter file
param_deformed = ParamFile()
param_deformed.read_parameters(filename='data/parameters_mod.prm')
# Use NACA-0012 profiles for the blade sections, to apply parameters deformations on them
sections_deformed = np.asarray([NacaProfile(digits='0012') for i in range(8)])
# Instantiate a `Blade` class object, and assign the Blade parameters with those from the parameter file
blade_deformed = Blade(sections=sections_deformed,
radii=param_deformed.radii,
chord_lengths=param_deformed.parameters['chord'],
pitch=param_deformed.parameters['pitch'],
rake=param_deformed.parameters['rake'],
skew_angles=param_deformed.parameters['skew'])
# Apply transformations, without reflecting the profiles about the origin
blade_deformed.apply_transformations(reflect=False)
# Plot the deformed blade, with setting elevation and azimuth view angles
blade_deformed.plot(elev=45, azim=45)
```