Exemple #1
0
    def compute(self,
                inputs,
                outputs,
                discrete_inputs=None,
                discrete_outputs=None):
        # set values
        vsp.SetParmVal(self.vert_tail_id, "TotalArea", "WingGeom",
                       inputs['vert_tail_area'][0])
        vsp.SetParmVal(self.horiz_tail_id, "TotalArea", "WingGeom",
                       inputs['horiz_tail_area'][0])
        vsp.SetParmVal(self.wing_id, "TotalChord", "WingGeom",
                       inputs['wing_cord'][0])

        vsp.Update()
        vsp.Update()  # just in case..

        # run degen geom to get measurements
        dg: degen_geom.DegenGeomMgr = vsp.run_degen_geom(set_index=vsp.SET_ALL)
        obj_dict = {p.name: p for p in dg.get_all_objs()}

        # pull measurements out of degen_geom api
        degen_obj: degen_geom.DegenGeom = obj_dict[self.options['wing_name']]
        #wing_cuts = self.vsp_to_cuts(degen_obj, plane='xz')
        wing_pts = self.vsp_to_point_cloud(degen_obj)

        degen_obj: degen_geom.DegenGeom = obj_dict[
            self.options['horiz_tail_name']]
        #horiz_tail_cuts = self.vsp_to_cuts(degen_obj, plane='xz')
        horiz_tail_pts = self.vsp_to_point_cloud(degen_obj)

        degen_obj: degen_geom.DegenGeom = obj_dict[
            self.options['vert_tail_name']]
        #vert_tail_cuts = self.vsp_to_cuts(degen_obj, plane='xy')
        vert_tail_pts = self.vsp_to_point_cloud(degen_obj)

        # OAS expects x stripes.
        wing_pts = wing_pts.reshape((45, 33, 3), order='F')
        horiz_tail_pts = horiz_tail_pts.reshape((33, 9, 3), order='F')
        vert_tail_pts = vert_tail_pts.reshape((33, 9, 3), order='F')

        # Meshes have symmetry pts duplicated (not mirrored.) Use half.
        wing_pts = wing_pts[:23, :, :]
        horiz_tail_pts = horiz_tail_pts[:17, :, :]
        vert_tail_pts = vert_tail_pts[:17, :, :]

        # Reduce for testing. (See John Jasa's recommendations in the docs.)
        if self.options['reduced']:
            wing_pts = wing_pts[::2, ::4, :]
            horiz_tail_pts = horiz_tail_pts[::2, :, :]
            vert_tail_pts = vert_tail_pts[::2, :, :]

        # Flip around so that FEM normals yield positive areas.
        wing_pts = wing_pts[::-1, ::-1, :]
        horiz_tail_pts = horiz_tail_pts[::-1, ::-1, :]
        vert_tail_pts = vert_tail_pts[:, ::-1, :]

        # outputs go here
        outputs['wing_mesh'] = wing_pts
        outputs['vert_tail_mesh'] = vert_tail_pts
        outputs['horiz_tail_mesh'] = horiz_tail_pts
Exemple #2
0
    def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None):
        # set values
        vsp.SetParmVal(self.vert_tail_id, "TotalArea", "WingGeom", inputs['vert_tail_area'][0])
        vsp.SetParmVal(self.horiz_tail_id, "TotalArea", "WingGeom", inputs['horiz_tail_area'][0])
        vsp.SetParmVal(self.wing_id, "TotalChord", "WingGeom", inputs['wing_cord'][0])

        vsp.Update()
        vsp.Update()  # just in case..

        # run degen geom to get measurements
        dg:degen_geom.DegenGeomMgr = vsp.run_degen_geom(set_index=vsp.SET_ALL)
        obj_dict = {p.name:p for p in dg.get_all_objs()}

        # pull measurements out of degen_geom api
        #degen_obj: degen_geom.DegenGeom = list(dg.get_degen_obj_by_name(self.wing_name)[0].copies.values())[0][0]
        degen_obj: degen_geom.DegenGeom = obj_dict[self.wing_name]
        wing_cuts = self.vsp_to_cuts(degen_obj, plane='xz')
        wing_pts = self.vsp_to_point_cloud(degen_obj)

        ##degen_obj: degen_geom.DegenGeom = list(dg.get_degen_obj_by_name(self.horiz_tail_name)[0].copies.values())[0][0]
        #degen_obj: degen_geom.DegenGeom = list(dg.FindGeomsWithName(self.horiz_tail_name)[0])[0][0]
        degen_obj: degen_geom.DegenGeom = obj_dict[self.horiz_tail_name]
        horiz_tail_cuts = self.vsp_to_cuts(degen_obj, plane='xz')
        horiz_tail_pts = self.vsp_to_point_cloud(degen_obj)

        ##degen_obj: degen_geom.DegenGeom = list(dg.get_degen_obj_by_name(self.vert_tail_name)[0].copies.values())[0][0]
        #degen_obj: degen_geom.DegenGeom = list(dg.FindGeomsWithName(self.vert_tail_name)[0])[0][0]
        degen_obj: degen_geom.DegenGeom = obj_dict[self.vert_tail_name]
        vert_tail_cuts = self.vsp_to_cuts(degen_obj, plane='xy')
        vert_tail_pts = self.vsp_to_point_cloud(degen_obj)

        # OAS expects x stripes.
        wing_pts = wing_pts.reshape((33, 45, 3), order='F')
        horiz_tail_pts = horiz_tail_pts.reshape((33, 9, 3), order='F')
        vert_tail_pts = vert_tail_pts.reshape((33, 9, 3), order='F')

        # Reduce for testing. (See John Jasa's recommendations)
        wing_pts = wing_pts[::4, ::4, :]
        horiz_tail_pts = horiz_tail_pts[::4, :, :]
        vert_tail_pts = vert_tail_pts[::4, :, :]

        # Flip around to match expected order from examples.
        wing_pts = wing_pts[::-1, ::-1, :]
        horiz_tail_pts = horiz_tail_pts[::-1, ::-1, :]
        vert_tail_pts = vert_tail_pts[::-1, ::-1, :]

        # outputs go here
        outputs['wing_mesh'] = wing_pts
        outputs['vert_tail_mesh'] = horiz_tail_pts
        outputs['horiz_tail_mesh'] = vert_tail_pts
