Exemple #1
0
def run_degen_geom(set_index=None, set_name=None):
    """
    Runs degen geom on input set
    :param set_index: set index, will take precendence if both set index and set name are specified
    :param set_name: name of set, will be used if set index is not specified
    :return: degen geom manager object
    """
    import degen_geom as dg

    if set_index is None and set_name is None:
        raise ValueError("set_index and set_name cannot both be None")

    # Get set index from name, if set index was not specified
    if set_index is None:
        set_index = vsp.GetSetIndex(set_name)

    # Run degen geom on the input set
    vsp.SetAnalysisInputDefaults("DegenGeom")
    vsp.SetIntAnalysisInput("DegenGeom", "Set", [set_index], 0)
    vsp.SetIntAnalysisInput("DegenGeom", "WriteCSVFlag", [0], 0)
    vsp.SetIntAnalysisInput("DegenGeom", "WriteMFileFlag", [0], 0)
    degen_res_id = vsp.ExecAnalysis("DegenGeom")

    degen_objs = vsp.parse_degen_geom(degen_res_id)

    degen_mgr = dg.DegenGeomMgr(degen_objs)

    return degen_mgr
    def test_parse_degen_geom(self):
        vsp.VSPRenew()
        vsp.ClearVSPModel()
        wing_id = vsp.AddGeom("WING")

        vsp.Update()

        vsp.SetIntAnalysisInput("DegenGeom", "WriteCSVFlag", [0], 0)
        vsp.SetIntAnalysisInput("DegenGeom", "WriteMFileFlag", [0], 0)

        degen_results_id = vsp.ExecAnalysis("DegenGeom")
        for degen_obj in vsp.parse_degen_geom(degen_results_id):
            print(degen_obj)
Exemple #3
0
    def test_simple_prop_degen(self):
        vsp.VSPRenew()
        vsp.ClearVSPModel()
        prop_id = vsp.AddGeom("PROP")
        vsp.Update()

        print(vsp.GetAnalysisInputNames("DegenGeom"))
        vsp.SetAnalysisInputDefaults("DegenGeom")
        vsp.PrintAnalysisInputs("DegenGeom")
        vsp.SetIntAnalysisInput("DegenGeom", "WriteCSVFlag", [0], 0)
        vsp.SetIntAnalysisInput("DegenGeom", "WriteMFileFlag", [0], 0)
        vsp.PrintAnalysisInputs("DegenGeom")

        self.assertTrue(True)
Exemple #4
0
    def test_degen_transform_mat(self):
        import degen_geom as dg
        vsp.VSPRenew()
        vsp.ClearVSPModel()
        prop_id = vsp.AddGeom("PROP")

        vsp.SetParmVal(prop_id, "Y_Rel_Location", "XForm", 60.0)
        vsp.SetParmVal(prop_id, "Y_Rel_Rotation", "XForm", 90.0)
        vsp.SetParmVal(prop_id, "X_Rel_Rotation", "XForm", 10.0)
        vsp.SetParmVal(prop_id, "Sym_Planar_Flag", "Sym", vsp.SYM_XZ)

        vsp.Update()

        vsp.SetIntAnalysisInput("DegenGeom", "WriteCSVFlag", [0], 0)
        vsp.SetIntAnalysisInput("DegenGeom", "WriteMFileFlag", [0], 0)

        degen_results_id = vsp.ExecAnalysis("DegenGeom")
        degen_objects = vsp.parse_degen_geom(degen_results_id)

        degen_mgr = dg.DegenGeomMgr(degen_objects)
        dg_prop_comp = degen_mgr.degen_objs[prop_id]

        orig_copy = dg_prop_comp.copies[0]

        origin = orig_copy[0].transmat.get_translations()
        self.assertAlmostEqual(origin[0], 0.0, places=6)
        self.assertAlmostEqual(origin[1], 60.0, places=6)
        self.assertAlmostEqual(origin[2], 0.0, places=6)

        angles = orig_copy[0].transmat.get_angles()
        self.assertAlmostEqual(angles[0], 10.0, places=6)
        self.assertAlmostEqual(angles[1], 90.0, places=6)
        self.assertAlmostEqual(angles[2], 0.0, places=6)

        sym_copy = dg_prop_comp.copies[1]
        origin = sym_copy[0].transmat.get_translations()
        self.assertAlmostEqual(origin[0], 0.0, places=6)
        self.assertAlmostEqual(origin[1], -60.0, places=6)
        self.assertAlmostEqual(origin[2], 0.0, places=6)

        angles = sym_copy[0].transmat.get_angles()
        self.assertAlmostEqual(angles[0], -180.0 + 10.0, places=6)
        self.assertAlmostEqual(angles[1], 90.0, places=6)
        self.assertAlmostEqual(angles[2], 0.0, places=6)

        self.assertTrue(True)
