001/* 002* NACA4ModCambered -- An arbitrary cambered NACA 4 digit modified airfoil. 003* 004* Copyright (C) 2000-2012, 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 032* modified 4 digit airfoil section with 2 digit camber 033* such as a NACA 2512-34 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 next two digits are 037* the airfoil thickness in percent chord. The 1st digit 038* after the hyphen is the leading edge radius index and 039* the last digit after the hyphen is the position of 040* maximum thickness in tenths of chord. 041* </p> 042* 043* <p> Ported from FORTRAN "NACA4.FOR" to Java by: 044* Joseph A. Huwaldt, October 20, 2000 </p> 045* 046* <p> Original FORTRAN "NACA4" code had the following note: </p> 047* 048* <pre> 049* AUTHORS - Charles L.Ladson and Cuyler W. Brooks, NASA Langley 050* Liam Hardy, NASA Ames 051* Ralph Carmichael, Public Domain Aeronautical Software 052* Last FORTRAN version: 8Aug95 1.7 RLC 053* 054* NOTES - This program has been known by the names ANALIN, FOURDIGIT and NACA4. 055* REFERENCES- NASA Technical Memorandum TM X-3284 (November, 1975), 056* "Development of a Computer Program to Obtain Ordinates for 057* NACA 4-Digit, 4-Digit Modified, 5-Digit and 16-Digit Airfoils", 058* by Charles L. Ladson and Cuyler W. Brooks, Jr., 059* NASA Langley Research Center. 060* 061* NASA Technical Memorandum TM 4741 (December 1996), 062* "Computer Program to Obtain Ordinates for NACA Airfoils", 063* by Charles L. Ladson, Cuyler W. Brooks, Jr., and Acquilla S. Hill, 064* NASA Langley Research Center and 065* Darrell W. Sproles, Computer Sciences Corporation, Hampton, VA. 066* 067* "Theory of Wing Sections", by Ira Abbott and Albert Von Doenhoff. 068* </pre> 069* 070* <p> Modified by: Joseph A. Huwaldt </p> 071* 072* @author Joseph A. Huwaldt Date: October 20, 2000 073* @version September 15, 2012 074**/ 075public class NACA4ModCambered extends NACA4ModUncambered { 076 077 /** 078 * The amount of camber in terms of maximum ordinate-to-chord ratio. 079 **/ 080 private double CMB; 081 082 /** 083 * The position in x/c of the maximum camber. 084 **/ 085 private double xCM = 0.50; 086 087 088 /** 089 * Create a cambered NACA modified 4 digit airfoil with the 090 * specified parameters. For example: a NACA 2512-34 airfoil 091 * translates to: thickness = 0.12, camber = 0.02, xcamber = 0.50, 092 * Rle = 0.003967, and xThickness = 0.40. 093 * 094 * @param thickness The thickness to chord ratio (e.g.: 0.09 ==> 9% t/c). 095 * @param camber The maximum camber ordinate-to-chord ratio 096 * (e.g.: 0.06 ==> 6% camber/c). 097 * @param xcamber The position of maximum camber in tenths of chord 098 * (e.g.: 0.40 ==> max camber at 4% chord). 099 * @param Rle The radius of the leading edge of the airfoil in 100 * percent chord. 101 * @param xThickness The position of maximum thickness in percent chord 102 * (e.g.: 0.40 => 40% t/c). 103 * @param length The chord length. 104 **/ 105 public NACA4ModCambered(double thickness, double camber, double xcamber, 106 double Rle, double xThickness, double length) { 107 super(thickness, Rle, xThickness, length); 108 109 CMB = camber; 110 xCM = xcamber; 111 } 112 113 114 /** 115 * Create a cambered NACA modified 4 digit airfoil with the 116 * specified parameters. For example: a NACA 2512-34 airfoil 117 * translates to: thickness = 0.12, camber = 0.02, xcamber = 0.50, 118 * LEindex = 3, xThickness = 0.40.. 119 * 120 * @param thickness The thickness to chord ratio (e.g.: 0.09 ==> 9% t/c). 121 * @param camber The maximum camber ordinate-to-chord ratio 122 * (e.g.: 0.06 ==> 6% camber/c). 123 * @param xcamber The position of maximum camber in tenths of chord 124 * (e.g.: 0.40 ==> max camber at 4% chord). 125 * @param LEindex The leading edge radius index for this airfoil. Should 126 * be a number from 1 to 8. 127 * @param xThickness The position of maximum thickness in percent chord 128 * (e.g.: 0.40 => 40% t/c). 129 * @param length The chord length. 130 **/ 131 public NACA4ModCambered(double thickness, double camber, double xcamber, 132 int LEindex, double xThickness, double length) { 133 super(thickness, LEindex, xThickness, length); 134 135 CMB = camber; 136 xCM = xcamber; 137 } 138 139 /** 140 * Returns a string representation of this airfoil 141 * (the NACA designation of this airfoil). 142 **/ 143 @Override 144 public String toString() { 145 StringBuilder buffer = new StringBuilder("NACA "); 146 147 buffer.append((int)(CMB*100)); 148 buffer.append((int)(xCM*10)); 149 150 if (TOC < 0.1) 151 buffer.append("0"); 152 buffer.append((int)(TOC*100)); 153 154 buffer.append("-"); 155 156 if (leIndex == 0) 157 buffer.append("?"); 158 else 159 buffer.append(leIndex); 160 161 buffer.append((int)(xMaxT*10)); 162 163 if (chord != 1.0) { 164 buffer.append(" c="); 165 buffer.append(chord); 166 } 167 return buffer.toString(); 168 } 169 170 //----------------------------------------------------------------------------------- 171 172 /** 173 * Method to determine the local slope of the airfoil at 174 * the leading edge. This implementation sets the LE 175 * slope to a very large number and sets the tanth 176 * parameter to 2*CMB/xCM just as the NACA 4 digit 177 * uncambered implementation does. 178 * This method sets the class variables: tanth, yp, ypp. 179 * 180 * @param o The ordinate data structure. The following are set: tanth, yp, ypp. 181 **/ 182 @Override 183 protected void calcLESlope(Ordinate o) { 184 if (CMB < EPS) 185 o.tanth = EPS; 186 else 187 o.tanth = 2*CMB/xCM; 188 o.yp = BIG; 189 o.ypp = BIG; 190 } 191 192 /** 193 * Method to calculate the camber distribution for the airfoil. 194 * This implementation computes a camber distribution that is 195 * appropriate for a modified, NACA 4 digit, cambered airfoil. 196 * This method sets the class variables: yCMB, tanth, thp. 197 * 198 * @param x The x/c location currently being calculated. 199 * @param o The ordinate data structure. The following are set: yCMB, tanth, thp. 200 * @return The following function value is returned: sqrt(1 + tanth^2). 201 **/ 202 @Override 203 protected double calcCamber(double x, Ordinate o) { 204 if (x > xCM) { 205 double OneMxCM = 1 - xCM; 206 double OneMxCM2 = OneMxCM*OneMxCM; 207 o.yCMB = CMB*(1 - 2*xCM + 2*xCM*x - x*x)/OneMxCM2; 208 o.tanth = (2*xCM - 2*x)*CMB/OneMxCM2; 209 210 } else { 211 o.yCMB = CMB*(2*xCM*x - x*x)/(xCM*xCM); 212 o.tanth = 2*CMB*(1 - x/xCM)/xCM; 213 } 214 215 double func = Math.sqrt(1 + o.tanth*o.tanth); 216 217 if (x > xCM) { 218 double OneMxCM = 1 - xCM; 219 o.thp = -2*CMB/(OneMxCM*OneMxCM)/(func*func); 220 221 } else 222 o.thp = -2*CMB/(xCM*xCM)/(func*func); 223 224 return func; 225 } 226 227 //----------------------------------------------------------------------------------- 228 229 /** 230 * Simple method to test this class. 231 **/ 232 public static void main(String[] args) { 233 234 DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(); 235 nf.setMaximumFractionDigits(5); 236 nf.setMinimumFractionDigits(5); 237 238 System.out.println("Start NACA4ModCambered..."); 239 240 System.out.println("Creating a NACA 6409-34 airfoil..."); 241 Airfoil af = new NACA4ModCambered(0.09, 0.06, 0.4, 3, 0.4, 1); 242 243 System.out.println("Airfoil = " + af.toString()); 244 245 // Output the upper surface of the airfoil. 246 List<Point2D> upper = af.getUpper(); 247 List<Double> ypArr = af.getUpperYp(); 248 249 System.out.println(" X \t Y \t dy/dx"); 250 int length = upper.size(); 251 for (int i=0; i < length; ++i) { 252 Point2D o = upper.get(i); 253 System.out.println(" " + nf.format(o.getX()) + "\t" + nf.format(o.getY()) + 254 "\t" + nf.format(ypArr.get(i))); 255 } 256 257 System.out.println("# ordinates = " + length); 258 System.out.println("Done!"); 259 } 260} 261 262