Exemple #3
0
    def writePlot3D(self, fileName, exportSet=0):
        """
        Write the current design to Plot3D file

        Parameters
        __________
        fileName : str
            name of the output Plot3D file
        exportSet : int
            optional argument to specify the export set in VSP
        """

        for dvName in self.DVs:
            DV = self.DVs[dvName]
            # We use float here since sometimes pyOptsparse will give
            # stupid numpy zero-dimensional arrays, which swig does
            # not like.
            openvsp.SetParmVal(DV.parmID, float(DV.value))
        openvsp.Update()

        # First set the export flag for exportSet to False for everyone
        for comp in self.allComps:
            openvsp.SetSetFlag(comp, exportSet, False)

        for comp in self.allComps:
            # Check if this one is in our list:
            compName = openvsp.GetContainerName(comp)
            if compName in self.compNames:
                openvsp.SetSetFlag(comp, exportSet, True)
                self.exportComps.append(compName)

        # Write the export file.
        openvsp.ExportFile(fileName, exportSet, openvsp.EXPORT_PLOT3D)
Exemple #4
0
    def test_plate_degen_geom(self):
        vsp.VSPRenew()
        vsp.ClearVSPModel()
        prop_id = vsp.AddGeom("PROP")

        vsp.Update()
        dg_mgr = vsp.run_degen_geom(set_index=vsp.SET_ALL)
        dg_mgr.degen_objs[prop_id].plot_copies_plates()
        plt.savefig(os.path.join(self.OUTPUT_FOLDER, "plates.png"), dpi=300)
Exemple #5
0
    def test_get_prop_info(self):
        import matplotlib.pyplot as plt
        vsp.VSPRenew()
        vsp.ClearVSPModel()

        prop_id = vsp.AddGeom("PROP")

        valid_location = np.array([-30.0, 60.0, 0.0]).reshape((3, 1))

        vsp.SetParmVal(prop_id, "Y_Rel_Location", "XForm", valid_location[1,
                                                                          0])
        vsp.SetParmVal(prop_id, "X_Rel_Location", "XForm", valid_location[0,
                                                                          0])
        vsp.SetParmVal(prop_id, "Y_Rel_Rotation", "XForm", 0.0)
        vsp.SetParmVal(prop_id, "X_Rel_Rotation", "XForm", 0.0)
        vsp.SetParmVal(prop_id, "Sym_Planar_Flag", "Sym",
                       vsp.SYM_XZ | vsp.SYM_YZ)

        valid_location_sym = np.array(valid_location)
        valid_location_sym[1] *= -1.0
        valid_location_aft = np.array(valid_location)
        valid_location_aft[0] *= -1.0
        valid_location_aft_sym = np.array(valid_location_sym)
        valid_location_aft_sym[0] *= -1.0

        vsp.Update()

        prop_info = vsp.get_propeller_thrust_vectors(vsp.SET_ALL)

        # Plot prop objects
        vsp.plot_propeller_info(prop_info, vector_scale=30.0, markersize=5)
        plt.draw()
        plt.savefig(os.path.join(self.OUTPUT_FOLDER, "prop_plots.png"),
                    dpi=300)

        valid_thrust_dir = np.array([-1.0, 0.0, 0.0]).reshape((3, 1))
        valid_thrust_dir_aft_props = np.array([1.0, 0.0, 0.0]).reshape((3, 1))

        # Check thrust vectors
        npt.assert_allclose(prop_info[0].thrust_vector, valid_thrust_dir)
        npt.assert_allclose(prop_info[1].thrust_vector, valid_thrust_dir)
        npt.assert_allclose(prop_info[2].thrust_vector,
                            valid_thrust_dir_aft_props)
        npt.assert_allclose(prop_info[3].thrust_vector,
                            valid_thrust_dir_aft_props)

        # Check origins
        npt.assert_allclose(prop_info[0].hub_center, valid_location)
        npt.assert_allclose(prop_info[1].hub_center, valid_location_sym)
        npt.assert_allclose(prop_info[2].hub_center, valid_location_aft)
        npt.assert_allclose(prop_info[3].hub_center, valid_location_aft_sym)

        # Check rotation directions
        self.assertTrue(prop_info[0].rotation_direction == 1)
        self.assertTrue(prop_info[1].rotation_direction == -1)
        self.assertTrue(prop_info[2].rotation_direction == -1)
        self.assertTrue(prop_info[3].rotation_direction == 1)