Exemple #5
0
def export_surface_patches(export_set: int, remove_degenerate=True):
    """
    Function that export surfaces patches of current set
    :param export_set: vsp set to export
    :param remove_degenerate: if true, degenerate surface patches are removed
    :return: list components with surface patches
    """
    import numpy as np

    components = []

    vsp.SetIntAnalysisInput("SurfacePatches", "Set", [export_set])
    surf_patch_res_id = vsp.ExecAnalysis("SurfacePatches")

    patch_results = vsp.parse_results_object(surf_patch_res_id)
    comp_ids = patch_results.components
    for comp_id in comp_ids:
        comp_res = vsp.parse_results_object(comp_id)
        surface_ids = comp_res.surfaces

        surfaces = []
        for surf_id in surface_ids:
            surf_res = vsp.parse_results_object(surf_id)
            patch_ids = surf_res.patches

            patches = []
            for patch_id in patch_ids:
                patch_res = vsp.parse_results_object(patch_id)

                add_patch = True
                if remove_degenerate and (len(patch_res.x) <= 1
                                          or len(patch_res.x[0]) <= 1):
                    add_patch = False

                if add_patch:
                    patches.append(
                        SurfacePatch(patch_res.comp_id[0],
                                     patch_res.surf_index[0],
                                     patch_res.patch_index[0],
                                     np.array(patch_res.x),
                                     np.array(patch_res.y),
                                     np.array(patch_res.z),
                                     np.array(patch_res.nx),
                                     np.array(patch_res.ny),
                                     np.array(patch_res.nz)))

            surfaces.append(
                Surface(surf_res.comp_id[0], surf_res.surf_index[0], patches))
        if len(surfaces) > 0:
            components.append(
                SurfaceComponent(comp_res.name[0], comp_res.id[0], surfaces))

    return components
Exemple #6
0
def parasitedrag_sweep(speeds,
                       alts_ft,
                       sref=None,
                       length_unit=None,
                       speed_unit=vsp.V_UNIT_MACH,
                       set=None):
    """
    Runs a parasite drag sweep over a range of speeds and altitudes. For subsonic data only.

    :param speeds: list of speeds to sweep over
    :param alts_ft: list of altitudes to sweep over
    :param speed_unit: units of speed array
    :param set: vsp geometry set to use for build up
    :param length_unit: length unit of the vsp model
    :param sref: reference area
    :return: named tuple with results
    """
    # Reset default values to ensure values that have been read from a vsp file are used by default
    vsp.SetAnalysisInputDefaults('ParasiteDrag')

    # inputs that don't change during a sweep

    vsp.SetIntAnalysisInput("ParasiteDrag", "VelocityUnit", [speed_unit])
    if length_unit is not None:
        vsp.SetIntAnalysisInput("ParasiteDrag", "LengthUnit", [length_unit])

    vsp.SetStringAnalysisInput("ParasiteDrag", "FileName", ["/dev/null"])

    if set is not None:
        vsp.SetIntAnalysisInput("ParasiteDrag", "GeomSet", [set])

    if sref is not None:
        vsp.SetIntAnalysisInput("ParasiteDrag", "RefFlag", [0])
        vsp.SetDoubleAnalysisInput("ParasiteDrag", "Sref", [float(sref)])

    vsp.SetVSP3FileName('/dev/null')

    results = []
    first_val = True
    for speed in speeds:
        for alt in alts_ft:
            vsp.SetDoubleAnalysisInput("ParasiteDrag", "Vinf", [float(speed)])
            vsp.SetDoubleAnalysisInput("ParasiteDrag", "Altitude",
                                       [float(alt)])
            if first_val:
                vsp.SetIntAnalysisInput("ParasiteDrag", "RecomputeGeom",
                                        [True])
                first_val = False
            else:
                vsp.SetIntAnalysisInput("ParasiteDrag", "RecomputeGeom",
                                        [False])
            results.append(
                vsp.parse_results_object(vsp.ExecAnalysis("ParasiteDrag")))

    return ParasiteDragResults(results)
