001/*
002*   NACA5Reflexed -- An arbitrary cambered NACA 5 digit reflexed 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, reflexed,
032*      NACA 5 digit airfoil section with 3 digit camber such
033*      as a NACA 23112 airfoil.
034*      The 1st digit is defined as 2/3 of the design lift
035*      coefficient (in tenths, i.e.: 2 denotes cl = 0.3).
036*      The 2nd digit is twice the chordwise location of maximum
037*      camber in tenths of chord.  The 3rd digit of one
038*      indicates a reflexed trailing edge and the
039*      last two digits indicate the thickness ratio in
040*      percent chord.
041*  </p>
042*
043*  <p> Ported from FORTRAN "NACA4.FOR" to Java by:
044*                Joseph A. Huwaldt, October 11, 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 11, 2000
073*  @version March 7, 2013
074**/
075public class NACA5Reflexed extends NACA4Uncambered {
076
077        /**
078        *  The camber function K factor.
079        **/
080        private double k1;
081        
082        /**
083        *  The camber function k2/k1.
084        **/
085        private double k2ok1;
086        
087        /**
088        *  The camber function "r" factor.
089        **/
090        private double rFactor;
091        
092        /**
093        *  The postion in x/c of the maximum camber.
094        **/
095        private double xCM;
096        
097        
098        /**
099        *  Create a cambered reflexed NACA 5 digit airfoil with the
100        *  specified parameters.  For example:  a NACA 23112 airfoil
101        *  translates to:  thickness = 0.12, cl*2/3 = 2, xcamber*2 = 0.30.
102        *  The 3rd digit must be 1 for a reflexed airfoil.
103        *  This constructor requires the user to specify the 5 digit airfoil
104        *  k and r factors and position of max camber explicitly.
105        *  See NASA TM X-3284.
106        *
107        *  @param  thickness  The thickness to chord ratio (e.g.: 0.09 ==> 9% t/c).
108        *  @param  k1         The airfoil camber k1 factor as described in
109        *                     NASA TM X-3284.
110        *  @param  k2ok1      The ratio of the k2 to k1 camber factors as
111        *                     described in NASA TM X-3284.
112        *  @param  r          The airfoil camber r factor as described in
113        *                     NASA TM X-3284.
114        *  @param  xcamber    The position of maximum camber in tenths of chord
115        *                     (e.g.:  0.40 ==> max camber at 4% chord).
116        *  @param  length     The chord length.
117        **/
118        public NACA5Reflexed(double thickness, double k1, double k2ok1, double r,
119                                                        double xcamber, double length) {
120                super(thickness, length);
121                
122                this.k1 = k1;
123                this.k2ok1 = k2ok1;
124                rFactor = r;
125                xCM = xcamber;
126        }
127        
128        /**
129        *  Create a cambered reflexed NACA 5 digit airfoil with the
130        *  specified parameters.  For example:  a NACA 23112 airfoil
131        *  translates to:  thickness = 0.12, cl*2/3 = 2, xcamber*2 = 0.30.
132        *  The 3rd digit must be 1 for a reflexed airfoil.
133        *  This constructor requires the thickness and camber code (the
134        *  1st 2 digits of the airfoil designation).
135        *
136        *  @param  thickness  The thickness to chord ratio (e.g.: 0.09 ==> 9% t/c).
137        *  @param  code       The 1st 2 digits of the airfoil designation.
138        *                     Acceptable values are:  22, 23, 24, and 25.
139        *  @param  length     The chord length.
140        **/
141        public NACA5Reflexed(double thickness, int code, double length) {
142                super(thickness, length);
143                
144                switch (code) {
145                        case 22:
146                                xCM = 0.10;
147                                rFactor = 0.1300;
148                                k1 = 51.990;
149                                k2ok1 = 0.000764;
150                                break;
151                        
152                        case 23:
153                                xCM = 0.15;
154                                rFactor = 0.2170;
155                                k1 = 15.793;
156                                k2ok1 = 0.00677;
157                                break;
158                        
159                        case 24:
160                                xCM = 0.20;
161                                rFactor = 0.3180;
162                                k1 = 6.520;
163                                k2ok1 = 0.0303;
164                                break;
165                        
166                        case 25:
167                                xCM = 0.25;
168                                rFactor = 0.4410;
169                                k1 = 3.191;
170                                k2ok1 = 0.1355;
171                                break;
172                        
173                        default:
174                                throw new IllegalArgumentException("Unknown camber code.");
175                }
176                
177                
178        }
179        
180
181        /**
182        *  Returns a string representation of this airfoil
183        *  (the NACA designation of this airfoil).
184        **/
185    @Override
186        public String toString() {
187                StringBuilder buffer = new StringBuilder("NACA 2");
188                
189                buffer.append((int)(xCM*20));
190                buffer.append("1");
191                
192                if (TOC < 0.1)
193                        buffer.append("0");
194                buffer.append((int)(TOC*100));
195                
196                if (chord != 1.0) {
197                        buffer.append(" c=");
198                        buffer.append(chord);
199                }
200                return buffer.toString();
201        }
202        
203        //-----------------------------------------------------------------------------------
204
205        /**
206        *  Method to determine the local slope of the airfoil at
207        *  the leading edge.  This implementation sets the LE
208        *  slope to a very large number and computes a value for
209        *  tanth that is appropriate for a NACA 5 digit reflexed
210        *  airfoil.
211        *  This method sets the class variables:  tanth, yp, ypp.
212        *
213        *  @param  o  The ordinate data structure.  The following are set:  tanth, yp, ypp.
214        **/
215    @Override
216        protected void calcLESlope(Ordinate o) {
217                if (k1 < EPS)
218                        o.tanth = EPS;
219                else {
220                        double r2 = rFactor*rFactor;
221                        double oneMr = 1 - rFactor;
222                        double oneMr3 = oneMr*oneMr*oneMr;
223                        o.tanth = k1*(3*r2 - k2ok1*oneMr3 - r2*rFactor)/6;
224                }
225                o.yp = BIG;
226                o.ypp = BIG;
227        }
228        
229        /**
230        *  Method to calculate the camber distribution for the airfoil.
231        *  This method computes a camber distribution that is appropriate
232        *  for a NACA 5 digit reflexed airfoil.
233        *  This method sets the class variables:  yCMB, tanth, thp.
234        *
235        *  @param  x  The x/c location currently being calculated.
236        *  @param  o  The ordinate data structure. The following are set: yCMB, tanth, thp.
237        *  @return The following function value is returned: sqrt(1 + tanth^2).
238        **/
239    @Override
240        protected double calcCamber(double x, Ordinate o) {
241        
242                double r3 = rFactor*rFactor*rFactor;
243                double oneMr = 1 - rFactor;
244                double oneMr3 = oneMr*oneMr*oneMr;
245                double xMr = x - rFactor;
246                double xMr2 = xMr*xMr;
247                
248                if (x > rFactor) {
249                        o.yCMB = k1*(k2ok1*xMr2*xMr - k2ok1*oneMr3*x - r3*x + r3)/6;
250                        o.tanth = k1*(3*k2ok1*xMr2 - k2ok1*oneMr3 - r3)/6;
251                        
252                } else {
253                        o.yCMB = k1*(xMr2*xMr - k2ok1*oneMr3*x - r3*x + r3)/6;
254                        o.tanth = k1*(3*xMr2 - k2ok1*oneMr3 - r3)/6;
255                }
256                
257                double func = Math.sqrt(1 + o.tanth*o.tanth);
258                
259                if (x > rFactor) {
260                        o.thp = k2ok1*k1*xMr/(func*func);
261                        
262                } else 
263                        o.thp = k1*xMr/(func*func);
264                
265                return func;
266        }
267        
268        //-----------------------------------------------------------------------------------
269
270        /**
271        *  Simple method to test this class.
272        **/
273        public static void main(String[] args) {
274        
275                DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance();
276                nf.setMaximumFractionDigits(5);
277                nf.setMinimumFractionDigits(5);
278                
279                System.out.println("Start NACA5Reflexed...");
280                
281                System.out.println("Creating a NACA 23112 airfoil...");
282                Airfoil af = new NACA5Reflexed(0.12, 23, 1);
283                
284                System.out.println("Airfoil = " + af.toString());
285                
286                //      Output the upper surface of the airfoil.
287                List<Point2D> upper = af.getUpper();
288                List<Double> ypArr = af.getUpperYp();
289                
290                System.out.println("        X    \t    Y    \t    dy/dx");
291                int length = upper.size();
292                for (int i=0; i < length; ++i) {
293                        Point2D o = upper.get(i);
294                        System.out.println("    " + nf.format(o.getX()) + "\t" + nf.format(o.getY()) +
295                                                                        "\t" + nf.format(ypArr.get(i)));
296                }
297                
298                System.out.println("# ordinates = " + length);
299                System.out.println("Done!");
300        }
301}
302
303