Exemple #6
0
    def test_copy_paste_ids(self):
        vsp.VSPRenew()
        vsp.ClearVSPModel()
        prop_id1 = vsp.AddGeom("PROP")
        vsp.Update()

        vsp.CopyGeomToClipboard(prop_id1)
        prop_id2 = vsp.PasteGeomClipboard()

        self.assertTrue(prop_id1 != prop_id2[0])
    def test_surface_patches(self):
        vsp.VSPRenew()
        vsp.ClearVSPModel()
        vsp.AddGeom("PROP")

        vsp.Update()

        components = vsp.export_surface_patches(vsp.SET_ALL,
                                                remove_degenerate=True)
        vsp.plot_surface_components(components)
    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 #9
0
    def test_surface_patches(self):
        vsp.VSPRenew()
        vsp.ClearVSPModel()
        vsp.AddGeom("PROP")

        vsp.Update()

        components = vsp.export_surface_patches(vsp.SET_ALL,
                                                remove_degenerate=True)
        vsp.plot_surface_components(components)
        plt.savefig(os.path.join(self.OUTPUT_FOLDER, "surface_patches.png"),
                    dpi=300)
        self.assertTrue(True)
Exemple #10
0
def create_geom():
    vsp.ClearVSPModel()
    vsp.DeleteAllResults()

    wing_id = vsp.AddGeom("WING")
    rotor_id = vsp.AddGeom("PROP")
    vsp.SetParmVal(wing_id, "X_Rel_Location", "XForm", 10.0)
    vsp.Update()

    dg_mgr = vsp.run_degen_geom(set_index=vsp.SET_ALL)

    vsp.WriteVSPFile(os.path.join(path, "testfile.vsp3"))

    return dg_mgr, wing_id, rotor_id
Exemple #11
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 #12
0
def genX3d(file=None, set=vsp.SET_ALL, dims=[1000, 400], **kwargs):

    if file is not None:
        vsp.ClearVSPModel()
        vsp.ReadVSPFile(file)
        vsp.Update()

    with RunManager(**kwargs):
        vsp.ExportFile("prop.x3d", set, vsp.EXPORT_X3D)
        with open("prop.x3d", "r") as f:
            x3d_str = f.read()

        x3d_str = x3d_str[0:26] + " width=\"{}px\" height=\"{}px\"".format(
            dims[0], dims[1]) + x3d_str[26:-1]

    return x3d_str
Exemple #13
0
    def test_double_mat(self):
        vsp.VSPRenew()
        vsp.ClearVSPModel()
        pod_id = vsp.AddGeom("POD")

        vsp.Update()

        degen_results_id = vsp.ExecAnalysis("DegenGeom")
        degen_ids = vsp.GetStringResults(degen_results_id, "Degen_DegenGeoms")

        for degen_id in degen_ids:
            surf_id = vsp.GetStringResults(degen_id, "surf", 0)[0]
            vsp.PrintResults(surf_id)
            areas = vsp.GetDoubleMatResults(surf_id, "area")

            print(areas[0][0])
        self.assertTrue(True)
Exemple #14
0
    def test_plate_degen_geom_area(self):
        vsp.VSPRenew()
        vsp.ClearVSPModel()
        prop_id = vsp.AddGeom("PROP")

        vsp.Update()
        dg_mgr = vsp.run_degen_geom(set_index=vsp.SET_ALL)
        prop_dg = dg_mgr.degen_objs[prop_id]

        for comp in prop_dg.copies.values():
            for surf in comp:
                for plate in surf.plates:
                    area_brute_force = plate._compute_areas_brute_force().sum()
                    area_vectorized = plate.compute_areas().sum()
                    self.assertAlmostEqual(area_brute_force,
                                           area_vectorized,
                                           delta=1.0e-1)
