29AIRFOIL::AIRFOIL(
void )
53 memset(
cName, 0, 100 );
70 memset(
cName, 0, 100 );
77 fprintf(stderr,
"iReadType %d\n",iReadType);
79 getiTypeByContent(cFile);
80 if( iReadType == 0 ||
iType == -1 )
86 fprintf(stderr,
"No correct file was provided!\n");
90 fprintf(stderr,
"airfoil %s type %d\n", cFile,
iType );
96 if( Read_PRF_0( cFile ) )
return -1;
99 if( Read_PRF_1( cFile ) )
return -1;
102 if( Read_KOO( cFile ) )
return -1;
105 if( Read_DAT( cFile ) )
return -1;
108 if( Read_DAT_LEDNICER( cFile ) )
return -1;
121 if( Write_PRF( cFile ) )
return -1;
130 if( Write_DAT( cFile ) )
return -1;
140 sprintf(cNACA,
"%04ld", iNACA );
146 sprintf(
cName,
"NACA %s", cNACA );
153 Xf =
new double[
Nf+1];
154 Zf =
new double[
Nf+1];
156 for(
int i=0; i<
Nf; i++ )
158 Xf[i] = NacaProfile->
X[i];
159 Zf[i] = NacaProfile->
Z[i];
172void AIRFOIL::getiTypeByContent(
char *cFile)
176 FILE *ff =
fopen( cFile,
"r" );
186 regex integer(
"\\s*\\d+\\s*");
187 regex number(
"\\s*(\\+|-)?[\\d\\.]+\\s*");
188 regex prfHeader(
"\\d+\\s+#\\s+.+");
189 regex kooHeader(
".+\\s+,\\s+\\d+");
190 regex datNLines(
"\\s*\\d+\\.\\s*\\d+\\.\\s*");
191 regex twoCols (
"\\s*(\\+|-)?[\\d\\.]+\\s+(\\+|-)?[\\d\\.]+\\s*");
192 regex threeCols(
"\\s*(\\+|-)?[\\d\\.]+\\s+(\\+|-)?[\\d\\.]+\\s+(\\+|-)?[\\d\\.]+\\s*");
193 regex fourCols (
"\\s*(\\+|-)?[\\d\\.]+\\s+(\\+|-)?[\\d\\.]+\\s+(\\+|-)?[\\d\\.]+\\s+(\\+|-)?[\\d\\.]+\\s*");
202 if(regex_match(cc,prfHeader)||regex_match(cc,integer))
205 fseek(ff,0, SEEK_SET);
211 sprintf(comment,
"Number of lines is incorrect, should be %d\n",
N);
212 fprintf(stderr,
"Number of lines is incorrect, should be %d\n",
N);
220 for(
int i=0; i<
N; i++)
223 if(!regex_match(cc,fourCols))
226 sprintf(comment,
"%s - line incorrect!\n",cc);
227 fprintf(stderr,
"%s - line incorrect!\n",cc);
243 fseek(ff,0, SEEK_SET);
248 if(regex_match(cc,integer))
253 sprintf(comment,
"Number of lines is incorrect, should be %d\n",
N);
254 fprintf(stderr,
"Number of lines is incorrect, should be %d\n",
N);
262 for(
int i=0; i<
N; i++)
265 if(!regex_match(cc,twoCols)&&!regex_match(cc,threeCols))
268 sprintf(comment,
"%s - line incorrect!\n",cc);
269 fprintf(stderr,
"%s - line incorrect!\n",cc);
285 fseek(ff,0, SEEK_SET);
288 if(regex_match(cc,kooHeader))
291 int iLen = strlen( cc );
293 for(
int i=0; i<iLen; i++ )
306 sprintf(comment,
"Number of lines is incorrect, should be %d\n",
N);
307 fprintf(stderr,
"Number of lines is incorrect, should be %d\n",
N);
324 fseek(ff,0, SEEK_SET);
329 for(
int i=0; i <
N/2; i++)
332 if(!regex_match(cc,twoCols))
334 sprintf(comment,
"%s - line incorrect(3)!\n",cc);
335 fprintf(stderr,
"%s - line incorrect(3)!\n",cc);
353 fseek(ff,0, SEEK_SET);
357 if(regex_match(cc,datNLines))
359 fseek(ff,0, SEEK_SET);
368 sprintf(comment,
"Number of lines incorrect, should be %d, is %d\n",
N,n1+n2);
369 fprintf(stderr,
"Number of lines incorrect, should be %d, is %d\n",
N,n1+n2);
376 for(
int i=0; i <
N; i++)
381 if(!regex_match(cc,twoCols) && cc[0]!=
'\0' )
384 sprintf(comment,
"%s - line incorrect!\n",cc);
385 fprintf(stderr,
"%s - line incorrect!\n",cc);
401void AIRFOIL::getiTypeByExt(
char *cFile)
405 for(
int i=0; i<3; i++)ext[i] = toupper( pext[i+1] );
409 fprintf( stderr,
"ext %s\n", ext );
411 if( strcmp( ext,
"PRF" ) == 0 )
414 FILE *ff =
fopen( cFile,
"r" );
427 else if( strcmp( ext,
"KOO" ) == 0 )
431 else if( strcmp( ext,
"DAT" ) == 0 )
435 FILE *ff =
fopen( cFile,
"r" );
440 double topCoords, bottomCoords;
444 ReadPar( ff,
"%lf %lf", &topCoords, &bottomCoords );
446 if( topCoords > 1 && bottomCoords > 1 )
iType = 4;
459int AIRFOIL::Read_PRF_0(
char *cFile )
462 ff =
fopen( cFile,
"r" );
465 sprintf( comment,
"File: %s not found!\n", cFile );
466 fprintf( stderr,
"File: %s not found!\n", cFile );
477 for(
int i=0; i<
N; i++)
481 double dAd = dAverage(
Zd,
N );
482 double dAg = dAverage(
Zg,
N );
485 ff =
fopen( cFile,
"r" );
488 for(
int i=0; i<
N; i++)
493 double dCa = max( tabmax(
Xd,
N ), tabmax(
Xg,
N ) );
494 double dX0 = min( tabmin(
Xd,
N ), tabmin(
Xg,
N ) );
497 double dMnoz = 100./dCa;
499 if( dCa < 80. || dCa > 120. )
500 for(
int i=0; i<
N; i++)
525int AIRFOIL::Read_PRF_1(
char *cFile )
528 ff =
fopen( cFile,
"r" );
531 sprintf( comment,
"File: %s not found!\n", cFile );
532 fprintf( stderr,
"File: %s not found!\n", cFile );
540 Xrob =
new double[2*Nrob];
541 Zrob =
new double[2*Nrob];
543 if( iTyp == 1 )
Nf =
Nf*2 - 1;
550 ReadPar( ff,
"%lf %lf %lf", &Xrob[i], &Zrob[i], &Zrob[Nrob] );
553 for(i=1; i<Nrob; i++)
555 ReadPar( ff,
"%lf %lf %lf", &Xrob[i], &Zrob[i], &Zrob[i+Nrob-1] );
558 Xf[i+Nrob-1] = Xrob[i+Nrob-1] = Xrob[i];
559 Zf[i+Nrob-1] = Zrob[i+Nrob-1];
565 for(
int i=0; i<Nrob; i++)
567 ReadPar( ff,
"%lf %lf", &Xrob[i], &Zrob[i] );
583 double *Xfrob =
new double[Nrob];
584 for(
int i=0; i<Nrob; i++ )Xfrob[i] = Xrob[i];
586 SortClean( &
N, Xfrob );
590 double dCa = dMaxT( Xrob, &nmax );
591 double dX0 = dMinT( Xrob, &nmin );
594 double dMnoz = 100./dCa;
598 for(
int i=Nrob; i>NN+1; i-- )
603 Xrob[NN+1] = Xrob[0];
604 Zrob[NN+1] = Zrob[0];
611 for(
int i=0; i<
N; i++ )
614 Zd[i] = inter1( &Xrob[NN+1], &Zrob[NN+1], Nrob-NN-1,
Xd[i] );
616 Zg[i] = inter1( Xrob, Zrob, NN+1,
Xg[i] );
619 for(
int i=0; i<
N; i++ )
635 while(
Xf[nf2] <
Xf[nf2+1] && nf2 <
Nf )nf2++;
636 Sort2( nf2+1,
Xf,
Zf, -1 );
637 for(
int i=0; i<
Nf; i++ )
647void AIRFOIL::PRF2XFOIL(
void )
652 for(
int i=0; i<
N; i++)
654 Xf[i] =
Xd[
N-1-i]/100.;
655 Zf[i] =
Zd[
N-1-i]/100.;
657 for(
int i=
N; i<
Nf; i++)
659 Xf[i] =
Xg[i-
N+1]/100.;
660 Zf[i] =
Zg[i-
N+1]/100.;
664int AIRFOIL::Write_PRF(
char *cFile )
667 ff =
fopen( cFile,
"w" );
668 fprintf(ff,
"%d\t#\t%s\n",
N,
cName );
669 for(
int i=0; i<
N; i++ )
670 fprintf( ff,
"%f %f %f %f\n",
Xg[i],
Zg[i],
Xd[i],
Zd[i] );
676int AIRFOIL::Read_KOO(
char *cFile )
678 return Read_DAT( cFile );
683 fprintf(f,
"%d\t#\t%s\n",
N,
cName );
684 for(
int i=0; i<
N; i++ )
685 fprintf(f,
"%f %f %f %f\n",
Xg[i],
Zg[i],
Xd[i],
Zd[i] );
689int AIRFOIL::Read_DAT_LEDNICER(
char *cFile )
693 ff =
fopen( cFile,
"r" );
696 sprintf( comment,
"File: %s not found!\n", cFile );
697 fprintf( stderr,
"File: %s not found!\n", cFile );
705 int rowsPos, rowsNeg;
707 ReadPar(ff,
"%f %f", &f1, &f2);
712 Xf =
new double[rowsPos+rowsNeg];
713 Zf =
new double[rowsPos+rowsNeg];
715 Nf = rowsPos+rowsNeg-1;
717 for(
int i=rowsPos-1; i>=0; i-- ) {
721 for(
int i=0; i<rowsNeg; i++ ) {
722 ReadPar(ff,
"%lf %lf",&
Xf[rowsPos-1 + i],&
Zf[rowsPos-1 + i]);
734int AIRFOIL::Read_DAT(
char *cFile )
737 ff =
fopen( cFile,
"r" );
740 sprintf( comment,
"File: %s not found!\n", cFile );
741 fprintf( stderr,
"File: %s not found!\n", cFile );
750 sprintf( comment,
"File: %s - the number of rows is too small!\n", cFile );
751 fprintf( stderr,
"File: %s - the number of rows is too small!\n", cFile );
756 Xf =
new double[
Nf+1];
757 Zf =
new double[
Nf+1];
758 ff =
fopen( cFile,
"r" );
762 int iLen = strlen(
cName );
763 for(
int i=iLen; i>0; i-- )
if(
cName[i] ==
',' )
cName[i] =
'\0';
765 for(
int i=0; i<
Nf; i++ )
769 for(
int ii=0; ii < (int)strlen( cc ); ii++)
if( cc[ii] ==
',' )cc[ii] =
' ';
770 sscanf( cc,
"%lf %lf", &
Xf[i], &
Zf[i] );
773 if(
ReadPar( ff,
"%lf %lf", &
Xf[i], &
Zf[i] ) == EOF )
787void AIRFOIL::XFOIL2PRF(
void )
791 double dCa = dMaxT(
Xf, &nmax );
792 double dX0 = dMinT(
Xf, &nmin );
795 if(
Xf[nmin-1] ==
Xf[nmin] )
798 for(
int i=0; i<4; i++)
803 double Y0 = 0.5*(YY[2]+YY[1]);
804 double X0 = apr3( Y0, YY, XX );
805 for(
int i=
Nf; i>nmin; i-- )
815 dCa = dMaxT(
Xf, &nmax );
816 dX0 = dMinT(
Xf, &nmin );
819 double dMnoz = 100./dCa;
823 int NN = min( nmin, nmax );
824 if( nmax > nmin || nmax == 0 )
826 dW1 = dAverage(
Zf, nmin );
827 dW2 = dAverage( &
Zf[nmin],
Nf - nmin );
828 if( dW2 > dW1 )iSter = 1;
833 dW1 = dAverage(
Zf, nmax );
834 dW2 = dAverage( &
Zf[nmax], nmin - nmax );
835 if( dW2 > dW1 )iSter = 1;
839 fprintf( stderr,
"ReadDAT - Xfoil2Prf:\n" );
840 fprintf( stderr,
"Nf = %d NN = %d iSter = %d\n",
Nf, NN, iSter );
841 fprintf( stderr,
"max %d min %d\n", nmax, nmin );
842 fprintf( stderr,
"X0 %f Ca %f\n", dX0, dCa );
845 double *Xfrob =
new double[
Nf];
846 for(
int i=0; i<
Nf; i++ )Xfrob[i] =
Xf[i];
848 SortClean( &
N, Xfrob );
856 for(
int i=0; i<
N; i++ )
859 Zd[i] = inter1(
Xf,
Zf, NN+1,
Xd[i] );
861 Zg[i] = inter1( &
Xf[NN], &
Zf[NN],
Nf-NN,
Xg[i] );
866 for(
int i=0; i<
N; i++ )
869 Zd[i] = inter1( &
Xf[NN], &
Zf[NN],
Nf-NN,
Xd[i] );
871 Zg[i] = inter1(
Xf,
Zf, NN+1,
Xg[i] );
875 for(
int i=0; i<
N; i++ )
887 for(
int i=0; i<
Nf; i++ )
896int AIRFOIL::Write_DAT(
char *cFile )
899 ff =
fopen( cFile,
"w" );
900 fprintf(ff,
"%s\n",
cName );
901 for(
int i=0; i<
Nf; i++ )
902 fprintf( ff,
" %f %f \n",
Xf[i],
Zf[i] );
908void AIRFOIL::TE_correct(
void )
910 double zz = 0.5*(
Zd[
N-1]+
Zg[
N-1]);
916double AIRFOIL::dAverage(
double *dTab,
int i1 )
919 for(
int i=0; i<i1; i++) dSum += dTab[i];
925double AIRFOIL::tabmax(
double* dTab,
int n )
927 double dWyn = dTab[0];
928 if(n>1)
for(
int i=1; i<n; i++ )dWyn = max( dWyn, dTab[i] );
932double AIRFOIL::tabmin(
double* dTab,
int n )
934 double dWyn = dTab[0];
935 if(n>1)
for(
int i=1; i<n; i++ )dWyn = min( dWyn, dTab[i] );
939double AIRFOIL::dMaxT(
double *dTab,
int *i1 )
943 double dRob = dTab[0];
944 for(
int i=0; i<n; i++)
946 dRob = max( dTab[i], dRob );
947 if( dRob == dTab[i] )*i1 = i;
952double AIRFOIL::dMinT(
double *dTab,
int *i1 )
956 double dRob = dTab[0];
957 for(
int i=0; i<n; i++)
959 dRob = min( dTab[i], dRob );
960 if( dRob == dTab[i] )*i1 = i;
965void AIRFOIL::Check(
int *nn,
double *X,
double *Z )
968 for(
int i=0; i<
N-1; i++)
970 if( X[i] == X[i+1] && Z[i] == Z[i+1] )
972 for(
int ii=i; ii<
N-1; ii++ )
983unsigned long AIRFOIL::locate(
double xx[],
unsigned long n,
double x )
986 unsigned long ju,jm,jl;
989 ascnd = ( xx[n-1] >= xx[0] );
995 else if ( x >= xx[n-1] )
1004 if( (x >= xx[jm]) == ascnd)
1016 else if ( x <= xx[n-1] )
1025 if( (x >= xx[jm]) == ascnd)
1042double AIRFOIL::inter1(
double *xx,
double *yy,
unsigned long n,
double x )
1044 unsigned long numer;
1047 if( (xx[n-1]-xx[0]) < 0. )
1049 x = min( x, xx[0] );
1050 x = max( x, xx[n-1] );
1054 x = max( x, xx[0] );
1055 x = min( x, xx[n-1] );
1057 numer = locate(xx, n, x );
1062 y = yy[numer+1]*(x-xx[numer]) + yy[numer]*(xx[numer+1]-x);
1063 y /= xx[numer+1]-xx[numer];
1069double AIRFOIL::apr3(
double dX,
double *dXX,
double *dYY )
1080 double X13 = pow( X1, 3.0 );
1081 double X23 = pow( X2, 3.0 );
1082 double X33 = pow( X3, 3.0 );
1083 double X43 = pow( X4, 3.0 );
1085 double Q1 = X33*(X2-X1) - X23*(X3-X1) + X13*(X3-X2);
1086 double Q2 = X43*(X2-X1) - X23*(X4-X1) + X13*(X4-X2);
1087 double Q3 = (X3-X2)*(X2-X1)*(X3-X1);
1088 double Q4 = (X4-X2)*(X2-X1)*(X4-X1);
1089 double Q5 = F3*(X2-X1) - F2*(X3-X1) + F1*(X3-X2);
1090 double Q6 = F4*(X2-X1) - F2*(X4-X1) + F1*(X4-X2);
1092 double a3 = (Q3*Q6-Q4*Q5)/(Q2*Q3-Q1*Q4);
1093 double a2 = (Q5-a3*Q1)/Q3;
1094 double a1 = (F2-F1)/(X2-X1) - a3*(X23-X13)/(X2-X1) - a2*(X1+X2);
1095 double a0 = F1 - a1*X1 - a2*X1*X1 - a3*X13;
1097 return( a0 + a1*dX + a2*dX*dX + a3*dX*dX*dX );
1104void AIRFOIL::SortClean(
int *N,
double *X )
1108 for(
int i=0; i<NN-1; i++ )
1110 if( X[i] == X[i+1] )
1112 for(
int ii=i; ii<NN-1; ii++ )X[ii]=X[ii+1];
1123void AIRFOIL::Sort1(
int N,
double dRA[] )
1132 for( j=0; j<(
N-k); j++ )
1133 for( i=j; i>=0; i-=k )
1135 if( dRA[i] > dRA[i+k] )
1146bool AIRFOIL::check_order(
double d1,
double d2,
int iFlag )
1158void AIRFOIL::Sort2(
int iN,
double dRA[],
double dKOL[],
int iOrder )
1167 if( iN <= 1 )
return;
1182 dKOL[iR-1] = dKOL[0];
1196 if( ( j < iR ) && check_order( dRA[j-1], dRA[j], iOrder ) )j++;
1197 if( check_order( dRRA, dRA[j-1], iOrder ) )
1199 dRA[i-1] = dRA[j-1];
1200 dKOL[i-1] = dKOL[j-1];
double * Xf
X coordinates (Nf points)
void Print(FILE *f=stdout)
prints PRF file (default on stdout)
double * Xd
X coordinates of lower contour (N points)
void Clean(void)
cleans local variables
int ReadNaca(long int iNACA, int NN=100)
generates NACA airfoil given by long int value (e.g. iNACA = 23012), NN - the number of points that...
double * Zf
Z coordinates (Nf points)
int Read(char *cFile)
reads profile file
int Nf
size of the vectors with geometry data - compatible with Xfoil
int Write(char *cFile, int iTyp=0)
saves profile file - two types are available: 0 - native PANUKL (4 columns) 3 - SELIG (Xfoil comp...
char cName[100]
filename (without path)
int iType
File type: 0 - PRF - PANUKL (prf1) - native PANUKL (4 columns) format 1 - PRF - prf2 - by L....
int N
size of the vectors with geometry data - 4 column native PANUKL format
int iGUI
GUI flag - messages displayed using wrapping function "alert".
double * Zg
Z coordinates of upper contour (N points)
void(* alert)(char *c)
virtual fuction to display the message (if iGUI > 0)
double * Zd
Z coordinates of lower contour (N points)
double * Xg
X coordinates of upper contour (N points)
static void ReadStrL(FILE *stream, char *Par, int *len)
Function to read the string (Par) from FILE "stream". It reads from current pointer of FILE to the en...
static FILE * fopen(const char *filename, const char *mode)
Cross-platform function to fopen function that supports UTF-8 encoded name.
static const char * filename_name(const char *name)
Returns pointer to filename without path.
static int nLines(FILE *stream)
Returns number of lines of text file from current pointer to EOF.
static int ReadStr(FILE *stream, char *Par)
Function to read the new line from FILE "stream" and to store it in table of char "Par"....
static int ReadPar(FILE *stream, const char *Format, void *Par)
Function to read one variable. The type of variable depends on Format, compatible with stdio library.
static const char * filename_ext(const char *buf)
Returns pointer to filename extension.
NACA_PROFILE class to generate 4-digit and 5-digit naca airfoils Created by Alexandre Naaman (hoser...
int generate_naca(char *name, int num, FILE *fp)
generates naca airfoil coordinates (NN points) and stores it in file defined by stream "fp"
void setTE0(int TE=1)
TE=1 forces the zero thickness trailing edge.
double * Z
z coordinates vecotr
int N
coordiantes vectors' size
double * X
x coordinates vector
#define DELETE_(OBJ)
Macro for safe deleteing the object and sets the pointer to zero.
#define DELETE_TAB(OBJ)
Macro for safe deleteing the array and sets the pointer to zero.