Results 1 to 10 of 80

Thread: XFOIL with MATLAB

Hybrid View

  1. #1
    Join Date
    Apr 2008
    Beans
    135

    XFOIL with MATLAB

    Hi all,

    I am trying to write a code in MATLAB that would be able to call up XFOIL from the MATLAB shell and have it run simulations. The closest I can get to doing so is writing a Perl wrapper to take inputs, generate a config file for XFOIL to use, then have XFOIL load it.

    The issue is, I plan on many many iterations of this, and there's no "scripting language" within XFOIL to write an XFOIL script. I don't want to have to manually type in "oper; iter 100; alfa _____" for as many iterations as I need. The idea was something like this:

    Code:
    while (answer == unconverged)
        use initial guess/previous iteration to  generate config file for XFOIL
        open XFOIL, load config file
        have XFOIL automatically generate CL, CD, other data
        return values back to MATLAB
    end
    Is there any way to get XFOIL to run these commands with having to manually type them in?

    Thanks for the help!

  2. #2
    Join Date
    Aug 2007
    Beans
    874
    Distro
    Ubuntu 11.10 Oneiric Ocelot

    Re: XFOIL with MATLAB

    I don't know what XFOIL is and I've no clue if what I'm going to suggest will help you, but can't hurt to try.

    You can easily start up external apps using the 'system' command in matlab. Depending on your output, you may be able to grab the results from your xfoil app. However, I guess xfoil dumps its data somewhere. Which in that case you can simply let matlab import the data and do your convergence analysis.

  3. #3
    Join Date
    Apr 2008
    Beans
    135

    Re: XFOIL with MATLAB

    Quote Originally Posted by XCan View Post
    I don't know what XFOIL is and I've no clue if what I'm going to suggest will help you, but can't hurt to try.

    You can easily start up external apps using the 'system' command in matlab. Depending on your output, you may be able to grab the results from your xfoil app. However, I guess xfoil dumps its data somewhere. Which in that case you can simply let matlab import the data and do your convergence analysis.
    I am very familiar with the system() command, and so far that is how I'm accessing XFOIL.

    XFOIL is a computational fluid dynamics tool used to calculate boundary layers and pressure distributions along airfoil (2D wings). The issue that I am having is that a user needs to run an xfoil "shell" to interact with it. This wouldn't be a problem, since MATLAB is the same way - except with MATLAB, you can write scripts to automate these processes. XFOIL has no way for a user to just run a bunch of commands without having the user actually interact with XFOIL.. i'm not worried about capturing the outputs of XFOIL, that's relatively simple.
    Last edited by azredwing; October 31st, 2009 at 05:25 AM.

  4. #4
    Join Date
    Dec 2009
    Beans
    1

    Re: XFOIL with MATLAB

    Hey, did you find a solution for your problem? I am also trying to use Xfoil via MATLAB. How do you check if your results are converged?

  5. #5
    Join Date
    Apr 2008
    Beans
    135

    Re: XFOIL with MATLAB

    Quote Originally Posted by udai87 View Post
    Hey, did you find a solution for your problem? I am also trying to use Xfoil via MATLAB. How do you check if your results are converged?
    I did, actually! I totally forgot that you could use pipes in/out of files, so I have a Perl script generating an XFOIL "script" that gets executed. Here's the code of interest:

    Code:
    #!/usr/bin/perl
    
    # xfoilwrapper.pl - Wrapper script to interact between MATLAB, XFOIL
    
    use strict;
    use warnings;
    
    sub cleandie{
        unlink $_ for qw(commands.xfoil coords.dat xfoil.def coeffs.txt);
    	die @_;
    }
    	
    sub cleanup{
        unlink $_ for qw(commands.xfoil coords.dat xfoil.def coeffs.txt);
    }
    
    my ($alfa, $Re, $Ma, $NACA, $coeff_type) = @ARGV;
    
    # If the user wants a NACA foil, make sure it's a 4 or 5-series only.
    if (defined $NACA && (length($NACA) <4 || length($NACA) >5 ||  $NACA =~ /\D+/)){
        die "Only 4 or 5-digit series NACA foils allowed";
    }
    
    
    my $Re_10e6 = $Re/10**6; # Config file accepts Re/10^6 as input; need to transform it.
    
    $Re_10e6 = sprintf("%.4f", $Re_10e6);
    $Ma      = sprintf("%.4f", $Ma);
    
    #--------------------------------------------------  
    # Generate the coordinate files (see end of program)
    #--------------------------------------------------  
    open my $COORDINATES, ">", "coords.dat"
        or cleandie "Couldn't open coords.dat for writing: $!";
    
    my $coords = get_coords();
    print {$COORDINATES} $coords;
    close $COORDINATES;
    
    #--------------------------------------------------
    # Build the config file using input $Re, $Ma
    #--------------------------------------------------
    
    my $xfoil_def = <<"EOF";
      160       1.0000   0.1500   0.2000 | Npan    PPanel  TErat  REFrat
        1.0000   1.0000   1.0000   1.0000 | XrefS1  XrefS2  XrefP1 XrefP2
       10.0000   0.5500   0.0150   0.8000 | Size    plotAR  CHsize ScrnFr
       11.0000   8.5000   0.0000   0.0000 | Xpage   Ypage   Xmargn Ymargn
      F        T                          | Lcolor  Lcursor
        1.0000  -4.0000  -0.5000          | CPmax   CPmin   CPdel
        0.0900   0.7000   0.0200          | XoffAir ScalAir BLUwt
        0.0000   1.5000   0.5000          | CLmin   CLmax   CLdel
        0.0000   0.0400   0.0100          | CDmin   CDmax   CDdel
       -4.0000  10.0000   2.0000          | ALmin   ALmax   ALdel
       -0.2500   0.0000   0.0500          | CMmin   CMmax   CMdel
       1         $Ma   0.0100          | MAtype  Mach    Vaccel
       1         $Re_10e6   9.0000          | REtype  Re/10^6 Ncrit
        0.1000   0.2500                   | XtripT  XtripB
    EOF
    
    open my $XFOIL_DEF, ">", "xfoil.def"
        or cleandie "Couldn't open xfoil.def for writing: $!";
    print {$XFOIL_DEF} $xfoil_def;
    close $XFOIL_DEF;
    
    # Build the XFOIL command list using $alfa and $Re.
    # Start with 100 iterations; if the output result is a diverage, add 100 more iterations.
    # die() the program after 1000 iterations fail.
    
    my $numit = 100;
    ITERATION:
    while ($numit <= 1000){
        my $command_file = defined $NACA ? <<"EOF"
    y
    plop
    G
    
    naca $NACA
    oper
    visc $Re
    iter $numit
    pacc
    coeffs.txt
    
    alfa $alfa
    pacc
    
    quit
    EOF
          : <<"EOF";
    y
    plop
    G
    
    oper
    visc $Re
    iter $numit
    pacc
    coeffs.txt
    
    alfa $alfa
    pacc
    
    quit
    EOF
          
        open my $COMMANDS, ">", "commands.xfoil"
            or cleandie "Couldn't open commands.xfoil for writing: $!";
        print {$COMMANDS} $command_file;
        close $COMMANDS;
    
        
        if ($^O eq "linux" || $^O eq "darwin"){
            if ($NACA){
                system("xfoil <commands.xfoil >/dev/null");
            }
            else{
                system("xfoil coords.dat <commands.xfoil >/dev/null");
            }
        }
        else{
            if ($NACA){
                system('C:\xfoil\bin\xfoil.exe <commands.xfoil >nul');
            }
            else{
                system('C:\xfoil\bin\xfoil.exe coords.dat <commands.xfoil >nul');
            }
        }
    
        # Check coeffs.txt for CL and CD. If there's no numbers, divergence occurred.
    
        open my $COEFF_FILE, "<", "coeffs.txt"
            or cleandie("Couldn't open coeffs.txt for reading: $!");
    
        while (my $line = <$COEFF_FILE>){        
            # CONVERAGE OCCURED! PRINT CL AND CD, RETURN TO MATLAB
            if ($line =~ /(\d+[.]\d+) \s+ (\d+[.]\d+) \s+ (\d+[.]\d+)/xms){
                print $coeff_type eq "lift" ? "CL=$2;\n"       :
                      $coeff_type eq "drag" ? "CD=$3;\n"       :
                                              "CL=$2; CD=$3;\n";
                cleanup();
    			unlink("coeffs.txt");
                exit
            }
        }
        $numit += 100;
    	close $COEFF_FILE;
    }
    
    # At this point we've failed to converge after 1000 iterations. Return inf to caller and let the caller deal with what to do.
    cleanup();
    print "CL=inf;CD=inf;\n";
    
    
    sub get_coords{
        my $coords = <<"EOF";
    # Coordinates for your airfoil go here
    EOF
        return $coords;
    }
    And here's the MATLAB function calling this wrapper:

    Code:
    % get_coeffs - Get the lift and drag coefficients for an airfoil
    %
    % USAGE: [CL, CD] = get_coeffs(alfa, Re, Ma, [NACA])
    %    (r) alfa: Desired angle of attack 
    %    (r)  Re : Reynolds number
    %    (r)  Ma : Mach number
    %    (s) NACA: NACA Airfoil designation. Must be a 4- or 5-digit string only.
    
    function [CL,CD] = get_coeffs(alfa, Re, Ma, NACA)
        
        % perl() command expects all arguments to be strings - transform into strings... 
        alfa = sprintf('%.5f', alfa);
        Re   = sprintf('%d'  , Re);
        Ma   = sprintf('%0.5f', Ma);
        
        % Result of the eval() command is CL and CD.
        if (exist('NACA') && ~ isempty(NACA))
            eval(perl('xfoilwrapper.pl', alfa, Re, Ma, NACA));
        else
            eval(perl('xfoilwrapper.pl', alfa, Re, Ma));
        end
        
        % In Windows, xfoilwrapper.pl fails to unlink coeffs.txt. Take care of
        % it here.
        if (exist('coeffs.txt'))
            delete('coeffs.txt');
        end
    Note in the XFOIL wrapper that if divergence occurs, I return CL=inf, CD=inf, and these will be what the MATLAB function returns as well. So you need to check your return vals and have some kind of error catching in place. If I generate CL/CD data and there's holes in it (inf's), I kick the holes out and perform a spline interpolation to fill those holes back in:

    Code:
    if (y_of_interest(i) == inf)
         y_of_interest(i) = fill_gaps(x_of_interest, y_of_interest, i);
    end
    
    function yy = fill_gap(x,y,i)
        y_interp = [y(1:i-1) y(i+1:length(x))];
        x_interp = [x(1:i-1) x(i+1:length(x))];
        yy = interp1(x_interp, y_interp, x(i), 'spline');
    end
    Hope this helps!

  6. #6
    Join Date
    Aug 2008
    Beans
    14

    Question Re: XFOIL with MATLAB

    Hi!

    I'm designing a windmill for my Mechanical Engineering undergrad project, and I think this may help me. What I want to do is this:

    1. Choose six or seven standard profiles at specific lengths across the blade.
    2. Calculate the Cd and Cl for the design Tip speed ratio (or design windspeed) for the entire blade. This should involve:
    - Calculating Cd and Cl for each Blade Element at design wind speed using XFOIL.
    - Integrating over the blade (is this correct?).
    3. Calculate Cd and Cl over a range of windspeeds for the entire blade (perhaps an iteration of steps in two above).
    4. Introduce an additional blade angle of twist to make the blade stall in higher speeds, and re-calculate the Cd, Cl for the above. This will have the effect of changing the Angle of Attack across the blade.

    I think your script is a good starting point, however, I'm completely new to XFOIL, python, matlab, and pearl. (New as in, haven't even run Hello World yet). I'm pretty sure I can adopt your matlab code to python though.

    I'm confused on a few things:

    1. Does the above list seem to miss anything?
    2. I don't understand the XFOIL interface... help here is very much appreciated.
    3. Using your scripts produce a bunch of files. How do I find the Cd and Cl of my profile under the conditions specified?

    Thanks so much!

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •