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

feat(Result): add plotperf

parent 75f15da2
No related branches found
No related tags found
No related merge requests found
......@@ -9,6 +9,9 @@ to [Semantic Versioning][sem_ver].
### Added
- Basic result summary table
- Basic result plotting function
### Changed
### Deprecated
......
......@@ -10,6 +10,4 @@ automatically generated and do not contain all dependencies.
This release features:
- Functions to plot the velocity triangles
- Simpler interface to get the advance ratio
- **BREAKING** Output results as a separate object
- Result output and analysis methods
......@@ -76,7 +76,8 @@ classdef Result < handle
% Note: A bug in Matlab prevents the user of variable names when size checks are added
% in the property definition. https://stackoverflow.com/q/48423003
self.operPts = val;
self.operPts.Properties.VariableNames = {'Alt', 'V_ax', 'RPM', 'Coll'};
self.operPts.Properties.VariableNames = {'altitude', 'speed', 'rpm', 'collective'};
end
% ---------------------------------------------
......
function plotperf(self, varargin)
% PLOTPERF Plot and compare rotor performance.
% This method plots and compares the performance of the rotor under various operating
% conditions and for various solvers.
%
% -----
%
% Syntax:
% Result.plotperf(perf, varOper, alt, rpm, coll, speed) Plot the rotor performance `perf`
% with respect to `varOper` for the operating point defined by `alt`, `rpm`, `coll`, `speed`.
%
% Result.plotperf(..., 'solvers', SolversList) Plots only the line for the solvers specified
% in `SolversList`. By default all solvers are used.
%
% Result.plotperf(..., 'newFig', true) Create the plot in a new figure.
%
% Inputs:
% perf : Performance metric to plot ('cT', 'cP', 'cQ')
% varOper : Operational points to plot against ('altitude', 'speed', 'rpm', 'collective')
% alt : Altitude, [m]
% rpm : Rotational speed, [rpm]
% coll : Collective pitch, [deg]
% speed : Axial velocity, [m/s]
%
% Outputs:
% plot(s) : Plots with the rotor performance.
%
% Example:
% ResRot.plotperf('cT', 'rpm', 0, 0, nan, 5, 'solvers', {'leishman'})
% ResRot.plotperf('cT', 'collective', 0, 10, 200, 5, 'solvers', {'leishman','indvel'})
%
% See also: rotare, Result, template.
%
% <a href="https://gitlab.uliege.be/rotare/documentation">Complete documentation (online)</a>
% ----------------------------------------------------------------------------------------------
% (c) Copyright 2022-2023 University of Liege
% Author: Thomas Lambert <t.lambert@uliege.be>
% ULiege - Aeroelasticity and Experimental Aerodynamics
% MIT License
% Repo: https://gitlab.uliege.be/rotare/rotare
% Docs: https://gitlab.uliege.be/rotare/documentation
% Issues: https://gitlab.uliege.be/rotare/rotare/-/issues
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Defaults and constants
DEF.ALLOWED_PROPERTIES = {'cT', 'cQ', 'cP'};
DEF.allowed_oper = self.operPts.Properties.VariableNames;
DEF.ALLOWED_SOLVERS = {'leishman', 'indfact', 'indvel', 'stahlhut'};
% Parse inputs
[perf, oper, solvers, operPt, newFig] = parseinputs(DEF, varargin{:});
% Plot the figure
if newFig
figure('Name', 'Rotor performance');
end
filtered = filtertable(self.summarize, ...
operPt.altitude, operPt.speed, ...
operPt.rpm, operPt.collective);
for iSolv = 1:length(solvers)
perfSolv = sprintf('%s_%s', perf, solvers{iSolv});
plot(filtered.(oper), filtered.(perfSolv), 'DisplayName', solvers{iSolv});
if iSolv == 1
hold on;
end
end
end
function [perf, oper, solvers, operPt, newFig] = parseinputs(DEF, varargin)
% PARSEINPUTS Parse the varargin inputs
% - Only the parameter corresponding to oper can be nan, all others need to be defined
valData = @(x) validateattributes(x, {'numeric'}, {'scalar'});
valLogi = @(x) validateattributes(x, {'logical'}, {'scalar'});
p = inputParser;
addRequired(p, 'perf', @(x) any(validatestring(x, DEF.ALLOWED_PROPERTIES)));
addRequired(p, 'oper', @(x) any(validatestring(x, DEF.allowed_oper)));
addRequired(p, 'altitude', valData);
addRequired(p, 'speed', valData);
addRequired(p, 'rpm', valData);
addRequired(p, 'collective', valData);
addParameter(p, 'solvers', {'leishman', 'indfact', 'indvel', 'stahlhut'});
addParameter(p, 'newFig', false, valLogi);
parse(p, varargin{:});
perf = p.Results.perf;
oper = p.Results.oper;
solvers = p.Results.solvers;
operPt = struct('altitude', [], 'speed', [], 'rpm', [], 'collective', []);
for i = 1:length(DEF.allowed_oper)
curOp = DEF.allowed_oper{i};
operPt.(curOp) = p.Results.(curOp);
end
operPt.(p.Results.oper) = NaN;
newFig = p.Results.newFig;
end
function filtered = filtertable(inputTable, alt, speed, rpm, coll)
% FILTERTABLE Filter the data with corresponding alt, coll, rpm and speed from the summary table
iAlt = getidx('altitude', alt);
iSpeed = getidx('speed', speed);
iRpm = getidx('rpm', rpm);
iColl = getidx('collective', coll);
filtered = inputTable(iAlt & iColl & iRpm & iSpeed, :);
function idx = getidx(type, val)
idx = inputTable.(type) == val | isnan(val);
end
end
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