コード例 #1
0
ファイル: engine.py プロジェクト: teknologika/foil-generator
def TurbofanNacelle(EngineSection,
                    Chord,
                    CentreLocation=[0, 0, 0],
                    ScarfAngle=3,
                    HighlightRadius=1.45,
                    MeanNacelleLength=5.67):
    # The defaults yield a nacelle similar to that of an RR Trent 1000 / GEnx

    HighlightDepth = 0.12 * MeanNacelleLength
    SectionNo = 100

    # Draw the nacelle with the centre of the intake highlight circle in 0,0,0
    rs.EnableRedraw(False)
    Highlight = rs.AddCircle3Pt((0, 0, HighlightRadius),
                                (0, -HighlightRadius, 0),
                                (0, 0, -HighlightRadius))
    HighlightCutterCircle = rs.AddCircle3Pt((0, 0, HighlightRadius * 1.5),
                                            (0, -HighlightRadius * 1.5, 0),
                                            (0, 0, -HighlightRadius * 1.5))

    # Fan disk for CFD boundary conditions
    FanCircle = rs.CopyObject(Highlight, (MeanNacelleLength * 0.25, 0, 0))
    FanDisk = rs.AddPlanarSrf(FanCircle)
    # Aft outflow for CFD boundary conditions
    BypassCircle = rs.CopyObject(Highlight, (MeanNacelleLength * 0.85, 0, 0))
    BypassDisk = rs.AddPlanarSrf(BypassCircle)
    rs.DeleteObjects([FanCircle, BypassCircle])

    # Outflow cone
    TailConeBasePoint = [MeanNacelleLength * 0.84, 0, 0]
    TailConeApex = [MeanNacelleLength * 1.35, 0, 0]
    TailConeRadius = HighlightRadius * 0.782
    TailCone = rs.AddCone(TailConeBasePoint, TailConeApex, TailConeRadius)
    # Spinner cone
    SpinnerConeBasePoint = [MeanNacelleLength * 0.26, 0, 0]
    SpinnerConeApex = [MeanNacelleLength * 0.08, 0, 0]
    SpinnerConeRadius = MeanNacelleLength * 0.09
    Spinner = rs.AddCone(SpinnerConeBasePoint, SpinnerConeApex,
                         SpinnerConeRadius)

    # Tilt the intake
    RotVec = rs.VectorCreate((0, 0, 0), (0, 1, 0))
    Highlight = rs.RotateObject(Highlight, (0, 0, 0), ScarfAngle, axis=RotVec)

    # Set up the disk for separating the intake lip later
    HighlightCutterCircle = rs.RotateObject(HighlightCutterCircle, (0, 0, 0),
                                            ScarfAngle,
                                            axis=RotVec)
    HighlightCutterDisk = rs.AddPlanarSrf(HighlightCutterCircle)
    rs.DeleteObject(HighlightCutterCircle)
    rs.MoveObject(HighlightCutterDisk, (HighlightDepth, 0, 0))

    # Build the actual airfoil sections to define the nacelle
    HighlightPointVector = rs.DivideCurve(Highlight, SectionNo)

    Sections = []
    TailPoints = []
    Rotation = 0
    Twist = 0
    AirfoilSeligName = 'goe613'
    SmoothingPasses = 1

    for HighlightPoint in HighlightPointVector:
        ChordLength = MeanNacelleLength - HighlightPoint.X
        Af = primitives.Airfoil(HighlightPoint, ChordLength, Rotation, Twist,
                                airconics_setup.SeligPath)
        AfCurve, Chrd = primitives.Airfoil.AddAirfoilFromSeligFile(
            Af, AirfoilSeligName, SmoothingPasses)
        rs.DeleteObject(Chrd)
        P = rs.CurveEndPoint(AfCurve)
        list.append(TailPoints, P)
        AfCurve = act.AddTEtoOpenAirfoil(AfCurve)
        list.append(Sections, AfCurve)
        Rotation = Rotation + 360.0 / SectionNo

    list.append(TailPoints, TailPoints[0])

    # Build the actual nacelle OML surface
    EndCircle = rs.AddInterpCurve(TailPoints)
    Nacelle = rs.AddSweep2([Highlight, EndCircle], Sections, closed=True)
    # Separate the lip
    Cowling, HighlightSection = rs.SplitBrep(Nacelle, HighlightCutterDisk,
                                             True)

    # Now build the pylon between the engine and the specified chord on the wing
    CP1 = [
        MeanNacelleLength * 0.26 + CentreLocation[0], CentreLocation[1],
        CentreLocation[2] + HighlightRadius * 0.1
    ]
    CP2 = [
        MeanNacelleLength * 0.4 + CentreLocation[0], CentreLocation[1],
        HighlightRadius * 1.45 + CentreLocation[2]
    ]
    CP3 = rs.CurveEndPoint(Chord)
    rs.ReverseCurve(Chord)
    CP4 = rs.CurveEndPoint(Chord)

    # Move the engine into its actual place on the wing
    rs.MoveObjects(
        [HighlightSection, Cowling, FanDisk, BypassDisk, TailCone, Spinner],
        CentreLocation)

    # Pylon wireframe
    PylonTop = rs.AddInterpCurve([CP1, CP2, CP3, CP4])
    PylonAf = primitives.Airfoil(CP1, MeanNacelleLength * 1.35, 90, 0,
                                 airconics_setup.SeligPath)
    PylonAfCurve, PylonChord = primitives.Airfoil.AddNACA4(
        PylonAf, 0, 0, 12, 3)
    LowerTE = rs.CurveEndPoint(PylonChord)
    PylonTE = rs.AddLine(LowerTE, CP4)

    # Create the actual pylon surface
    PylonLeft = rs.AddNetworkSrf([PylonTop, PylonAfCurve, PylonTE])
    rs.MoveObject(PylonLeft, (0, -CentreLocation[1], 0))
    PylonRight = act.MirrorObjectXZ(PylonLeft)
    rs.MoveObject(PylonLeft, (0, CentreLocation[1], 0))
    rs.MoveObject(PylonRight, (0, CentreLocation[1], 0))
    PylonAfCurve = act.AddTEtoOpenAirfoil(PylonAfCurve)
    PylonAfSrf = rs.AddPlanarSrf(PylonAfCurve)

    # Assigning basic surface properties
    act.AssignMaterial(Cowling, "ShinyBABlueMetal")
    act.AssignMaterial(HighlightSection, "UnpaintedMetal")
    act.AssignMaterial(TailCone, "UnpaintedMetal")
    act.AssignMaterial(FanDisk, "FanDisk")
    act.AssignMaterial(Spinner, "ShinyBlack")
    act.AssignMaterial(BypassDisk, "FanDisk")
    act.AssignMaterial(PylonLeft, "White_composite_external")
    act.AssignMaterial(PylonRight, "White_composite_external")

    # Clean-up
    rs.DeleteObject(HighlightCutterDisk)
    rs.DeleteObjects(Sections)
    rs.DeleteObject(EndCircle)
    rs.DeleteObject(Highlight)
    rs.DeleteObjects([PylonTop, PylonAfCurve, PylonChord, PylonTE])

    rs.Redraw()

    TFEngine = [
        Cowling, HighlightSection, TailCone, FanDisk, Spinner, BypassDisk
    ]
    TFPylon = [PylonLeft, PylonRight, PylonAfSrf]

    return TFEngine, TFPylon
