Ejemplo n.º 1
0
        /// <summary>
        /// These are just a few different attempts to figure drag for various blunt bodies
        /// </summary>
        private void DragModel(Vector3d local_velocity, double M, double rho)
        {
            // Has the same x/y/z as the vertices in PartMaxBoundaries etc
            Vector3d model_velocity = to_model_rotation * local_velocity;

            double viscousLift, potentialLift, newtonianLift;

            viscousLift = potentialLift = newtonianLift = 0;
            double CdAdd = 0;
            //float AxialProportion = Vector3.Dot(localUpVector, local_velocity);
            double AxialProportion     = model_velocity.y;
            float  AxialProportion_flt = (float)model_velocity.y;
            double AxialProportion_2   = AxialProportion * AxialProportion;
            double OneMinusAxial_2     = Math.Abs(1 - AxialProportion_2);
            double M_2       = M * M;
            double M_2_recip = 1 / M_2;
            double maxPressureCoeff;

            if (FARDebugValues.useSplinesForSupersonicMath)
            {
                maxPressureCoeff = FARAeroUtil.MaxPressureCoefficient.Evaluate((float)M);
            }
            else
            {
                maxPressureCoeff = FARAeroUtil.MaxPressureCoefficientCalc(M);
            }

            double sepFlowCd = SeparatedFlowDrag(M, M_2, M_2_recip);

            //This handles elliptical and other non-circular cross sections
            //float crossflowParameter = Vector3.Dot(localForwardVector, Vector3.Exclude(localUpVector, local_velocity).normalized);
            //crossflowParameter *= crossflowParameter;
            double crossflowParameter = model_velocity.z * model_velocity.z;
            double crossflow          = model_velocity.x * model_velocity.x + crossflowParameter;

            if (crossflow != 0)
            {
                crossflowParameter /= crossflow;
            }

            crossflowParameter = crossflowParameter * majorMinorAxisRatio + (1 - crossflowParameter) / majorMinorAxisRatio;
            if (AxialProportion_2 > 0.98)
            {
                crossflowParameter *= 50 * OneMinusAxial_2;
            }

            Cd += CdCurve.Evaluate(AxialProportion_flt);



            viscousLift = ClViscousCurve.Evaluate(AxialProportion_flt);

            double axialDirectionFactor = cosAngleCutoff * AxialProportion;

            if (axialDirectionFactor > 0)
            {
                Cd = Math.Min(Cd, sepFlowCd * taperCrossSectionAreaRatio) * AxialProportion_2 + Cd * OneMinusAxial_2;
            }
            else
            {
                Cd = Math.Min(Cd, maxPressureCoeff * taperCrossSectionAreaRatio) * AxialProportion_2 + Cd * OneMinusAxial_2;
            }

            if (M_2 > 1)
            {
                potentialLift = ClPotentialCurve.Evaluate(AxialProportion_flt) * M_2_recip;
            }
            else
            {
                potentialLift = ClPotentialCurve.Evaluate(AxialProportion_flt);
            }


            Cm = CmCurve.Evaluate(AxialProportion_flt) * 0.1;

            CoDshift = CenterOfDrag;

            double MachMultiplier = MachDragEffect(M);

            Cd *= MachMultiplier;

            if (HighLogic.LoadedSceneIsFlight)
            {
                Cd += FARAeroUtil.SkinFrictionDrag(rho, lengthScale, local_velocity.magnitude, M, FlightGlobals.getExternalTemperature(part.transform.position) + FARAeroUtil.currentBodyTemp);       //Skin friction drag
            }
            else
            {
                Cd += 0.005;
            }

            for (int i = 0; i < attachNodeDragList.Count; i++)
            {
                attachNodeData node = attachNodeDragList[i];

                double dotProd = Vector3d.Dot(node.location.normalized, local_velocity);
                double tmp     = 0;
                double Cltmp   = 0;
                if (dotProd < 0)
                {
                    dotProd *= dotProd;
                    tmp      = sepFlowCd;

                    //                    Cltmp = tmp * (dotProd - 1);
                    //                    Cltmp *= pair.Value;

                    tmp *= node.areaValue * dotProd;


                    //                    Vector3 CoDshiftOffset = -Vector3.Exclude(pair.Key, part.transform.worldToLocalMatrix.MultiplyVector(velocity.normalized)).normalized;
                    //                    CoDshiftOffset *= Mathf.Sqrt(Mathf.Clamp01(1 - dotProd));
                    //                    CoDshiftOffset *= Mathf.Sqrt(1.5f * pair.Value);

                    CoDshift += node.location * (tmp / (tmp + Cd));
                }
                else
                {
                    Vector3d worldPairVec = part_transform.TransformDirection(node.location.normalized);
                    double   dotProd_2    = dotProd * dotProd;
                    double   liftProd_2   = 1 - dotProd_2;
                    double   liftProd     = Vector3d.Dot(worldPairVec, liftDir);

                    double forceCoefficient = dotProd_2 * bluntBodyCosForceParameter;
                    forceCoefficient += liftProd_2 * bluntBodySinForceParameter;
                    forceCoefficient *= maxPressureCoeff * node.areaValue;      //force applied perependicular to the flat end of the node

                    tmp   = forceCoefficient * dotProd;
                    Cltmp = -forceCoefficient * liftProd;       //negative because lift is in opposite direction of projection of velocity vector onto node direction

                    double Cmtmp = dotProd * liftProd * bluntBodyMomentParameter;
                    Cmtmp *= node.areaValue * node.recipDiameter;

                    if (!node.pitchesAwayFromUpVec)
                    {
                        Cmtmp *= -1;
                    }

                    Cm += Cmtmp;

                    double tmpCdCl = Math.Sqrt(tmp * tmp + Cltmp * Cltmp);
                    CoDshift += node.location * (tmpCdCl / (tmpCdCl + Math.Sqrt(Cd * Cd + Cl * Cl)));

                    /*double liftProd = Vector3d.Dot(worldPairVec, liftDir);
                     *
                     * tmp = maxPressureCoeff * dotProd_2 * dotProd;
                     * tmp *= node.areaValue;
                     *
                     * Cltmp = maxPressureCoeff * dotProd_2 * liftProd;
                     * Cltmp *= -node.areaValue;
                     *
                     * double radius = Math.Sqrt(node.areaValue / Math.PI);
                     * Vector3 CoDshiftOffset = Vector3.Exclude(node.location, local_velocity).normalized;
                     * CoDshiftOffset *= (float)(Math.Abs(liftProd) * radius * 0.4);
                     *
                     * double Cmtmp;
                     * if (node.pitchesAwayFromUpVec)
                     *  Cmtmp = -0.325 * radius * node.areaValue / S * Math.Abs(liftProd);
                     * else
                     *  Cmtmp = 0.325 * radius * node.areaValue / S * Math.Abs(liftProd);
                     *
                     * double tmpCdCl = Math.Sqrt(tmp * tmp + Cltmp * Cltmp);
                     *
                     * CoDshift += node.location * (tmpCdCl / (tmpCdCl + Math.Sqrt(Cd * Cd + Cl * Cl))) + CoDshiftOffset;
                     *
                     * Cm += Cmtmp;*/
                }

                CdAdd         += tmp;
                newtonianLift += Cltmp;
            }


            viscousLift *= MachMultiplier;
            Cd          += CdAdd;
            Cl           = viscousLift + potentialLift;
            Cl          *= crossflowParameter;
            Cm          *= crossflowParameter;

            Cl += newtonianLift;

//            Debug.Log("Cd = " + Cd + " Cl = " + Cl + " Cm = " + Cm + "\nPot Lift = " + potentialLift + " Visc Lift = " + viscousLift + " Newt Lift = " + newtonianLift + "\nCdAdd = " + CdAdd + " sepFlowCd = " + sepFlowCd + " maxPressureCoeff = " + maxPressureCoeff + "\ntaperCrossSectionAreaRatio = " + taperCrossSectionAreaRatio + " crossflowParameter = " + crossflowParameter);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// These are just a few different attempts to figure drag for various blunt bodies
        /// </summary>
        private void DragModel(Vector3d local_velocity, double M)
        {
            // Has the same x/y/z as the vertices in PartMaxBoundaries etc
            Vector3d model_velocity = to_model_rotation * local_velocity;

            double viscousLift, potentialLift, newtonianLift;

            viscousLift = potentialLift = newtonianLift = 0;
            double CdAdd = 0;
            //float AxialProportion = Vector3.Dot(localUpVector, local_velocity);
            double AxialProportion     = model_velocity.y;
            float  AxialProportion_flt = (float)model_velocity.y;
            double AxialProportion_2   = AxialProportion * AxialProportion;
            double OneMinusAxial_2     = Math.Abs(1 - AxialProportion_2);
            double M_2       = M * M;
            double M_2_recip = 1 / M_2;
            double maxPressureCoeff;

            if (FARDebugValues.useSplinesForSupersonicMath)
            {
                maxPressureCoeff = FARAeroUtil.MaxPressureCoefficient.Evaluate((float)M);
            }
            else
            {
                maxPressureCoeff = FARAeroUtil.MaxPressureCoefficientCalc(M);
            }

            double sepFlowCd = SeparatedFlowDrag(M, M_2, M_2_recip);

            //This handles elliptical and other non-circular cross sections
            //float crossflowParameter = Vector3.Dot(localForwardVector, Vector3.Exclude(localUpVector, local_velocity).normalized);
            //crossflowParameter *= crossflowParameter;
            double crossflowParameter = model_velocity.z * model_velocity.z;
            double crossflow          = model_velocity.x * model_velocity.x + crossflowParameter;

            if (crossflow != 0)
            {
                crossflowParameter /= crossflow;
            }

            crossflowParameter = crossflowParameter * majorMinorAxisRatio + (1 - crossflowParameter) / majorMinorAxisRatio;
            if (AxialProportion_2 > 0.98)
            {
                crossflowParameter *= 50 * OneMinusAxial_2;
            }

            Cd         += CdCurve.Evaluate(AxialProportion_flt);
            viscousLift = ClViscousCurve.Evaluate(AxialProportion_flt);
            double axialDirectionFactor = cosAngleCutoff * AxialProportion;

            if (axialDirectionFactor > 0)
            {
                Cd = Math.Min(Cd, sepFlowCd * taperCrossSectionAreaRatio) * AxialProportion_2 + Cd * OneMinusAxial_2;
            }
            else
            {
                Cd = Math.Min(Cd, maxPressureCoeff * taperCrossSectionAreaRatio) * AxialProportion_2 + Cd * OneMinusAxial_2;
            }

            if (M_2 > 1)
            {
                potentialLift = ClPotentialCurve.Evaluate(AxialProportion_flt) * M_2_recip;
            }
            else
            {
                potentialLift = ClPotentialCurve.Evaluate(AxialProportion_flt);
            }
            Cm = CmCurve.Evaluate(AxialProportion_flt) * 0.1;


            CoDshift = CenterOfDrag;

            double MachMultiplier = MachDragEffect(M);

            Cd += 0.003;       //Skin friction drag

            Cd *= MachMultiplier;

            foreach (KeyValuePair <Vector3d, attachNodeData> pair in attachNodeDragDict)
            {
                double dotProd = Vector3d.Dot(pair.Key.normalized, local_velocity);
                double tmp     = 0;
                double Cltmp   = 0;
                if (dotProd < 0)
                {
                    dotProd *= dotProd;
                    tmp      = sepFlowCd;

//                    Cltmp = tmp * (dotProd - 1);
//                    Cltmp *= pair.Value;

                    tmp *= pair.Value.areaValue * dotProd;


//                    Vector3 CoDshiftOffset = -Vector3.Exclude(pair.Key, part.transform.worldToLocalMatrix.MultiplyVector(velocity.normalized)).normalized;
//                    CoDshiftOffset *= Mathf.Sqrt(Mathf.Clamp01(1 - dotProd));
//                    CoDshiftOffset *= Mathf.Sqrt(1.5f * pair.Value);

                    CoDshift += pair.Key * (tmp / (tmp + Cd));
                }
                else
                {
                    Vector3d worldPairVec = part_transform.TransformDirection(pair.Key.normalized);
                    double   dotProd_2    = dotProd * dotProd;
                    double   liftProd     = Vector3d.Dot(worldPairVec, liftDir);

                    tmp  = maxPressureCoeff * dotProd_2 * dotProd;
                    tmp *= pair.Value.areaValue;

                    Cltmp  = maxPressureCoeff * dotProd_2 * liftProd;
                    Cltmp *= -pair.Value.areaValue;

                    double  radius         = Math.Sqrt(pair.Value.areaValue / Math.PI);
                    Vector3 CoDshiftOffset = Vector3.Exclude(pair.Key, local_velocity).normalized;
                    CoDshiftOffset *= (float)(Math.Abs(liftProd) * radius);

                    double tmpCdCl = tmp + Math.Abs(Cltmp);

                    CoDshift += pair.Key * ((tmpCdCl) / (tmpCdCl + Cd)) + CoDshiftOffset;
                    if (pair.Value.pitchesAwayFromUpVec)
                    {
                        Cm -= 0.25 * radius * pair.Value.areaValue / S * Math.Abs(liftProd);
                    }
                    else
                    {
                        Cm += 0.25 * radius * pair.Value.areaValue / S * Math.Abs(liftProd);
                    }
                }



                CdAdd         += tmp;
                newtonianLift += Cltmp;
            }

            viscousLift *= MachMultiplier;
            Cd          += CdAdd;
            Cl           = viscousLift + potentialLift;
            Cl          *= crossflowParameter;
            Cm          *= crossflowParameter;

            Cl += newtonianLift;

//            Debug.Log("Cd = " + Cd + " Cl = " + Cl + " Cm = " + Cm + "\nPot Lift = " + potentialLift + " Visc Lift = " + viscousLift + " Newt Lift = " + newtonianLift + "\nCdAdd = " + CdAdd + " sepFlowCd = " + sepFlowCd + " maxPressureCoeff = " + maxPressureCoeff + "\ntaperCrossSectionAreaRatio = " + taperCrossSectionAreaRatio + " crossflowParameter = " + crossflowParameter);
        }