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
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)
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
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)
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)
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
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()
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
# Add Fuse fuse_id = vsp.AddGeom("FUSELAGE") errorMgr.PopErrorAndPrint(stdout) # Add Pod pod_id = vsp.AddGeom("POD", fuse_id) errorMgr.PopErrorAndPrint(stdout) # Set Name vsp.SetGeomName(pod_id, "Pod") errorMgr.PopErrorAndPrint(stdout) # Change Length len_id = vsp.GetParm(pod_id, "Length", "Design") vsp.SetParmVal(len_id, 7.0) # Change Finess Ratio vsp.SetParmVal(pod_id, "FineRatio", "Design", 10.0) # Change Y Location y_loc_id = vsp.GetParm(pod_id, "Y_Location", "XForm") vsp.SetParmVal(y_loc_id, 1.0) # Change X Location vsp.SetParmVal(pod_id, "X_Location", "XForm", 3.0) # Change Symmetry sym_flag_id = vsp.GetParm(pod_id, "Sym_Planar_Flag", "Sym") vsp.SetParmVal(sym_flag_id, vsp.SYM_XZ)
vsp.VSPRenew() errorMgr.PopErrorAndPrint(stdout) geoms = vsp.FindGeoms() print("All geoms in Vehicle.") print(geoms) vsp.SetComputationFileName(vsp.DEGEN_GEOM_CSV_TYPE, 'wing_DegenGeom.csv') # Wing Properties wing_id = vsp.AddGeom("WING") vsp.SetParmVal(wing_id, "TotalSpan", "WingGeom", 10) vsp.SetParmVal(wing_id, "Sweep", "XSec_1", 0) vsp.SetParmVal(wing_id, "Tip_Chord", "XSec_1", 0.3) vsp.SetParmVal(wing_id, "Root_Chord", "XSec_1", 0.3) vsp.SetParmVal(wing_id, "ThickChord", "XSecCurve_0", 0.18) vsp.SetParmVal(wing_id, "Camber", "XSecCurve_0", 0.04) vsp.SetParmVal(wing_id, "CamberLoc", "XSecCurve_0", 0.4) vsp.SetParmVal(wing_id, "ThickChord", "XSecCurve_1", 0.18) vsp.SetParmVal(wing_id, "Camber", "XSecCurve_1", 0.04) vsp.SetParmVal(wing_id, "CamberLoc", "XSecCurve_1", 0.4) vsp.SetParmVal(wing_id, "SectTess_U", "XSec_1", 30) # Make the geometry file vsp.ComputeDegenGeom(vsp.SET_ALL, vsp.DEGEN_GEOM_CSV_TYPE)
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)