34double NACA_PROFILE::xcoord(
double angle)
36 return 0.5 + cos(angle)/2.0;
39double NACA_PROFILE::ytfunc(
double x,
double thmax)
41 if (x == 1.0)
return 0.0;
44 for(
int i=1; i<4; i++ )
46 y = y*x + A[0] * sqrt(x);
48 return 5. * thmax * y;
54void NACA_PROFILE::camber_four(
double *yc,
double *slope,
55 double x,
double maxor,
double posmax)
58 *yc = maxor/sqr(posmax) * (2.0*posmax*x - sqr(x));
59 *slope = 2*(maxor/posmax) * (1.0-(x/posmax));
62 *yc = maxor/sqr(1.0-posmax) * ( 1 - 2*posmax + 2*posmax*x - sqr(x));
63 *slope = 2*(maxor/sqr(1-posmax))*(posmax-x);
67void NACA_PROFILE::camber_five(
double *yc,
double *slope,
68 double x,
double maxor,
double posmax,
double k1,
int iReflex )
74 double k21 = (3.*sqr(maxor-posmax)-cube(maxor))/(1-maxor);
77 *yc = d16*k1*(cube(x-maxor) - k21*sqr(1-maxor)*x - cube(maxor)*(x-1) );
78 *slope = d16*k1*(3*sqr(x-maxor) - k21*sqr(1-maxor) - cube(maxor) );
82 *yc = d16*k1*(k21*cube(x-maxor) - k21*sqr(1-maxor)*x - cube(maxor)*(x-1));
83 *slope = d16*k1*(3*k21*sqr(x-maxor) - k21*sqr(1-maxor) - cube(maxor) );
90 *yc = d16*k1*(cube(x) - 3.0*maxor*sqr(x) + sqr(maxor)*(3.0-maxor)*x);
91 *slope = d16*k1*( 3.0*sqr(x) - 6.0*maxor*x + sqr(maxor)*(3.0-maxor) );
95 *yc = d16*k1*cube(maxor)*(1.0-x);
96 *slope = d16*k1*cube(maxor);
101void NACA_PROFILE::out_point(
double x,
double yc,
double yt,
double slope,
int is_upper, FILE *fp)
103 double xloc, yloc, h;
106 fprintf(stderr,
" >>> x: %.4g\tcamber: %.3g\tthickness: %.3g\n", x, yc, yt);
109 h = sqrt(1+sqr(slope));
111 xloc = x - yt*slope/h;
115 xloc = x + yt*slope/h;
120 fprintf(fp,
"%5.5f %5.5f\n", xloc, yloc);
129 fprintf(stderr,
"%5.5f %5.5f %d\n", xloc, yloc, iLicz);
134#define dig(c) ((c)-'0')
143 if( data->
iTE0 == 0 )
149 if(strlen(name) == 4)
151 data->
serie = four_digit;
152 data->
maxor = dig(name[0])/100.0;
153 data->
posmax = dig(name[1])/10.0;
154 data->
thmax = atoi(name+2)/100.0;
160 data->
serie = five_digit;
161 data->
thmax = atoi(name+3)/100.0;
168 if( d3 == 0 || d3 == 1 )
170 int code = d1*100 + d2*10 + d3;
173 case 210: data->
maxor=0.0580; data->
k1=361.4;
break;
174 case 220: data->
maxor=0.1260; data->
k1=51.64;
break;
175 case 230: data->
maxor=0.2025; data->
k1=15.957;
break;
176 case 240: data->
maxor=0.2900; data->
k1=6.643;
break;
177 case 250: data->
maxor=0.3910; data->
k1=3.23;
break;
179 case 211: data->
maxor=0.0621; data->
k1=28.51;
break;
180 case 221: data->
maxor=0.1300; data->
k1=51.99;
break;
181 case 231: data->
maxor=0.2170; data->
k1=15.793;
break;
182 case 241: data->
maxor=0.3180; data->
k1=6.52;
break;
183 case 251: data->
maxor=0.4410; data->
k1=3.191;
break;
190 fprintf(stderr,
"wrong number ireflex = %d\n", d3 );
195void NACA_PROFILE::draw_surface(
int ndiv,
const struct NACA_AIRFOIL_DATA *data, FILE *fp)
197 double ainc = M_PI / (ndiv-1);
199 double x, yt, yc, slope;
203 x = xcoord(i * ainc);
204 yt = ytfunc(x, data->
thmax);
205 if (data->
serie == four_digit)
206 camber_four(&yc, &slope, x, data->
maxor, data->
posmax);
209 out_point(x, yc, yt, slope, inc==1, fp);
210 if (i >= ndiv-1 && inc == 1)
223char* NACA_PROFILE::check_name(
char *name)
228 if(!strncmp(name,
"NACA", 4) || !strncmp(name,
"naca", 4))
233 if(len < 4 || len > 5) {
240 for(i = 0; i < 4; i++)
241 if(!isdigit(name[i]))
246 if(!strchr(
"2346", name[0]))
251 if(name[1] <
'1' || name[1] >
'5')
253 if(strchr(
"346", name[0]))
254 if(!strchr(
"234", name[1]))
258 if(name[2] <
'0' || name[2] >
'1')
262 if(!isdigit(name[3]) || !isdigit(name[4]))
275 if(!(cname = check_name(cNACA)))
277 fprintf(stderr,
"%s is not a valid NACA section name.\n", cNACA );
282 fprintf( stderr,
"NACA %s - cname %s\n", cNACA, cname );
288 get_params(&data, cname);
290 draw_surface(NN, &data, stderr);
297 FILE *fp = fopen( file_name,
"w" );
301 if(!(cname = check_name(cNACA)))
303 fprintf(stderr,
"%s is not a valid NACA section name.\n", cNACA );
308 fprintf( stderr,
"NACA %s - cname %s\n", cNACA, cname );
318 get_params(&data, name);
320 fprintf(fp,
"NACA %s\n", name);
323 fprintf(stderr,
"%s:\n camber: %g\n thickness: %g\n max_camber_pos: %g\n series: %s\n",
325 ((data.
serie == four_digit)?
"four digit" :
"five digit"));
328 draw_surface(num, &data, fp);
335void NACA_PROFILE::ClearTabs(
void )
341void NACA_PROFILE::CreateTabs(
int nn )
348NACA_PROFILE::~NACA_PROFILE(
void)
int generate_naca(char *name, int num, FILE *fp)
generates naca airfoil coordinates (NN points) and stores it in file defined by stream "fp"
double * Z
z coordinates vecotr
int N
coordiantes vectors' size
double * X
x coordinates vector
#define DELETE_TAB(OBJ)
Macro for safe deleteing the array and sets the pointer to zero.
A struct containing airfoil data.
double posmax
the location of maximum camber
int ireflex
reflex flag - if ireflex = 1, Cm should be close to 0 (5-digit serie)
double thmax
the maximum thickness
enum series serie
type of serie - 4- or 5-digit
double maxor
the maximum camber
double k1
constant to determine the desired lift coefficient (5-digit serie)
int iTE0
trailing edge flag, 1 - TE thickness equal to zero
const char * name
4- or 5-digit airfoil code