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

refact(polar)!: change polar type to object

Use Polar object instead of using a loosly defined Polar structure.
This adds robustness to these functions and will simplify future
developments.

BREAKING CHANGE: xf2mat no longer generates structures.
BREAKING CHANGE: any function that could took a polar structre as
input must now take a polar Object instead.
parent e64cf0b1
No related branches found
No related tags found
No related merge requests found
Pipeline #7116 passed
......@@ -41,11 +41,9 @@ function [alpha, c_l, c_d, c_m, idxOpts] = parsepolarinputs(optList, varargin)
[alpha, c_l, c_d, c_m] = extractpolar(tmp.Polar);
clear tmp;
else
if isstruct(varargin{1})
if isequal(class(varargin{1}), 'af_tools.Polar')
idxOpts = 2;
% Extract polar values
Polar = varargin{1};
validateattributes(Polar, {'struct'}, {'nonempty'}, mfilename(), 'Polar', 1);
[alpha, c_l, c_d, c_m] = extractpolar(varargin{1});
else
[alpha, c_l, c_d, c_m, idxOpts] = parsearrays(optList, varargin);
......@@ -84,7 +82,7 @@ end
function [alpha, c_l, c_d, c_m] = extractpolar(Polar)
% EXTRACTPOLAR Extract alpha, cl, cd and cm fields Polar structure.
alpha = Polar.alpha;
alpha = Polar.aoa;
c_l = Polar.cl;
c_d = Polar.cd;
c_m = Polar.cm;
......
......@@ -56,7 +56,6 @@ classdef Polar
cl (:, :) double {mustBeReal}
cd (:, :) double {mustBeReal}
cm (:, :) double {mustBeReal}
origin (1, :) cell
end
properties (SetAccess = private)
......
function Polar = xf2mat(varargin)
% XF2MAT Aggregates multiple XFOIL or XFLR5 polar results into a single structure.
% XF2MAT Aggregates multiple XFOIL or XFLR5 polar results into a Polar object.
% This function aggregates different airfoil polars obtained with XFOIL or XFLR5 (saved as
% textfiles) into a single structure for easier handling in other scripts.
% separate textfiles) into a single object for easier handling in other scripts.
%
% This function can be run without arguments, in this case it will prompt the user for the
% input. Otherwhile, the function asks for two main arguments:
% 1. inputDir: the directory where to look for the files
% 2. inputFiles: the files to load
% input. Otherwhile, the function asks for a list of files to load.
%
% The function also comes with options to save automatically the resulting Polar structure and
% The function also comes with options to save automatically the resulting Polar object and
% to trim all results to the same range of angles of attack.
%
% Important:
% If the inputfiles are for different airfoils, this script will return an error.
%
% Note:
% If multiple textfiles are selected as input, by default, the function will extend every
% polar to the maximum range of angles of attack found. Polars with fewer data will be
% assigned NaN values at the missing angles of attack.
% If the 'trimAoas' is set to true, the function will find the largest common range of angles
% of attack accross the various input polars and trim everything to that range. This prevents
% NaN values in the polars, but removes some data from the most complete inputs.
% If the option 'trimAoas' is set to true, the function will find the largest common range of
% angles of attack accross the various input polars and trim everything to that range. This
% prevents NaN values in the polars, but removes some data from the most complete inputs.
%
% <a href="https://gitlab.uliege.be/thlamb/airfoil_toolbox">Documentation (README)</a>
% <a href="https://gitlab.uliege.be/thlamb/airfoil_toolbox/-/issues">Report an issue</a>
......@@ -25,12 +26,12 @@ function Polar = xf2mat(varargin)
%
% Usage:
% POLAR = XF2MAT prompts the user for all inputs, then aggregate and convert the polar in a
% single POLAR structure.
% single POLAR object.
%
% POLAR = XF2MAT(INPUTFILES) aggregates only the polars specified by INPUTFILES into a single
% Polar structure.
% POLAR object.
%
% POLAR = XF2MAT(..., 'autosave', true) saves the resulting POLAR structure automatically in
% POLAR = XF2MAT(..., 'autosave', true) saves the resulting POLAR object automatically in
% a MAT-file.
%
% POLAR = XF2MAT(..., 'trimAoas', true) trims all input polars to the largest common range of
......@@ -40,16 +41,16 @@ function Polar = xf2mat(varargin)
% inputFiles : Files to select (ex: 'dir/file', 'subdir/*' , 'dir/*0012*', {'file1','file2'})
%
% Output:
% Polar : Structure collecting the results
% - Polar.alpha : Angles of attack [Rad]
% - Polar.airfoil : Airfoil name
% Polar : Object collecting the different results. The following properties are populated:
% - Polar.aoa : Angles of attack [Rad]
% - Polar.airfoil : Airfoil name (parsed from the input files)
% - Polar.reynolds : Reynolds number [-]
% - Polar.mach : Mach number [-]
% - Polar.nCrit : BL trnansition factor [-]
% - Polar.cl : Lift coefficient [-]
% - Polar.cd : Drag coefficient [-]
% - Polar.cm : Moment coefficient [-]
% - Polar.origin : XFOIL / XFLR5
% - Polar.progName : Progam that generated the polars (XFOIL / XFLR5)
%
% Example:
% XF2MAT
......@@ -59,7 +60,7 @@ function Polar = xf2mat(varargin)
% XF2MAT('test_data/*', 'autosave', true)
% XF2MAT('test_data/*', 'trimAoas', true)
%
% See also: EXTENDPOLAR, PLOTPOLARS.
% See also: POLAR, EXTENDPOLAR, PLOTPOLARS.
%
% -----
% XFOIL: http://web.mit.edu/drela/Public/web/xfoil/
......@@ -95,8 +96,9 @@ function Polar = xf2mat(varargin)
% Number of files found
nbFiles = length(allFileNames);
% Initialize structure
% Initialize structure and polar object
Tmp(nbFiles).resultArray = [];
Polar = af_tools.Polar();
% Initialize AOA range
if trimAoas
......@@ -122,7 +124,6 @@ function Polar = xf2mat(varargin)
progName = 'XFLR5';
end
end
Polar.origin{1, i} = progName;
% Parse the rest of the results
% (! textscan works as a pointer, headerlines are from the previous line, not the top)
......@@ -153,12 +154,11 @@ function Polar = xf2mat(varargin)
end
% Interpolate results over proper range of AOA if needed
[Polar.alpha, Polar.cl, Polar.cd, Polar.cm] = standardizepolar(Tmp, aoaRange);
[Polar.aoa, Polar.cl, Polar.cd, Polar.cm] = standardizepolar(Tmp, aoaRange);
clear Tmp;
% Sort everything by increasing Reynolds
[Polar.reynolds, indSort] = sort(Polar.reynolds);
Polar.origin(:) = Polar.origin(indSort);
Polar.airfoil(:) = Polar.airfoil(indSort);
Polar.mach(:) = Polar.mach(indSort);
Polar.nCrit(:) = Polar.nCrit(indSort);
......@@ -239,17 +239,17 @@ function aoaRange = findmaxrange(aoaRange, resArray)
end
% --------------------------------------------------------------------------------------------------
function [alpha, c_l, c_d, c_m] = standardizepolar(Input, aoaRange)
function [aoa, c_l, c_d, c_m] = standardizepolar(Input, aoaRange)
% STANDARDIZEPOLAR Standardize polar output.
% Re-interpolate everything over the same range of AOAs
alpha = zeros(length(aoaRange), length(Input));
aoa = zeros(length(aoaRange), length(Input));
c_l = zeros(length(aoaRange), length(Input));
c_d = zeros(length(aoaRange), length(Input));
c_m = zeros(length(aoaRange), length(Input));
for i = 1:length(Input)
alpha(:, i) = deg2rad(aoaRange');
aoa(:, i) = deg2rad(aoaRange');
c_l(:, i) = interp1(Input(i).resultArray(:, 1), Input(i).resultArray(:, 2), aoaRange);
c_d(:, i) = interp1(Input(i).resultArray(:, 1), Input(i).resultArray(:, 3), aoaRange);
c_m(:, i) = interp1(Input(i).resultArray(:, 1), Input(i).resultArray(:, 5), aoaRange);
......
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