Ejemplo n.º 1
0
def test_RectangularWing():
    """For a simple straight wing with known area, calculate the projected
    area and test the output is equal to the expected value"""
    NSeg = 1
    wing = LiftingSurface(ChordFunct=SimpleChordFunction,
                          DihedralFunct=SimpleDihedralFunction,
                          SweepFunct=SimpleSweepFunction,
                          AirfoilFunct=SimpleAirfoilFunction,
                          TwistFunct=SimpleTwistFunction,
                          ScaleFactor=5,
                          ChordFactor=0.2,
                          SegmentNo=NSeg)
    # reference values (area and aspect ratio of a 5 by 1 rectangular wing)
    ex_area = 5
    ex_AR = 5
    span = 5
    # Test that the area and calculated aspect ratio are as expected
    tol = 1e-5
    assert (np.abs(wing.LSP_area - ex_area) < tol)
    assert (np.abs(wing.AR - ex_AR) < tol)
    assert (np.abs(wing.ActualSemiSpan - span) < tol)

    # Also test that a multiple segment wing gives the same result
    NSeg = 21
    wing = LiftingSurface(ChordFunct=SimpleChordFunction,
                          DihedralFunct=SimpleDihedralFunction,
                          SweepFunct=SimpleSweepFunction,
                          AirfoilFunct=SimpleAirfoilFunction,
                          TwistFunct=SimpleTwistFunction,
                          ScaleFactor=5,
                          ChordFactor=0.2,
                          SegmentNo=NSeg)
    assert (np.abs(wing.LSP_area - ex_area) < tol)
    assert (np.abs(wing.AR - ex_AR) < tol)
    assert (np.abs(wing.ActualSemiSpan - span) < tol)
Ejemplo n.º 2
0
def test_GenerateLeadingEdge():
    # Test if GenerateLeadingEdge function matches previous version for
    # the Transonic Airliner example: Note this is only to 3dp
    LEPoints_ref = np.array([[0.000e+00, 0.000e+00, 0.000e+00],
                             [9.088e-02, 2.147e-03, 2.644e-04],
                             [1.752e-01, 3.580e-02, 4.508e-03],
                             [2.274e-01, 1.096e-01, 1.425e-02],
                             [2.795e-01, 1.834e-01, 2.463e-02],
                             [3.317e-01, 2.570e-01, 3.586e-02],
                             [3.838e-01, 3.304e-01, 4.815e-02],
                             [4.359e-01, 4.037e-01, 6.171e-02],
                             [4.881e-01, 4.766e-01, 7.675e-02],
                             [5.402e-01, 5.492e-01, 9.346e-02],
                             [5.924e-01, 6.213e-01, 1.121e-01],
                             [6.707e-01, 6.655e-01, 1.248e-01]])

    # Predefined Transonic Airliner example functions used here
    P = [0., 0., 0.]
    NSeg = 11
    Wing = LiftingSurface(P,
                          mySweepAngleFunctionAirliner,
                          myDihedralFunctionAirliner,
                          myTwistFunctionAirliner,
                          myChordFunctionAirliner,
                          myAirfoilFunctionAirliner,
                          SegmentNo=NSeg)

    LEPoints = Wing.GenerateLeadingEdge()
    # Test First and final point first (easier to debug)
    assert (np.all(np.abs(LEPoints[1] - LEPoints_ref[1]) < 1e-3))
    assert (np.all(np.abs(LEPoints[-1] - LEPoints_ref[-1]) < 1e-3))

    # Now check that the entire array is less than 3 dp. out:
    assert (np.all(np.abs(LEPoints - LEPoints_ref) < 1e-3))
Ejemplo n.º 3
0
def test_empty_liftingsurface_Build_error():
    """Tests whether building a lifting surface with undefined functional
    parameters raises an error"""
    with pytest.raises(AssertionError):
        wing = LiftingSurface(construct_geometry=False)
        # No f(eps) parameters have been defined so this should raise an error
        wing.Build()