Exemple #15
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 #16
0
    def _updateVSPModel(self):
        """
        Set each of the DVs. We have the parmID stored so its easy.
        """

        for dvName in self.DVs:
            DV = self.DVs[dvName]

            # for angle parameters, vsp only takes in degrees between -180 and +180,
            # which creates an unnecessary discontinuity at +-180.
            # to fix this, we take the mod of the value and set it to the correct range
            # that is allowed by VSP. Because all of the FD jacobian routine also goes
            # through here to update the model, we effectively maintain consistency
            if "angle" in DV.parm.lower():
                # set this new value separately to leave the DV.value itself untouched
                new_value = ((DV.value + 180.0) % 360.0) - 180.0
                openvsp.SetParmVal(DV.parmID, float(new_value))
            else:
                # We use float here since sometimes pyOptsparse will give
                # numpy zero-dimensional arrays, which swig does not like
                openvsp.SetParmVal(DV.parmID, float(DV.value))

        # update the model
        openvsp.Update()
Exemple #17
0
    def compute(self,
                inputs,
                outputs,
                discrete_inputs=None,
                discrete_outputs=None):
        # Set values.
        vsp.SetParmVal(self.vert_tail_id, "TotalArea", "WingGeom",
                       inputs['vert_tail_area'][0])
        vsp.SetParmVal(self.horiz_tail_id, "TotalArea", "WingGeom",
                       inputs['horiz_tail_area'][0])
        vsp.SetParmVal(self.wing_id, "TotalChord", "WingGeom",
                       inputs['wing_cord'][0])

        vsp.Update()
        vsp.Update()  # just in case..

        # run degen geom to get measurements
        dg: degen_geom.DegenGeomMgr = vsp.run_degen_geom(set_index=vsp.SET_ALL)
        obj_dict = {p.name: p for p in dg.get_all_objs()}

        # pull measurements out of degen_geom api
        degen_obj: degen_geom.DegenGeom = obj_dict[self.options['wing_name']]
        wing_cloud = self.vsp_to_point_cloud(degen_obj)

        degen_obj: degen_geom.DegenGeom = obj_dict[
            self.options['horiz_tail_name']]
        horiz_cloud = self.vsp_to_point_cloud(degen_obj)

        degen_obj: degen_geom.DegenGeom = obj_dict[
            self.options['vert_tail_name']]
        vert_cloud = self.vsp_to_point_cloud(degen_obj)

        # VSP outputs wing outer mold lines at points along the span.
        # Reshape to (chord, span, dimension)
        wing_cloud = wing_cloud.reshape((45, 33, 3), order='F')
        horiz_cloud = horiz_cloud.reshape((33, 9, 3), order='F')
        vert_cloud = vert_cloud.reshape((33, 9, 3), order='F')

        # Meshes have upper and lower surfaces, so we average the z (or y for vertical).
        wing_pts = wing_cloud[:23, :, :]
        wing_pts[1:-1, :, 2] = 0.5 * (wing_cloud[-2:-23:-1, :, 2] +
                                      wing_pts[1:-1, :, 2])
        horiz_tail_pts = horiz_cloud[:17, :, :]
        horiz_tail_pts[1:-1, :, 2] = 0.5 * (horiz_cloud[-2:-17:-1, :, 2] +
                                            horiz_tail_pts[1:-1, :, 2])
        vert_tail_pts = vert_cloud[:17, :, :]
        vert_tail_pts[1:-1, :, 1] = 0.5 * (vert_cloud[-2:-17:-1, :, 1] +
                                           vert_tail_pts[1:-1, :, 1])

        # Reduce the mesh size for testing. (See John Jasa's recommendations in the docs.)
        if self.options['reduced']:
            wing_pts = wing_pts[:, ::4, :]
            wing_pts = wing_pts[[0, 4, 8, 12, 16, 22], ...]
            horiz_tail_pts = horiz_tail_pts[::4, ::2, :]
            vert_tail_pts = vert_tail_pts[::4, ::2, :]

        # Flip around so that FEM normals yield positive areas.
        wing_pts = wing_pts[::-1, ::-1, :]
        horiz_tail_pts = horiz_tail_pts[::-1, ::-1, :]
        vert_tail_pts = vert_tail_pts[:, ::-1, :]

        # outputs go here
        outputs['wing_mesh'] = wing_pts
        outputs['vert_tail_mesh'] = vert_tail_pts
        outputs['horiz_tail_mesh'] = horiz_tail_pts
Exemple #18
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 #19
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)