コード例 #2
0
    def _BuildLS(self, ChordFactor, ScaleFactor):
        # Generates a tentative lifting surface, given the general, nondimensio-
        # nal parameters of the object (variations of chord length, dihedral, etc.)
        # and the two scaling factors.

        LEPoints = self._GenerateLeadingEdge()

        Sections = []
        ProjectedSections = []
        TEPoints_u = []
        TEPoints_l = []

        for i, LEP in enumerate(LEPoints):
            Eps = float(i)/self.SegmentNo
            Airfoil, Chrd = self.AirfoilFunct(Eps, LEP, self.ChordFunct, ChordFactor, self.DihedralFunct, self.TwistFunct)
            list.append(Sections, Airfoil)

            Pr = rs.ProjectCurveToSurface(Chrd,self.XoY_Plane,self.ProjVectorZ)
            list.append(ProjectedSections, Pr)

            list.append(TEPoints_l, rs.CurveEndPoint(Airfoil))
            list.append(TEPoints_u, rs.CurveStartPoint(Airfoil))

            rs.DeleteObjects(Chrd)

        LS = rs.AddLoftSrf(Sections,loft_type=self.LooseSurf)

        if LS==None:
            # Failed to fit loft surface. Try another fitting algorithm
            TECurve_u = rs.AddInterpCurve(TEPoints_u)
            TECurve_l = rs.AddInterpCurve(TEPoints_l)

            rails = []
            list.append(rails, TECurve_u)
            list.append(rails, TECurve_l)

            # Are the first and last curves identical?
            # AddSweep fails if they are, so if that is the case, one is skipped
            CDev = rs.CurveDeviation(Sections[0],Sections[-1])
            if CDev==None:
                shapes = Sections
                LS = rs.AddSweep2(rails, shapes, False)
            else:
                shapes = Sections[:-1]
                LS = rs.AddSweep2(rails, shapes, True)

            rs.DeleteObjects(rails)
            rs.DeleteObjects([TECurve_u, TECurve_l])

        WingTip = None

        if self.TipRequired:
            TipCurve = Sections[-1]
            TipCurve = act.AddTEtoOpenAirfoil(TipCurve)
            WingTip = rs.AddPlanarSrf(TipCurve)
            rs.DeleteObject(TipCurve)

        # Calculate projected area
        # In some cases the projected sections cannot all be lofted in one go
        # (it happens when parts of the wing fold back onto themselves), so
        # we loft them section by section and we compute the area as a sum.
        LSP_area = 0
        # Attempt to compute a projected area
        try:
            for i, LEP in enumerate(ProjectedSections):
                if i < len(ProjectedSections)-1:
                    LSPsegment = rs.AddLoftSrf(ProjectedSections[i:i+2])
                    SA = rs.SurfaceArea(LSPsegment)
                    rs.DeleteObject(LSPsegment)
                    LSP_area = LSP_area + SA[0]
        except:
            print "Failed to compute projected area. Using half of surface area instead."
            LS_area = rs.SurfaceArea(LS)
            LSP_area = 0.5*LS_area[0]

        BB = rs.BoundingBox(LS)
        if BB:
            ActualSemiSpan = BB[2].Y - BB[0].Y
        else:
            ActualSemiSpan = 0.0

        # Garbage collection
        rs.DeleteObjects(Sections)
        try:
            rs.DeleteObjects(ProjectedSections)
        except:
            print "Cleanup: no projected sections to delete"
        rs.DeleteObjects(LEPoints)


        # Scaling
        Origin = rs.AddPoint([0,0,0])
        ScaleXYZ = (ScaleFactor, ScaleFactor, ScaleFactor)
        LS = rs.ScaleObject(LS, Origin, ScaleXYZ)
        if self.TipRequired and WingTip:
            WingTip = rs.ScaleObject(WingTip, Origin, ScaleXYZ)

        rs.DeleteObject(Origin)

        ActualSemiSpan = ActualSemiSpan*ScaleFactor
        LSP_area = LSP_area*ScaleFactor**2.0
        RootChord = (self.ChordFunct(0)*ChordFactor)*ScaleFactor
        AR = ((2.0*ActualSemiSpan)**2.0)/(2*LSP_area)

        return LS, ActualSemiSpan, LSP_area, RootChord, AR, WingTip