Exemple #7
0
def create_input_from_degen_geom(degen_objects=None,
                                 degen_set=None,
                                 title="DegenAvl",
                                 mach=0.0,
                                 Sref=1.0,
                                 Bref=1.0,
                                 Cref=1.0,
                                 cgRef=(0.0, 0.0, 0.0),
                                 cdp=0.0):
    """
    Creates an AvlInput object from a list of degen geometry objects

    The degen objects can be created by passing the vsp set from which to create them

    :param degen_objects: List of degen geom objects, these can be created from openvsp. If degen_objects is None,
    degen objects will be created by using OpenVSP on the input degen set
    :param degen_set: OpenVSP set to create degen objects from if :param degen_objects is None
    :param title: title of the avl geometry
    :param mach: mach number
    :param Sref: reference area
    :param Bref: span
    :param Cref: reference chord
    :param cgRef: moment calculation location
    :param cdp: fixed parasite drag value to add to computed induced drag
    :return: AvlInput object
    """
    import degen_geom as dg
    import numpy as np
    header = AvlHeader(title,
                       Mach=mach,
                       Sref=Sref,
                       Cref=Cref,
                       Bref=Bref,
                       CGref=cgRef,
                       CDp=cdp)
    surfaces = []
    components = {}

    # Create degen objects from OpenVSP if no degen objects were passed in. Throw an exception if both degen_objects
    # and degen_set are None
    if degen_objects is None and degen_set is None:
        raise ValueError(
            "degen_objects and degen_set cannot both be set to None")

    if degen_objects is None:
        # Import vsp locally to limit module dependency on openvsp
        import openvsp as vsp

        # Turn off file exports
        vsp.SetIntAnalysisInput("DegenGeom", "WriteCSVFlag", [0], 0)
        vsp.SetIntAnalysisInput("DegenGeom", "WriteMFileFlag", [0], 0)

        # Select the appropriate Set
        vsp.SetIntAnalysisInput("DegenGeom", "Set", [degen_set])

        # Run DegenGeom
        vsp.Update()
        degen_results_id = vsp.ExecAnalysis("DegenGeom")

        # Post process the results from the vsp api into more useful objects
        degen_objects = vsp.parse_degen_geom(degen_results_id)

    for degen_obj in degen_objects:
        component = len(components) + 1
        if degen_obj.name in components:
            component = components[degen_obj.name]
        else:
            components[degen_obj.name] = component

        for stick in degen_obj.sticks:
            surf = AvlSurface(name=degen_obj.name,
                              Nchord=degen_obj.surf.num_pnts,
                              Component=component,
                              Nspan=None,
                              Sspace=None)

            # TODO: Add support for bodies
            if degen_obj.type == dg.DegenTypeEnum.LIFTING:
                # Sort sticks such that increase in y value. If y is constant (e.g. vertical tail) then order from z+ to z-
                # (top to bottom)
                le = np.array(stick.le)
                te = np.array(stick.te)
                chord = np.array(stick.chord)
                u = np.array(stick.u)

                sort_inds = []

                uniq_y = np.unique(le[:, 1])
                if len(uniq_y) > 1:
                    # y is not constant, so now sort based on y coordinate
                    sort_inds = le[:, 1].argsort()
                else:
                    sort_inds = le[:, 2].argsort()[::-1]

                le = le[sort_inds]
                te = te[sort_inds]
                chord = chord[sort_inds]
                u = u[sort_inds]

                nspan = 1
                for i in range(len(le)):
                    nspan += 1
                    if abs(round(u[i]) - u[i]) > 1.0e-10:
                        continue
                    # Compute ainc
                    x_vec = np.array([1.0, 0.0, 0.0])
                    chord_vec = te[i, :] - le[i, :]
                    cos_theta = np.dot(chord_vec,
                                       x_vec) / np.linalg.norm(chord_vec)
                    rot_axis = np.cross(x_vec, chord_vec)
                    angle_sign = 1.0
                    if rot_axis[np.argmax(np.abs(rot_axis))] < 0.0:
                        angle_sign = -1.0

                    ainc = np.rad2deg(np.arccos(np.clip(cos_theta, -1,
                                                        1))) * angle_sign
                    sect = AvlSection(le=le[i, :],
                                      chord=chord[i],
                                      ainc=ainc,
                                      Nspan=nspan,
                                      Sspace=1.0)
                    surf.addSection(sect)
                    if len(surf.sections) > 1:
                        surf.sections[-2].Nspan = nspan
                    nspan = 2

            if degen_obj.type == dg.DegenTypeEnum.BODY:
                continue

            surfaces.append(surf)

    return AvlInput(header, surfaces)
