struct Flist *nCopyFlistStruct(struct Flist *src, int srcnum) { struct Flist *flist = NULL; flist = AllocFlistStruct(src->portion); flist->num = srcnum; flist->max = srcnum; if ((flist->list = (float *)calloc(flist->max, sizeof(float))) == NULL) { fatal("calloc failed on (float)!"); } memcpy(flist->list, src->list, srcnum * sizeof(float)); return flist; }
void GetBladeAnglesPlotData(struct radial *rr, float *xpl, float *ypl, float *xy) { int i, num, pcount; float dl, ds, rad2deg, alpha; struct Flist *le_ang; struct Flist *te_ang; struct Point *cl; le_ang = AllocFlistStruct(rr->be_num+1); te_ang = AllocFlistStruct(rr->be_num+1); rad2deg = 180.0f/(float)M_PI; pcount = 0; // calc blade angles at inlet & outlet for(i = 0; i < rr->be_num; i++) { if( (cl = rr->be[i]->cl)) { num = cl->nump-1; // le angle dl = sqrt(pow(cl->x[1]-cl->x[0],2) + pow(cl->z[1]-cl->z[0],2)); ds = 0.5*(cl->x[1] + cl->x[0]) * (cl->y[0] - cl->y[1]); if( (alpha = atan(dl/ds)*rad2deg) < 0.0) alpha += 180.0; Add2Flist(le_ang, alpha); // te_angle dl = sqrt(pow(cl->x[num]-cl->x[num-1],2) + pow(cl->z[num]-cl->z[num-1],2)); ds = 0.5*(cl->x[num] + cl->x[num-1]) * (cl->y[num-1] - cl->y[num]); if( (alpha = atan(dl/ds)*rad2deg) < 0.0) alpha += 180.0; Add2Flist(te_ang, alpha); } } if((rr->be_num != le_ang->num) ||(rr->be_num != te_ang->num)) { fatal("point number mismatch for blade angles!"); return; } // fill plot vectors xpl[pcount] = rr->be[0]->para; xy[1] = xy[3] = ypl[pcount] = le_ang->list[0]; pcount++; for(i = 1; i < rr->be_num; i++) { xpl[pcount] = rr->be[i]->para; if(xy[1] > (ypl[pcount] = le_ang->list[i])) xy[1] = ypl[pcount]; else if (xy[3] < ypl[pcount]) xy[3] = ypl[pcount]; pcount++; if(i < rr->be_num-1) { xpl[pcount] = rr->be[i]->para; ypl[pcount] = le_ang->list[i]; pcount++; } } xpl[pcount] = rr->be[0]->para; ypl[pcount] = te_ang->list[0]; pcount++; for(i = 1; i < rr->be_num; i++) { xpl[pcount] = rr->be[i]->para; if(xy[1] > (ypl[pcount] = te_ang->list[i])) xy[1] = ypl[pcount]; else if (xy[3] < ypl[pcount]) xy[3] = ypl[pcount]; pcount++; if(i < rr->be_num-1) { xpl[pcount] = rr->be[i]->para; ypl[pcount] = te_ang->list[i]; pcount++; } } //xy[1] *= (1.0 - PLOT_SCALE_ENLARGE); xy[1] = 0.0; //xy[3] *= (1.0 + PLOT_SCALE_ENLARGE); xy[3] = 90.0; xy[0] = 0.0; xy[2] = 1.0; FreeFlistStruct(le_ang); FreeFlistStruct(te_ang); }
int CreateRR_BladeEdge(struct edge *e) { int i; float angle, roma[2][2]; float hub[3], shroud[3], inter[3], mid1[3], mid2[3]; float h_vec[3], s_vec[3]; float sec, p[3]; struct Point *poly; // edge spline polygon struct Flist *knot; // edge spline knot vector // for backward compatibility if(!e->spara[0] && !e->spara[1]) { e->spara[0] = e->spara[1] = 0.6f; } mid1[1] = 0.0; mid2[1] = 0.0; hub[1] = 0.0; shroud[1] = 0.0; inter[1] = 0.0; h_vec[1] = 0.0; s_vec[1] = 0.0; // point and gradient hub side hub[0] = e->c->p->x[0]; hub[2] = e->c->p->z[0]; angle = e->angle[0] - M_PI_2; roma[0][0] = cos(angle); roma[0][1] = -sin(angle); roma[1][0] = sin(angle); roma[1][1] = cos(angle); h_vec[0] = e->h_norm[0] * roma[0][0] + e->h_norm[2] * roma[0][1]; h_vec[2] = e->h_norm[0] * roma[1][0] + e->h_norm[2] * roma[1][1]; // move hub point to properly intersect with meridian contour hub[0] -= (0.01 * h_vec[0]); hub[2] -= (0.01 * h_vec[2]); // point and gradient shroud side shroud[0] = e->c->p->x[e->c->p->nump-1]; shroud[2] = e->c->p->z[e->c->p->nump-1]; angle = e->angle[1] - M_PI_2; roma[0][0] = cos(angle); roma[0][1] = -sin(angle); roma[1][0] = sin(angle); roma[1][1] = cos(angle); s_vec[0] = e->s_norm[0] * roma[0][0] + e->s_norm[2] * roma[0][1]; s_vec[2] = e->s_norm[0] * roma[1][0] + e->s_norm[2] * roma[1][1]; // move shroud point to properly intersect with meridian contour #ifdef GAP shroud[0] += (0.05 * s_vec[0]); shroud[2] += (0.05 * s_vec[2]); #else shroud[0] += (0.01 * s_vec[0]); shroud[2] += (0.01 * s_vec[2]); #endif // intersection and partition points LineIntersectXZ(hub, h_vec, shroud, s_vec, inter); mid1[0] = hub[0] + e->spara[0] * (inter[0] - hub[0]); mid1[2] = hub[2] + e->spara[0] * (inter[2] - hub[2]); mid2[0] = shroud[0] + e->spara[1] * (inter[0] - shroud[0]); mid2[2] = shroud[2] + e->spara[1] * (inter[2] - shroud[2]); poly = AllocPointStruct(); AddVPoint(poly, hub); AddVPoint(poly, mid1); AddVPoint(poly, mid2); AddVPoint(poly, shroud); // calculate spline and points for curve (overwrite) knot = AllocFlistStruct(0); knot = BSplineKnot(poly, BSPLN_DEGREE); e->c->p->nump = 0; for (i = 0; i <= NPOIN_EDGE; i++) { sec = (float)i/(float)NPOIN_EDGE; BSplinePoint(BSPLN_DEGREE, poly, knot, sec, p); AddCurvePoint(e->c, p[0], p[1], p[2], 0.0, sec); } CalcCurveArclen(e->c); return 0; }
int SurfacesAR_BladeElement(struct be *be, float bangle, float /*ref*/, int clock, int clspline) // caller: CreateAR_BladeElements() { int i, t_sec; float phi_r, cl_sec, scale_te, te, t, tmax, angle, factor; float p1[3], p2[3], p3[3], p4[3], q1[3], q2[3], q3[3],q4[3],roma[2][2]; float qeq_a, qeq_b, qeq_c, qeq_r, s[3], m[3]; float ratio, len, alpha = 0.0; struct Point *he_poly = NULL; struct Flist *he_knot = NULL; struct Point *cl_poly = NULL; struct Flist *cl_knot = NULL; FILE *fp=NULL, *fp2=NULL; char fname[255]; char *fn; static int nbe = 0; sprintf(fname, "ar_beplane_%02d.txt", nbe++); fn = DebugFilename(fname); if(fn) fp = fopen(fn, "w"); // delete previous data and allocate new if (cl_poly) { FreePointStruct(cl_poly); cl_poly = NULL; } if (cl_knot) { FreeFlistStruct(cl_knot); cl_knot = NULL; } FreePointStruct(be->cl); FreePointStruct(be->clg); FreePointStruct(be->ps); FreePointStruct(be->ss); FreePointStruct(be->cl_cart); FreePointStruct(be->ps_cart); FreePointStruct(be->ss_cart); // CALCULATE BLADE TRIANGLE FROM ANGLES AND ARC LENGTH // solve quadratic equation to determine p2 and p4 s[0] = s[1] = s[2] = 0.0; qeq_a = qeq_b = qeq_c = qeq_r = 0.0; qeq_a = (1.0 - be->camb_pos) * pow(tan(RAD(be->angle[0])), 2); qeq_a += (2.0 * be->camb_pos - 1.0) * tan(RAD(be->angle[0])) * tan(RAD(be->angle[1])); qeq_a -= be->camb_pos * pow(tan(RAD(be->angle[1])), 2); qeq_b = (1.0 - 2.0 * be->camb_pos) * tan(RAD(be->angle[0])) * tan(RAD(be->angle[1])); qeq_b += 2.0 * (be->camb_pos - 1.0) * pow(tan(RAD(be->angle[0])), 2); qeq_b -= 1.0; qeq_c = (1.0 - be->camb_pos) * pow(tan(RAD(be->angle[0])), 2); qeq_c += (1.0 - be->camb_pos); qeq_r = pow(qeq_b, 2) + 4.0 * qeq_a * qeq_c; if (qeq_r < 0.0) { fatal("ERROR-calc. of quadratic eqn. for camber position: only complex solutions."); } else { s[0] = (-qeq_b + sqrt(pow(qeq_b, 2) - 4.0 * qeq_a * qeq_c)) / (2.0 * qeq_a); s[1] = s[0] * tan(RAD(be->angle[1])); if ((s[0] < (0.0 - TOLERANCE)) || (s[0] > (1.0 + TOLERANCE))) { s[0] = (-qeq_b - sqrt(pow(qeq_b, 2) - 4.0 * qeq_a * qeq_c)) / (2.0 * qeq_a); s[1] = s[0] * tan(RAD(be->angle[1])); if ((s[0] < (0.0 - TOLERANCE)) || (s[0] > (1.0 + TOLERANCE))) { fatal("ERROR-calc. of camber position: solutions are outside [0.0;1.0]."); } } } // calculate blade triangle points, scale to arc length phi_r = be->bl_wrap * be->rad; p1[0] = p1[1] = p1[2] = 0.0; p2[0] = p2[1] = p2[2] = 0.0; p3[0] = p3[1] = p3[2] = 0.0; p4[0] = p4[1] = p4[2] = 0.0; p1[0] = phi_r; p1[1] = phi_r * (s[0] * tan(RAD(be->angle[1])) + (1.0 - s[0]) * tan(RAD(be->angle[0]))); p2[0] = s[0] * phi_r; p2[1] = s[1] * phi_r; p3[0] = p3[1] = p3[2] = 0.0; p4[0] = (1.0 - be->camb_pos) * p1[0]; p4[1] = (1.0 - be->camb_pos) * p1[1]; // rotate blade triangle around TE point, base to x-axis q1[0] = q1[1] = q1[2] = 0.0; q2[0] = q2[1] = q2[2] = 0.0; q3[0] = q3[1] = q3[2] = 0.0; q4[0] = q4[1] = q4[2] = 0.0; angle = M_PI - atan(p1[1]/p1[0]); roma[0][0] = cos(angle); roma[0][1] = -sin(angle); roma[1][0] = sin(angle); roma[1][1] = cos(angle); q1[0] = roma[0][0] * p1[0] + roma[0][1] * p1[1]; q1[1] = roma[1][0] * p1[0] + roma[1][1] * p1[1]; q2[0] = roma[0][0] * p2[0] + roma[0][1] * p2[1]; q2[1] = roma[1][0] * p2[0] + roma[1][1] * p2[1]; q3[0] = roma[0][0] * p3[0] + roma[0][1] * p3[1]; q3[1] = roma[1][0] * p3[0] + roma[1][1] * p3[1]; q4[0] = roma[0][0] * p4[0] + roma[0][1] * p4[1]; q4[1] = roma[1][0] * p4[0] + roma[1][1] * p4[1]; // CL AND SURFACE CALCULATION cl_poly = AllocPointStruct(); // ************************************************** // create curve from two single splines if(clspline) { // move q4 according to blade element camber and skew param. q4[0] += (be->le_part[2]-0.5)*(q1[0]-q3[0]); q4[1] = be->camb * q2[1]; // le point (q1) and first two le points on cl polygon AddVPoint(cl_poly, q1); ratio = be->camb / 12.0; s[0] = q1[0] + ratio * (q2[0] - q1[0]); s[1] = q1[1] + ratio * (q2[1] - q1[1]); AddVPoint(cl_poly, s); /*ratio = be->camb / 4.0; s[0] = q1[0] + ratio * (q2[0] - q1[0]); s[1] = q1[1] + ratio * (q2[1] - q1[1]); s[2] = 0.0; AddVPoint(cl_poly, s);*/ // help polygon from third le point to q4 (max camber point) m[1] = q4[1]; // always m[2] = 0.0; // always m[0] = q1[0] + (q2[0] - q1[0]) / (q2[1] - q1[1]) * (m[1] - q1[1]); he_poly = CurvePolygon(s, m, q4, be->le_part[0], be->le_part[1]); he_knot = BSplineKnot(he_poly, BSPLN_DEGREE); for(i = 1; i < NPOIN_HELP_POLY; i++) { ratio = (float)i / (float)(NPOIN_HELP_POLY-1); BSplinePoint(BSPLN_DEGREE, he_poly, he_knot, ratio, s); AddVPoint(cl_poly, s); } FreePointStruct(he_poly); FreeFlistStruct(he_knot); // help polygon from q4 to third last te point he_poly = AllocPointStruct(); he_knot = AllocFlistStruct(INIT_PORTION); m[0] = q3[0] + (q2[0] - q3[0]) / (q2[1] - q3[1]) * (m[1] - q3[1]); ratio = be->camb / 8.0; s[0] = q3[0] + ratio * (q2[0] - q3[0]); s[1] = q3[1] + ratio * (q2[1] - q3[1]); s[2] = 0.0; he_poly = CurvePolygon(q4, m, s, be->te_part[0], be->te_part[1]); he_knot = BSplineKnot(he_poly, BSPLN_DEGREE); for (i = 1; i < NPOIN_HELP_POLY; i++) { ratio = (float)i / (float)(NPOIN_HELP_POLY-1); BSplinePoint(BSPLN_DEGREE, he_poly, he_knot, ratio, m); AddVPoint(cl_poly, m); } // last two te points on cl polygon and te point (q3) AddVPoint(cl_poly, s); /*ratio = be->camb / 8.0; s[0] = q3[0] + ratio * (q2[0] - q3[0]); s[1] = q3[1] + ratio * (q2[1] - q3[1]); s[2] = 0.0; AddVPoint(cl_poly, s);*/ } else { // only one spline in triangle cl_poly->nump = 0; AddVPoint(cl_poly, q1); ratio = be->camb / 12.0; s[0] = q1[0] + ratio * (q2[0] - q1[0]); s[1] = q1[1] + ratio * (q2[1] - q1[1]); AddVPoint(cl_poly,s); ratio = be->camb / 8.0; m[0] = q3[0] + ratio * (q2[0] - q3[0]); m[1] = q3[1] + ratio * (q2[1] - q3[1]); he_poly = CurvePolygon(s, q2, m, be->le_part[0], be->le_part[1]); he_knot = BSplineKnot(he_poly, BSPLN_DEGREE); for (i = 1; i < 2*NPOIN_HELP_POLY; i++) { ratio = (float)i / (float)(2*NPOIN_HELP_POLY-1); BSplinePoint(BSPLN_DEGREE, he_poly, he_knot, ratio, m); AddVPoint(cl_poly, m); } } AddVPoint(cl_poly, q3); FreePointStruct(he_poly); FreeFlistStruct(he_knot); // INDEX 0: cl polygon points, construction for (i = 0; fp && i < cl_poly->nump; i++) { if(i < cl_poly->nump-1) alpha = atan((cl_poly->y[i]-cl_poly->y[i+1])/ (cl_poly->x[i]-cl_poly->x[i+1])); fprintf(fp, "%f %f %f\n", cl_poly->x[i], cl_poly->y[i], alpha*180.0/M_PI); } if (fp) fprintf(fp, "\n\n"); // rotate back cl polygon points, calculate arc length roma[0][0] = cos(-angle); roma[0][1] = -sin(-angle); roma[1][0] = sin(-angle); roma[1][1] = cos(-angle); for(i = 0; i < cl_poly->nump; i++) { s[0] = roma[0][0] * cl_poly->x[i] + roma[0][1] * cl_poly->y[i]; s[1] = roma[1][0] * cl_poly->x[i] + roma[1][1] * cl_poly->y[i]; s[2] = 0.0; cl_poly->x[i] = s[0]; cl_poly->y[i] = s[1]; cl_poly->z[i] = s[2]; if (i) { len = pow((cl_poly->x[i] - cl_poly->x[i-1]), 2); len += pow((cl_poly->y[i] - cl_poly->y[i-1]), 2); len += pow((cl_poly->z[i] - cl_poly->z[i-1]), 2); len = sqrt(len); be->cl_len += len; } } // INDEX 1: cl polygon points, rotated back if(fp) fprintf(fp,"# cl polygon points, INDEX 1\n"); for (i = 0; fp && i < cl_poly->nump; i++) { if(i < cl_poly->nump-1) alpha = atan((cl_poly->y[i]-cl_poly->y[i+1])/ (cl_poly->x[i]-cl_poly->x[i+1])); fprintf(fp, "%f %f %f\n", cl_poly->x[i], cl_poly->y[i], alpha*180.0/M_PI); } if (fp) fprintf(fp, "\n\n"); // CL AND CL GRADIENT be->cl = AllocPointStruct(); be->clg = AllocPointStruct(); cl_knot = BSplineKnot(cl_poly, BSPLN_DEGREE); // cl points and gradient sprintf(fname, "ar_becl_%02d.txt", nbe-1); fn = DebugFilename(fname); if(fn) fp2 = fopen(fn, "w"); for (i = 0; i < be->bp->num; i++) { cl_sec = pow(be->bp->c[i], be->bp_shift); BSplinePoint(BSPLN_DEGREE, cl_poly, cl_knot, cl_sec, &s[0]); AddVPoint(be->cl, s); BSplineNormal(BSPLN_DEGREE, cl_poly, cl_knot, cl_sec, &s[0]); AddVPoint(be->clg, s); if(fp2) fprintf(fp2,"%f %f %f\n",s[0], s[1], s[2]); } if(fp2) fclose(fp2); // CALCULATE PS/SS // scale_te is tot. profile thickness scale up be->ss = AllocPointStruct(); be->ps = AllocPointStruct(); t_sec = be->bp->t_sec; tmax = be->bp->t[t_sec] * be->cl_len + be->bp->c[t_sec] * be->te_thick; scale_te = be->p_thick / tmax; for (i = 0; i < be->bp->num; i++) { // pressure side (-) and suction side (+), machine size te = 0.5 * be->bp->c[i] * be->te_thick; t = 0.5 * be->cl_len * be->bp->t[i]; s[0] = be->cl->x[i] - be->clg->x[i] * (scale_te * t + te); s[1] = be->cl->y[i] - be->clg->y[i] * (scale_te * t + te); s[2] = be->cl->z[i] - be->clg->z[i] * (scale_te * t + te); AddVPoint(be->ps, s); s[0] = be->cl->x[i] + be->clg->x[i] * (scale_te * t + te); s[1] = be->cl->y[i] + be->clg->y[i] * (scale_te * t + te); s[2] = be->cl->z[i] + be->clg->z[i] * (scale_te * t + te); AddVPoint(be->ss, s); } // INDEX 2: cl, ps/ss surfaces for (i = 0; fp && i < be->cl->nump; i++) { if(i < be->cl->nump-1) alpha = atan((be->cl->y[i]-be->cl->y[i+1])/ (be->cl->x[i]-be->cl->x[i+1])); fprintf(fp, "%f %f %f ", be->cl->x[i], be->cl->y[i], alpha*180.0/M_PI); fprintf(fp, "%f %f %f ", be->ps->x[i], be->ps->y[i], be->ps->z[i]); fprintf(fp, "%f %f %f\n", be->ss->x[i], be->ss->y[i], be->ss->z[i]); } if (fp) fprintf(fp, "\n\n"); // calculate pivot coords, translate blade elements BSplinePoint(BSPLN_DEGREE, cl_poly, cl_knot, be->pivot, &s[0]); for (i = 0; i < be->cl->nump; i++) { be->cl->x[i] -= s[0]; be->cl->y[i] -= s[1]; be->cl->z[i] -= s[2]; be->ps->x[i] -= s[0]; be->ps->y[i] -= s[1]; be->ps->z[i] -= s[2]; be->ss->x[i] -= s[0]; be->ss->y[i] -= s[1]; be->ss->z[i] -= s[2]; } // INDEX 3: cl, ps/ss surfaces, translated for (i = 0; fp && i < be->cl->nump; i++) { fprintf(fp, "%f %f %f ", be->cl->x[i], be->cl->y[i], be->cl->z[i]); fprintf(fp, "%f %f %f ", be->ps->x[i], be->ps->y[i], be->ps->z[i]); fprintf(fp, "%f %f %f\n", be->ss->x[i], be->ss->y[i], be->ss->z[i]); } if (fp) fprintf(fp, "\n\n"); // rotate blade element around pivot roma[0][0] = cos(RAD(bangle)); roma[0][1] = -sin(RAD(bangle)); roma[1][0] = sin(RAD(bangle)); roma[1][1] = cos(RAD(bangle)); for (i = 0; i < be->cl->nump; i++) { s[0] = roma[0][0] * be->cl->x[i] + roma[0][1] * be->cl->y[i]; s[1] = roma[1][0] * be->cl->x[i] + roma[1][1] * be->cl->y[i]; s[2] = 0.0; be->cl->x[i] = s[0]; be->cl->y[i] = s[1]; be->cl->z[i] = s[2]; s[0] = roma[0][0] * be->ps->x[i] + roma[0][1] * be->ps->y[i]; s[1] = roma[1][0] * be->ps->x[i] + roma[1][1] * be->ps->y[i]; s[2] = 0.0; be->ps->x[i] = s[0]; be->ps->y[i] = s[1]; be->ps->z[i] = s[2]; s[0] = roma[0][0] * be->ss->x[i] + roma[0][1] * be->ss->y[i]; s[1] = roma[1][0] * be->ss->x[i] + roma[1][1] * be->ss->y[i]; s[2] = 0.0; be->ss->x[i] = s[0]; be->ss->y[i] = s[1]; be->ss->z[i] = s[2]; } // INDEX 4: cl, ps/ss surfaces, translated and rotated for (i = 0; fp && i < be->cl->nump; i++) { if(i < be->cl->nump-1) alpha = atan((be->cl->y[i]-be->cl->y[i+1])/ (be->cl->x[i]-be->cl->x[i+1])); fprintf(fp, "%f %f %f ", be->cl->x[i], be->cl->y[i], alpha*180.0/M_PI); fprintf(fp, "%f %f %f ", be->ps->x[i], be->ps->y[i], be->ps->z[i]); fprintf(fp, "%f %f %f\n", be->ss->x[i], be->ss->y[i], be->ss->z[i]); } if (fp) fprintf(fp, "\n\n"); // transform into cartesian coords be->cl_cart = AllocPointStruct(); be->ps_cart = AllocPointStruct(); be->ss_cart = AllocPointStruct(); for (i = 0; i < be->cl->nump; i++) { if(clock) factor = -1.0/be->rad; else factor = 1.0/be->rad; s[0] = be->rad * cos(be->cl->x[i]*factor); s[1] = be->rad * sin(be->cl->x[i]*factor); s[2] = be->cl->y[i]; AddVPoint(be->cl_cart, s); s[0] = be->rad * cos(be->ps->x[i]*factor); s[1] = be->rad * sin(be->ps->x[i]*factor); s[2] = be->ps->y[i]; AddVPoint(be->ps_cart, s); s[0] = be->rad * cos(be->ss->x[i]*factor); s[1] = be->rad * sin(be->ss->x[i]*factor); s[2] = be->ss->y[i]; AddVPoint(be->ss_cart, s); } if (fp) fclose(fp); return 1; }