Example #1
0
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
Example #2
0
    def test_1(self, train=False, refDeriv=False):
        refFile = os.path.join(self.base_path, "ref/test_Cylinder_01.ref")

        with BaseRegTest(refFile, train=train) as handler:
            handler.root_print("Test 1: Basic FFD, global DVs")
            radius = 1.0
            height = 10.0

            DVCon = DVConstraints()
            surf = self.make_cylinder_mesh(radius, height)
            DVCon.setSurface(surf)
            # DVCon.writeSurfaceTecplot('cylinder_surface.dat')

            ffd_name = os.path.join(self.base_path,
                                    "../inputFiles/cylinder_ffd.xyz")
            self.make_ffd(ffd_name, radius, height)
            DVGeo = DVGeometry(ffd_name)
            nAxPts = DVGeo.addRefAxis("thru",
                                      xFraction=0.5,
                                      alignIndex="i",
                                      raySize=1.0)

            def scale_circle(val, geo):
                for i in range(nAxPts):
                    geo.scale["thru"].coef[i] = val[0]

            DVGeo.addGlobalDV("scale_circle", func=scale_circle, value=[1])
            DVCon.setDVGeo(DVGeo)

            leList = [[0, 0, 0], [-radius / 2, 0, height]]
            xAxis = [-1, 0, 0]
            yAxis = [0, 1, 0]
            DVCon.addLERadiusConstraints(leList,
                                         nSpan=5,
                                         axis=yAxis,
                                         chordDir=xAxis,
                                         scaled=False)
            # DVCon.writeTecplot('cylinder_constraints.dat')

            funcs = {}
            DVCon.evalFunctions(funcs)
            print(funcs)
            handler.root_add_dict("funcs1", funcs, rtol=1e-6, atol=1e-6)

            DVGeo.setDesignVars({"scale_circle": 0.5})

            funcs = {}
            DVCon.evalFunctions(funcs)
            handler.root_add_dict("funcs2", funcs, rtol=1e-6, atol=1e-6)
            print(funcs)

            funcsSens = {}
            DVCon.evalFunctionsSens(funcsSens)
            print(funcsSens)
            handler.root_add_dict("funcsSens", funcsSens, rtol=1e-6, atol=1e-6)
            print(funcsSens)
Example #3
0
def deform_DVGeo(geo):
    # =========================================================================
    # Setup DVGeometry object
    # =========================================================================
    # rst DVGeometry
    DVGeo = DVGeometry(input_files + "deform_geometry_ffd.xyz")

    # Create reference axis
    nRefAxPts = DVGeo.addRefAxis("wing", xFraction=0.25, alignIndex="k")

    # Set the Twist Variable
    def twist(val, geo):
        for i in range(nRefAxPts):
            geo.rot_z["wing"].coef[i] = val[i]

    # Add the Twist Design Variable to DVGeo
    DVGeo.addGlobalDV(dvName="twist",
                      value=[0] * nRefAxPts,
                      func=twist,
                      lower=-10,
                      upper=10,
                      scale=1.0)

    # Get Design Variables
    dvDict = DVGeo.getValues()

    # Set First Twist Section to 5deg
    dvDict["twist"][0] = 5

    # Set Design Variables
    DVGeo.setDesignVars(dvDict)
    # rst DVGeometry (end)

    # =========================================================================
    # Update pyGeo Object and output result
    # =========================================================================
    # rst UpdatePyGeo
    DVGeo.updatePyGeo(geo, "tecplot", "wingNew", nRefU=10, nRefV=10)
Example #4
0
    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)
Example #5
0
DVGeo = DVGeometry(FFDFile)

# Create reference axis
nRefAxPts = DVGeo.addRefAxis("wing", xFraction=0.25, alignIndex="k")
nTwist = nRefAxPts - 1


# 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)
Example #6
0
        # 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)
Example #7
0
    C = geo.extractCoef("bodyAxis")

    length = val[0]

    C[1, 0] = C[2, 0] - length

    geo.restoreCoef(C, "bodyAxis")

    return


# lower = [-2.,-2.,-2.,-2.,5.]
# upper = [-2.,5.,5.,5.,5.]
# DVGeo.addGlobalDV('length', x, length,
#                      lower=lower, upper=upper, scale=1.0)
DVGeo.addGlobalDV("noseLength", 0.3, noseLength, lower=0, upper=0.5, scale=1.0)

# DVGeoChild.addGlobalDV('rampAngle', 35.1, rampAngle,
#                      lower=0., upper=90., scale=1.0)
DVGeoChild.addGlobalDV("doubleRampAngle", [35.1, -5.0],
                       doubleRampAngle,
                       lower=[0.0, -45.0],
                       upper=[45.0, 5.0],
                       scale=[1.0, 1.0])
# lowerA = [0.,0.,0.,0.]
# upperA = [0.3,0.3,0.3,0.3]
# DVGeoChild.addGlobalDV('angleVars', z1, angleVars,
#                      lower=lowerA, upper=upperA, scale=1.0)

# lowerL = [-1.,-1.,-1.,-1.]
# upperL = [2.0,2.0,2.0,2.0]
Example #8
0
    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)
Example #9
0
    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
Example #10
0
def twist(val, geo):
    for i in range(1, nRefAxPts):
        geo.rot_z["wing"].coef[i] = val[i - 1]


# rst Taper
def taper(val, geo):
    s = geo.extractS("wing")
    slope = (val[1] - val[0]) / (s[-1] - s[0])
    for i in range(nRefAxPts):
        geo.scale_x["wing"].coef[i] = slope * (s[i] - s[0]) + val[0]


# rst Add global dvs
nTwist = nRefAxPts - 1
DVGeo.addGlobalDV(dvName="dihedral", value=[0] * nTwist, func=dihedral, lower=-10, upper=10, scale=1)
DVGeo.addGlobalDV(dvName="twist", value=[0] * nTwist, func=twist, lower=-10, upper=10, scale=1)
DVGeo.addGlobalDV(dvName="taper", value=[1] * 2, func=taper, lower=0.5, upper=1.5, scale=1)

# rst Add local dvs
# Comment out one or the other
DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1)
DVGeo.addLocalSectionDV("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")