Exemplo n.º 1
0
    def test_getValues(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        nUpper = 5
        nLower = 3
        self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"),
                                   numCST=[nUpper, nLower])

        upper = np.full((nUpper, ), 0.3)
        lower = 0.1 * np.ones(nLower)
        N1 = np.array([0.4])
        N2_lower = np.array([1.2])
        chord = np.array([0.5])

        self.DVGeo.addDV("upper", dvType="upper", default=upper)
        self.DVGeo.addDV("lower", dvType="lower")
        self.DVGeo.addDV("n1", dvType="n1")
        self.DVGeo.addDV("n2_lower", dvType="n2_lower")
        self.DVGeo.addDV("chord", dvType="chord")

        DVs = {
            "upper": upper,
            "lower": lower,
            "n1": N1,
            "n2_lower": N2_lower,
            "chord": chord,
        }
        self.DVGeo.setDesignVars(DVs)

        valDVs = self.DVGeo.getValues()

        for dvName in DVs.keys():
            np.testing.assert_array_equal(DVs[dvName], valDVs[dvName])
Exemplo n.º 2
0
    def setUp(self):
        self.curDir = os.path.abspath(os.path.dirname(__file__))
        self.datFile = os.path.join(self.curDir, "naca2412.dat")
        self.rng = np.random.default_rng(1)
        self.comm = MPI.COMM_WORLD
        if self.dvName in ["upper", "lower"]:
            numCST = self.dvNum
        else:
            numCST = 4
        self.DVGeo = DVGeometryCST(self.datFile,
                                   comm=self.comm,
                                   isComplex=True,
                                   numCST=numCST)

        # Read in airfoil coordinates (use NACA 2412)
        coords = readCoordFile(self.datFile)
        coords = np.hstack((coords, np.zeros(
            (coords.shape[0], 1))))  # z-coordinates
        self.coords = coords.astype(complex)
        idxLE = np.argmin(coords[:, 0])
        self.idxUpper = np.arange(0, idxLE)
        self.idxLower = np.arange(idxLE, coords.shape[0])
        self.thickTE = coords[0, 1] - coords[-1, 1]
        self.ptName = "pt"

        self.sensTol = 1e-10
        self.coordTol = 1e-10
        self.CS_delta = 1e-200
