Example #1
0
 def get_merge_profile(self, factor):
     factor = max(0, min(len(self.profiles) - 1, factor))
     k = factor % 1
     i = int(factor // 1)
     first = self.profiles[i].copy()
     if k > 0:
         second = self.profiles[i + 1]
         airfoil = first * (1 - k) + second * k
     else:
         airfoil = first
     return Profile2D(airfoil.data)
Example #2
0
def plot_test():
    arf = Profile2D()
    arf.importdat("../../tests/testprofile.dat")
    arf.numpoints = 100
    pan = panel_methode_2d(arf.data, aoa=5 * numpy.pi / 180, wake_length=5, wake_numpoints=10)
    print(pan.mat_douplet_cooef)
    from matplotlib import pyplot

    pyplot.plot(pan.douplet, marker="o")
    pyplot.plot(pan.velocity, marker="x")
    # pyplot.plot(pan.pressure, marker="x")
    pyplot.show()
Example #3
0
def test():
    p1 = numpy.array([0, 0])
    p2 = numpy.array([1, 0])
    pj = numpy.array([5, 5])
    arf = Profile2D()
    # arf.importdat("../../tests/testprofile.dat")
    arf.compute_naca(2400)
    arf.numpoints = 30
    pan = panel_methode_2d([p1, p2, pj, p1], aoa=2 * numpy.pi / 180.)
    print(pan._douplet_const(pj, [p1, p2]))
    print(pan._douplet_lin(pj, [p1, p2]))
    print(pan._source_const(pj, [p1, p2]))
Example #4
0
    def __init__(self, obj):
        self.prof = Profile2D()
        self.prof.compute_naca(2422, numpoints=120)

        obj.addProperty("App::PropertyInteger", "Numpoints", "airfoil",
                        "Number of points").Numpoints = self.prof.numpoints
        obj.addProperty(
            "App::PropertyFloat", "Thickness", "airfoil",
            "Thickness of airfoil").Thickness = self.prof.thickness * 1000
        #obj.addProperty("App::PropertyFloat", "Camber", "airfoil", "Camber of airfoil").Camber = max(self.prof.Camber[:,1]) * 1000
        obj.addProperty("App::PropertyString", "Name", "airfoil",
                        "Name of airfoil").Name = self.prof.name
        obj.addProperty("App::PropertyVectorList", "coords", "airfoil",
                        "profilcoords")
        obj.addProperty("App::PropertyPath", "FilePath", "airfoil",
                        "Name of airfoil").FilePath = ""
        obj.Proxy = self
Example #5
0
def visual_test_airfoil():

    arf = Profile2D()
    arf.importdat("../../tests/testprofile.dat")
    arf.numpoints = 30
    pan = panel_methode_2d(arf.data, aoa=10 * numpy.pi / 180, wake_length=5, wake_numpoints=10)
    x = numpy.linspace(-0.3, 1.3, 30)
    y = numpy.linspace(-0.2, 0.2, 30)
    X, Y = meshgrid(x, y)
    z = numpy.zeros([len(x), len(y)])
    for i in range(len(z)):
        for j in range(len(z[0])):
            for k in range(len(pan.douplet)):
                z[i][j] += -dot([x[j], y[i]], pan.v_inf)  + 100 * pan.douplet[k] * _douplet_const([x[j], y[i]], pan.panel[k])

    contourf(X, Y, z, levels = linspace(z.min(), z.max(), len(x)), ls = '-', cmap=cm.winter, origin="lower")
    show()
Example #6
0
def graphics_test():
    from openglider.graphics import Graphics2D, Line

    arf = Profile2D()
    #arf.importdat("../../tests/testprofile.dat")
    #arf.numpoints = 100
    arf.compute_naca(2420, numpoints=120)
    arf.close()
    arf.normalize()
    pan = panel_methode_2d(arf.data, aoa=10 * numpy.pi / 180, wake_length=5, wake_numpoints=10)
    arrows = []
    for i in range(pan.length):
        mid = pan.panel_mids[i]
        normal = pan.panel_normals[i]
        cp = pan.pressure[i]
        arrows.append([mid, mid + normal * cp * pan.half_lenghts[i] * 10])
    arrows = numpy.array(arrows)
    Graphics2D([Line(pan.airfoil), Line(arrows[:, 1])] + map(Line, arrows))
Example #7
0
def profileimp(sheet):
    num = sheet.row_len(1) / 2
    profiles = []

    for i in range(num):
        prof = Profile2D()
        j = 0

        if isinstance(sheet.cell(0, 2 * i).value, str):
            prof.name = sheet.cell(0, 2 * i).value
            j += 1
        temp = []
        while j < sheet.nrows and isinstance(
                sheet.cell(j, 2 * i).value, float):
            #print(sheet.cell(j,2*i).value)
            temp += [[
                sheet.cell(j, 2 * i).value,
                sheet.cell(j, 2 * i + 1).value
            ]]
            j += 1
        prof.data = temp

        profiles += [prof]
    return profiles
Example #8
0
import numpy

from openglider.glider.cell import Cell
from openglider.glider.rib import Rib, MiniRib


try:
    import openglider
except ImportError:
    sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))))
