def test_24_rot0_nonaligned(self, train=False, refDeriv=False): """ Test 24 This test ensures that the scaling attributes (scale_x, scale_y, and scale_z) are effective when rotType=0 is selected. Moreover, this test ensures that rotType=0 reference axis can handle (given appropriate input parameters) FFD blocks that are not aligned with the main system of reference, e.g. the blades of a 3-bladed wind turbine rotor. The newly added input parameters rot0ang and rot0axis are used to provide the user control on this. The operations that pyGeo performs for this test are the following: We start from an initial "vertical" FFD box which, using the combination of rotType=0, rot0ang=-90, and rot0axis=[1,0,0] for addRefAxis(), is first rotated to have its "spanwise" axis along the y axis. Then, the script scales the 2nd section along the z axis for a "thickness" increase and the 4th section along the x axis for "chord" increase, it adds a +/- 30 deg twist respectively, and finally rotates the deformed FFD back in the initial position. The twist is added to ensure that the operation order is maintained, and the scaling preserves the orthogonality of the FFD in the section plane. This is a particular case as the FFD box is already aligned with the main axis and we "flip" the y and z axes, but the same criteria can be applied to a general rotation. """ refFile = os.path.join(self.base_path, "ref/test_DVGeometry_24.ref") with BaseRegTest(refFile, train=train) as handler: handler.root_print("Test twist and scaling for FFDs non-aligned to main system of reference") DVGeo = DVGeometry(os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.xyz")) rotType = 0 xfraction = 0.5 nRefAxPts = DVGeo.addRefAxis("RefAx", xFraction=xfraction, alignIndex="k", rotType=rotType, rot0ang=-90) fix_root_sect = 1 nTwist = nRefAxPts - fix_root_sect DVGeo.addGlobalDV(dvName="twist", value=[0] * nTwist, func=commonUtils.twist, lower=-90, upper=90, scale=1) DVGeo.addGlobalDV( dvName="thickness", value=[1.0] * nTwist, func=commonUtils.thickness, lower=0.7, upper=5.0, scale=1 ) DVGeo.addGlobalDV( dvName="chord", value=[1.0] * nTwist, func=commonUtils.chord, lower=0.7, upper=5.0, scale=1 ) commonUtils.testSensitivities(DVGeo, refDeriv, handler, pointset=2) x = DVGeo.getValues() # Modifying the twist keyName = "twist" twistTest = [30, 0, -30] x[keyName] = twistTest # Modifying the chord keyName = "thickness" thickTest = [3.0, 1.0, 1.0] x[keyName] = thickTest # Modifying the chord keyName = "chord" chordTest = [1.0, 1.0, 2.0] x[keyName] = chordTest DVGeo.setDesignVars(x) DVGeo.update("testPoints") FFD_coords = DVGeo.FFD.coef.copy() handler.root_add_val("Updated FFD coordinates", FFD_coords, rtol=1e-12, atol=1e-12)
def test_parent_shape_child_rot(self, train=False, refDeriv=False): ffd_name = '../../tests/inputFiles/small_cube.xyz' self.make_cube_ffd(ffd_name, 0.1, 0.1, 0.1, 0.8, 0.8, 0.8) small = DVGeometry(ffd_name, child=True) small.addRefAxis('ref', xFraction=0.5, alignIndex='j') x0 = 0.0 y0 = 0.0 z0 = 0.0 dx = 1.0 dy = 1.0 dz = 1.0 axes = ['k', 'j', 'i'] slices = numpy.array( # Slice 1 [ [[[x0, y0, z0], [x0 + dx, y0, z0], [x0 + 2 * dx, y0, z0]], [[x0, y0 + dy, z0], [x0 + dx, y0 + dy, z0], [x0 + 2 * dx, y0 + dy, z0]]], # Slice 2 [[[x0, y0, z0 + dz], [x0 + dx, y0, z0 + dz], [x0 + 2 * dx, y0, z0 + dz]], [[x0, y0 + dy, z0 + dz], [x0 + dx, y0 + dy, z0 + dz], [x0 + 2 * dx, y0 + dy, z0 + dz]]] ], dtype='d') N0 = [2] N1 = [2] N2 = [3] ffd_name = '../../tests/inputFiles/big_cube.xyz' geo_utils.write_wing_FFD_file(ffd_name, slices, N0, N1, N2, axes=axes) big = DVGeometry(ffd_name) big.addRefAxis('ref', xFraction=0.5, alignIndex='j') big.addChild(small) # Add point set points = numpy.array([[0.5, 0.5, 0.5]]) big.addPointSet(points, 'X') # Add only translation variables add_vars(big, 'big', local='z', rotate='y') add_vars(small, 'small', rotate='y') ang = 45 ang_r = numpy.deg2rad(ang) # Modify design variables x = big.getValues() # add a local shape change x['local_z_big'] = numpy.array( [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5]) big.setDesignVars(x) Xs = big.update('X') # add a rotation of the child FFD x['rotate_y_small'] = ang big.setDesignVars(x) Xrot_ffd = big.update('X') # the modification caused by the child FFD should be the same as rotating the deformed point of the parent # (you would think) rot_mat = numpy.array([[numpy.cos(ang_r), 0, numpy.sin(ang_r)], [0, 1, 0], [-numpy.sin(ang_r), 0, numpy.cos(ang_r)]]) Xrot = numpy.dot(rot_mat, (Xs - points).T) + points.T numpy.testing.assert_array_almost_equal(Xrot_ffd.T, Xrot)
#rst Add local dvs # Comment out one or the other DVGeo.addGeoDVLocal('local', lower=-0.5, upper=0.5, axis='y', scale=1) DVGeo.addGeoDVSectionLocal('slocal', secIndex='k', axis=1, lower=-0.5, upper=0.5, scale=1) #rst Embed points gridFile = 'wing_vol.cgns' meshOptions = {'gridFile': gridFile} mesh = USMesh(options=meshOptions) coords = mesh.getSurfaceCoordinates() DVGeo.addPointSet(coords, 'coords') #rst Change dvs dvDict = DVGeo.getValues() dvDict['twist'] = numpy.linspace(0, 50, nRefAxPts)[1:] dvDict['dihedral'] = numpy.linspace(0, 3, nRefAxPts)[1:] dvDict['taper'] = numpy.array([1.2, 0.5]) dvDict['slocal'][::5] = 0.5 DVGeo.setDesignVars(dvDict) #rst Update DVGeo.update('coords') DVGeo.writePlot3d('ffd_deformed.xyz') DVGeo.writePointSet('coords', 'surf')
# Case 1: Rear Ramp angle, fixed length # Case 2: Upper and lower ramp angles, fixed length # Case 3: Nose length ( Do with global FFD) # Case 4: Overall length ( Do with global FFD) # Case 5: Shape # xDV['length'][2] = 1.75#2.0#1.05 # xDV['angleVars'][2] = 0.15 # xDV['angleVars'][0] = 0.19 # xDV['noseLen'][0] = -0.1 # xDV['angleVars'][1] = 0.18 # xDV['angleVars'][2] = 0.18 # xDV['angleVars'][3] = 0.12 DVGeo.setDesignVars(xDV) mesh.setSurfaceCoordinates(DVGeo.update(ptSetName)) mesh.warpMesh() DVGeo.writeTecplot("warpedFFD.dat") # mesh.writeOFGridTecplot('warped.dat') mesh.writeGrid() # # Repeat ================ # #xDV['length'][2] = 1.25#2.0#1.05 # xDV['angleVars'][2] = 0.3 # DVGeo.setDesignVars(xDV) # #coords = DVGeo.update(ptSetName) # # for i in range(coords0.shape[0]): # # if coords0[i,1]==0: # # print 'x',coords[i,:] # # # end
# Set the chord as well geo.scale["wing"].coef[-1] = val[3] coords = hyp.getSurfaceCoordinates() DVGeo = DVGeometry(ffdFile) coef = DVGeo.FFD.vols[0].coef.copy() # First determine the reference chord lengths: nSpan = coef.shape[2] ref = numpy.zeros((nSpan, 3)) for k in range(nSpan): max_x = numpy.max(coef[:, :, k, 0]) min_x = numpy.min(coef[:, :, k, 0]) ref[k, 0] = min_x + 0.25 * (max_x - min_x) ref[k, 1] = numpy.average(coef[:, :, k, 1]) ref[k, 2] = numpy.average(coef[:, :, k, 2]) c0 = Curve(X=ref, k=2) DVGeo.addRefAxis("wing", c0) DVGeo.addGlobalDV("winglet", [0, 0, 0, 1], winglet, lower=-5, upper=5) DVGeo.addPointSet(coords, "coords") DVGeo.setDesignVars({"winglet": [1.5, 2.5, -2.0, 0.60]}) hyp.setSurfaceCoordinates(DVGeo.update("coords")) # Run and write grid hyp.run() hyp.writeCGNS(volumeFile)
-0.05, 0.05, 10) newDV[idx] = const_offset + local_perturb # add a constant offset (downward) to the upper points, plus a linear ramp and a trigonometric local change # this will shrink the cylinder height-wise and make it wavy for idx in [upper_front_idx, upper_rear_idx]: const_offset = -0.3 * np.ones(10) local_perturb = np.sin(np.linspace(0, 4 * np.pi, 10)) / 20 + np.linspace( 0.05, -0.10, 10) newDV[idx] = const_offset + local_perturb # we've created an array with design variable perturbations. Now set the FFD control points with them # and update the point sets so we can see how they changed DVGeo.setDesignVars({"shape": newDV.copy()}) Xmod = DVGeo.update("cylinder") FFDmod = DVGeo.update("ffd") # Create tecplot output that contains the FFD control points, embedded volume, and pointset DVGeo.writeTecplot(fileName="deformed_embedded.dat", solutionTime=1) # rst plot # cast the 3D pointsets to 2D for plotting (ignoring depth) FFDplt = FFDptset[:, :2] FFDmodplt = FFDmod[:, :2] Xptplt = Xpt[:, :2] Xmodplt = Xmod[:, :2] # plot the new and deformed pointsets and control points plt.figure() plt.title("Applying FFD deformations to a cylinder")
# Set the chord as well geo.scale['wing'].coef[-1] = val[3] coords = hyp.getSurfaceCoordinates() DVGeo = DVGeometry(ffd_file) coef = DVGeo.FFD.vols[0].coef.copy() # First determine the reference chord lengths: nSpan = coef.shape[2] ref = numpy.zeros((nSpan, 3)) for k in range(nSpan): max_x = numpy.max(coef[:, :, k, 0]) min_x = numpy.min(coef[:, :, k, 0]) ref[k, 0] = min_x + 0.25 * (max_x - min_x) ref[k, 1] = numpy.average(coef[:, :, k, 1]) ref[k, 2] = numpy.average(coef[:, :, k, 2]) c0 = pySpline.Curve(X=ref, k=2) DVGeo.addRefAxis('wing', c0) DVGeo.addGeoDVGlobal('winglet', [0, 0, 0, 1], winglet, lower=-5, upper=5) DVGeo.addPointSet(coords, 'coords') DVGeo.setDesignVars({'winglet': [1.5, 2.5, -2.0, .60]}) hyp.setSurfaceCoordinates(DVGeo.update('coords')) # Run and write grid hyp.run() hyp.writeCGNS('717.cgns')
def test_parent_shape_child_rot(self, train=False, refDeriv=False): ffd_name = "../../input_files/small_cube.xyz" self.make_cube_ffd(ffd_name, 0.1, 0.1, 0.1, 0.8, 0.8, 0.8) small = DVGeometry(ffd_name, child=True) small.addRefAxis("ref", xFraction=0.5, alignIndex="j") x0 = 0.0 y0 = 0.0 z0 = 0.0 dx = 1.0 dy = 1.0 dz = 1.0 axes = ["k", "j", "i"] slices = np.array( # Slice 1 [ [ [[x0, y0, z0], [x0 + dx, y0, z0], [x0 + 2 * dx, y0, z0]], [[x0, y0 + dy, z0], [x0 + dx, y0 + dy, z0], [x0 + 2 * dx, y0 + dy, z0]], ], # Slice 2 [ [[x0, y0, z0 + dz], [x0 + dx, y0, z0 + dz], [x0 + 2 * dx, y0, z0 + dz]], [[x0, y0 + dy, z0 + dz], [x0 + dx, y0 + dy, z0 + dz], [x0 + 2 * dx, y0 + dy, z0 + dz]], ], ], dtype="d", ) N0 = [2] N1 = [2] N2 = [3] ffd_name = "../../input_files/big_cube.xyz" geo_utils.write_wing_FFD_file(ffd_name, slices, N0, N1, N2, axes=axes) big = DVGeometry(ffd_name) big.addRefAxis("ref", xFraction=0.5, alignIndex="j") big.addChild(small) # Add point set points = np.array([[0.5, 0.5, 0.5]]) big.addPointSet(points, "X") # Add only translation variables add_vars(big, "big", local="z", rotate="y") add_vars(small, "small", rotate="y") ang = 45 ang_r = np.deg2rad(ang) # Modify design variables x = big.getValues() # add a local shape change x["local_z_big"] = np.array( [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5]) big.setDesignVars(x) Xs = big.update("X") # add a rotation of the child FFD x["rotate_y_small"] = ang big.setDesignVars(x) Xrot_ffd = big.update("X") # the modification caused by the child FFD should be the same as rotating the deformed point of the parent # (you would think) rot_mat = np.array([[np.cos(ang_r), 0, np.sin(ang_r)], [0, 1, 0], [-np.sin(ang_r), 0, np.cos(ang_r)]]) Xrot = np.dot(rot_mat, (Xs - points).T) + points.T np.testing.assert_array_almost_equal(Xrot_ffd.T, Xrot)
# rst Add local dvs # Comment out one or the other DVGeo.addGeoDVLocal("local", lower=-0.5, upper=0.5, axis="y", scale=1) DVGeo.addGeoDVSectionLocal("slocal", secIndex="k", axis=1, lower=-0.5, upper=0.5, scale=1) # rst Embed points gridFile = "wing_vol.cgns" meshOptions = {"gridFile": gridFile} mesh = USMesh(options=meshOptions) coords = mesh.getSurfaceCoordinates() DVGeo.addPointSet(coords, "coords") # rst Change dvs dvDict = DVGeo.getValues() dvDict["twist"] = np.linspace(0, 50, nRefAxPts)[1:] dvDict["dihedral"] = np.linspace(0, 3, nRefAxPts)[1:] dvDict["taper"] = np.array([1.2, 0.5]) dvDict["slocal"][::5] = 0.5 DVGeo.setDesignVars(dvDict) # rst Update DVGeo.update("coords") DVGeo.writePlot3d("ffd_deformed.xyz") DVGeo.writePointSet("coords", "surf")