def setDVGeo(ffdFile, cmplx=False): # Setup geometry/mesh DVGeo = DVGeometry(ffdFile, complex=cmplx) nTwist = 6 DVGeo.addRefAxis( "wing", Curve( x=numpy.linspace(5.0 / 4.0, 1.5 / 4.0 + 7.5, nTwist), y=numpy.zeros(nTwist), z=numpy.linspace(0, 14, nTwist), k=2, ), ) def twist(val, geo): for i in range(nTwist): geo.rot_z["wing"].coef[i] = val[i] def span(val, geo): C = geo.extractCoef("wing") s = geo.extractS("wing") for i in range(len(C)): C[i, 2] += s[i] * val[0] geo.restoreCoef(C, "wing") DVGeo.addGlobalDV("twist", [0] * nTwist, twist, lower=-10, upper=10, scale=1.0) DVGeo.addGlobalDV("span", [0], span, lower=-10, upper=10, scale=1.0) DVGeo.addLocalDV("shape", lower=-0.5, upper=0.5, axis="y", scale=10.0) return DVGeo
def test_ffdSplineOrder(self, train=False, refDeriv=False): """ Test custom FFD spline order """ refFile = os.path.join(self.base_path, "ref/test_ffd_spline_order.ref") with BaseRegTest(refFile, train=train) as handler: handler.root_print("Test custom FFD spline order") ffdfile = os.path.join(self.base_path, "../../input_files/deform_geometry_ffd.xyz") DVGeo = DVGeometry(ffdfile, kmax=6) # create local DVs DVGeo.addLocalDV("xdir", lower=-1.0, upper=1.0, axis="x", scale=1.0) DVGeo.addLocalDV("ydir", lower=-1.0, upper=1.0, axis="y", scale=1.0) DVGeo.addLocalDV("zdir", lower=-1.0, upper=1.0, axis="z", scale=1.0) commonUtils.testSensitivities(DVGeo, refDeriv, handler, pointset=3)
# Set up global design variables def twist(val, geo): for i in range(1, nRefAxPts): geo.rot_z["wing"].coef[i] = val[i - 1] DVGeo.addGlobalDV(dvName="twist", value=[0] * nTwist, func=twist, lower=-10, upper=10, scale=0.01) # Set up local design variables DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) # Add DVGeo object to CFD solver CFDSolver.setDVGeo(DVGeo) # rst dvgeo (end) # ====================================================================== # DVConstraint Setup, and Thickness and Volume Constraints # ====================================================================== # rst dvconVolThick (beg) DVCon = DVConstraints() DVCon.setDVGeo(DVGeo) # Only ADflow has the getTriangulatedSurface Function DVCon.setSurface(CFDSolver.getTriangulatedMeshSurface()) # Volume constraints
chordRef=1.0, evalFuncs=["cl", "cd"], ) # Add angle of attack variable ap.addDV("alpha", value=alpha[i], lower=0, upper=10.0, scale=1.0) aeroProblems.append(ap) # rst aeroproblem (end) # ====================================================================== # Geometric Design Variable Set-up # ====================================================================== # rst dvgeo (beg) # Create DVGeometry object FFDFile = "ffd.xyz" DVGeo = DVGeometry(FFDFile) # DVGeo = DVGeometry_FFD(FFDFile) DVGeo.addLocalDV("shape", lower=-0.05, upper=0.05, axis="y", scale=1.0) span = 1.0 pos = np.array([0.5]) * span CFDSolver.addSlices("z", pos, sliceType="absolute") # Add DVGeo object to CFD solver CFDSolver.setDVGeo(DVGeo) # rst dvgeo (end) # ====================================================================== # DVConstraint Setup # ====================================================================== # rst dvcon (beg) DVCon = DVConstraints() # DVCon = DVConstraints_FFD_data() DVCon.setDVGeo(DVGeo)
def test_triangulatedSurface_intersected_2DVGeos(self, train=False, refDeriv=False): refFile = os.path.join(self.base_path, "ref/test_DVConstraints_triangulatedSurface_intersected_2DVGeos.ref") with BaseRegTest(refFile, train=train) as handler: meshFile = os.path.join(self.base_path, "../../input_files/bwb.stl") objFile = os.path.join(self.base_path, "../../input_files/blob_bwb_wing.stl") ffdFile = os.path.join(self.base_path, "../../input_files/bwb.xyz") testMesh = mesh.Mesh.from_file(meshFile) testObj = mesh.Mesh.from_file(objFile) # test mesh dim 0 is triangle index # dim 1 is each vertex of the triangle # dim 2 is x, y, z dimension # create a DVGeo object with a few local thickness variables DVGeo1 = DVGeometry(ffdFile) nRefAxPts = DVGeo1.addRefAxis("wing", xFraction=0.25, alignIndex="k") self.nTwist = nRefAxPts - 1 def twist(val, geo): for i in range(1, nRefAxPts): geo.rot_z["wing"].coef[i] = val[i - 1] DVGeo1.addGlobalDV(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1) DVGeo1.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) # create a DVGeo object with a few local thickness variables DVGeo2 = DVGeometry(ffdFile, name="blobdvgeo") DVGeo2.addLocalDV("local_2", lower=-0.5, upper=0.5, axis="y", scale=1) # check that DVGeos with duplicate var names are not allowed DVGeo3 = DVGeometry(ffdFile) DVGeo3.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) # create a DVConstraints object for the wing DVCon = DVConstraints() DVCon.setDVGeo(DVGeo1) DVCon.setDVGeo(DVGeo2, name="second") with self.assertRaises(ValueError): DVCon.setDVGeo(DVGeo3, name="third") p0 = testMesh.vectors[:, 0, :] v1 = testMesh.vectors[:, 1, :] - p0 v2 = testMesh.vectors[:, 2, :] - p0 DVCon.setSurface([p0, v1, v2], addToDVGeo=True) p0b = testObj.vectors[:, 0, :] v1b = testObj.vectors[:, 1, :] - p0b v2b = testObj.vectors[:, 2, :] - p0b p0b = p0b + np.array([0.0, 0.3, 0.0]) DVCon.setSurface([p0b, v1b, v2b], name="blob", addToDVGeo=True, DVGeoName="second") DVCon.addTriangulatedSurfaceConstraint("default", "default", "blob", "second", rho=10.0, addToPyOpt=True) funcs = {} DVCon.evalFunctions(funcs, includeLinear=True) handler.root_add_dict("funcs_base", funcs, rtol=1e-6, atol=1e-6) funcsSens = {} DVCon.evalFunctionsSens(funcsSens, includeLinear=True) # regress the derivatives handler.root_add_dict("derivs_base", funcsSens, rtol=1e-6, atol=1e-6) # FD check DVGeo1 funcsSensFD = evalFunctionsSensFD(DVGeo1, DVCon, fdstep=1e-3) at_least_one_var = False for outkey in funcs.keys(): for inkey in DVGeo1.getValues().keys(): analytic = funcsSens[outkey][inkey] fd = funcsSensFD[outkey][inkey] handler.assert_allclose(analytic, fd, name="finite_diff_check", rtol=1e-3, atol=1e-3) # make sure there are actually checks happening self.assertTrue(np.abs(np.sum(fd)) > 1e-10) at_least_one_var = True self.assertTrue(at_least_one_var) # FD check DVGeo2 funcsSensFD = evalFunctionsSensFD(DVGeo2, DVCon, fdstep=1e-3) at_least_one_var = False for outkey in funcs.keys(): for inkey in DVGeo2.getValues().keys(): analytic = funcsSens[outkey][inkey] fd = funcsSensFD[outkey][inkey] handler.assert_allclose(analytic, fd, name="finite_diff_check", rtol=1e-3, atol=1e-3) self.assertTrue(np.abs(np.sum(fd)) > 1e-10) at_least_one_var = True self.assertTrue(at_least_one_var)
def generate_dvgeo_dvcon(self, geometry, addToDVGeo=False, intersected=False): """ This function creates the DVGeometry and DVConstraints objects for each geometry used in this class. The C172 wing represents a typical use case with twist and shape variables. The rectangular box is primarily used to test unscaled constraint function values against known values for thickness, volume, and surface area. The BWB is used for the triangulated surface and volume constraint tests. The RAE 2822 wing is used for the curvature constraint test. """ if geometry == "c172": meshFile = os.path.join(self.base_path, "../../input_files/c172.stl") ffdFile = os.path.join(self.base_path, "../../input_files/c172.xyz") xFraction = 0.25 meshScale = 1e-3 elif geometry == "box": meshFile = os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.stl") ffdFile = os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.xyz") xFraction = 0.5 meshScale = 1 elif geometry == "bwb": meshFile = os.path.join(self.base_path, "../../input_files/bwb.stl") ffdFile = os.path.join(self.base_path, "../../input_files/bwb.xyz") xFraction = 0.25 meshScale = 1 elif geometry == "rae2822": ffdFile = os.path.join(self.base_path, "../../input_files/deform_geometry_ffd.xyz") xFraction = 0.25 DVGeo = DVGeometry(ffdFile, child=self.child) DVCon = DVConstraints() nRefAxPts = DVGeo.addRefAxis("wing", xFraction=xFraction, alignIndex="k") self.nTwist = nRefAxPts - 1 if self.child: parentFFD = os.path.join(self.base_path, "../../input_files/parent.xyz") self.parentDVGeo = DVGeometry(parentFFD) self.parentDVGeo.addChild(DVGeo) DVCon.setDVGeo(self.parentDVGeo) else: DVCon.setDVGeo(DVGeo) # Add design variables def twist(val, geo): for i in range(1, nRefAxPts): geo.rot_z["wing"].coef[i] = val[i - 1] DVGeo.addGlobalDV(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1) DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) # RAE 2822 does not have a DVCon surface so we just return if geometry == "rae2822": return DVGeo, DVCon # Get the mesh from the STL testMesh = mesh.Mesh.from_file(meshFile) # dim 0 is triangle index # dim 1 is each vertex of the triangle # dim 2 is x, y, z dimension p0 = testMesh.vectors[:, 0, :] * meshScale v1 = testMesh.vectors[:, 1, :] * meshScale - p0 v2 = testMesh.vectors[:, 2, :] * meshScale - p0 DVCon.setSurface([p0, v1, v2], addToDVGeo=addToDVGeo) # Add the blob surface for the BWB if geometry == "bwb": objFile = os.path.join(self.base_path, "../../input_files/blob_bwb_wing.stl") testObj = mesh.Mesh.from_file(objFile) p0b = testObj.vectors[:, 0, :] v1b = testObj.vectors[:, 1, :] - p0b v2b = testObj.vectors[:, 2, :] - p0b if intersected: p0b = p0b + np.array([0.0, 0.3, 0.0]) DVCon.setSurface([p0b, v1b, v2b], name="blob") return DVGeo, DVCon