void approx_sqrti(double val,double *realans,double *imagans) { double result; result=approx_pow(zabsf(val),0.5); if(val>=0) { *realans=result; *imagans=0; } else { *realans=0; *imagans=result; } }
void FlexAirfoil::updateForces() { if(!airfoil) return; if (broken) return; // if (innan) {LOG("STEP "+TOSTRING(innan)+" "+TOSTRING(nblu));innan++;} //evaluate wind direction Vector3 wind=-(nodes[nfld].Velocity+nodes[nfrd].Velocity)/2.0; //add wash int i; for (i=0; i<free_wash; i++) wind-=(0.5*washpropratio[i]*aeroengines[washpropnum[i]]->getpropwash())*aeroengines[washpropnum[i]]->getAxis(); float wspeed=wind.length(); //chord vector, front to back Vector3 chordv=((nodes[nbld].RelPosition-nodes[nfld].RelPosition)+(nodes[nbrd].RelPosition-nodes[nfrd].RelPosition))/2.0; float chord=chordv.length(); //span vector, left to right Vector3 spanv=((nodes[nfrd].RelPosition-nodes[nfld].RelPosition)+(nodes[nbrd].RelPosition-nodes[nbld].RelPosition))/2.0; float span=spanv.length(); //lift vector //if (_isnan(spanv.x) || _isnan(spanv.y) || _isnan(spanv.z)) LOG("spanv is NaN "+TOSTRING(nblu)); //if (_isnan(wind.x) || _isnan(wind.y) || _isnan(wind.z)) LOG("wind is NaN "+TOSTRING(nblu)); Vector3 liftv=spanv.crossProduct(-wind); //if (_isnan(liftv.x) || _isnan(liftv.y) || _isnan(liftv.z)) LOG("liftv0 is NaN "+TOSTRING(nblu)); //if (_isnan(liftv.x) || _isnan(liftv.y) || _isnan(liftv.z)) LOG("liftv1 is NaN "+TOSTRING(nblu)); //wing normal float s=span*chord; Vector3 normv=chordv.crossProduct(spanv); normv.normalise(); //calculate angle of attack Vector3 pwind; pwind=Plane(Vector3::ZERO, normv, chordv).projectVector(-wind); Vector3 dumb; Degree daoa; chordv.getRotationTo(-pwind).ToAngleAxis(daoa, dumb); aoa=daoa.valueDegrees(); float raoa=daoa.valueRadians(); if (dumb.dotProduct(spanv)>0) {aoa=-aoa; raoa=-raoa;}; //if (_isnan(aoa)) LOG("aoa is NaN "+TOSTRING(nblu)); //get airfoil data float cz, cx, cm; if (isstabilator) airfoil->getparams(aoa-deflection, chordratio, 0, &cz, &cx, &cm); else airfoil->getparams(aoa, chordratio, deflection, &cz, &cx, &cm); //compute surface //if (_isnan(cz)) LOG("cz is NaN "+TOSTRING(nblu)); //float fs=span*(fabs(thickness*cos(raoa))+fabs(chord*sin(raoa))); //float ts=span*(fabs(chord*cos(raoa))+fabs(thickness*sin(raoa))); //tropospheric model valid up to 11.000m (33.000ft) float altitude=nodes[nfld].AbsPosition.y; //float sea_level_temperature=273.15+15.0; //in Kelvin (not used) float sea_level_pressure=101325; //in Pa //float airtemperature=sea_level_temperature-altitude*0.0065; //in Kelvin (not used) float airpressure=sea_level_pressure*approx_pow(1.0-0.0065*altitude/288.15, 5.24947); //in Pa float airdensity=airpressure*0.0000120896;//1.225 at sea level Vector3 wforce=Vector3::ZERO; //drag wforce=(cx*0.5*airdensity*wspeed*s)*wind; //if (_isnan(wforce.x) || _isnan(wforce.y) || _isnan(wforce.z)) LOG("wforce1 is NaN "+TOSTRING(nblu)); //induced drag if (useInducedDrag) { Vector3 idf=(cx*cx*0.25*airdensity*wspeed*idArea*idArea/(3.14159*idSpan*idSpan))*wind; //if (_isnan(idf.length())) LOG("idf is NaN "+TOSTRING(nblu)); if (idLeft) { nodes[nblu].Forces+=idf; nodes[nbld].Forces+=idf; } else { nodes[nbru].Forces+=idf; nodes[nbrd].Forces+=idf; } } //if (_isnan(wforce.x) || _isnan(wforce.y) || _isnan(wforce.z)) LOG("wforce1a is NaN "+TOSTRING(nblu)); //if (_isnan(cz)) LOG("cz is NaN "+TOSTRING(nblu)); //if (_isnan(wspeed)) LOG("wspeed is NaN "+TOSTRING(nblu)); //if (_isnan(airdensity)) LOG("airdensity is NaN "+TOSTRING(nblu)); //if (_isnan(s)) LOG("s is NaN "+TOSTRING(nblu)); //if (_isnan(liftv.x) || _isnan(liftv.y) || _isnan(liftv.z)) LOG("liftv is NaN "+TOSTRING(nblu)); //lift wforce+=(cz*0.5*airdensity*wspeed*chord)*liftv; /*if (_isnan(wforce.x) || _isnan(wforce.y) || _isnan(wforce.z)) { if (innan==0) innan=1; LOG("wforce2 is NaN "+TOSTRING(nblu)); } */ //moment float moment=-cm*0.5*airdensity*wspeed*wspeed*s;//*chord; //apply forces Vector3 f1=wforce*(liftcoef * 0.75/4.0f)+normv*(liftcoef *moment/(4.0f*0.25f)); Vector3 f2=wforce*(liftcoef *0.25/4.0f)-normv*(liftcoef *moment/(4.0f*0.75f)); //focal at 0.25 chord nodes[nfld].Forces+=f1; nodes[nflu].Forces+=f1; nodes[nfrd].Forces+=f1; nodes[nfru].Forces+=f1; nodes[nbld].Forces+=f2; nodes[nblu].Forces+=f2; nodes[nbrd].Forces+=f2; nodes[nbru].Forces+=f2; // sprintf(debug, "wind %i kts, aoa %i, cz %f, vf %f ", (int)(wspeed*1.9438), (int)aoa, cz, normv.y); }
double approx_sqrt(double val) { return approx_pow(val,0.5); }