Skip to content
Snippets Groups Projects
Polar.m 7.83 KiB
classdef Polar
    % POLAR Airfoil polars and some associated properties.
    %   The Polar class is used to store an airfoil polars (cl, cd, cm values for different angles
    %   of attacks, at different Reynolds and Mach numbers).
    %   It can also contain some interesting extra properties such as the stall point, the zero-lift
    %   points, the linear lift range. It is also possible to compute the extrapolation of the
    %   polars over the complete range of angles of attack if needed.
    %
    % Note:
    %   - One Polar object correspond to one Airfoil. The properties of the Polar object are
    %     vectors/matrices whose the columns represent a single polar curve.
    %   - The method 'loadpolar' can be used instead of the constructor to load a previously saved
    %     polar object.
    % -----
    %
    % Polar properties:
    %   reynolds - Rynolds number of each polar curve, [-]
    %   mach     - Mach number of each polar curve, [-]
    %   nCrit    - nCrit number of each polar curve, [-]
    %   aoa      - Angles of attack (one column per Reynolds), [rad]
    %   cl       - Lift coefficient (one row per aoa, one column per Reynolds), [-]
    %   cd       - Drag coefficient (one row per aoa, one column per Reynolds), [-]
    %   cm       - Moment coefficient (one row per aoa, one column per Reynolds), [-]
    %   Ext      - Struct with the data of the extended polars
    %   Stall    - Struct with the data of the stall point for each curve
    %   Zero     - Struct with the data of the zero-lift point for each curve
    %   Lin      - Struct with the data of the linear range each curve
    %
    % Polar methods:
    %   Polar          - Constructor
    %   loadpolar      - Load a polar from the MAT-file
    %   extendpolar    - Extend polar curves over [-pi, pi]
    %   findstall      - Find stall point
    %   findzerolift   - Find zero-lift point
    %   findcllinrange - Find lift curve linear range
    %   analyze        - Runs the above three functions
    %   plotpolars     - Plot the polars
    %
    % Polar constructor:
    %   Pol = Polar() creates an empty object.
    %
    %   Pol = Polar(reynolds, aoa, c_l) creates a polar object with only the lift coefficient data.
    %
    %   Pol = Polar(reynolds, aoa, c_l, c_d, c_m) creates a polar object with only the lift and drag
    %   coefficients data.
    %
    %   Pol = Polar(reynolds, aoa, c_l, c_d, c_m) creates a polar object with the data for the lift,
    %   drag and moment coefficient.
    %
    % Constructor input:
    %   reynolds : Rynolds number of each polar curve, [-]
    %   aoa      : Angles of attack (one column per Reynolds), [rad]
    %   cl       : Lift coefficient (one row per aoa, one column per Reynolds), [-]
    %   cd       : Drag coefficient (one row per aoa, one column per Reynolds), [-]
    %   cm       : Drag coefficient (one row per aoa, one column per Reynolds), [-]
    %
    % See also: af_tools.Airfoil, af_tools.xf2mat.
    %
    % <a href="https://gitlab.uliege.be/am-dept/matlab_airfoil_toolbox">Documentation (online)</a>

    % TODO: make this class handle class, verify everything, simplfiy methods
    % -------------------------------------------
    % (c) Copyright 2022 University of Liege
    % Author: Thomas Lambert <t.lambert@uliege.be>
    % ULiege - Aeroelasticity and Experimental Aerodynamics
    % MIT License
    % Repo: https://gitlab.uliege.be/am-dept/matlab_airfoil_toolbox
    % Issues: https://gitlab.uliege.be/am-dept/matlab_airfoil_toolbox/-/issues
    % ----------------------------------------------------------------------------------------------
    properties
        reynolds (1, :) double {mustBeNonnegative} % Rynolds number, [-]
        mach     (1, :) double {mustBeNonnegative} % Mach number, [-]
        nCrit    (1, :) double {mustBeNonnegative} % nCrit number, [-]
        aoa      (:, :) double {mustBeReal} % Angles of attack, [rad]
        cl       (:, :) double {mustBeReal} % Lift coefficient, [-]
        cd       (:, :) double {mustBeReal} % Drag coefficient, [-]
        cm       (:, :) double {mustBeReal} % Moment coefficient, [-]
    end

    properties (SetAccess = private)
        Ext   = struct('aoa', [], 'cl', [], 'cd', [], 'cm', []) % Extended polar data
        Stall = struct('aoa', [], 'cl', [], 'cd', []) % Stall point data
        Zero  = struct('aoa', [], 'cd', []) % Zero-lift point data
        Lin   = struct('slope', [], 'aoaRange', [],  'clRange', []) % Lift linear range data
    end

    % ----------------------------------------------------------------------------------------------
    methods

        function self = Polar(reynolds, aoa, c_l, c_d, c_m)
            % POLAR Constructor for Polar object
            %   Instantiate a polar object using basic information. See the main class help for
            %   details about the constructor inputs.
            %
            %   It is also possible to populate the properties of the object based on a saved polar
            %   using the Polar.loadpolar method.
            %
            % See also: af_tools.Polar.loadpolar

            if nargin > 0
                narginchk(3, 5);

                self.reynolds = reynolds;
                self.aoa = aoa;
                self.cl = c_l;
                if nargin >= 4
                    self.cd = c_d;
                    if nargin >= 5
                        self.cm = c_m;
                    end
                end
            end

        end

        % ---------------------------------------
        function self = extendpolar(self)
            % EXTENDPOLAR  Extends the polar data over the full range of AOA ([-180, 180] deg)
            %
            % See also: af_tools.extendpolar.
            [self.Ext.aoa, self.Ext.cl, self.Ext.cd] = af_tools.extendpolar(self);
        end

        % ---------------------------------------
        function self = findstall(self)
            % FINDSTALL  Find the stall point of the polars
            %
            % See also: af_tools.findstall.

            [self.Stall.aoa, self.Stall.cl, self.Stall.cd] = af_tools.findstall(self);
        end

        % ---------------------------------------
        function self = findzerolift(self)
            % FINDZEROLIFT  Find the zero-lift angle and associated cd
            %
            % See also: af_tools.findzerolift.

            [self.Zero.aoa, self.Zero.cd] = af_tools.findzerolift(self);
        end

        % ---------------------------------------
        function self = findcllinrange(self)
            % FINDZEROLIFT  Find the linear range of the cl and its slope
            %
            % See also: af_tools.findcllinearrange.

            [self.Lin.clRange, self.Lin.aoaRange, self.Lin.slope] = ...
                af_tools.findcllinearrange(self);
        end

        % ---------------------------------------
        function plotpolars(self)
            % PLOTPOLARS  Plot the polars
            %
            % See also: af_tools.plotpolars.

            af_tools.plotpolars(self);
        end

        % ---------------------------------------
        function self = analyze(self)
            % ANALYZE  Get all useful information from the polar curves at once
            %
            % See also: af_tools.findstall, af_tools.findzerolift, af_tools.findcllinearrange.

            self = findstall(self);
            self = findzerolift(self);
            self = findcllinrange(self);
        end

        % Interpolate coefficients based on AoAs and Reynolds
        [cl, cd, cm] = getcoeffs(self, aoa, reynolds)

    end

    % ----------------------------------------------------------------------------------------------

    methods (Static)
        self = loadpolar(polarFile) % Load polar from file
    end

    % ----------------------------------------------------------------------------------------------

    methods (Static)
        self = polypolar(polyCl, polyCd) % Create polar using polynomial coefficients
    end
end