Exemple #8
0
    def test_degen_geom(self):
        # Test analysis manager
        vsp.VSPRenew()
        vsp.ClearVSPModel()

        # Print all types
        print(vsp.GetGeomTypes())

        prop_id = vsp.AddGeom("PROP")
        blank_id = vsp.AddGeom("BLANK")
        disk_id = vsp.AddGeom("Disk")
        vsp.SetParmVal(blank_id, "Point_Mass_Flag", "Mass", 1)
        vsp.SetParmVal(blank_id, "Point_Mass", "Mass", 5.0)
        wing_id = vsp.AddGeom("WING")
        pod_id = vsp.AddGeom("POD")
        vsp.AddSubSurf(pod_id, vsp.SS_RECTANGLE)
        vsp.AddSubSurf(wing_id, vsp.SS_CONTROL)

        vsp.Update()

        # Run Degen Geom
        print(vsp.FindGeoms())
        print(vsp.GetAnalysisInputNames("DegenGeom"))
        vsp.SetAnalysisInputDefaults("DegenGeom")
        vsp.SetIntAnalysisInput("DegenGeom", "WriteMFileFlag", [0], 0)
        vsp.SetIntAnalysisInput("DegenGeom", "WriteCSVFlag", [0], 0)
        vsp.PrintAnalysisInputs("DegenGeom")
        degen_results_id = vsp.ExecAnalysis("DegenGeom")

        print(vsp.GetAllResultsNames())
        vsp.PrintResults(degen_results_id)
        blank_ids = vsp.GetStringResults(degen_results_id, "Degen_BlankGeoms")
        degen_ids = vsp.GetStringResults(degen_results_id, "Degen_DegenGeoms")

        for blank_id in blank_ids:
            vsp.PrintResults(blank_id)

        for degen_id in degen_ids:
            vsp.PrintResults(degen_id)
            t = vsp.GetStringResults(degen_id, "type", 0)[0]
            if t == "DISK":
                disk_id = vsp.GetStringResults(degen_id, "disk", 0)[0]
                vsp.PrintResults(disk_id)
            surf_id = vsp.GetStringResults(degen_id, "surf", 0)[0]
            vsp.PrintResults(surf_id)
            areas = vsp.GetDoubleMatResults(surf_id, "area")

            plate_ids = vsp.GetStringResults(degen_id, "plates")
            for plate_id in plate_ids:
                vsp.PrintResults(plate_id)

            stick_ids = vsp.GetStringResults(degen_id, "sticks")
            for stick_id in stick_ids:
                vsp.PrintResults(stick_id)

            if t != "DISK":
                point_id = vsp.GetStringResults(degen_id, "point")[0]
                vsp.PrintResults(point_id)

            subsurf_ids = vsp.GetStringResults(degen_id, "subsurfs")
            for ss_id in subsurf_ids:
                vsp.PrintResults(ss_id)

            hinge_ids = vsp.GetStringResults(degen_id, "hinges")
            for hinge_id in hinge_ids:
                vsp.PrintResults(hinge_id)

        self.assertTrue(True)