Ejemplo n.º 4
0
def test_SweptWing():
    """For a 15 deg swept wing with known area (unit chord, Aspect Ratio 5),
    calculate the projected area and test the output is equal to the expected
    value"""
    NSeg = 1
    LAMBDA = 15  # uniform sweep, in degrees
    ScaleFactor = 5
    ChordFactor = 0.2
    wing = LiftingSurface(ChordFunct=SimpleChordFunction,
                          DihedralFunct=SimpleDihedralFunction,
                          SweepFunct=(lambda eps: np.ones_like(eps) * 15),
                          AirfoilFunct=SimpleAirfoilFunction,
                          TwistFunct=SimpleTwistFunction,
                          ScaleFactor=ScaleFactor,
                          ChordFactor=ChordFactor,
                          SegmentNo=NSeg)
    # expected area = b * h, where b is the wing chord, h is the semi-span
    LE_length = ScaleFactor  # LE is straight: new length is 1 * ScaleFactor
    span = LE_length * np.cos(np.radians(LAMBDA))
    chord = ChordFactor * ScaleFactor

    ex_area = chord * span
    ex_AR = span / float(chord)

    tol = 1e-5
    assert (np.abs(wing.LSP_area - ex_area) < tol)
    assert (np.abs(wing.AR - ex_AR) < tol)
    assert (np.abs(wing.ActualSemiSpan - span) < tol)
def test_update_ApexPoint():
    """Tests that Build is triggered on updating Apex Point"""
    # Create example airliner wing
    P = (0, 0, 0)
    wing = LiftingSurface(P, mySweepAngleFunctionAirliner,
                          myDihedralFunctionAirliner,
                          myTwistFunctionAirliner,
                          myChordFunctionAirliner,
                          myAirfoilFunctionAirliner)

    # By adding a point to the wing, we will see if the move transformation
    # has been performed when the ApexPoint attribute is changed:
    from OCC.BRepBuilderAPI import BRepBuilderAPI_MakeVertex
    v = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0)).Vertex()
    wing['test_pnt'] = v

    # Updating the apex should move the surface (and test vertex) through
    # the vector newApex - oldApex
    wing.ApexPoint = gp_Pnt(10, 10, 10)

    # Retrieve the vertex and point from the translated shape
    from OCC.TopoDS import topods_Vertex
    from OCC.BRep import BRep_Tool_Pnt
    vout = topods_Vertex(wing['test_pnt'])
    p = BRep_Tool_Pnt(vout)

    # Check that the vertex was correctly transformed
    xyz = [p.X(), p.Y(), p.Z()]
    assert(xyz == [10, 10, 10])


# def test_Fit_BlendedTipDevice(simple_wing):
#     # Fit a blended winglet to this wing and test the output
#     wing = simple_wing

#     wing.Fit_BlendedTipDevice(rootchord_norm=0.8, spanfraction=0.1, cant=40,
#                              transition=0.1, sweep=40, taper=0.7)

#     # Test the (theoretical) tip chord equals the winglet root chord:
#     assert((Wing.ChordFunct(1) * Wing.ScaleFactor * Wing.ChordFactor) ==
#         Winglet.ChordFunct(0) * Winglet.ScaleFactor * Winglet.ChordFactor)

#     # Test the length of the LE curve is the correct spanfraction
Ejemplo n.º 6
0
def test_update_ApexPoint():
    """Tests that Build is triggered on updating Apex Point"""
    # Create example airliner wing
    P = (0, 0, 0)
    wing = LiftingSurface(P, mySweepAngleFunctionAirliner,
                          myDihedralFunctionAirliner, myTwistFunctionAirliner,
                          myChordFunctionAirliner, myAirfoilFunctionAirliner)

    # By adding a point to the wing, we will see if the move transformation
    # has been performed when the ApexPoint attribute is changed:
    from OCC.BRepBuilderAPI import BRepBuilderAPI_MakeVertex
    v = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0)).Vertex()
    wing['test_pnt'] = v

    # Updating the apex should move the surface (and test vertex) through
    # the vector newApex - oldApex
    wing.ApexPoint = gp_Pnt(10, 10, 10)

    # Retrieve the vertex and point from the translated shape
    from OCC.TopoDS import topods_Vertex
    from OCC.BRep import BRep_Tool_Pnt
    vout = topods_Vertex(wing['test_pnt'])
    p = BRep_Tool_Pnt(vout)

    # Check that the vertex was correctly transformed
    xyz = [p.X(), p.Y(), p.Z()]
    assert (xyz == [10, 10, 10])


# def test_Fit_BlendedTipDevice(simple_wing):
#     # Fit a blended winglet to this wing and test the output
#     wing = simple_wing

#     wing.Fit_BlendedTipDevice(rootchord_norm=0.8, spanfraction=0.1, cant=40,
#                              transition=0.1, sweep=40, taper=0.7)

#     # Test the (theoretical) tip chord equals the winglet root chord:
#     assert((Wing.ChordFunct(1) * Wing.ScaleFactor * Wing.ChordFactor) ==
#         Winglet.ChordFunct(0) * Winglet.ScaleFactor * Winglet.ChordFactor)

