Skip to content
Snippets Groups Projects
Verified Commit ad70fcba authored by Thomas Lambert's avatar Thomas Lambert :helicopter:
Browse files

perf(Rotor): improve airfoil interpolation

The airfoil interpolation process leads to a significant computational
hoverhead when the CL and CD coefficients must be calculated for each
section, as this process is O(N), N being the number of different
airfoils.

The basic interpolation as defined previously was creating a specific
Airfoil for each section, even when some contiguous sections shared the
same profile. This commit tries to limit the total number of Airfoils
generated by reusing the same object when it is possible.

Currently this only works by trimming airfoils when two contiguous
sections share the same profile. Ideally, we could also detect if the
same profile appears in non-contiguous sections (i.e. a blade with
sections (0012/0015/0012/0012) to reduce it even a bit more. However, as
the gain here is expected to be very limited, this final optimization
has not been implemented.
parent 8c462a34
No related branches found
No related tags found
No related merge requests found
Pipeline #21636 passed
......@@ -11,15 +11,19 @@ to [Semantic Versioning][sem_ver].
### Changed
- Allow user to decide if airfoils should be interpolated between reference
sections (slow) or if same airfoil should be used until next section (fast)
### Deprecated
### Removed
### Fixed
## [0.2.2] - 2024-03-13
### Changed
- Allow user to decide if airfoils should be interpolated between reference
sections (slow) or if same airfoil should be used until next section (fast)
## [0.2.1] - 2024-03-13
### Fixed
......@@ -148,7 +152,8 @@ _Initial commit_: single rotor in hover/axial flows
[sem_ver]:<https://semver.org/spec/v2.0.0.html>
[keep_chglog]: <https://keepachangelog.com/en/1.0.0/>
[Unreleased]: https://gitlab.uliege.be/rotare/rotare/compare/0.2.1...main
[Unreleased]: https://gitlab.uliege.be/rotare/rotare/compare/0.2.2...main
[0.2.2]: https://gitlab.uliege.be/rotare/rotare/compare/0.2.1...0.2.2
[0.2.1]: https://gitlab.uliege.be/rotare/rotare/compare/0.2.0...0.2.1
[0.1.6]: https://gitlab.uliege.be/rotare/rotare/compare/0.1.5...0.1.6
[0.1.5]: https://gitlab.uliege.be/rotare/rotare/compare/0.1.4...0.1.5
......
......@@ -10,4 +10,5 @@ automatically generated and do not contain all dependencies.
This release features:
- Bigfix: Issue with Polar interpolation
- Allow user to decide if airfoils should be interpolated between reference
sections (slow) or if same airfoil should be used until next section (fast)
......@@ -31,6 +31,7 @@ classdef Blade < handle
% afInterp - Interpolate airfoil between base sections, [true/false]
%
% Blade methods:
% optimizeairfoils - Optimize airfoils to avoid unecessary calls for interpolated airfoils
%
% Blade constructor:
% Bl = Blade() creates an empty object.
......@@ -52,9 +53,6 @@ classdef Blade < handle
%
% <a href="https:/gitlab.uliege.be/rotare/documentation">Complete documentation (online)</a>
% ----------------------------------------------------------------------------------------------
% TODO: Improve interpolation. If we have two contiguous ref sections with the same airfoil, we
% should not need to interpolate and could use the same iAf
% ----------------------------------------------------------------------------------------------
% (c) Copyright 2022-2023 University of Liege
% Author: Thomas Lambert <t.lambert@uliege.be>
......@@ -134,5 +132,13 @@ classdef Blade < handle
sol = self.nBlades .* self.chord ./ (2 * pi * self.y);
end
% ---------------------------------------------
% Other methods
function self = optimizeairfoils(self, newiAf)
% OPTIMIZEAIRFOILS Optimize airfoils to avoid unecessary calls for interpolated airfoils
self.iAf = newiAf;
end
end
end
......@@ -53,8 +53,6 @@ classdef Rotor < handle
% ----------------------------------------------------------------------------------------------
% TODO: Verify solidity calculation.
% TODO: Improve interpolation. If we have two contiguous ref sections with the same airfoil, we
% should not need to interpolate and could use the same iAf
% ----------------------------------------------------------------------------------------------
% (c) Copyright 2022-2023 University of Liege
% Author: Thomas Lambert <t.lambert@uliege.be>
......@@ -102,6 +100,9 @@ classdef Rotor < handle
% Note: Angles should be passed IN DEGREE.
if nargin > 0
import af_tools.Airfoil
self.nBlades = nBlades;
if nargin >= 9
self.position = position;
......@@ -120,29 +121,54 @@ classdef Rotor < handle
% Interpolate airfoils (polars) between reference sections or use only reference
if afInterp
self.Af = af_tools.Airfoil;
self.Af = Airfoil;
self.Af(1) = BaseAf(iAf(1));
self.Af(nElem) = BaseAf(iAf(end));
newiAf = ones(1, nElem);
for i = 2:nElem - 1
afCount = numel(self.Af);
% Get previous/next refSection
prevRef = find(self.Bl.y(i) > rad, 1, 'last');
nextRef = find(self.Bl.y(i) < rad, 1, 'first');
% Calculate weight of second refsection
weightNextAf = (self.Bl.y(i) - rad(prevRef)) / ...
(rad(nextRef) - rad(prevRef));
% Interpolate airfoils between reference sections
self.Af(i) = af_tools.Airfoil.interpairfoil(BaseAf(iAf(prevRef)), ...
BaseAf(iAf(nextRef)), ...
weightNextAf);
self.Af(i).Polar.analyze();
self.Af(i).Polar.extrapMethod = BaseAf(1).Polar.extrapMethod;
% Interpolate airfoils only when necessary
if iAf(prevRef) ~= iAf(nextRef) % Interp between two reference sections
% Calculate weight of second refsection
weightNextAf = (self.Bl.y(i) - rad(prevRef)) / ...
(rad(nextRef) - rad(prevRef));
% Interpolate airfoils between reference sections
self.Af(afCount + 1) = Airfoil.interpairfoil(BaseAf(iAf(prevRef)), ...
BaseAf(iAf(nextRef)), ...
weightNextAf);
self.Af(afCount + 1).Polar.analyze();
self.Af(afCount + 1).Polar.extrapMethod = BaseAf(1).Polar.extrapMethod;
newiAf(i) = newiAf(i - 1) + 1;
elseif self.Af(afCount) ~= BaseAf(iAf(prevRef)) % New airfoil Section
self.Af(afCount + 1) = BaseAf(iAf(prevRef));
newiAf(i) = newiAf(i - 1) + 1;
else % No need to interpolate
newiAf(i) = newiAf(i - 1);
end
end
% Last airfoil
if iAf(end) ~= iAf(end - 1)
self.Af(end + 1) = BaseAf(iAf(end));
newiAf(end) = newiAf(end - 1) + 1;
else
newiAf(end) = newiAf(end - 1);
end
% Optimize Blade structure to limit calls to interpolated airfoils
self.Bl.optimizeairfoils(newiAf);
else
self.Af = BaseAf;
end
end
end
......
Subproject commit 10649d7e568f9a261e7157417cf26de53cc97ef8
Subproject commit 0995fa2ae733a5f7df81c6d9eb0cae7b801b9e2e
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment