001/* 002* NACA4Cambered -- An arbitrary cambered NACA 4 digit airfoil. 003* 004* Copyright (C) 2000-2013 by Joseph A. Huwaldt 005* All rights reserved. 006* 007* This library is free software; you can redistribute it and/or 008* modify it under the terms of the GNU Lesser General Public 009* License as published by the Free Software Foundation; either 010* version 2.1 of the License, or (at your option) any later version. 011* 012* This library is distributed in the hope that it will be useful, 013* but WITHOUT ANY WARRANTY; without even the implied warranty of 014* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015* Lesser General Public License for more details. 016* 017* You should have received a copy of the GNU Lesser General Public License 018* along with this program; if not, write to the Free Software 019* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 020* Or visit: http://www.gnu.org/licenses/lgpl.html 021**/ 022package jahuwaldt.aero.airfoils; 023 024import java.util.List; 025import java.awt.geom.Point2D; 026import java.text.DecimalFormat; 027import java.text.NumberFormat; 028 029 030/** 031* <p> This class represents an arbitrary cambered NACA 4 032* digit airfoil section with 2 digit camber such as a 033* NACA 6409 airfoil. 034* The 1st digit is the maximum camber in percent chord. 035* The 2nd digit is the chordwise location of maximum 036* camber in tenths of chord. The last two digits are 037* the airfoil thickness in percent chord. 038* </p> 039* 040* <p> Ported from FORTRAN "NACA4.FOR" to Java by: 041* Joseph A. Huwaldt, October 8, 2000 </p> 042* 043* <p> Original FORTRAN "NACA4" code had the following note: </p> 044* 045* <pre> 046* AUTHORS - Charles L.Ladson and Cuyler W. Brooks, NASA Langley 047* Liam Hardy, NASA Ames 048* Ralph Carmichael, Public Domain Aeronautical Software 049* Last FORTRAN version: 8Aug95 1.7 RLC 050* 051* NOTES - This program has been known by the names ANALIN, FOURDIGIT and NACA4. 052* REFERENCES- NASA Technical Memorandum TM X-3284 (November, 1975) 053* "Development of a Computer Program to Obtain Ordinates for 054* NACA 4-Digit, 4-Digit Modified, 5-Digit and 16-Digit Airfoils", 055* by Charles L. Ladson and Cuyler W. Brooks, Jr., 056* NASA Langley Research Center. 057* 058* NASA Technical Memorandum TM 4741 (December 1996), 059* "Computer Program to Obtain Ordinates for NACA Airfoils", 060* by Charles L. Ladson, Cuyler W. Brooks, Jr., and Acquilla S. Hill, 061* NASA Langley Research Center and 062* Darrell W. Sproles, Computer Sciences Corporation, Hampton, VA. 063* 064* "Theory of Wing Sections", by Ira Abbott and Albert Von Doenhoff. 065* </pre> 066* 067* <p> Modified by: Joseph A. Huwaldt </p> 068* 069* @author Joseph A. Huwaldt Date: October 8, 2000 070* @version March 7, 2013 071**/ 072public class NACA4Cambered extends NACA4Uncambered { 073 074 /** 075 * The amount of camber in terms of maximum ordinate-to-chord ratio. 076 **/ 077 private double CMB; 078 079 /** 080 * The position in x/c of the maximum camber. 081 **/ 082 private double xCM; 083 084 085 /** 086 * Create a cambered NACA 4 digit airfoil with the 087 * specified parameters. For example: a NACA 6409 airfoil 088 * translates to: thickness = 0.09, camber = 0.06, xcamber = 0.40. 089 * 090 * @param thickness The thickness to chord ratio (e.g.: 0.09 ==> 9% t/c). 091 * @param camber The maximum camber ordinate-to-chord ratio 092 * (e.g.: 0.06 ==> 6% camber/c). 093 * @param xcamber The position of maximum camber in tenths of chord 094 * (e.g.: 0.40 ==> max camber at 4% chord). 095 * @param length The chord length. 096 **/ 097 public NACA4Cambered(double thickness, double camber, double xcamber, double length) { 098 super(thickness, length); 099 100 CMB = camber; 101 xCM = xcamber; 102 } 103 104 105 /** 106 * Returns a string representation of this airfoil 107 * (the NACA designation of this airfoil). 108 **/ 109 @Override 110 public String toString() { 111 StringBuilder buffer = new StringBuilder("NACA "); 112 113 buffer.append((int)(CMB*100)); 114 buffer.append((int)(xCM*10)); 115 116 if (TOC < 0.1) 117 buffer.append("0"); 118 buffer.append((int)(TOC*100)); 119 120 if (chord != 1.0) { 121 buffer.append(" c="); 122 buffer.append(chord); 123 } 124 return buffer.toString(); 125 } 126 127 /** 128 * Method to determine the local slope of the airfoil at 129 * the leading edge. This implementation sets the 130 * slope of the leading edge to a very large number and 131 * sets tanth to 2*CMB/xCM. 132 * This method sets the class variables: tanth, yp, ypp. 133 * 134 * @param o The ordinate data structure. The following are set: tanth, yp, ypp. 135 **/ 136 @Override 137 protected void calcLESlope(Ordinate o) { 138 if (CMB < EPS) 139 o.tanth = EPS; 140 else 141 o.tanth = 2*CMB/xCM; 142 o.yp = BIG; 143 o.ypp = BIG; 144 } 145 146 /** 147 * Method to calculate the camber distribution for the airfoil. 148 * This implementation computes a camber distribution that is 149 * appropriate for a cambered NACA 4 digit airfoil. 150 * 151 * @param x The x/c location currently being calculated. 152 * @param o The ordinate data structure. The following are set: yCMB, tanth, thp. 153 * @return The following function value is returned: sqrt(1 + tanth^2). 154 **/ 155 @Override 156 protected double calcCamber(double x, Ordinate o) { 157 if (x > xCM) { 158 double OneMxCM = 1 - xCM; 159 double OneMxCM2 = OneMxCM*OneMxCM; 160 o.yCMB = CMB*(1 - 2*xCM + 2*xCM*x - x*x)/OneMxCM2; 161 o.tanth = (2*xCM - 2*x)*CMB/OneMxCM2; 162 163 } else { 164 o.yCMB = CMB*(2*xCM*x - x*x)/(xCM*xCM); 165 o.tanth = 2*CMB*(1 - x/xCM)/xCM; 166 } 167 168 double func = Math.sqrt(1 + o.tanth*o.tanth); 169 170 if (x > xCM) { 171 double OneMxCM = 1 - xCM; 172 o.thp = -2*CMB/(OneMxCM*OneMxCM)/(func*func); 173 174 } else 175 o.thp = -2*CMB/(xCM*xCM)/(func*func); 176 177 return func; 178 } 179 180 181 /** 182 * Simple method to test this class. 183 **/ 184 public static void main(String[] args) { 185 186 DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(); 187 nf.setMaximumFractionDigits(5); 188 nf.setMinimumFractionDigits(5); 189 190 System.out.println("Start NACA4Cambered..."); 191 192 System.out.println("Creating a NACA 6409 airfoil..."); 193 Airfoil af = new NACA4Cambered(0.09, 0.06, 0.4, 1); 194 195 System.out.println("Airfoil = " + af.toString()); 196 197 // Output the upper surface of the airfoil. 198 List<Point2D> upper = af.getUpper(); 199 List<Double> ypArr = af.getUpperYp(); 200 201 System.out.println(" X \t Y \t dy/dx"); 202 int length = upper.size(); 203 for (int i=0; i < length; ++i) { 204 Point2D o = upper.get(i); 205 System.out.println(" " + nf.format(o.getX()) + "\t" + nf.format(o.getY()) + 206 "\t" + nf.format(ypArr.get(i))); 207 } 208 209 System.out.println("# ordinates = " + length); 210 System.out.println("Done!"); 211 } 212} 213 214