from openglider.airfoil import Profile2D
import openglider.graphics as Graph
from openglider.glider.ballooning import BallooningBezier


a = Profile2D()
a.importdat(os.path.dirname(os.path.abspath(__file__)) + "/testprofile.dat")
#a.Numpoints = 40

midribs = [
    #MiniRib(0.2, 0.8, 1),
    MiniRib(0.5, 0.7, 1),
    #MiniRib(0.8, 0.8, 1),
]

b1 = BallooningBezier()
b2 = BallooningBezier()
b2.Amount *= 0.8

r2 = Rib(a, b1, [0, 0.12, 0], 1., 20 * math.pi / 180, 2 * math.pi / 180, 0, 7)
r1 = r2.copy()
Example #9
0
def import_ods(filename, glider=None):
    ods = ezodf.opendoc(filename)
    sheets = ods.sheets
    # Profiles -> map xvalues
    profiles = [Profile2D(profile) for profile in transpose_columns(sheets[3])]
    xvalues = sorted(profiles, key=lambda prof: prof.numpoints)[0].x_values  # Use airfoil with maximum profilepoints
    for profile in profiles:
        profile.x_values = xvalues
        # Ballooning old : 1-8 > upper (prepend/append (0,0),(1,0)), 9-16 > lower (same + * (1,-1))
    balloonings_temp = transpose_columns(sheets[4])
    balloonings = []
    for baloon in balloonings_temp:
        upper = [[0, 0]] + baloon[:7] + [[1, 0]]
        lower = [[0, 0]] + [[i[0], -1 * i[1]] for i in baloon[8:15]] + [[1, 0]]
        balloonings.append(BallooningBezier([upper, lower]))

    # Data
    data = {}
    datasheet = sheets[-1]
    assert isinstance(datasheet, ezodf.Sheet)
    for i in range(datasheet.nrows()):
        data[datasheet.get_cell([i, 0]).value] = datasheet.get_cell([i, 1]).value
        #print(data["GLEITZAHL"])
    glider.data = data

    cells = []
    main = sheets[0]
    x = y = z = span_last = 0.
    alpha2 = 0.
    thisrib = None
    # TODO: Glide -> DATAIMPORT
    for i in range(1, main.nrows()):
        line = [main.get_cell([i, j]).value for j in range(main.ncols())]
        if not line[0]:
            #print("leere zeile:", i, main.nrows())
            break

        chord = line[1]  # Rib-Chord
        span = line[2]  # spanwise-length (flat)
        alpha1 = alpha2  # angle before the rib
        alpha2 += line[4] * numpy.pi / 180  # angle after the rib
        alpha = (span > 0) * (alpha1 + alpha2) * 0.5 + line[6] * numpy.pi / 180  # rib's angle
        x = line[3]  # x-value -> front/back (ribwise)
        y += numpy.cos(alpha1) * (span - span_last)  # y-value -> spanwise
        z -= numpy.sin(alpha1) * (span - span_last)  # z-axis -> up/down
        aoa = line[5] * numpy.pi / 180
        zrot = line[7] * numpy.pi / 180
        span_last = span

        profile = merge(line[8], profiles)
        ballooning = merge(line[9], balloonings)

        lastrib = thisrib
        thisrib = Rib(profile, ballooning, numpy.array([x, y, z]), chord, alpha, aoa, zrot, data["GLEITZAHL"])
        if i == 1 and y != 0:  # Middle-cell
            #print("midrib!", y)
            lastrib = thisrib.copy()
            lastrib.mirror()
        if lastrib:
            cell = Cell(lastrib, thisrib, [])
            cell.name = "Cell_no"+str(i)
            cells.append(cell)




    if glider:
        glider.cells = cells
        glider.close_rib()
        glider.attachment_points = read_elements(sheets[2], "AHP", AttachmentPoint)
        glider.attachment_points_lower = get_lower_aufhaengepunkte(glider.data)
        for p in glider.attachment_points:
            p.force = numpy.array([0, 0, 1])
            p.get_position(glider)

        glider.lines = tolist_lines(sheets[6], glider.attachment_points_lower, glider.attachment_points)
        glider.lines.calc_geo()
        glider.lines.calc_sag()

        return
    return cells