#     # Test the length of the LE curve is the correct spanfraction
Ejemplo n.º 7
0
def simple_wing():
    """Initialises a simple wing class, with zero twist, zero sweep, zero taper
    zero dihedral, AR=5, chord=1"""
    NSeg = 11
    wing = LiftingSurface(ChordFunct=SimpleChordFunction,
                          DihedralFunct=SimpleDihedralFunction,
                          SweepFunct=SimpleSweepFunction,
                          AirfoilFunct=SimpleAirfoilFunction,
                          TwistFunct=SimpleTwistFunction,
                          ScaleFactor=5,
                          ChordFactor=0.2,
                          SegmentNo=NSeg)
    return wing
Ejemplo n.º 8
0
def test_GenerateSectionCurves_Numpy_Functs():
    """Tests the GenerateSectionCurves function given a set of Lifting surface
    functional parameters f(eps) which expects a numpy array """
    def myNumpyFunct(eps):
        # This will be used for twist, sweep. dihedral, and chord. returns
        # an array, as eps is expected to be an array
        return np.ones_like(eps) * 5

    wing = LiftingSurface(construct_geometry=False)
    wing.ChordFunct = myNumpyFunct
    wing.SweepFunct = myNumpyFunct
    wing.DihedralFunct = myNumpyFunct
    wing.TwistFunct = myNumpyFunct
    wing.AirfoilFunct = myAirfoilFunctionAirliner  # Builtin example
    wing.GenerateSectionCurves()
    assert (len(wing._Sections) > 0)
Ejemplo n.º 9
0
def test_GenerateSectionCurves_NonNumpy_ChordFunct():
    """Tests the GenerateSectionCurves function given a set of Lifting surface
    functional parameters f(eps) which expects a single input (and output) """
    def mySingleInputFunct(eps):
        # This will be used for twist, sweep. dihedral, and chord. Returns a
        # single value, as eps is expected to be a single value
        return 5

    wing = LiftingSurface(construct_geometry=False)
    wing.ChordFunct = mySingleInputFunct
    wing.SweepFunct = mySingleInputFunct
    wing.DihedralFunct = mySingleInputFunct
    wing.TwistFunct = mySingleInputFunct
    wing.AirfoilFunct = myAirfoilFunctionAirliner  # Builtin example
    wing.GenerateSectionCurves()
    assert (len(wing._Sections) > 0)
Ejemplo n.º 10
0
def test_GenerateSectionCurves_Numpy_Functs():
    """Tests the GenerateSectionCurves function given a set of Lifting surface
    functional parameters f(eps) which expects a numpy array """
    def myNumpyFunct(eps):
        # This will be used for twist, sweep. dihedral, and chord. returns
        # an array, as eps is expected to be an array
        return np.ones_like(eps) * 5
    wing = LiftingSurface(construct_geometry=False)
    wing.ChordFunct = myNumpyFunct
    wing.SweepFunct = myNumpyFunct
    wing.DihedralFunct = myNumpyFunct
    wing.TwistFunct = myNumpyFunct
    wing.AirfoilFunct = myAirfoilFunctionAirliner   # Builtin example
    wing.GenerateSectionCurves()
    assert(len(wing._Sections) > 0)
Ejemplo n.º 11
0
def test_GenerateSectionCurves_NonNumpy_ChordFunct():
    """Tests the GenerateSectionCurves function given a set of Lifting surface
    functional parameters f(eps) which expects a single input (and output) """
    def mySingleInputFunct(eps):
        # This will be used for twist, sweep. dihedral, and chord. Returns a
        # single value, as eps is expected to be a single value
        return 5
    wing = LiftingSurface(construct_geometry=False)
    wing.ChordFunct = mySingleInputFunct
    wing.SweepFunct = mySingleInputFunct
    wing.DihedralFunct = mySingleInputFunct
    wing.TwistFunct = mySingleInputFunct
    wing.AirfoilFunct = myAirfoilFunctionAirliner   # Builtin example
    wing.GenerateSectionCurves()
    assert(len(wing._Sections) > 0)
Ejemplo n.º 12
0

if __name__ == "__main__":
    from OCC.Display.SimpleGui import init_display
    display, start_display, add_menu, add_function_to_menu = init_display()

#    Generate a wing first to attach the engine to
    P = (0, 0, 0)

    SegmentNo = 10
    ChordFactor = 1
    ScaleFactor = 44.56
    Wing = LiftingSurface(P, wingex.mySweepAngleFunctionAirliner,
                          wingex.myDihedralFunctionAirliner,
                          wingex.myTwistFunctionAirliner,
                          wingex.myChordFunctionAirliner,
                          wingex.myAirfoilFunctionAirliner,
                          SegmentNo=SegmentNo,
                          ChordFactor=ChordFactor,
                          ScaleFactor=ScaleFactor)

    Wing.Display(display)
    SpanStation = 0.3              # The engine is to be placed at 30% span
    EngineDia = 2.9
    NacelleLength = 1.95*EngineDia

    EngineSection, HChord = act.CutSect(Wing['Surface'], SpanStation)
    Chord = HChord.GetObject()
    CEP = Chord.EndPoint()
    display.DisplayShape(Chord, update=True, color='black')
    # Variables controlling the position of the engine with respect to the wing
    EngineCtrFwdOfLE = 0.98
