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]. ...@@ -11,15 +11,19 @@ to [Semantic Versioning][sem_ver].
### Changed ### 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 ### Deprecated
### Removed ### Removed
### Fixed ### 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 ## [0.2.1] - 2024-03-13
### Fixed ### Fixed
...@@ -148,7 +152,8 @@ _Initial commit_: single rotor in hover/axial flows ...@@ -148,7 +152,8 @@ _Initial commit_: single rotor in hover/axial flows
[sem_ver]:<https://semver.org/spec/v2.0.0.html> [sem_ver]:<https://semver.org/spec/v2.0.0.html>
[keep_chglog]: <https://keepachangelog.com/en/1.0.0/> [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.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.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 [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. ...@@ -10,4 +10,5 @@ automatically generated and do not contain all dependencies.
This release features: 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 ...@@ -31,6 +31,7 @@ classdef Blade < handle
% afInterp - Interpolate airfoil between base sections, [true/false] % afInterp - Interpolate airfoil between base sections, [true/false]
% %
% Blade methods: % Blade methods:
% optimizeairfoils - Optimize airfoils to avoid unecessary calls for interpolated airfoils
% %
% Blade constructor: % Blade constructor:
% Bl = Blade() creates an empty object. % Bl = Blade() creates an empty object.
...@@ -52,9 +53,6 @@ classdef Blade < handle ...@@ -52,9 +53,6 @@ classdef Blade < handle
% %
% <a href="https:/gitlab.uliege.be/rotare/documentation">Complete documentation (online)</a> % <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 % (c) Copyright 2022-2023 University of Liege
% Author: Thomas Lambert <t.lambert@uliege.be> % Author: Thomas Lambert <t.lambert@uliege.be>
...@@ -134,5 +132,13 @@ classdef Blade < handle ...@@ -134,5 +132,13 @@ classdef Blade < handle
sol = self.nBlades .* self.chord ./ (2 * pi * self.y); sol = self.nBlades .* self.chord ./ (2 * pi * self.y);
end end
% ---------------------------------------------
% Other methods
function self = optimizeairfoils(self, newiAf)
% OPTIMIZEAIRFOILS Optimize airfoils to avoid unecessary calls for interpolated airfoils
self.iAf = newiAf;
end
end end
end end
...@@ -53,8 +53,6 @@ classdef Rotor < handle ...@@ -53,8 +53,6 @@ classdef Rotor < handle
% ---------------------------------------------------------------------------------------------- % ----------------------------------------------------------------------------------------------
% TODO: Verify solidity calculation. % 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 % (c) Copyright 2022-2023 University of Liege
% Author: Thomas Lambert <t.lambert@uliege.be> % Author: Thomas Lambert <t.lambert@uliege.be>
...@@ -102,6 +100,9 @@ classdef Rotor < handle ...@@ -102,6 +100,9 @@ classdef Rotor < handle
% Note: Angles should be passed IN DEGREE. % Note: Angles should be passed IN DEGREE.
if nargin > 0 if nargin > 0
import af_tools.Airfoil
self.nBlades = nBlades; self.nBlades = nBlades;
if nargin >= 9 if nargin >= 9
self.position = position; self.position = position;
...@@ -120,29 +121,54 @@ classdef Rotor < handle ...@@ -120,29 +121,54 @@ classdef Rotor < handle
% Interpolate airfoils (polars) between reference sections or use only reference % Interpolate airfoils (polars) between reference sections or use only reference
if afInterp if afInterp
self.Af = af_tools.Airfoil; self.Af = Airfoil;
self.Af(1) = BaseAf(iAf(1)); self.Af(1) = BaseAf(iAf(1));
self.Af(nElem) = BaseAf(iAf(end)); newiAf = ones(1, nElem);
for i = 2:nElem - 1 for i = 2:nElem - 1
afCount = numel(self.Af);
% Get previous/next refSection % Get previous/next refSection
prevRef = find(self.Bl.y(i) > rad, 1, 'last'); prevRef = find(self.Bl.y(i) > rad, 1, 'last');
nextRef = find(self.Bl.y(i) < rad, 1, 'first'); nextRef = find(self.Bl.y(i) < rad, 1, 'first');
% Calculate weight of second refsection % Interpolate airfoils only when necessary
weightNextAf = (self.Bl.y(i) - rad(prevRef)) / ... if iAf(prevRef) ~= iAf(nextRef) % Interp between two reference sections
(rad(nextRef) - rad(prevRef)); % Calculate weight of second refsection
weightNextAf = (self.Bl.y(i) - rad(prevRef)) / ...
% Interpolate airfoils between reference sections (rad(nextRef) - rad(prevRef));
self.Af(i) = af_tools.Airfoil.interpairfoil(BaseAf(iAf(prevRef)), ...
BaseAf(iAf(nextRef)), ... % Interpolate airfoils between reference sections
weightNextAf); self.Af(afCount + 1) = Airfoil.interpairfoil(BaseAf(iAf(prevRef)), ...
self.Af(i).Polar.analyze(); BaseAf(iAf(nextRef)), ...
self.Af(i).Polar.extrapMethod = BaseAf(1).Polar.extrapMethod; 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 end
% Optimize Blade structure to limit calls to interpolated airfoils
self.Bl.optimizeairfoils(newiAf);
else else
self.Af = BaseAf; self.Af = BaseAf;
end end
end 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