Example #10
0
def import_ods(filename, glider):
    ods = ezodf.opendoc(filename)
    sheets = ods.sheets
    # Profiles -> map xvalues
    profiles = [Profile2D(profile) for profile in transpose_columns(sheets[3])]
    xvalues = sorted(profiles, key=lambda prof: prof.numpoints)[0].x_values  # Use airfoil with maximum profilepoints
    for profile in profiles:
        profile.x_values = xvalues

    # Ballooning old : 1-8 > upper (prepend/append (0,0),(1,0)), 9-16 > lower (same + * (1,-1))
    balloonings_temp = transpose_columns(sheets[4])
    balloonings = []
    for baloon in balloonings_temp:
        upper = [[0, 0]] + baloon[:7] + [[1, 0]]
        lower = [[0, 0]] + [[i[0], -1 * i[1]] for i in baloon[8:15]] + [[1, 0]]
        balloonings.append(BallooningBezier(upper, lower))

    # Data
    data = {}
    datasheet = sheets[-1]
    assert isinstance(datasheet, ezodf.Sheet)
    for i in range(datasheet.nrows()):
        data[datasheet.get_cell([i, 0]).value] = datasheet.get_cell([i, 1]).value
        #print(data["GLEITZAHL"])
    glider.data = data

    cells = []
    main = sheets[0]
    x = y = z = span_last = 0.
    alpha2 = 0.
    thisrib = None
    for i in range(1, main.nrows()):
        line = [main.get_cell([i, j]).value for j in range(main.ncols())]
        if not line[0]:
            break  # skip empty line

        chord = line[1]  # Rib-Chord
        span = line[2]  # spanwise-length (flat)
        alpha1 = alpha2  # angle before the rib
        alpha2 += line[4] * np.pi / 180  # angle after the rib
        alpha = (span > 0) * (alpha1 + alpha2) * 0.5 + line[6] * np.pi / 180  # rib's angle
        x = line[3]  # x-value -> front/back (ribwise)
        y += np.cos(alpha1) * (span - span_last)  # y-value -> spanwise
        z -= np.sin(alpha1) * (span - span_last)  # z-axis -> up/down
        aoa = line[5] * np.pi / 180
        zrot = line[7] * np.pi / 180
        span_last = span

        profile = merge(line[8], profiles)
        ballooning = merge(line[9], balloonings)

        lastrib = thisrib
        thisrib = Rib(profile, np.array([x, y, z]), chord, alpha, aoa, zrot, data["GLIDE"],
                      name="Rib ({})".format(i))
        if i == 1 and y != 0:  # Middle-cell
            #print("midrib!", y)
            lastrib = thisrib.copy()
            lastrib.mirror()
        if lastrib:
            cell = Cell(lastrib, thisrib, ballooning)
            cell.name = "Cell_no"+str(i)
            cells.append(cell)

    glider.cells = cells
    glider.close_rib()

    ######################################LINESET######################################################
    attachment_points = [AttachmentPoint(glider.ribs[args[0]], args[1], args[2]) for args in read_elements(sheets[2], "AHP", len_data=2)]
    attachment_points.sort(key=lambda element: element.name)
    attachment_points_lower = get_lower_aufhaengepunkte(glider.data)

    for p in attachment_points:
        p.force = np.array([0, 0, 10])
        p.get_position()

    glider.lineset = tolist_lines(sheets[6], attachment_points_lower, attachment_points)
    glider.lineset.recalc()

    ####################################PANELS##########################################################
    cuts = [cut+[1, glider.data["Designzugabe"]] for cut in read_elements(sheets[1], "DESIGNO")]
    cuts += [cut+[1, glider.data["Designzugabe"]] for cut in read_elements(sheets[1], "DESIGNM")]
    cuts += [cut+[2, glider.data["EKzugabe"]] for cut in read_elements(sheets[1], "EKV")]
    cuts += [cut+[2, glider.data["EKzugabe"]] for cut in read_elements(sheets[1], "EKH")]
    for i, cell in enumerate(glider.cells):  # cut = [cell_no, x_left, x_right, cut_type, amount_add]
        cuts_this = [cut for cut in cuts if cut[0] == i]
        cuts_this.sort(key=lambda cut: cut[1])
        cuts_this.sort(key=lambda cut: cut[2])
        # Insert leading-/trailing-edge
        cuts_this.insert(0, [i, -1, -1, 3, glider.data["HKzugabe"]])
        cuts_this.append([i, 1, 1, 3, glider.data["HKzugabe"]])
        cell.panels = []
        for j in range(len(cuts_this)-1):
            if cuts_this[j][3] != 2 or cuts_this[j+1][3] != 2:  # skip entry
                cell.panels.append(Panel(cuts_this[j][1:], cuts_this[j+1][1:]))
    return glider