Exemplo n.º 3
0
    def test_addPointSet_closed(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        datFile = os.path.join(curDir, "naca0012_closed.dat")
        comm = MPI.COMM_WORLD
        DVGeo = DVGeometryCST(datFile, comm=comm)

        # Read in airfoil coordinates to test with and split up the surfaces
        coords = readCoordFile(datFile)
        coords = np.hstack((coords, np.zeros((coords.shape[0], 1))))
        idxLE = np.argmin(coords[:, 0]) + 1

        # Don't include the points at the corners of the trailing edge because it's not guaranteed
        # that they'll be included in the upper and lower surface (which is ok)
        idxUpper = np.arange(1, idxLE)
        idxLower = np.arange(idxLE, coords.shape[0] - 2)
        thickTE = coords[0, 1] - coords[-2, 1]

        DVGeo.addPointSet(coords, "test")

        # Arrays are short so this is fast enough
        for idx in idxUpper:
            self.assertIn(idx, DVGeo.points["test"]["upper"])
        for idx in idxLower:
            self.assertIn(idx, DVGeo.points["test"]["lower"])
        np.testing.assert_equal(thickTE, DVGeo.points["test"]["thicknessTE"])
        self.assertEqual(min(coords[:, 0]), DVGeo.points["test"]["xMin"])
        self.assertEqual(max(coords[:, 0]), DVGeo.points["test"]["xMax"])
        self.assertFalse(DVGeo.sharp)
Exemplo n.º 4
0
    def test_print(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        nUpper = 5
        nLower = 3
        self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"),
                                   numCST=[nUpper, nLower])

        self.DVGeo.addDV("upper", dvType="upper")
        self.DVGeo.addDV("lower", dvType="lower")
        self.DVGeo.addDV("n1", dvType="n1")
        self.DVGeo.addDV("n2", dvType="n2")
        self.DVGeo.addDV("chord", dvType="chord")
        self.DVGeo.printDesignVariables()
Exemplo n.º 5
0
    def test_fitCST(self):
        """Test the CST parameter fitting"""
        # Read in airfoil coordinates to test with and split up the surfaces
        coords = readCoordFile(os.path.join(self.curDir, self.fName))
        coords = np.hstack((coords, np.zeros((coords.shape[0], 1))))
        idxLE = np.argmin(coords[:, 0])
        idxUpper = np.arange(0, idxLE + self.LEUpper)
        idxLower = np.arange(idxLE + self.LEUpper, coords.shape[0])
        yTE = coords[0, 1]
        N1 = 0.5
        N2 = 1.0

        for nCST in range(2, 10):
            # Fit the CST parameters and then compute the coordinates
            # with those parameters and check that it's close
            upperCST = DVGeometryCST.computeCSTfromCoords(coords[idxUpper, 0],
                                                          coords[idxUpper, 1],
                                                          nCST,
                                                          N1=N1,
                                                          N2=N2)
            lowerCST = DVGeometryCST.computeCSTfromCoords(coords[idxLower, 0],
                                                          coords[idxLower, 1],
                                                          nCST,
                                                          N1=N1,
                                                          N2=N2)
            fitCoordsUpper = DVGeometryCST.computeCSTCoordinates(
                coords[idxUpper, 0], N1, N2, upperCST, yTE)
            fitCoordsLower = DVGeometryCST.computeCSTCoordinates(
                coords[idxLower, 0], N1, N2, lowerCST, -yTE)

            # Loosen the tolerances for the challenging e63 airfoil
            if self.fName == "e63.dat":
                if nCST < 4:
                    atol = 1e-1
                    rtol = 1.0
                else:
                    atol = 1e-2
                    rtol = 6e-1
            else:
                atol = 1e-3
                rtol = 1e-1

            np.testing.assert_allclose(fitCoordsUpper,
                                       coords[idxUpper, 1],
                                       atol=atol,
                                       rtol=rtol)
            np.testing.assert_allclose(fitCoordsLower,
                                       coords[idxLower, 1],
                                       atol=atol,
                                       rtol=rtol)
Exemplo n.º 6
0
    def test_getNDV(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        nUpper = 5
        nLower = 3
        nOther = 3  # N1, N2, and chord
        self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"),
                                   numCST=[nUpper, nLower])

        self.DVGeo.addDV("upper", dvType="upper")
        self.DVGeo.addDV("lower", dvType="lower")
        self.DVGeo.addDV("n1", dvType="n1")
        self.DVGeo.addDV("n2", dvType="n2")
        self.DVGeo.addDV("chord", dvType="chord")

        self.assertEqual(nUpper + nLower + nOther, self.DVGeo.getNDV())
Exemplo n.º 7
0
    def test_getVarNames(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"))

        dvNames = ["amy", "joesph", "maryann", "tobysue", "sir blue bus"]

        self.DVGeo.addDV(dvNames[0], dvType="upper")
        self.DVGeo.addDV(dvNames[1], dvType="lower")
        self.DVGeo.addDV(dvNames[2], dvType="n1")
        self.DVGeo.addDV(dvNames[3], dvType="n2_lower")
        self.DVGeo.addDV(dvNames[4], dvType="chord")

        names = self.DVGeo.getVarNames()

        for name in names:
            self.assertTrue(name in dvNames)
Exemplo n.º 8
0
 def test_ShapeFunctions(self):
     """Test that the shape functions sum to 1 when all weights are 1"""
     for n in range(1, self.maxNumCoeff + 1):
         w = np.ones(n)
         y = DVGeometryCST.computeShapeFunctions(self.x, w)
         np.testing.assert_allclose(y.sum(axis=0),
                                    1.0,
                                    atol=self.coordTol,
                                    rtol=self.coordTol)
Exemplo n.º 9
0
 def test_ClassShape(self):
     """Test that for w_i = 1, the class shape has the expected shape"""
     N1 = 0.5
     N2 = 1.0
     yExact = np.sqrt(self.x) * (1 - self.x)
     y = DVGeometryCST.computeClassShape(self.x, N1, N2)
     np.testing.assert_allclose(y,
                                yExact,
                                atol=self.coordTol,
                                rtol=self.coordTol)
Exemplo n.º 10
0
 def test_dydN2(self):
     """Test the derivatives of the CST curve height w.r.t N2"""
     N1 = self.rng.random(1)
     N2 = self.rng.random(1)
     for n in range(1, self.maxNumCoeff + 1):
         w = self.rng.random(n)
         dydN2 = DVGeometryCST.computeCSTdydN2(self.x, N1, N2, w)
         dydN2_CS = (np.imag(
             DVGeometryCST.computeCSTCoordinates(self.x,
                                                 N1,
                                                 N2 + self.CS_delta * 1j,
                                                 w,
                                                 self.yte,
                                                 dtype=complex)) /
                     self.CS_delta)
         np.testing.assert_allclose(dydN2,
                                    dydN2_CS,
                                    atol=self.sensTol,
                                    rtol=self.sensTol)
Exemplo n.º 11
0
    def test_dydw(self):
        """Test the derivatives of the CST curve height w.r.t N2"""
        N1 = self.rng.random(1)
        N2 = self.rng.random(1)
        for n in range(1, self.maxNumCoeff + 1):
            w = self.rng.random(n)
            dydw = DVGeometryCST.computeCSTdydw(self.x, N1, N2, w)
            dydw_CS = np.zeros((n, self.x.size), dtype=float)
            w = w.astype(complex)
            for i in range(n):
                w[i] += self.CS_delta * 1j
                dydw_CS[i, :] = (np.imag(
                    DVGeometryCST.computeCSTCoordinates(
                        self.x, N1, N2, w, self.yte, dtype=complex)) /
                                 self.CS_delta)
                w[i] -= self.CS_delta * 1j

            np.testing.assert_allclose(dydw,
                                       dydw_CS,
                                       atol=self.sensTol,
                                       rtol=self.sensTol)
Exemplo n.º 12
0
class DVGeometryCSTSensitivity(unittest.TestCase):
    # Test in serial
    N_PROCS = 1

    def setUp(self):
        self.curDir = os.path.abspath(os.path.dirname(__file__))
        self.datFile = os.path.join(self.curDir, "naca2412.dat")
        self.rng = np.random.default_rng(1)
        self.comm = MPI.COMM_WORLD
        if self.dvName in ["upper", "lower"]:
            numCST = self.dvNum
        else:
            numCST = 4
        self.DVGeo = DVGeometryCST(self.datFile,
                                   comm=self.comm,
                                   isComplex=True,
                                   numCST=numCST)

        # Read in airfoil coordinates (use NACA 2412)
        coords = readCoordFile(self.datFile)
        coords = np.hstack((coords, np.zeros(
            (coords.shape[0], 1))))  # z-coordinates
        self.coords = coords.astype(complex)
        idxLE = np.argmin(coords[:, 0])
        self.idxUpper = np.arange(0, idxLE)
        self.idxLower = np.arange(idxLE, coords.shape[0])
        self.thickTE = coords[0, 1] - coords[-1, 1]
        self.ptName = "pt"

        self.sensTol = 1e-10
        self.coordTol = 1e-10
        self.CS_delta = 1e-200

    def test_DV_sensitivityProd(self):
        """
        Test DVGeo.totalSensitivityProd for all design variables
        """
        self.DVGeo.addDV(self.dvName, dvType=self.dvName)
        self.DVGeo.addPointSet(self.coords, self.ptName)

        # Set DV to random values
        self.DVGeo.setDesignVars({self.dvName: self.rng.random(self.dvNum)})
        self.DVGeo.update(self.ptName)

        DVs = self.DVGeo.getValues()

        # First compute the analytic ones with the built in function
        sensProd = []
        for i in range(self.dvNum):
            vec = np.zeros(self.dvNum)
            vec[i] = 1
            sensProd.append(
                np.real(
                    self.DVGeo.totalSensitivityProd({self.dvName: vec},
                                                    self.ptName)))

        # Then check them against doing it with complex step
        valDV = DVs[self.dvName]
        for i in range(DVs[self.dvName].size):
            valDV[i] += self.CS_delta * 1j
            self.DVGeo.setDesignVars({self.dvName: valDV})
            pertCoords = self.DVGeo.update(self.ptName)
            valDV[i] -= self.CS_delta * 1j

            dXdDV = np.imag(pertCoords) / self.CS_delta
            np.testing.assert_allclose(sensProd[i],
                                       dXdDV,
                                       atol=self.sensTol,
                                       rtol=self.sensTol)

    def test_DV_sensitivity_simple(self):
        """
        Test DVGeo.totalSensitivity for all design variables with dIdXpt of all ones
        """
        self.DVGeo.addDV(self.dvName, dvType=self.dvName)
        self.DVGeo.addPointSet(self.coords, self.ptName)

        # Set DV to random values
        self.DVGeo.setDesignVars({self.dvName: self.rng.random(self.dvNum)})
        self.DVGeo.update(self.ptName)

        # dIdXpt of all ones means the total sensitivities will just be the sum of the
        # derivatives at each of the coordianates
        dIdXpt = np.ones_like(self.coords)

        DVs = self.DVGeo.getValues()

        # First compute the analytic ones with the built in function
        sens = np.real(
            self.DVGeo.totalSensitivity(dIdXpt, self.ptName)[self.dvName])

        # Then check them against doing it with complex step
        valDV = DVs[self.dvName]
        sensCS = np.zeros(self.dvNum)
        for i in range(DVs[self.dvName].size):
            valDV[i] += self.CS_delta * 1j
            self.DVGeo.setDesignVars({self.dvName: valDV})
            pertCoords = self.DVGeo.update(self.ptName)
            valDV[i] -= self.CS_delta * 1j

            dXdDV = np.imag(pertCoords) / self.CS_delta

            # Sum the derivatives
            sensCS[i] = np.sum(dXdDV)

        np.testing.assert_allclose(sens,
                                   sensCS,
                                   atol=self.sensTol,
                                   rtol=self.sensTol)

    def test_DV_sensitivity_parallel(self):
        """
        Test DVGeo.totalSensitivity for all design variables with dIdXpt containing
        three different Npts x 3 arrays (another possible input)
        """
        self.DVGeo.addDV(self.dvName, dvType=self.dvName)
        self.DVGeo.addPointSet(self.coords, self.ptName)

        # Set DV to random values
        self.DVGeo.setDesignVars({self.dvName: self.rng.random(self.dvNum)})
        self.DVGeo.update(self.ptName)

        # dIdXpt of all ones means the total sensitivities will just be the sum of the
        # derivatives at each of the coordianates
        dIdXpt = np.ones_like(self.coords)
        coeff = np.array([0.1, 0.5, 1.0])
        dIdXptVectorized = np.array(
            [coeff[0] * dIdXpt, coeff[1] * dIdXpt, coeff[2] * dIdXpt])

        DVs = self.DVGeo.getValues()

        # First compute the analytic ones with the built in function
        sens = np.real(
            self.DVGeo.totalSensitivity(dIdXptVectorized,
                                        self.ptName,
                                        comm=self.comm)[self.dvName])

        # Then check them against doing it with complex step
        valDV = DVs[self.dvName]
        sensCS = np.zeros((dIdXptVectorized.shape[0], self.dvNum))
        for i in range(DVs[self.dvName].size):
            valDV[i] += self.CS_delta * 1j
            self.DVGeo.setDesignVars({self.dvName: valDV})
            pertCoords = self.DVGeo.update(self.ptName)
            valDV[i] -= self.CS_delta * 1j

            dXdDV = np.imag(pertCoords) / self.CS_delta

            # Sum the derivatives
            for j in range(sensCS.shape[0]):
                sensCS[j, i] = coeff[j] * np.sum(dXdDV)

        np.testing.assert_allclose(sens,
                                   sensCS,
                                   atol=self.sensTol,
                                   rtol=self.sensTol)
Exemplo n.º 13
0
 def test_plotCST(self):
     DVGeometryCST.plotCST(np.ones(4), np.ones(3))
Exemplo n.º 14
0
class TestFunctionality(unittest.TestCase):
    """
    This class tests that some simple methods run without errors.
    """
    def test_plotCST(self):
        DVGeometryCST.plotCST(np.ones(4), np.ones(3))

    def test_print(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        nUpper = 5
        nLower = 3
        self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"),
                                   numCST=[nUpper, nLower])

        self.DVGeo.addDV("upper", dvType="upper")
        self.DVGeo.addDV("lower", dvType="lower")
        self.DVGeo.addDV("n1", dvType="n1")
        self.DVGeo.addDV("n2", dvType="n2")
        self.DVGeo.addDV("chord", dvType="chord")
        self.DVGeo.printDesignVariables()

    def test_getNDV(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        nUpper = 5
        nLower = 3
        nOther = 3  # N1, N2, and chord
        self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"),
                                   numCST=[nUpper, nLower])

        self.DVGeo.addDV("upper", dvType="upper")
        self.DVGeo.addDV("lower", dvType="lower")
        self.DVGeo.addDV("n1", dvType="n1")
        self.DVGeo.addDV("n2", dvType="n2")
        self.DVGeo.addDV("chord", dvType="chord")

        self.assertEqual(nUpper + nLower + nOther, self.DVGeo.getNDV())

    def test_getValues(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        nUpper = 5
        nLower = 3
        self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"),
                                   numCST=[nUpper, nLower])

        upper = np.full((nUpper, ), 0.3)
        lower = 0.1 * np.ones(nLower)
        N1 = np.array([0.4])
        N2_lower = np.array([1.2])
        chord = np.array([0.5])

        self.DVGeo.addDV("upper", dvType="upper", default=upper)
        self.DVGeo.addDV("lower", dvType="lower")
        self.DVGeo.addDV("n1", dvType="n1")
        self.DVGeo.addDV("n2_lower", dvType="n2_lower")
        self.DVGeo.addDV("chord", dvType="chord")

        DVs = {
            "upper": upper,
            "lower": lower,
            "n1": N1,
            "n2_lower": N2_lower,
            "chord": chord,
        }
        self.DVGeo.setDesignVars(DVs)

        valDVs = self.DVGeo.getValues()

        for dvName in DVs.keys():
            np.testing.assert_array_equal(DVs[dvName], valDVs[dvName])

    def test_getVarNames(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"))

        dvNames = ["amy", "joesph", "maryann", "tobysue", "sir blue bus"]

        self.DVGeo.addDV(dvNames[0], dvType="upper")
        self.DVGeo.addDV(dvNames[1], dvType="lower")
        self.DVGeo.addDV(dvNames[2], dvType="n1")
        self.DVGeo.addDV(dvNames[3], dvType="n2_lower")
        self.DVGeo.addDV(dvNames[4], dvType="chord")

        names = self.DVGeo.getVarNames()

        for name in names:
            self.assertTrue(name in dvNames)
Exemplo n.º 15
0
class DVGeometryCSTPointSetSerial(unittest.TestCase):
    # Test in serial
    N_PROCS = 1

    def setUp(self):
        self.curDir = os.path.abspath(os.path.dirname(__file__))
        self.datFile = os.path.join(self.curDir, self.fName)
        self.comm = MPI.COMM_WORLD
        self.DVGeo = DVGeometryCST(self.datFile, comm=self.comm)

    def test_addPointSet_sorted(self):
        # Read in airfoil coordinates to test with and split up the surfaces
        coords = readCoordFile(self.datFile)
        coords = np.hstack((coords, np.zeros((coords.shape[0], 1))))
        idxLE = np.argmin(coords[:, 0])
        # Don't include the points at the corners of the trailing edge because it's not guaranteed
        # that they'll be included in the upper and lower surface (which is ok)
        idxUpper = np.arange(1, idxLE + self.LEUpper)
        idxLower = np.arange(idxLE + self.LEUpper, coords.shape[0] - 1)
        thickTE = coords[0, 1] - coords[-1, 1]

        self.DVGeo.addPointSet(coords, "test")

        # Arrays are short so this is fast enough
        for idx in idxUpper:
            self.assertIn(idx, self.DVGeo.points["test"]["upper"])
        for idx in idxLower:
            self.assertIn(idx, self.DVGeo.points["test"]["lower"])
        np.testing.assert_equal(thickTE,
                                self.DVGeo.points["test"]["thicknessTE"])
        self.assertEqual(min(coords[:, 0]), self.DVGeo.points["test"]["xMin"])
        self.assertEqual(max(coords[:, 0]), self.DVGeo.points["test"]["xMax"])

    def test_addPointSet_randomized(self):
        # Read in airfoil coordinates to test with and split up the surfaces
        coords = readCoordFile(self.datFile)
        coords = np.hstack((coords, np.zeros((coords.shape[0], 1))))
        idxLE = np.argmin(coords[:, 0])
        idxUpper = np.arange(0, idxLE + self.LEUpper)
        idxLower = np.arange(idxLE + self.LEUpper, coords.shape[0])
        thickTE = coords[0, 1] - coords[-1, 1]

        # Randomize the index order (do indices so we can track where they end up)
        rng = np.random.default_rng(1)
        # Maps from the original index to the new one (e.g., the first value is the index the first coordinate ends up at)
        idxShuffle = np.arange(0, coords.shape[0])
        rng.shuffle(idxShuffle)
        coordsRand = np.zeros(coords.shape)
        coordsRand[idxShuffle, :] = coords
        idxUpperRand = np.sort(idxShuffle[idxUpper])
        idxLowerRand = np.sort(idxShuffle[idxLower])

        self.DVGeo.addPointSet(coordsRand, "test")

        # Don't include the points at the corners of the trailing edge because it's not guaranteed
        # that they'll be included in the upper and lower surface (which is ok)
        # Arrays are short so this is fast enough
        for idx in idxUpperRand:
            if idx != idxShuffle[0]:
                self.assertIn(idx, self.DVGeo.points["test"]["upper"])
        for idx in idxLowerRand:
            if idx != idxShuffle[-1]:
                self.assertIn(idx, self.DVGeo.points["test"]["lower"])
        np.testing.assert_equal(thickTE,
                                self.DVGeo.points["test"]["thicknessTE"])
        self.assertEqual(min(coords[:, 0]), self.DVGeo.points["test"]["xMin"])
        self.assertEqual(max(coords[:, 0]), self.DVGeo.points["test"]["xMax"])

    def test_addPointSet_bluntTE(
            self):  # includes a blunt trailing edge with points along it
        # Read in airfoil coordinates to test with and split up the surfaces
        coords = readCoordFile(self.datFile)
        coords = np.hstack((coords, np.zeros((coords.shape[0], 1))))
        nPointsTE = 6  # total points on the trailing edge
        pointsTE = np.ones((nPointsTE - 2, 3), dtype=float)
        pointsTE[:, 2] = 0  # z coordinates are zero
        pointsTE[:, 1] = np.linspace(coords[-1, 1] + 1e-4, coords[0, 1] - 1e-4,
                                     pointsTE.shape[0])
        coords = np.vstack((coords, pointsTE))
        idxLE = np.argmin(coords[:, 0])
        # Don't include the points at the corners of the trailing edge because it's not guaranteed
        # that they'll be included in the upper and lower surface (which is ok)
        idxUpper = np.arange(1, idxLE + self.LEUpper)
        idxLower = np.arange(idxLE + self.LEUpper,
                             coords.shape[0] - nPointsTE + 2 - 1)
        thickTE = coords[0, 1] - coords[coords.shape[0] - nPointsTE + 1, 1]

        self.DVGeo.addPointSet(coords, "test")

        # Arrays are short so this is fast enough
        for idx in idxUpper:
            self.assertIn(idx, self.DVGeo.points["test"]["upper"])
        for idx in idxLower:
            self.assertIn(idx, self.DVGeo.points["test"]["lower"])
        np.testing.assert_equal(thickTE,
                                self.DVGeo.points["test"]["thicknessTE"])
        self.assertEqual(min(coords[:, 0]), self.DVGeo.points["test"]["xMin"])
        self.assertEqual(max(coords[:, 0]), self.DVGeo.points["test"]["xMax"])
Exemplo n.º 16
0
class TestErrorChecking(unittest.TestCase):
    def setUp(self):
        curDir = os.path.abspath(os.path.dirname(__file__))
        self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"),
                                   numCST=4)

    def test_addPointSet_min_out_of_bounds(self):
        points = np.array([
            [0.5, 0.1, 4.0],
            [-0.5, 0.1, 4.0],
        ])
        with self.assertRaises(ValueError):
            self.DVGeo.addPointSet(points, "bjork")

    def test_addPointSet_max_out_of_bounds(self):
        points = np.array([
            [0.5, 0.1, 4.0],
            [1.5, 0.1, 4.0],
        ])
        with self.assertRaises(ValueError):
            self.DVGeo.addPointSet(points, "jacobo")

    def test_addDV_invalid_type(self):
        with self.assertRaises(ValueError):
            self.DVGeo.addDV("samantha", dvType="this is an invalid type")

    def test_addDV_duplicate_n1(self):
        self.DVGeo.addDV("silver baboon", dvType="n1", default=np.array([0.4]))
        with self.assertRaises(ValueError):
            self.DVGeo.addDV("panda express", dvType="n1_upper")

    def test_addDV_duplicate_n1_reverse(self):
        self.DVGeo.addDV("candace", dvType="n1_lower")
        with self.assertRaises(ValueError):
            self.DVGeo.addDV("richard", dvType="n1")

    def test_addDV_duplicate_n2(self):
        self.DVGeo.addDV("harry", dvType="n2")
        with self.assertRaises(ValueError):
            self.DVGeo.addDV("bobby", dvType="n2_upper")

    def test_addDV_duplicate_n2_reverse(self):
        self.DVGeo.addDV("bob haimes", dvType="n2_lower")
        with self.assertRaises(ValueError):
            self.DVGeo.addDV("hannah", dvType="n2")

    def test_addDV_duplicate_same_type(self):
        self.DVGeo.addDV("ali", dvType="upper")
        with self.assertRaises(ValueError):
            self.DVGeo.addDV("anil", dvType="upper")

    def test_addDV_duplicate_same_name(self):
        self.DVGeo.addDV("josh", dvType="upper")
        with self.assertRaises(ValueError):
            self.DVGeo.addDV("josh", dvType="lower")

    def test_addDV_duplicate_invalid_default_type(self):
        with self.assertRaises(ValueError):
            self.DVGeo.addDV("timo", dvType="chord", default=5.0)

    def test_addDV_duplicate_invalid_default_size(self):
        with self.assertRaises(ValueError):
            self.DVGeo.addDV("brick",
                             dvType="upper",
                             default=np.array([5.0, 1]))

    def test_setDesignVars_invalid_shape(self):
        self.DVGeo.addDV("mafa", dvType="upper")
        with self.assertRaises(ValueError):
            self.DVGeo.setDesignVars({"mafa": np.array([1.0, 3.0])})
Exemplo n.º 17
0
 def setUp(self):
     self.curDir = os.path.abspath(os.path.dirname(__file__))
     self.datFile = os.path.join(self.curDir, self.fName)
     self.comm = MPI.COMM_WORLD
     self.DVGeo = DVGeometryCST(self.datFile, comm=self.comm)
Exemplo n.º 18
0
class DVGeometryCSTPointSetParallel(unittest.TestCase):
    # Test in parallel
    N_PROCS = 4

    def setUp(self):
        self.curDir = os.path.abspath(os.path.dirname(__file__))
        self.datFile = os.path.join(self.curDir, self.fName)
        self.comm = MPI.COMM_WORLD
        self.DVGeo = DVGeometryCST(self.datFile, comm=self.comm)

    def test_addPointSet_sorted(self):
        # Read in airfoil coordinates to test with and split up the surfaces
        coords = readCoordFile(self.datFile)
        coords = np.hstack((coords, np.zeros((coords.shape[0], 1))))
        idxLE = np.argmin(coords[:, 0])

        isUpper = np.zeros(coords.shape[0])
        isUpper[:idxLE + self.LEUpper] = 1
        isUpper = isUpper == 1
        isLower = np.logical_not(isUpper)

        thickTE = coords[0, 1] - coords[-1, 1]

        # Divide up the points among the procs (mostly evenly, but not quite to check the harder case)
        if self.N_PROCS == 1:
            nPerProc = coords.shape[0]
        else:
            nPerProc = int(coords.shape[0] // (self.N_PROCS - 0.5))
        rank = self.comm.rank
        if self.comm.rank < self.comm.size - 1:  # all but last proc takes nPerProc elements
            self.DVGeo.addPointSet(
                coords[rank * nPerProc:(rank + 1) * nPerProc, :], "test")
            idxUpper = np.where(isUpper[rank * nPerProc:(rank + 1) *
                                        nPerProc])[0]
            idxLower = np.where(isLower[rank * nPerProc:(rank + 1) *
                                        nPerProc])[0]
        else:
            self.DVGeo.addPointSet(coords[rank * nPerProc:, :], "test")
            idxUpper = np.where(isUpper[rank * nPerProc:])[0]
            idxLower = np.where(isLower[rank * nPerProc:])[0]

        # Don't include the points at the corners of the trailing edge because it's not guaranteed
        # that they'll be included in the upper and lower surface (which is ok)
        # Arrays are short so this is fast enough
        for idx in idxUpper:
            if idx != 0:
                self.assertIn(idx, self.DVGeo.points["test"]["upper"])
        for idx in idxLower:
            if idx != coords.shape[0] - 1:
                self.assertIn(idx, self.DVGeo.points["test"]["lower"])
        np.testing.assert_equal(thickTE,
                                self.DVGeo.points["test"]["thicknessTE"])
        self.assertEqual(min(coords[:, 0]), self.DVGeo.points["test"]["xMin"])
        self.assertEqual(max(coords[:, 0]), self.DVGeo.points["test"]["xMax"])

    def test_addPointSet_randomized(self):
        # Read in airfoil coordinates to test with and split up the surfaces
        coords = readCoordFile(self.datFile)
        coords = np.hstack((coords, np.zeros((coords.shape[0], 1))))
        idxLE = np.argmin(coords[:, 0])

        isUpper = np.zeros(coords.shape[0])
        isUpper[:idxLE + self.LEUpper] = 1
        isUpper = isUpper == 1
        isLower = np.logical_not(isUpper)

        thickTE = coords[0, 1] - coords[-1, 1]

        # Randomize the index order (do indices so we can track where they end up)
        rng = np.random.default_rng(1)
        # Maps from the original index to the new one (e.g., the first value is the index the first coordinate ends up at)
        idxShuffle = np.arange(0, coords.shape[0])
        rng.shuffle(idxShuffle)
        # idxShuffle = (idxShuffle + 10) % coords.shape[0]
        coordsRand = np.zeros(coords.shape)
        isUpperRand = np.full(isUpper.shape, False)
        isLowerRand = np.full(isLower.shape, False)
        coordsRand[idxShuffle, :] = coords
        isUpperRand[idxShuffle] = isUpper
        isLowerRand[idxShuffle] = isLower

        # Maps from the shuffled index to the original one (e.g., the first value is
        # the original index of the first value in the shuffled array)
        idxInverseShuffle = np.zeros(idxShuffle.shape[0])
        idxInverseShuffle[idxShuffle] = np.arange(0, coords.shape[0])

        # Divide up the points among the procs (mostly evenly, but not quite to check the harder case)
        nPerProc = int(coordsRand.shape[0] // 3.5)
        rank = self.comm.rank
        if self.comm.rank < self.comm.size - 1:  # all but last proc takes nPerProc elements
            self.DVGeo.addPointSet(coordsRand[rank * nPerProc:(rank + 1) *
                                              nPerProc, :],
                                   "test",
                                   rank=self.comm.rank)
            idxUpper = np.where(isUpperRand[rank * nPerProc:(rank + 1) *
                                            nPerProc])[0]
            idxLower = np.where(isLowerRand[rank * nPerProc:(rank + 1) *
                                            nPerProc])[0]

            # Figure out the local indices where the first and last coordinates in the dat file ended up
            idxStart = np.argwhere(
                0 == idxInverseShuffle[rank * nPerProc:(rank + 1) * nPerProc])
            idxEnd = np.argwhere(
                coords.shape[0] == idxInverseShuffle[rank *
                                                     nPerProc:(rank + 1) *
                                                     nPerProc])
        else:
            self.DVGeo.addPointSet(coordsRand[rank * nPerProc:, :],
                                   "test",
                                   rank=self.comm.rank)
            idxUpper = np.where(isUpperRand[rank * nPerProc:])[0]
            idxLower = np.where(isLowerRand[rank * nPerProc:])[0]

            # Figure out the local indices where the first and last coordinates in the dat file ended up
            idxStart = np.argwhere(0 == idxInverseShuffle[rank * nPerProc:])
            idxEnd = np.argwhere(
                coords.shape[0] == idxInverseShuffle[rank * nPerProc:])

        # Turn the single element array to a number or None if the first
        # or last points aren't in this partition
        if idxStart:
            idxStart = idxStart.item()
        else:
            idxStart = None
        if idxEnd:
            idxEnd = idxEnd.item()
        else:
            idxEnd = None

        # Don't include the points at the corners of the trailing edge because it's not guaranteed
        # that they'll be included in the upper and lower surface (which is ok)
        # Arrays are short so this is fast enough
        for idx in idxUpper:
            if idx != idxStart:
                self.assertIn(idx, self.DVGeo.points["test"]["upper"])
        for idx in idxLower:
            if idx != idxEnd:
                self.assertIn(idx, self.DVGeo.points["test"]["lower"])
        np.testing.assert_equal(thickTE,
                                self.DVGeo.points["test"]["thicknessTE"])
        self.assertEqual(min(coords[:, 0]), self.DVGeo.points["test"]["xMin"])
        self.assertEqual(max(coords[:, 0]), self.DVGeo.points["test"]["xMax"])
Exemplo n.º 19
0
 def setUp(self):
     curDir = os.path.abspath(os.path.dirname(__file__))
     self.DVGeo = DVGeometryCST(os.path.join(curDir, "naca2412.dat"),
                                numCST=4)
Exemplo n.º 20
0
    ax.set_yticks([])

    if filename:
        fig.savefig(filename)

    return fig, ax
    # rst Plot func (end)


# rst Init (beg)
# Initialize the DVGeometryCST object
curDir = os.path.dirname(__file__)  # directory of this script
airfoilFile = os.path.join(curDir, "naca2412.dat")
nCoeff = 4  # number of CST coefficients on each surface

DVGeo = DVGeometryCST(airfoilFile, numCST=nCoeff)
# rst Init (end)

# rst DV (beg)
# Add design variables that we can perturb
DVGeo.addDV("upper_shape", dvType="upper", lowerBound=-0.1, upperBound=0.5)
DVGeo.addDV("lower_shape", dvType="lower", lowerBound=-0.5, upperBound=0.1)
DVGeo.addDV("class_shape_n1", dvType="N1")
DVGeo.addDV("class_shape_n2", dvType="N2")
DVGeo.addDV("chord", dvType="chord")
# rst DV (end)

# rst Create pointset (beg)
# For this case, we'll just use the points in the airfoil file as the pointset
points = []
with open(airfoilFile, "r") as f: