def __init__(self, fileName, comm=MPI.COMM_WORLD, scale=1.0, comps=[], projTol=0.01): if comm.rank == 0: print("Initializing DVGeometryVSP") t0 = time.time() super().__init__(fileName=fileName, comm=comm, scale=scale, projTol=projTol) self.exportComps = [] # Clear the vsp model openvsp.ClearVSPModel() t1 = time.time() # read the model openvsp.ReadVSPFile(fileName) t2 = time.time() if self.comm.rank == 0: print("Loading the vsp model took:", (t2 - t1)) # List of all componets returned from VSP. Note that this # order is important. It is the order that we use to map the # actual geom_id by using the geom_names allComps = openvsp.FindGeoms() allNames = [] for c in allComps: allNames.append(openvsp.GetContainerName(c)) if not comps: # no components specified, we use all self.allComps = allComps[:] else: # we get the vsp comp IDs from the comps list self.allComps = [] for c in comps: self.allComps.append(allComps[allNames.index(c)]) # we need the names and bounding boxes of components self.compNames = [] self.bbox = OrderedDict() self.bboxuv = self._getuv() for c in self.allComps: self.compNames.append(openvsp.GetContainerName(c)) self.bbox[c] = self._getBBox(c) # Now, we need to form our own quad meshes for fast projections if comm.rank == 0: print("Building a quad mesh for fast projections.") self._getQuads() if comm.rank == 0: t3 = time.time() print("Initialized DVGeometry VSP in", (t3 - t0), "seconds.")
vsp.PasteGeomClipboard(fuse_id) # make fuse parent # Set Name vsp.SetGeomName(pod_id, "Original_Pod") second_pod_id = vsp.FindGeom("Pod", 0) # Change Location and Symmetry vsp.SetParmVal(second_pod_id, "Sym_Planar_Flag", "Sym", 0) vsp.SetParmVal(second_pod_id, "Y_Location", "XForm", 0.0) vsp.SetParmVal(second_pod_id, "Z_Location", "XForm", 1.0) fname = "apitest1.vsp3" vsp.WriteVSPFile(fname) geoms = vsp.FindGeoms() print("All geoms in Vehicle.") print(geoms) errorMgr.PopErrorAndPrint(stdout) # ==== Use Case 2 ====# vsp.VSPRenew() errorMgr.PopErrorAndPrint(stdout) geoms = vsp.FindGeoms() print("All geoms in Vehicle.") print(geoms)
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)
def test_2(self, train=False, refDeriv=False): """ Test 2: OpenVSP wing test """ # we skip parallel tests for now if not train and self.N_PROCS > 1: self.skipTest("Skipping the parallel test for now.") def sample_uv(nu, nv): # function to create sample uv from the surface and save these points. u = np.linspace(0, 1, nu + 1) v = np.linspace(0, 1, nv + 1) uu, vv = np.meshgrid(u, v) # print (uu.flatten(), vv.flatten()) uv = np.array((uu.flatten(), vv.flatten())) return uv refFile = os.path.join(self.base_path, "ref/test_DVGeometryVSP_02.ref") with BaseRegTest(refFile, train=train) as handler: handler.root_print("Test 2: OpenVSP NACA 0012 wing") vspFile = os.path.join(self.base_path, "../../input_files/naca0012.vsp3") DVGeo = DVGeometryVSP(vspFile) dh = 1e-6 openvsp.ClearVSPModel() openvsp.ReadVSPFile(vspFile) geoms = openvsp.FindGeoms() DVGeo = DVGeometryVSP(vspFile) comp = "WingGeom" # loop over sections # normally, there are 9 sections so we should loop over range(9) for the full test # to have it run faster, we just pick 2 sections for i in [0, 5]: # Twist DVGeo.addVariable(comp, "XSec_%d" % i, "Twist", lower=-10.0, upper=10.0, scale=1e-2, scaledStep=False, dh=dh) # loop over coefs # normally, there are 7 coeffs so we should loop over range(7) for the full test # to have it run faster, we just pick 2 sections for j in [0, 4]: # CST Airfoil shape variables group = "UpperCoeff_%d" % i var = "Au_%d" % j DVGeo.addVariable(comp, group, var, lower=-0.1, upper=0.5, scale=1e-3, scaledStep=False, dh=dh) group = "LowerCoeff_%d" % i var = "Al_%d" % j DVGeo.addVariable(comp, group, var, lower=-0.5, upper=0.1, scale=1e-3, scaledStep=False, dh=dh) # now lets generate ourselves a quad mesh of these cubes. uv_g = sample_uv(8, 8) # total number of points ntot = uv_g.shape[1] # rank on this proc rank = MPI.COMM_WORLD.rank # first, equally divide nuv = ntot // MPI.COMM_WORLD.size # then, add the remainder if rank < ntot % MPI.COMM_WORLD.size: nuv += 1 # allocate the uv array on this proc uv = np.zeros((2, nuv)) # print how mant points we have MPI.COMM_WORLD.Barrier() # loop over the points and save all that this proc owns ii = 0 for i in range(ntot): if i % MPI.COMM_WORLD.size == rank: uv[:, ii] = uv_g[:, i] ii += 1 # get the coordinates nNodes = len(uv[0, :]) openvsp.CompVecPnt01(geoms[0], 0, uv[0, :], uv[1, :]) # extract node coordinates and save them in a numpy array coor = np.zeros((nNodes, 3)) for i in range(nNodes): pnt = openvsp.CompPnt01(geoms[0], 0, uv[0, i], uv[1, i]) coor[i, :] = (pnt.x(), pnt.y(), pnt.z()) # Add this pointSet to DVGeo DVGeo.addPointSet(coor, "test_points") # We will have nNodes*3 many functions of interest... dIdpt = np.zeros((nNodes * 3, nNodes, 3)) # set the seeds to one in the following fashion: # first function of interest gets the first coordinate of the first point # second func gets the second coord of first point etc.... for i in range(nNodes): for j in range(3): dIdpt[i * 3 + j, i, j] = 1 # first get the dvgeo result funcSens = DVGeo.totalSensitivity(dIdpt.copy(), "test_points") # now perturb the design with finite differences and compute FD gradients DVs = DVGeo.getValues() funcSensFD = {} for x in DVs: # perturb the design xRef = DVs[x].copy() DVs[x] += dh DVGeo.setDesignVars(DVs) # get the new points coorNew = DVGeo.update("test_points") # calculate finite differences funcSensFD[x] = (coorNew.flatten() - coor.flatten()) / dh # set back the DV DVs[x] = xRef.copy() # now loop over the values and compare # when this is run with multiple procs, VSP sometimes has a bug # that leads to different procs having different spanwise # u-v distributions. as a result, the final values can differ up to 1e-5 levels # this issue does not come up if this tests is ran with a single proc biggest_deriv = 1e-16 for x in DVs: err = np.array(funcSens[x].squeeze()) - np.array(funcSensFD[x]) maxderiv = np.max(np.abs(funcSens[x].squeeze())) normalizer = np.median(np.abs(funcSensFD[x].squeeze())) if np.abs(normalizer) < 1: normalizer = np.ones(1) normalized_error = err / normalizer if maxderiv > biggest_deriv: biggest_deriv = maxderiv handler.assert_allclose(normalized_error, 0.0, name=f"{x}_grad_normalized_error", rtol=1e0, atol=5e-5) # make sure that at least one derivative is nonzero self.assertGreater(biggest_deriv, 0.005)