Example #1
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 #2
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)
    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)
Example #4
0
#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')
Example #5
0
# lowerL = [-1.,-1.,-1.,-1.]
# upperL = [2.0,2.0,2.0,2.0]
# DVGeoChild.addGeoDVGlobal('noseLen', x1, noseLength,
#                      lower=lowerL, upper=upperL, scale=1.0)

# DVGeo.addGeoDVGlobal('angleVars', z1, angleVars,
#                      lower=lowerA, upper=upperA, scale=1.0)

# Add the child to the parent
DVGeo.addChild(DVGeoChild)

ptSetName = "allSurfs"
freezeDict = {
}  # '0':['jLow'],'1':['jLow'],'2':['jLow']}#'0':['jLow'],'1':['jHigh','jLow']}
DVGeo.addPointSet(coords0, ptSetName, faceFreeze=freezeDict)
xDV = DVGeo.getValues()

# Required design variables
# Rear ramp angle, fixed 200 mm length
# overall length
# nose length
# Ramp shape
# Ground separation
# Lower ramp angle

# 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
Example #6
0
print("FFD Coordinates:")
print(FFD[DVGeo.getLocalIndex(0)[:, 0, 0]])

# Create tecplot output that contains the FFD control points, embedded volume, and pointset
DVGeo.writeTecplot(fileName="undeformed_embedded.dat", solutionTime=1)

# rst perturb geometry
# Now let's deform the geometry.
# We want to set the front and rear control points the same so we preserve symmetry along the z axis
# and we ues the getLocalIndex function to accomplish this
lower_front_idx = DVGeo.getLocalIndex(0)[:, 0, 0]
lower_rear_idx = DVGeo.getLocalIndex(0)[:, 0, 1]
upper_front_idx = DVGeo.getLocalIndex(0)[:, 1, 0]
upper_rear_idx = DVGeo.getLocalIndex(0)[:, 1, 1]

currentDV = DVGeo.getValues()["shape"]
newDV = currentDV.copy()

# add a constant offset (upward) to the lower points, plus a linear ramp and a trigonometric local change
# this will shrink the cylinder height-wise and make it wavy
# set the front and back points the same to keep the cylindrical sections square along that axis
for idx in [lower_front_idx, lower_rear_idx]:
    const_offset = 0.3 * np.ones(10)
    local_perturb = np.cos(np.linspace(0, 4 * np.pi, 10)) / 10 + np.linspace(
        -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)
Example #7
0
    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)
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)