Ejemplo n.º 13
0
def test_default_args():
    """Tests that the default arguments do not raise an error. Note that
    no default surface is expected to be generated however"""
    wing = LiftingSurface()
    assert (len(wing) == 0)
    assert (len(wing.Sections) == 0)
Ejemplo n.º 14
0
def test_empty_liftingsurface():
    """Tests that construction"""
    wing = LiftingSurface(construct_geometry=False)
Ejemplo n.º 15
0
def example_topos(request):
    """Return both the topology object and the resulting string for a set of
    topologies"""
    topo_type = request.param[0]
    if topo_type == 'conventional':
        # Create mock components, without generating any geometry
        fus = Fuselage(construct_geometry=False)
        fin = LiftingSurface(construct_geometry=False)
        tailplane = LiftingSurface(construct_geometry=False)
        mirror_pln = gp_Ax2()
        wing = LiftingSurface(construct_geometry=False)
        engine = Engine(construct_geometry=False)

        # For now we must manually add parts and affinities
        topo = Topology()
        topo.AddPart(fus, 'Fuselage', 3)
        topo.AddPart(fin, 'fin', 0)
        topo.AddPart(mirror_pln, 'mirror_pln', 0)
        topo.AddPart(tailplane, 'tailplane', 0)
        topo.AddPart(wing, 'wing', 1)
        topo.AddPart(engine, 'engine', 0)

    if topo_type == 'thunderbolt_a10':
        fus = Fuselage(construct_geometry=False)
        mirror_pln = gp_Ax2()
        engine = Engine(construct_geometry=False)
        wing = LiftingSurface(construct_geometry=False)
        tailplane = LiftingSurface(construct_geometry=False)
        tail_fin = LiftingSurface(construct_geometry=False)

        topo = Topology()
        topo.AddPart(fus, 'Fuselage', 3)
        topo.AddPart(mirror_pln, 'mirror', 0)
        topo.AddPart(engine, 'powerplant', 0)
        topo.AddPart(tailplane, 'Tailplane', 1)
        topo.AddPart(tail_fin, "Tail fin", 0)
        topo.AddPart(wing, "wing", 0)


    if topo_type == 'predator':
        # Create mock components, without generating any geometry
        fus = Fuselage(construct_geometry=False)
        engine = Engine(construct_geometry=False)
        fin = LiftingSurface(construct_geometry=False)
        mirror_pln = gp_Ax2()
        wing = LiftingSurface(construct_geometry=False)
        Vfin = LiftingSurface(construct_geometry=False)

        # For now we must manually add parts and affinities
        topo = Topology()
        topo.AddPart(fus, 'Fuselage', 4)
        topo.AddPart(engine, 'engine', 0)
        topo.AddPart(fin, 'fin', 0)
        topo.AddPart(mirror_pln, 'mirror_pln', 0)
        topo.AddPart(wing, 'wing', 0)
        topo.AddPart(Vfin, 'V-Fin', 0)

    if topo_type == 'proteus':
        fus = Fuselage(construct_geometry=False)
        mirror_pln = gp_Ax2()
        engine = Engine(construct_geometry=False)
        wing = LiftingSurface(construct_geometry=False)
        wing_in = LiftingSurface(construct_geometry=False)
        tailplane = LiftingSurface(construct_geometry=False)
        pod = Fuselage(construct_geometry=False)
        finup = LiftingSurface(construct_geometry=False)
        findown = LiftingSurface(construct_geometry=False)
        wing_out = LiftingSurface(construct_geometry=False)


        topo = Topology()
        topo.AddPart(fus, 'Fuselage', 3)
        topo.AddPart(mirror_pln, 'mirror', 0)
        topo.AddPart(engine, 'powerplant', 0)
        topo.AddPart(wing, "wing", 0)
        topo.AddPart(wing_in, "TP/inbbd wing", 1)
        topo.AddPart(pod, 'Pod/tail boom', 3)
        topo.AddPart(wing_out, "outbd wing", 0)
        topo.AddPart(finup, "Fin (up)", 0)        
        topo.AddPart(findown, "Fin (dwn)", 0)

    return topo, request.param[1]