Example #11
0
 def flatten(self):
     """Flatten the airfoil and return a 2d-Representative"""
     layer = self.projection_layer
     return Profile2D([layer.projection(p) for p in self.data],
                      name=self.name or 'profile' + "_flattened")
Example #12
0
 def setUp(self):
     self.profile = Profile2D()
     prof = random.randint(1, 9999)
     self.profile.compute_naca(prof, 200)
Example #13
0
def import_ods_2d(Glider2D, filename, numpoints=4, calc_lineset_nodes=False):
    ods = ezodf.opendoc(filename)
    sheets = ods.sheets

    cell_sheet = sheets[1]
    rib_sheet = sheets[2]

    # file-version
    if cell_sheet[0, 0].value == "V2" or cell_sheet[0, 0].value == "V2":
        file_version = 2
    else:
        file_version = 1
    # ------------

    # profiles = [BezierProfile2D(profile) for profile in transpose_columns(sheets[3])]
    profiles = [
        Profile2D(profile, name)
        for name, profile in transpose_columns(sheets[3])
    ]
    for foil in profiles:
        foil.normalize()

    try:
        geometry = get_geometry_parametric(sheets[5])
    except Exception:
        geometry = get_geometry_explicit(sheets[0])

    balloonings = []
    for i, (name, baloon) in enumerate(transpose_columns(sheets[4])):
        ballooning_type = str(sheets[4][0, 2 * i + 1].value).upper()
        if baloon:
            if ballooning_type == "V1":
                i = 0
                while baloon[i + 1][0] > baloon[i][0]:
                    i += 1

                upper = baloon[:i + 1]
                lower = [(x, -y) for x, y in baloon[i + 1:]]

                balloonings.append(BallooningBezier(upper, lower, name=name))

            elif ballooning_type == "V2":
                i = 0
                while baloon[i + 1][0] > baloon[i][0]:
                    i += 1

                upper = baloon[:i + 1]
                lower = baloon[i + 1:]

                balloonings.append(BallooningBezier(upper, lower, name=name))

            elif ballooning_type == "V3":
                balloonings.append(BallooningBezierNeu(baloon))

            else:
                raise ValueError("No ballooning type specified")

    data = {}
    datasheet = sheets[-1]
    assert isinstance(datasheet, ezodf.Sheet)
    for row in datasheet.rows():
        if len(row) > 1:
            data[row[0].value] = row[1].value

    # Attachment points: rib_no, id, pos, force
    attachment_points = get_attachment_points(rib_sheet, cell_sheet)
    attachment_points_lower = get_lower_aufhaengepunkte(data)

    # RIB HOLES
    rib_hole_keywords = ["ribs", "pos", "size"]
    rib_holes = read_elements(rib_sheet, "QUERLOCH", len_data=2)
    rib_holes = to_dct(rib_holes, rib_hole_keywords)
    rib_holes = group(rib_holes, "ribs")

    rigidfoil_keywords = ["ribs", "start", "end", "distance"]
    rigidfoils = read_elements(rib_sheet, "RIGIDFOIL", len_data=3)
    rigidfoils = to_dct(rigidfoils, rigidfoil_keywords)
    rigidfoils = group(rigidfoils, "ribs")

    # CUTS
    def get_cuts(names, target_name):
        objs = []
        for name_src in names:
            objs += read_elements(cell_sheet, name_src, len_data=2)

        cuts_this = [{
            "cells": cut[0],
            "left": float(cut[1]),
            "right": float(cut[2]),
            "type": target_name
        } for cut in objs]

        return group(cuts_this, "cells")

    cuts = get_cuts(["EKV", "EKH", "folded"], "folded")
    cuts += get_cuts(["DESIGNM", "DESIGNO", "orthogonal"], "orthogonal")
    cuts += get_cuts(["singleskin"], "singleskin")

    # Diagonals: center_left, center_right, width_l, width_r, height_l, height_r
    diagonals = []
    for res in read_elements(cell_sheet, "QR", len_data=6):
        height1 = res[5]
        height2 = res[6]

        # migration
        if file_version == 1:
            # height (0,1) -> (-1,1)
            height1 = height1 * 2 - 1
            height2 = height2 * 2 - 1
        # ---------

        diagonals.append({
            "left_front": (res[1] - res[3] / 2, height1),
            "left_back": (res[1] + res[3] / 2, height1),
            "right_front": (res[2] - res[4] / 2, height2),
            "right_back": (res[2] + res[4] / 2, height2),
            "cells": res[0]
        })

    diagonals = group(diagonals, "cells")

    straps = []
    straps_keywords = ["cells", "left", "right"]
    for res in read_elements(cell_sheet, "VEKTLAENGE", len_data=2):
        straps.append({
            "left_front": (res[1] - 0.02, -1),
            "left_back": (res[1] + 0.02, -1),
            "right_front": (res[1] - 0.02, -1),
            "right_back": (res[1] - 0.02, -1),
            "cells": res[0]
        })

    for res in read_elements(cell_sheet, "STRAP", len_data=3):
        # [cell_no, x_left, x_right, width]
        straps.append({
            "left_front": (res[1] - res[3] / 2, -1),
            "left_back": (res[1] + res[3] / 2, -1),
            "right_front": (res[2] - res[3] / 2, -1),
            "right_back": (res[2] + res[3] / 2, -1),
            "cells": res[0]
        })
    straps = group(straps, "cells")

    materials = get_material_codes(cell_sheet)

    # minirib -> y, start (x)
    miniribs = []
    for minirib in read_elements(cell_sheet, "MINIRIB", len_data=2):
        miniribs.append({
            "yvalue": minirib[1],
            "front_cut": minirib[2],
            "cells": minirib[0]
        })
    miniribs = group(miniribs, "cells")

    lineset_table = Table.from_ods_sheet(sheets[6])
    lineset = LineSet2D.read_input_table(lineset_table,
                                         attachment_points_lower,
                                         attachment_points)

    glider_2d = Glider2D(elements={
        "cuts": cuts,
        "holes": rib_holes,
        "diagonals": diagonals,
        "rigidfoils": rigidfoils,
        "straps": straps,
        "materials": materials,
        "miniribs": miniribs
    },
                         profiles=profiles,
                         balloonings=balloonings,
                         lineset=lineset,
                         speed=data["SPEED"],
                         glide=data["GLIDE"],
                         **geometry)

    if calc_lineset_nodes:
        glider_3d = glider_2d.get_glider_3d()
        glider_2d.lineset.set_default_nodes2d_pos(glider_3d)
    return glider_2d