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

feat(coax): add coaxial config template

parent 98f1859a
No related branches found
No related tags found
No related merge requests found
......@@ -10,6 +10,7 @@ results/
# Ignore all configs by default and only add some to be kept
src/configs/*
!src/configs/template.m
!src/configs/templatecoax.m
!src/configs/caradonna1981.m
!src/configs/knight1937.m
......
......@@ -50,9 +50,6 @@ Sim.Misc.appli = 'heli'; % Type of application ('helicopter', 'propeller', 'win
% ==================================== Models and solvers ==========================================
% ==================================================================================================
% System
Mod.Syst.nRotors = 1; % Number of rotors (if >1, rotors are coaxial)
% Solvers
Mod.solvers = {'all'}; % BEMT Solver ('leishman', 'indfact', 'indvel', 'stahlhut', 'all')
......@@ -120,4 +117,4 @@ Blade.iAirfoil = [1, 1]; % Index of the airfoil to use for the base st
Blade.nElem = 100; % Number of blade elements, [-]
% Rotor base position
Blade.hubPos = [0, 0, 0]; % Rotor center position (used for coaxial rotors)
Blade.hubPos = [0, 0, 0]; % Rotor center position (used for coaxial rotors), [m]
......@@ -45,9 +45,6 @@ Sim.Misc.appli = 'heli'; % Type of application ('helicopter', 'propeller', 'win
% ==================================== Models and solvers ==========================================
% ==================================================================================================
% System
Mod.Syst.nRotors = 1; % Number of rotors (if >1, rotors are coaxial)
% Solvers
Mod.solvers = {'all'}; % BEMT Solver ('leishman', 'indfact', 'indvel', 'stahlhut', 'all')
......@@ -116,4 +113,4 @@ Blade.iAirfoil = [1, 1]; % Index of the airfoil to use for the base st
Blade.nElem = 100; % Number of blade elements, [-]
% Rotor base position
Blade.hubPos = [0, 0, 0]; % Rotor center position (used for coaxial rotors)
Blade.hubPos = [0, 0, 0]; % Rotor center position (used for coaxial rotors), [m]
% TEMPLATE Template configuration file for Rotare
% TEMPLATE Template configuration file for Rotare.
% This file gather all options, parameters and configurations needed for a complete simulation
% with Rotare.
% It specifies the simulation parameters, the models, the blade/rotor geometry, the operation
......@@ -82,9 +82,6 @@ Sim.Misc.appli = 'heli'; % Type of application ('helicopter', 'propeller', 'win
% ==================================== Models and solvers ==========================================
% ==================================================================================================
% System
Mod.Syst.nRotors = 1; % Number of rotors (if >1, rotors are coaxial)
% Solvers
Mod.solvers = 'stahlhut'; % BEMT Solver ('leishman', 'indfact', 'indvel', 'stahlhut', 'all')
......@@ -114,9 +111,9 @@ Flow.fluid = 'air'; % Fluid ('air', 'seawater', 'freshwater')
% Note that the code will loop on every combination of these fours. So the total number of
% simulations can be very large if you want lots of operating points.
Op.speed = 2:2:10; % (Axial) Velocity, [m/s]
Op.speed = 2:5:12; % (Axial) Velocity, [m/s]
Op.collective = [2, 5, 8]; % Collective pitch, [deg]
Op.rpm = [100, 1300, 1500]; % Rotor angular velocity, [RPM]
Op.rpm = [1000, 1300]; % Rotor angular velocity, [RPM]
Op.altitude = 0; % Flight altitude (only used if Flow.fluid = 'air'), [m]
% ==================================================================================================
......@@ -168,4 +165,4 @@ Blade.iAirfoil = [1, 2, 2]; % Index of the airfoil to use for the base s
Blade.nElem = 100; % Number of blade elements, [-]
% Rotor base position
Blade.hubPos = [0, 0, 0]; % Rotor center position (used for coaxial rotors)
Blade.hubPos = [0, 0, 0]; % Rotor center position (used for coaxial rotors), [m]
% TEMPLATECOAX Template configuration file for Coaxial rotors simulations with Rotare.
% This file extends the regular template configuration by adding a second rotor geometry.
% -----
%
% See also: template, rotare, validconfig.
%
% <a href="https://gitlab.uliege.be/thlamb/rotare-doc">Complete documentation (online)</a>
% --------------------------------------------------------------------------------------------------
% (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/thlamb/rotare
% Docs: https://gitlab.uliege.be/thlamb/rotare-doc
% Issues: https://gitlab.uliege.be/thlamb/rotare/-/issues
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ==================================================================================================
% ================================== Baseline configuration ========================================
% ==================================================================================================
template; % Just load exisiting template
% ==================================================================================================
% ================================= Blade and rotor geometry =======================================
% ==================================================================================================
% Adds a second element to the blade structure to represent the second rotor
Blade(2) = Blade(1); % Make second rotor identical to first one
if strcmp(Sim.Misc.appli, 'heli')
rotorShift = [0, 0, -1];
else
rotorShift = [-1, 0, 0];
end
Blade(2).hubPos = Blade(1).hubPos - rotorShift; % Shift second rotor w.r.t the application type
% ==================================================================================================
% ===================================== Operating points ===========================================
% ==================================================================================================
% Operating points must be set for the two rotors
% We simply extend the collective and rpm fields by adding values for the new rotor
Op.collective = [Op.collective; 1, 4, 7];
Op.rpm = [Op.rpm; 900, 1200];
......@@ -89,15 +89,17 @@ function [Sim, Mod, Flow, Op, Airfoil, Blade] = validateconfig(configFile)
Sim = checksim(Sim, configFile, DEF); % Simulation parameters
Mod = checkmod(Mod, configFile, DEF); % Models, solvers, etc.
Flow.fluid = validatestring(Flow.fluid, DEF.FLUID, configFile, 'Flow.fluid'); % Fluid
Op = checkop(Op, configFile, DEF, Mod.Syst.nRotors, Flow.fluid); % Operating points
Airfoil = checkairfoil(Airfoil, configFile, DEF); % Airfoils data
Blade = checkblade(Blade, configFile, Mod.Syst.nRotors, length(Airfoil), DEF); % Blade
Blade = checkblade(Blade, configFile, length(Airfoil), DEF); % Blade
Op = checkop(Op, configFile, DEF, numel(Blade), Flow.fluid); % Operating points
% ===========================================
% Extra warnings
if Sim.Warn.sonicTip
sonictip(Op, Blade);
for i = 1:numel(Blade)
sonictip(Op, Blade(i));
end
end
end
......@@ -170,19 +172,6 @@ end
% ==================================== Models and solvers ==========================================
% ==================================================================================================
function Mod = checkmod(Mod, configFile, DEF)
% System
validateattributes(Mod.Syst.nRotors, ...
{'numeric'}, ...
{'scalar', 'positive', 'integer'}, ...
configFile, 'Mod.Syst.nRotors');
if Mod.Syst.nRotors > 1
% TODO: Coaxial: Remove this error when coaxial is implemented
error('ROTARE:validateconfig:tooManyRotors', ...
['Rotare does not support more than 1 rotor at the moment. \n'...
'Please use Mod.Syst.nRotors = 1.']);
end
% Solvers
Mod.solvers = cellstr(Mod.solvers);
......@@ -220,15 +209,27 @@ function Op = checkop(Op, configFile, DEF, nRotors, fluid)
{'vector', 'nonempty', 'nonnegative'}, ...
configFile, 'Op.speed');
validateattributes(Op.collective, ...
{'numeric'}, ...
{'3d', 'nonempty', 'nrows', nRotors}, ...
configFile, 'Op.collective');
try
validateattributes(Op.collective, ...
{'numeric'}, ...
{'3d', 'nonempty', 'nrows', nRotors}, ...
configFile, 'Op.collective');
validateattributes(Op.rpm, ...
{'numeric'}, ...
{'3d', 'nonempty', 'positive', 'nrows', nRotors}, ...
configFile, 'Op.rpm');
validateattributes(Op.rpm, ...
{'numeric'}, ...
{'3d', 'nonempty', 'positive', 'nrows', nRotors}, ...
configFile, 'Op.rpm');
catch ME
msg = ['Undefined operating conditions for additional rotors.\n' ...
'The configuration file defined ', num2str(nRotors), ' rotors (using Blade '...
'structure). '...
'Therefore, the config variables ''Op.collective'' and ''Op.rpm'' must be '...
'arrays whose rows correspond to the operating condition a different rotor.\n'...
'See ''configs/templatecoax.m'' for an example of a valid coax configuration.'];
causeException = MException('ROTARE:validateconfig:NotEnoughOperPoints', msg);
ME = addCause(ME, causeException);
rethrow(ME);
end
if strcmpi(fluid, 'air')
validateattributes(Op.altitude, ...
......@@ -301,29 +302,29 @@ end
% ==================================================================================================
% ================================= Blade and rotor geometry =======================================
% ==================================================================================================
function Blade = checkblade(Blade, configFile, nRotors, nAirfoils, DEF)
function Blade = checkblade(Blade, configFile, nAirfoils, DEF)
validateattributes(Blade, ...
{'struct'}, ...
{'numel', nRotors}, ...
{}, ...
configFile, 'Blade');
for i = 1:length(Blade)
for i = 1:numel(Blade)
Blade(i).pitchRef = validatestring(Blade(i).pitchRef, DEF.PITCHREF, ...
configFile, 'Blade.pitchRef');
% Base dimensions
validateattributes(Blade.nBlades, ...
validateattributes(Blade(i).nBlades, ...
{'numeric'}, ...
{'scalar', 'positive', 'integer'}, ...
configFile, 'Blade.nBlades');
validateattributes(Blade.radius, ...
validateattributes(Blade(i).radius, ...
{'numeric'}, ...
{'vector', 'positive', 'increasing'}, ...
configFile, 'Blade.radius');
if numel(Blade.radius) < 2
if numel(Blade(i).radius) < 2
error('ROTARE:validateconfig:notEnoughStations', ...
['The blade geometry must specified with vectors of at least 2 elements' ...
' (see Blade.radius).\n'...
......@@ -331,24 +332,24 @@ function Blade = checkblade(Blade, configFile, nRotors, nAirfoils, DEF)
'blade tip.']);
end
validateattributes(Blade.chord, ...
validateattributes(Blade(i).chord, ...
{'numeric'}, ...
{'vector', 'positive', 'size', size(Blade.radius)}, ...
{'vector', 'positive', 'size', size(Blade(i).radius)}, ...
configFile, 'Blade.chord');
validateattributes(Blade.twist, ...
validateattributes(Blade(i).twist, ...
{'numeric'}, ...
{'vector', 'size', size(Blade.radius)}, ...
{'vector', 'size', size(Blade(i).radius)}, ...
configFile, 'Blade.twist');
validateattributes(Blade.iAirfoil, ...
validateattributes(Blade(i).iAirfoil, ...
{'numeric'}, ...
{'vector', 'positive', 'size', size(Blade.radius), 'integer', ...
{'vector', 'positive', 'size', size(Blade(i).radius), 'integer', ...
'<=', nAirfoils}, ...
configFile, 'Blade.iAirfoil');
end
% Discretization
validateattributes(Blade.nElem, ...
validateattributes(Blade(i).nElem, ...
{'double'}, ...
{'scalar', 'positive'}, ...
configFile, 'Blade.nElem');
......
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