Exemple #1
0
    def execute(self):
        """provides a default behavior (to not modify the airfoil)"""

        self.afOut = self.afIn
        
        # create polar object
        p = Polar(self.afIn.Re,
                  self.afIn.alpha,
                  self.afIn.cl,
                  self.afIn.cd,
                  self.afIn.cm)
        
        if self.AR == 0.0:
            AR = None
        else:
            AR = self.AR
            
        # extrapolate polar
        p_extrap = p.extrapolate(self.cdmax,
                                 AR,
                                 self.cdmin,
                                 self.nalpha)
        
        self.afOut.Re = p_extrap.Re
        self.afOut.alpha = p_extrap.alpha
        self.afOut.cl = p_extrap.cl
        self.afOut.cd = p_extrap.cd
        self.afOut.cm = p_extrap.cm
        
        
Exemple #2
0
    def setUp(self):

        alpha = [
            -10.1, -8.2, -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2, 11.3,
            12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1
        ]
        cl = [
            -0.6300, -0.5600, -0.6400, -0.4200, -0.2100, 0.0500, 0.3000,
            0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100,
            1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600
        ]
        cd = [
            0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116, 0.0144,
            0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648, 0.0776,
            0.0917, 0.0994, 0.2306, 0.3142, 0.3186
        ]
        cm = [
            -0.0044, -0.0051, 0.0018, -0.0216, -0.0282, -0.0346, -0.0405,
            -0.0455, -0.0507, -0.0404, -0.0321, -0.0281, -0.0284, -0.0322,
            -0.0361, -0.0363, -0.0393, -0.0398, -0.0983, -0.1242, -0.1155
        ]
        cm_zeros = np.zeros(len(cm))
        Re = 1
        self.polar = Polar(Re, alpha, cl, cd, cm)
        self.polar2 = Polar(Re, alpha, cl, cd, cm_zeros)
Exemple #3
0
    def setUp(self):
        alpha = [
            -9.000, -8.000, -7.000, -6.000, -5.000, -4.000, -3.000, -2.000,
            -1.000, 0.000, 1.000, 2.000, 3.000, 4.000, 5.000, 6.000, 7.000,
            8.000, 9.000, 10.000, 11.000, 12.000, 13.000, 14.000, 15.000,
            16.000, 17.000, 18.000, 19.000, 20.000, 30.000, 40.000, 50.000
        ]
        cl = [
            -0.802, -0.721, -0.611, -0.506, -0.408, -0.313, -0.220, -0.133,
            -0.060, 0.036, 0.227, 0.342, 0.436, 0.556, 0.692, 0.715, 0.761,
            0.830, 0.893, 0.954, 1.013, 1.042, 1.061, 1.083, 1.078, 0.882,
            0.811, 0.793, 0.793, 0.798, 0.772, 0.757, 0.700
        ]
        cd = [
            0.027, 0.025, 0.024, 0.023, 0.022, 0.022, 0.023, 0.025, 0.027,
            0.028, 0.024, 0.019, 0.017, 0.015, 0.017, 0.019, 0.021, 0.024,
            0.027, 0.031, 0.037, 0.046, 0.058, 0.074, 0.088, 0.101, 0.114,
            0.128, 0.142, 0.155, 0.321, 0.525, 0.742
        ]
        cm = [
            -0.0037, -0.0044, -0.0051, 0.0018, -0.0216, -0.0282, -0.0346,
            -0.0405, -0.0455, -0.0507, -0.0404, -0.0321, -0.0281, -0.0284,
            -0.0322, -0.0361, -0.0363, -0.0393, -0.0398, -0.0983, -0.1242,
            -0.1155, -0.1068, -0.0981, -0.0894, -0.0807, -0.072, -0.0633,
            -0.054, -0.045, -0.036, -0.22, -0.13
        ]
        cm_zeros = np.zeros(len(cm))
        Re = 1

        self.polar = Polar(Re, alpha, cl, cd, cm)
        self.polar2 = Polar(Re, alpha, cl, cd, cm_zeros)
Exemple #4
0
    def setUp(self):
        alpha = [
            -3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11, 6.13,
            7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18, 15.18, 16.17,
            17.14, 18.06, 19.06, 20.07, 25
        ]
        cl = [
            -0.071, 0.044, 0.144, 0.241, 0.338, 0.435, 0.535, 0.632, 0.728,
            0.813, 0.883, 0.946, 1.001, 1.054, 1.056, 1.095, 1.138, 1.114,
            1.073, 1.008, 0.95, 0.902, 0.795, 0.797, 0.8
        ]
        cd = [
            0.0122, 0.0106, 0.0114, 0.0134, 0.0136, 0.014, 0.0147, 0.0156,
            0.0162, 0.0173, 0.0191, 0.0215, 0.0248, 0.0339, 0.0544, 0.0452,
            0.0445, 0.067, 0.0748, 0.1028, 0.1473, 0.2819, 0.2819, 0.2819, 0.3
        ]
        cm = [
            -0.0044, -0.0051, 0.0018, -0.0216, -0.0282, -0.0346, -0.0405,
            -0.0455, -0.0507, -0.0404, -0.0321, -0.0281, -0.0284, -0.0322,
            -0.0361, -0.0363, -0.0393, -0.0398, -0.0983, -0.1242, -0.1155,
            -0.1068, -0.0981, -0.0894, -0.0807
        ]
        Re = 1

        self.polar1 = Polar(Re, alpha, cl, cd, cm)

        alpha = [
            -3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11, 6.13,
            7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18, 15.189, 16.17,
            17.14, 18.06, 19.06, 20.07, 21.08, 22.09, 23.1, 25
        ]
        cl = [
            -0.0852, 0.0528, 0.1728, 0.2892, 0.4056, 0.522, 0.642, 0.7584,
            0.8736, 0.9756, 1.0596, 1.1352, 1.2012, 1.2648, 1.2672, 1.314,
            1.3656, 1.3368, 1.2876, 1.2096, 1.14, 1.0824, 0.954, 0.9564, 1,
            1.2, 1.4, 1.6
        ]
        cd = [
            0.01464, 0.01272, 0.01368, 0.01608, 0.01632, 0.0168, 0.01764,
            0.01872, 0.01944, 0.02076, 0.02292, 0.0258, 0.02976, 0.04068,
            0.06528, 0.05424, 0.0534, 0.0804, 0.08976, 0.12336, 0.17676,
            0.33828, 0.33828, 0.33828, 0.35, 0.4, 0.45, 0.5
        ]
        cm = [
            -0.0037, -0.0044, -0.0051, 0.0018, -0.0216, -0.0282, -0.0346,
            -0.0405, -0.0455, -0.0507, -0.0404, -0.0321, -0.0281, -0.0284,
            -0.0322, -0.0361, -0.0363, -0.0393, -0.0398, -0.0983, -0.1242,
            -0.1155, -0.1068, -0.0981, -0.0894, -0.0807, -0.072, -0.0633
        ]

        self.polar2 = Polar(Re, alpha, cl, cd, cm)
    def setUp(self):
        alpha = [-3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11,
                 6.13, 7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18,
                 14.18, 15.18, 16.17, 17.14, 18.06, 19.06, 20.07, 25]
        cl = [-0.071, 0.044, 0.144, 0.241, 0.338, 0.435, 0.535, 0.632,
              0.728, 0.813, 0.883, 0.946, 1.001, 1.054, 1.056, 1.095,
              1.138, 1.114, 1.073, 1.008, 0.95, 0.902, 0.795, 0.797, 0.8]
        cd = [0.0122, 0.0106, 0.0114, 0.0134, 0.0136, 0.014, 0.0147,
              0.0156, 0.0162, 0.0173, 0.0191, 0.0215, 0.0248, 0.0339,
              0.0544, 0.0452, 0.0445, 0.067, 0.0748, 0.1028, 0.1473,
              0.2819, 0.2819, 0.2819, 0.3]
        Re = 1

        self.polar1 = Polar(Re, alpha, cl, cd)

        alpha = [-3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11,
                 6.13, 7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18,
                 15.189, 16.17, 17.14, 18.06, 19.06, 20.07, 21.08, 22.09,
                 23.1, 25]
        cl = [-0.0852, 0.0528, 0.1728, 0.2892, 0.4056, 0.522, 0.642, 0.7584,
              0.8736, 0.9756, 1.0596, 1.1352, 1.2012, 1.2648, 1.2672, 1.314,
              1.3656, 1.3368, 1.2876, 1.2096, 1.14, 1.0824, 0.954, 0.9564, 1,
              1.2, 1.4, 1.6]
        cd = [0.01464, 0.01272, 0.01368, 0.01608, 0.01632, 0.0168, 0.01764,
              0.01872, 0.01944, 0.02076, 0.02292, 0.0258, 0.02976, 0.04068,
              0.06528, 0.05424, 0.0534, 0.0804, 0.08976, 0.12336, 0.17676,
              0.33828, 0.33828, 0.33828, 0.35, 0.4, 0.45, 0.5]

        self.polar2 = Polar(Re, alpha, cl, cd)
    def setUp(self):

        alpha = [
            -10.1, -8.2, -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2, 11.3,
            12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1
        ]
        cl = [
            -0.6300, -0.5600, -0.6400, -0.4200, -0.2100, 0.0500, 0.3000,
            0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100,
            1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600
        ]
        cd = [
            0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116, 0.0144,
            0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648, 0.0776,
            0.0917, 0.0994, 0.2306, 0.3142, 0.3186
        ]
        Re = 1
        self.polar = Polar(Re, alpha, cl, cd)
    def setUp(self):

        alpha = [-10.1, -8.2, -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2,
                 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1]
        cl = [-0.6300, -0.5600, -0.6400, -0.4200, -0.2100, 0.0500, 0.3000,
              0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100,
              1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600]
        cd = [0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116, 0.0144,
              0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648, 0.0776,
              0.0917, 0.0994, 0.2306, 0.3142, 0.3186]
        Re = 1
        self.polar = Polar(Re, alpha, cl, cd)
    def setUp(self):
        alpha = [
            -9.000, -8.000, -7.000, -6.000, -5.000, -4.000, -3.000, -2.000,
            -1.000, 0.000, 1.000, 2.000, 3.000, 4.000, 5.000, 6.000, 7.000,
            8.000, 9.000, 10.000, 11.000, 12.000, 13.000, 14.000, 15.000,
            16.000, 17.000, 18.000, 19.000, 20.000, 30.000, 40.000, 50.000
        ]
        cl = [
            -0.802, -0.721, -0.611, -0.506, -0.408, -0.313, -0.220, -0.133,
            -0.060, 0.036, 0.227, 0.342, 0.436, 0.556, 0.692, 0.715, 0.761,
            0.830, 0.893, 0.954, 1.013, 1.042, 1.061, 1.083, 1.078, 0.882,
            0.811, 0.793, 0.793, 0.798, 0.772, 0.757, 0.700
        ]
        cd = [
            0.027, 0.025, 0.024, 0.023, 0.022, 0.022, 0.023, 0.025, 0.027,
            0.028, 0.024, 0.019, 0.017, 0.015, 0.017, 0.019, 0.021, 0.024,
            0.027, 0.031, 0.037, 0.046, 0.058, 0.074, 0.088, 0.101, 0.114,
            0.128, 0.142, 0.155, 0.321, 0.525, 0.742
        ]

        Re = 1

        self.polar = Polar(Re, alpha, cl, cd)
    def setUp(self):
        alpha = [-9.000, -8.000, -7.000, -6.000, -5.000, -4.000, -3.000,
                 -2.000, -1.000, 0.000, 1.000, 2.000, 3.000, 4.000, 5.000,
                 6.000, 7.000, 8.000, 9.000, 10.000, 11.000, 12.000, 13.000,
                 14.000, 15.000, 16.000, 17.000, 18.000, 19.000, 20.000,
                 30.000, 40.000, 50.000]
        cl = [-0.802, -0.721, -0.611, -0.506, -0.408, -0.313, -0.220, -0.133,
              -0.060, 0.036, 0.227, 0.342, 0.436, 0.556, 0.692, 0.715, 0.761,
              0.830, 0.893, 0.954, 1.013, 1.042, 1.061, 1.083, 1.078, 0.882,
              0.811, 0.793, 0.793, 0.798, 0.772, 0.757, 0.700]
        cd = [0.027, 0.025, 0.024, 0.023, 0.022, 0.022, 0.023, 0.025, 0.027,
              0.028, 0.024, 0.019, 0.017, 0.015, 0.017, 0.019, 0.021, 0.024,
              0.027, 0.031, 0.037, 0.046, 0.058, 0.074, 0.088, 0.101, 0.114,
              0.128, 0.142, 0.155, 0.321, 0.525, 0.742]

        Re = 1

        self.polar = Polar(Re, alpha, cl, cd)
class TestBlend(unittest.TestCase):

    def setUp(self):
        alpha = [-3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11,
                 6.13, 7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18,
                 14.18, 15.18, 16.17, 17.14, 18.06, 19.06, 20.07, 25]
        cl = [-0.071, 0.044, 0.144, 0.241, 0.338, 0.435, 0.535, 0.632,
              0.728, 0.813, 0.883, 0.946, 1.001, 1.054, 1.056, 1.095,
              1.138, 1.114, 1.073, 1.008, 0.95, 0.902, 0.795, 0.797, 0.8]
        cd = [0.0122, 0.0106, 0.0114, 0.0134, 0.0136, 0.014, 0.0147,
              0.0156, 0.0162, 0.0173, 0.0191, 0.0215, 0.0248, 0.0339,
              0.0544, 0.0452, 0.0445, 0.067, 0.0748, 0.1028, 0.1473,
              0.2819, 0.2819, 0.2819, 0.3]
        Re = 1

        self.polar1 = Polar(Re, alpha, cl, cd)

        alpha = [-3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11,
                 6.13, 7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18,
                 15.189, 16.17, 17.14, 18.06, 19.06, 20.07, 21.08, 22.09,
                 23.1, 25]
        cl = [-0.0852, 0.0528, 0.1728, 0.2892, 0.4056, 0.522, 0.642, 0.7584,
              0.8736, 0.9756, 1.0596, 1.1352, 1.2012, 1.2648, 1.2672, 1.314,
              1.3656, 1.3368, 1.2876, 1.2096, 1.14, 1.0824, 0.954, 0.9564, 1,
              1.2, 1.4, 1.6]
        cd = [0.01464, 0.01272, 0.01368, 0.01608, 0.01632, 0.0168, 0.01764,
              0.01872, 0.01944, 0.02076, 0.02292, 0.0258, 0.02976, 0.04068,
              0.06528, 0.05424, 0.0534, 0.0804, 0.08976, 0.12336, 0.17676,
              0.33828, 0.33828, 0.33828, 0.35, 0.4, 0.45, 0.5]

        self.polar2 = Polar(Re, alpha, cl, cd)


    def test_blend1(self):

        polar3 = self.polar1.blend(self.polar2, 0.5)

        alpha_blend = [-3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09,
                       5.11, 6.13, 7.14, 8.16, 9.17, 10.18, 11.18, 12.19,
                       13.18, 14.18, 15.18, 16.17, 17.14, 18.06, 19.06, 20.07,
                       25]
        cl_blend = [-0.078, 0.048, 0.158, 0.265, 0.372, 0.479, 0.589, 0.695,
                    0.801, 0.894, 0.971, 1.041, 1.101, 1.159, 1.162, 1.205,
                    1.252, 1.225, 1.181, 1.109, 1.045, 0.992, 0.875, 0.877,
                    1.200]
        cd_blend = [0.0134, 0.0117, 0.0125, 0.0147, 0.0150, 0.0154, 0.0162,
                    0.0172, 0.0178, 0.0190, 0.0210, 0.0237, 0.0273, 0.0373,
                    0.0598, 0.0497, 0.0490, 0.0737, 0.0822, 0.1131, 0.1620,
                    0.3101, 0.3101, 0.3101, 0.4000]

        # re-interpolate b/c angles of attack are different
        cl3 = np.interp(alpha_blend, polar3.alpha, polar3.cl)
        cd3 = np.interp(alpha_blend, polar3.alpha, polar3.cd)

        # should be within 1e-3
        np.testing.assert_allclose(cl3, cl_blend, atol=1e-3)
        np.testing.assert_allclose(cd3, cd_blend, atol=1e-3)


    def test_blend1_w_airfoil(self):

        af1 = Airfoil([self.polar1])
        af2 = Airfoil([self.polar2])
        af3 = af1.blend(af2, 0.5)
        polar3 = af3.polars[0]  # kind of bad practice for me to be accessing this

        alpha_blend = [-3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09,
                       5.11, 6.13, 7.14, 8.16, 9.17, 10.18, 11.18, 12.19,
                       13.18, 14.18, 15.18, 16.17, 17.14, 18.06, 19.06, 20.07,
                       25]
        cl_blend = [-0.078, 0.048, 0.158, 0.265, 0.372, 0.479, 0.589, 0.695,
                    0.801, 0.894, 0.971, 1.041, 1.101, 1.159, 1.162, 1.205,
                    1.252, 1.225, 1.181, 1.109, 1.045, 0.992, 0.875, 0.877,
                    1.200]
        cd_blend = [0.0134, 0.0117, 0.0125, 0.0147, 0.0150, 0.0154, 0.0162,
                    0.0172, 0.0178, 0.0190, 0.0210, 0.0237, 0.0273, 0.0373,
                    0.0598, 0.0497, 0.0490, 0.0737, 0.0822, 0.1131, 0.1620,
                    0.3101, 0.3101, 0.3101, 0.4000]

        # re-interpolate b/c angles of attack are different
        cl3 = np.interp(alpha_blend, polar3.alpha, polar3.cl)
        cd3 = np.interp(alpha_blend, polar3.alpha, polar3.cd)

        # should be within 1e-3
        np.testing.assert_allclose(cl3, cl_blend, atol=1e-3)
        np.testing.assert_allclose(cd3, cd_blend, atol=1e-3)



    def test_blend2(self):

        polar3 = self.polar1.blend(self.polar2, 0.7)

        alpha_blend = [-3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11,
                       6.13, 7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18,
                       14.18, 15.18, 16.17, 17.14, 18.06, 19.06, 20.07, 25]
        cl_blend = [-0.081, 0.050, 0.164, 0.275, 0.385, 0.496, 0.610, 0.720,
                    0.830, 0.927, 1.007, 1.078, 1.141, 1.202, 1.204, 1.248,
                    1.297, 1.270, 1.224, 1.149, 1.083, 1.028, 0.906, 0.909,
                    1.360]
        cd_blend = [0.0139, 0.0121, 0.0130, 0.0153, 0.0155, 0.0160, 0.0168,
                    0.0178, 0.0185, 0.0197, 0.0218, 0.0245, 0.0283, 0.0386,
                    0.0620, 0.0515, 0.0507, 0.0764, 0.0852, 0.1172, 0.1679,
                    0.3214, 0.3214, 0.3214, 0.4400]


        # re-interpolate b/c angles of attack are different
        cl3 = np.interp(alpha_blend, polar3.alpha, polar3.cl)
        cd3 = np.interp(alpha_blend, polar3.alpha, polar3.cd)

        # should be within 1e-3
        np.testing.assert_allclose(cl3, cl_blend, atol=1e-3)
        np.testing.assert_allclose(cd3, cd_blend, atol=1e-3)


    def test_blend3(self):

        polar3 = self.polar1.blend(self.polar2, 0.2)

        alpha_blend = [-3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11,
                       6.13, 7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18,
                       14.18, 15.18, 16.17, 17.14, 18.06, 19.06, 20.07, 25]
        cl_blend = [-0.074, 0.046, 0.150, 0.251, 0.352, 0.452, 0.556, 0.657,
                    0.757, 0.846, 0.918, 0.984, 1.041, 1.096, 1.098, 1.139,
                    1.184, 1.159, 1.116, 1.048, 0.988, 0.938, 0.827, 0.829,
                    0.960]
        cd_blend = [0.0127, 0.0110, 0.0119, 0.0139, 0.0141, 0.0146, 0.0153,
                    0.0162, 0.0168, 0.0180, 0.0199, 0.0224, 0.0258, 0.0353,
                    0.0566, 0.0470, 0.0463, 0.0697, 0.0778, 0.1069, 0.1532,
                    0.2932, 0.2932, 0.2932, 0.3400]


        # re-interpolate b/c angles of attack are different
        cl3 = np.interp(alpha_blend, polar3.alpha, polar3.cl)
        cd3 = np.interp(alpha_blend, polar3.alpha, polar3.cd)

        # should be within 1e-3
        np.testing.assert_allclose(cl3, cl_blend, atol=1e-3)
        np.testing.assert_allclose(cd3, cd_blend, atol=1e-3)
class TestExtrap(unittest.TestCase):

    def setUp(self):

        alpha = [-10.1, -8.2, -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2,
                 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1]
        cl = [-0.6300, -0.5600, -0.6400, -0.4200, -0.2100, 0.0500, 0.3000,
              0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100,
              1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600]
        cd = [0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116, 0.0144,
              0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648, 0.0776,
              0.0917, 0.0994, 0.2306, 0.3142, 0.3186]
        Re = 1
        self.polar = Polar(Re, alpha, cl, cd)


    def test_extrap1(self):

        cdmax = 1.29
        newpolar = self.polar.extrapolate(cdmax=cdmax)

        alpha_extrap = [-180, -170, -160, -150, -140, -130, -120, -110, -100,
                        -90, -80, -70, -60, -50, -40, -30, -20, -10.1, -8.2,
                        -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2, 11.3,
                        12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1,
                        30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140,
                        150, 160, 170, 180]
        cl_extrap = [0.0000, 0.2299, 0.4597, 0.4907, 0.5053, 0.4805, 0.4102,
                     0.2985, 0.1565, 0.0000, -0.1565, -0.2985, -0.4102,
                     -0.4805, -0.5053, -0.4907, -0.4637, -0.6300, -0.5600,
                     -0.6400, -0.4200, -0.2100, 0.0500, 0.3000, 0.5400,
                     0.7900, 0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100,
                     1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600, 0.7010,
                     0.7219, 0.6864, 0.5860, 0.4264, 0.2235, 0.0000, -0.1565,
                     -0.2985, -0.4102, -0.4805, -0.5053, -0.4907, -0.4597,
                     -0.2299, 0.0000]
        cd_extrap = [0.1770, 0.2132, 0.3173, 0.4758, 0.6686, 0.8708, 1.0560,
                     1.1996, 1.2818, 1.2900, 1.2818, 1.1996, 1.0560, 0.8708,
                     0.6686, 0.4758, 0.3158, 0.0390, 0.0233, 0.0131, 0.0134,
                     0.0119, 0.0122, 0.0116, 0.0144, 0.0146, 0.0162, 0.0274,
                     0.0303, 0.0369, 0.0509, 0.0648, 0.0776, 0.0917, 0.0994,
                     0.2306, 0.3142, 0.3186, 0.4758, 0.6686, 0.8708, 1.0560,
                     1.1996, 1.2818, 1.2900, 1.2818, 1.1996, 1.0560, 0.8708,
                     0.6686, 0.4758, 0.3173, 0.2132, 0.1770]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)


    def test_extrap1_w_airfoil(self):

        cdmax = 1.29
        af = Airfoil([self.polar])
        newaf = af.extrapolate(cdmax=cdmax)
        newpolar = newaf.polars[0]

        alpha_extrap = [-180, -170, -160, -150, -140, -130, -120, -110, -100,
                        -90, -80, -70, -60, -50, -40, -30, -20, -10.1, -8.2,
                        -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2, 11.3,
                        12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1,
                        30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140,
                        150, 160, 170, 180]
        cl_extrap = [0.0000, 0.2299, 0.4597, 0.4907, 0.5053, 0.4805, 0.4102,
                     0.2985, 0.1565, 0.0000, -0.1565, -0.2985, -0.4102,
                     -0.4805, -0.5053, -0.4907, -0.4637, -0.6300, -0.5600,
                     -0.6400, -0.4200, -0.2100, 0.0500, 0.3000, 0.5400,
                     0.7900, 0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100,
                     1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600, 0.7010,
                     0.7219, 0.6864, 0.5860, 0.4264, 0.2235, 0.0000, -0.1565,
                     -0.2985, -0.4102, -0.4805, -0.5053, -0.4907, -0.4597,
                     -0.2299, 0.0000]
        cd_extrap = [0.1770, 0.2132, 0.3173, 0.4758, 0.6686, 0.8708, 1.0560,
                     1.1996, 1.2818, 1.2900, 1.2818, 1.1996, 1.0560, 0.8708,
                     0.6686, 0.4758, 0.3158, 0.0390, 0.0233, 0.0131, 0.0134,
                     0.0119, 0.0122, 0.0116, 0.0144, 0.0146, 0.0162, 0.0274,
                     0.0303, 0.0369, 0.0509, 0.0648, 0.0776, 0.0917, 0.0994,
                     0.2306, 0.3142, 0.3186, 0.4758, 0.6686, 0.8708, 1.0560,
                     1.1996, 1.2818, 1.2900, 1.2818, 1.1996, 1.0560, 0.8708,
                     0.6686, 0.4758, 0.3173, 0.2132, 0.1770]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)


    def test_extrap2(self):

        cdmax = 1.0
        newpolar = self.polar.extrapolate(cdmax=cdmax)

        alpha_extrap = [-180, -170, -160, -150, -140, -130, -120, -110, -100,
                        -90, -80, -70, -60, -50, -40, -30, -20, -10.1, -8.2,
                        -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2, 11.3,
                        12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1,
                        30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140,
                        150, 160, 170, 180]
        cl_extrap = [0.0000, 0.2299, 0.4597, 0.4411, 0.4287, 0.3943, 0.3297,
                     0.2364, 0.1225, 0.0000, -0.1225, -0.2364, -0.3297,
                     -0.3943, -0.4287, -0.4411, -0.4637, -0.6300, -0.5600,
                     -0.6400, -0.4200, -0.2100, 0.0500, 0.3000, 0.5400,
                     0.7900, 0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100,
                     1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600, 0.6302,
                     0.6124, 0.5633, 0.4710, 0.3378, 0.1750, 0.0000, -0.1225,
                     -0.2364, -0.3297, -0.3943, -0.4287, -0.4411, -0.4597,
                     -0.2299, 0.0000]
        cd_extrap = [0.2135, 0.2404, 0.3176, 0.4349, 0.5767, 0.7241, 0.8568,
                     0.9560, 1.0069, 1.0000, 1.0069, 0.9560, 0.8568, 0.7241,
                     0.5767, 0.4349, 0.3158, 0.0390, 0.0233, 0.0131, 0.0134,
                     0.0119, 0.0122, 0.0116, 0.0144, 0.0146, 0.0162, 0.0274,
                     0.0303, 0.0369, 0.0509, 0.0648, 0.0776, 0.0917, 0.0994,
                     0.2306, 0.3142, 0.3186, 0.4349, 0.5767, 0.7241, 0.8568,
                     0.9560, 1.0069, 1.0000, 1.0069, 0.9560, 0.8568, 0.7241,
                     0.5767, 0.4349, 0.3176, 0.2404, 0.2135]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)


    def test_extrap3(self):

        cdmax = 1.5
        newpolar = self.polar.extrapolate(cdmax)

        alpha_extrap = [-180, -170, -160, -150, -140, -130, -120, -110, -100,
                        -90, -80, -70, -60, -50, -40, -30, -20, -10.1, -8.2,
                        -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2, 11.3,
                        12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1,
                        30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140,
                        150, 160, 170, 180]
        cl_extrap = [0.0000, 0.2299, 0.4597, 0.5266, 0.5608, 0.5429, 0.4685,
                     0.3434, 0.1810, 0.0000, -0.1810, -0.3434, -0.4685,
                     -0.5429, -0.5608, -0.5266, -0.4637, -0.6300, -0.5600,
                     -0.6400, -0.4200, -0.2100, 0.0500, 0.3000, 0.5400, 0.7900,
                     0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100, 1.0200,
                     1.0000, 0.9400, 0.8500, 0.7000, 0.6600, 0.7523, 0.8012,
                     0.7756, 0.6693, 0.4906, 0.2586, 0.0000, -0.1810, -0.3434,
                     -0.4685, -0.5429, -0.5608, -0.5266, -0.4597, -0.2299,
                     0.0000]
        cd_extrap = [0.1506, 0.1936, 0.3170, 0.5054, 0.7351, 0.9771, 1.2003,
                     1.3760, 1.4809, 1.5000, 1.4809, 1.3760, 1.2003, 0.9771,
                     0.7351, 0.5054, 0.3158, 0.0390, 0.0233, 0.0131, 0.0134,
                     0.0119, 0.0122, 0.0116, 0.0144, 0.0146, 0.0162, 0.0274,
                     0.0303, 0.0369, 0.0509, 0.0648, 0.0776, 0.0917, 0.0994,
                     0.2306, 0.3142, 0.3186, 0.5054, 0.7351, 0.9771, 1.2003,
                     1.3760, 1.4809, 1.5000, 1.4809, 1.3760, 1.2003, 0.9771,
                     0.7351, 0.5054, 0.3170, 0.1936, 0.1506]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
class Test3DStall(unittest.TestCase):

    def setUp(self):
        alpha = [-9.000, -8.000, -7.000, -6.000, -5.000, -4.000, -3.000,
                 -2.000, -1.000, 0.000, 1.000, 2.000, 3.000, 4.000, 5.000,
                 6.000, 7.000, 8.000, 9.000, 10.000, 11.000, 12.000, 13.000,
                 14.000, 15.000, 16.000, 17.000, 18.000, 19.000, 20.000,
                 30.000, 40.000, 50.000]
        cl = [-0.802, -0.721, -0.611, -0.506, -0.408, -0.313, -0.220, -0.133,
              -0.060, 0.036, 0.227, 0.342, 0.436, 0.556, 0.692, 0.715, 0.761,
              0.830, 0.893, 0.954, 1.013, 1.042, 1.061, 1.083, 1.078, 0.882,
              0.811, 0.793, 0.793, 0.798, 0.772, 0.757, 0.700]
        cd = [0.027, 0.025, 0.024, 0.023, 0.022, 0.022, 0.023, 0.025, 0.027,
              0.028, 0.024, 0.019, 0.017, 0.015, 0.017, 0.019, 0.021, 0.024,
              0.027, 0.031, 0.037, 0.046, 0.058, 0.074, 0.088, 0.101, 0.114,
              0.128, 0.142, 0.155, 0.321, 0.525, 0.742]

        Re = 1

        self.polar = Polar(Re, alpha, cl, cd)


    def test_stall1(self):
        R = 2.4
        r = 0.25*R
        chord = 0.18
        Omega = 200*pi/30
        Uinf = 10.0
        tsr = Omega*R/Uinf

        newpolar = self.polar.correction3D(r/R, chord/r, tsr,
                                           alpha_max_corr=30,
                                           alpha_linear_min=-4,
                                           alpha_linear_max=4)

        cl_3d = [-0.8466, -0.7523, -0.6420, -0.5342, -0.4302, -0.3284,
                 -0.2276, -0.1303, -0.0404, 0.0618, 0.2191, 0.3321, 0.4336,
                 0.5501, 0.6755, 0.7363, 0.8101, 0.8973, 0.9810, 1.0640,
                 1.1450, 1.2098, 1.2682, 1.3281, 1.3731, 1.3088, 1.3159,
                 1.3534, 1.4010, 1.4515, 1.9140, 1.8857, 1.6451]
        cd_3d = [0.0399, 0.0334, 0.0316, 0.0293, 0.0269, 0.0254, 0.0246,
                 0.0246, 0.0246, 0.0252, 0.0249, 0.0200, 0.0167, 0.0157,
                 0.0174, 0.0183, 0.0212, 0.0255, 0.0303, 0.0367, 0.0465,
                 0.0615, 0.0800, 0.1047, 0.1301, 0.1695, 0.2047, 0.2384,
                 0.2728, 0.3081, 0.8097, 1.2625, 1.6280]

        # test equality
        np.testing.assert_allclose(newpolar.cl, cl_3d, atol=1e-3)
        np.testing.assert_allclose(newpolar.cd, cd_3d, atol=1e-3)


    def test_stall1_w_airfoil(self):
        R = 2.4
        r = 0.25*R
        chord = 0.18
        Omega = 200*pi/30
        Uinf = 10.0
        tsr = Omega*R/Uinf

        af = Airfoil([self.polar])
        newaf = af.correction3D(r/R, chord/r, tsr,
                                alpha_max_corr=30,
                                alpha_linear_min=-4,
                                alpha_linear_max=4)

        newpolar = newaf.polars[0]

        cl_3d = [-0.8466, -0.7523, -0.6420, -0.5342, -0.4302, -0.3284,
                 -0.2276, -0.1303, -0.0404, 0.0618, 0.2191, 0.3321, 0.4336,
                 0.5501, 0.6755, 0.7363, 0.8101, 0.8973, 0.9810, 1.0640,
                 1.1450, 1.2098, 1.2682, 1.3281, 1.3731, 1.3088, 1.3159,
                 1.3534, 1.4010, 1.4515, 1.9140, 1.8857, 1.6451]
        cd_3d = [0.0399, 0.0334, 0.0316, 0.0293, 0.0269, 0.0254, 0.0246,
                 0.0246, 0.0246, 0.0252, 0.0249, 0.0200, 0.0167, 0.0157,
                 0.0174, 0.0183, 0.0212, 0.0255, 0.0303, 0.0367, 0.0465,
                 0.0615, 0.0800, 0.1047, 0.1301, 0.1695, 0.2047, 0.2384,
                 0.2728, 0.3081, 0.8097, 1.2625, 1.6280]

        # test equality
        np.testing.assert_allclose(newpolar.cl, cl_3d, atol=1e-3)
        np.testing.assert_allclose(newpolar.cd, cd_3d, atol=1e-3)


    def test_stall2(self):
        R = 2.4
        r = 0.75*R
        chord = 0.28
        Omega = 200*pi/30
        Uinf = 14.0
        tsr = Omega*R/Uinf

        newpolar = self.polar.correction3D(r/R, chord/r, tsr,
                                           alpha_max_corr=30,
                                           alpha_linear_min=-4,
                                           alpha_linear_max=4)

        cl_3d = [-0.81340155, -0.72876051, -0.61903798, -0.51322348,
                 -0.41336822, -0.31696485, -0.22214149, -0.13269893,
                 -0.05485453, 0.04222704, 0.22525537, 0.33917483,
                 0.43518608, 0.55464051, 0.68785835, 0.72023796,
                 0.77302335, 0.84665343, 0.91485674, 0.98191931, 1.04592758,
                 1.08446883, 1.11313747, 1.14423161, 1.15194066, 0.98921407,
                 0.93776667, 0.93384528, 0.94558296, 0.96199091, 1.05910388,
                 1.04054486, 0.93735382]
        cd_3d = [0.03050922, 0.02712935, 0.02589588, 0.02453937, 0.02341344,
                 0.02320787, 0.02359745, 0.02497252, 0.02653913, 0.02751806,
                 0.02430795, 0.01935093, 0.01663156, 0.01552516, 0.01698944,
                 0.01853615, 0.02107760, 0.02443710, 0.02784230, 0.03217433,
                 0.03929881, 0.05021192, 0.06322801, 0.08159739, 0.09837902,
                 0.11798276, 0.13692472, 0.15565820, 0.17470667, 0.19368328,
                 0.44408310, 0.71034295, 0.96437541]

        # test equality
        np.testing.assert_allclose(newpolar.cl, cl_3d, atol=1e-3)
        np.testing.assert_allclose(newpolar.cd, cd_3d, atol=1e-3)


    def test_stall3(self):
        R = 5.0
        r = 0.5*R
        chord = 0.5
        Omega = 100*pi/30
        Uinf = 10.0
        tsr = Omega*R/Uinf

        newpolar = self.polar.correction3D(r/R, chord/r, tsr,
                                           alpha_max_corr=30,
                                           alpha_linear_min=-4,
                                           alpha_linear_max=4)

        cl_3d = [-0.8240, -0.7363, -0.6264, -0.5199, -0.4188, -0.3206, -0.2239,
                 -0.1319, -0.0502, 0.0485, 0.2233, 0.3369, 0.4347, 0.5532,
                 0.6839, 0.7254, 0.7849, 0.8629, 0.9361, 1.0082, 1.0777,
                 1.1246, 1.1628, 1.2031, 1.2228, 1.0916, 1.0589, 1.0682,
                 1.0914, 1.1188, 1.3329, 1.3112, 1.1640]
        cd_3d = [0.0335, 0.0291, 0.0277, 0.0261, 0.0245, 0.0239, 0.0239,
                 0.0249, 0.0259, 0.0268, 0.0245, 0.0195, 0.0167, 0.0156,
                 0.0171, 0.0185, 0.0211, 0.0248, 0.0286, 0.0336, 0.0416,
                 0.0538, 0.0686, 0.0890, 0.1085, 0.1345, 0.1586, 0.1822,
                 0.2061, 0.2303, 0.5612, 0.8872, 1.1769]

        # test equality
        np.testing.assert_allclose(newpolar.cl, cl_3d, atol=1e-3)
        np.testing.assert_allclose(newpolar.cd, cd_3d, atol=1e-3)
    def setUp(self):
        alpha = [
            -9.000,
            -8.000,
            -7.000,
            -6.000,
            -5.000,
            -4.000,
            -3.000,
            -2.000,
            -1.000,
            0.000,
            1.000,
            2.000,
            3.000,
            4.000,
            5.000,
            6.000,
            7.000,
            8.000,
            9.000,
            10.000,
            11.000,
            12.000,
            13.000,
            14.000,
            15.000,
            16.000,
            17.000,
            18.000,
            19.000,
            20.000,
            30.000,
            40.000,
            50.000,
        ]
        cl = [
            -0.802,
            -0.721,
            -0.611,
            -0.506,
            -0.408,
            -0.313,
            -0.220,
            -0.133,
            -0.060,
            0.036,
            0.227,
            0.342,
            0.436,
            0.556,
            0.692,
            0.715,
            0.761,
            0.830,
            0.893,
            0.954,
            1.013,
            1.042,
            1.061,
            1.083,
            1.078,
            0.882,
            0.811,
            0.793,
            0.793,
            0.798,
            0.772,
            0.757,
            0.700,
        ]
        cd = [
            0.027,
            0.025,
            0.024,
            0.023,
            0.022,
            0.022,
            0.023,
            0.025,
            0.027,
            0.028,
            0.024,
            0.019,
            0.017,
            0.015,
            0.017,
            0.019,
            0.021,
            0.024,
            0.027,
            0.031,
            0.037,
            0.046,
            0.058,
            0.074,
            0.088,
            0.101,
            0.114,
            0.128,
            0.142,
            0.155,
            0.321,
            0.525,
            0.742,
        ]
        cm = [
            -0.0037,
            -0.0044,
            -0.0051,
            0.0018,
            -0.0216,
            -0.0282,
            -0.0346,
            -0.0405,
            -0.0455,
            -0.0507,
            -0.0404,
            -0.0321,
            -0.0281,
            -0.0284,
            -0.0322,
            -0.0361,
            -0.0363,
            -0.0393,
            -0.0398,
            -0.0983,
            -0.1242,
            -0.1155,
            -0.1068,
            -0.0981,
            -0.0894,
            -0.0807,
            -0.072,
            -0.0633,
            -0.054,
            -0.045,
            -0.036,
            -0.22,
            -0.13,
        ]
        cm_zeros = np.zeros(len(cm))
        Re = 1

        self.polar = Polar(Re, alpha, cl, cd, cm)
        self.polar2 = Polar(Re, alpha, cl, cd, cm_zeros)
    def setUp(self):

        alpha = [
            -10.1,
            -8.2,
            -6.1,
            -4.1,
            -2.1,
            0.1,
            2,
            4.1,
            6.2,
            8.1,
            10.2,
            11.3,
            12.1,
            13.2,
            14.2,
            15.3,
            16.3,
            17.1,
            18.1,
            19.1,
            20.1,
        ]
        cl = [
            -0.6300,
            -0.5600,
            -0.6400,
            -0.4200,
            -0.2100,
            0.0500,
            0.3000,
            0.5400,
            0.7900,
            0.9000,
            0.9300,
            0.9200,
            0.9500,
            0.9900,
            1.0100,
            1.0200,
            1.0000,
            0.9400,
            0.8500,
            0.7000,
            0.6600,
        ]
        cd = [
            0.0390,
            0.0233,
            0.0131,
            0.0134,
            0.0119,
            0.0122,
            0.0116,
            0.0144,
            0.0146,
            0.0162,
            0.0274,
            0.0303,
            0.0369,
            0.0509,
            0.0648,
            0.0776,
            0.0917,
            0.0994,
            0.2306,
            0.3142,
            0.3186,
        ]
        cm = [
            -0.0044,
            -0.0051,
            0.0018,
            -0.0216,
            -0.0282,
            -0.0346,
            -0.0405,
            -0.0455,
            -0.0507,
            -0.0404,
            -0.0321,
            -0.0281,
            -0.0284,
            -0.0322,
            -0.0361,
            -0.0363,
            -0.0393,
            -0.0398,
            -0.0983,
            -0.1242,
            -0.1155,
        ]
        cm_zeros = np.zeros(len(cm))
        Re = 1
        self.polar = Polar(Re, alpha, cl, cd, cm)
        self.polar2 = Polar(Re, alpha, cl, cd, cm_zeros)
class TestExtrap(unittest.TestCase):
    def setUp(self):

        alpha = [
            -10.1,
            -8.2,
            -6.1,
            -4.1,
            -2.1,
            0.1,
            2,
            4.1,
            6.2,
            8.1,
            10.2,
            11.3,
            12.1,
            13.2,
            14.2,
            15.3,
            16.3,
            17.1,
            18.1,
            19.1,
            20.1,
        ]
        cl = [
            -0.6300,
            -0.5600,
            -0.6400,
            -0.4200,
            -0.2100,
            0.0500,
            0.3000,
            0.5400,
            0.7900,
            0.9000,
            0.9300,
            0.9200,
            0.9500,
            0.9900,
            1.0100,
            1.0200,
            1.0000,
            0.9400,
            0.8500,
            0.7000,
            0.6600,
        ]
        cd = [
            0.0390,
            0.0233,
            0.0131,
            0.0134,
            0.0119,
            0.0122,
            0.0116,
            0.0144,
            0.0146,
            0.0162,
            0.0274,
            0.0303,
            0.0369,
            0.0509,
            0.0648,
            0.0776,
            0.0917,
            0.0994,
            0.2306,
            0.3142,
            0.3186,
        ]
        cm = [
            -0.0044,
            -0.0051,
            0.0018,
            -0.0216,
            -0.0282,
            -0.0346,
            -0.0405,
            -0.0455,
            -0.0507,
            -0.0404,
            -0.0321,
            -0.0281,
            -0.0284,
            -0.0322,
            -0.0361,
            -0.0363,
            -0.0393,
            -0.0398,
            -0.0983,
            -0.1242,
            -0.1155,
        ]
        cm_zeros = np.zeros(len(cm))
        Re = 1
        self.polar = Polar(Re, alpha, cl, cd, cm)
        self.polar2 = Polar(Re, alpha, cl, cd, cm_zeros)

    def test_extrap1(self):

        cdmax = 1.29
        newpolar = self.polar.extrapolate(cdmax=cdmax)

        alpha_extrap = [
            -180,
            -170,
            -160,
            -150,
            -140,
            -130,
            -120,
            -110,
            -100,
            -90,
            -80,
            -70,
            -60,
            -50,
            -40,
            -30,
            -20,
            -10.1,
            -8.2,
            -6.1,
            -4.1,
            -2.1,
            0.1,
            2,
            4.1,
            6.2,
            8.1,
            10.2,
            11.3,
            12.1,
            13.2,
            14.2,
            15.3,
            16.3,
            17.1,
            18.1,
            19.1,
            20.1,
            30,
            40,
            50,
            60,
            70,
            80,
            90,
            100,
            110,
            120,
            130,
            140,
            150,
            160,
            170,
            180,
        ]
        cl_extrap = [
            0.0000,
            0.2299,
            0.4597,
            0.4907,
            0.5053,
            0.4805,
            0.4102,
            0.2985,
            0.1565,
            0.0000,
            -0.1565,
            -0.2985,
            -0.4102,
            -0.4805,
            -0.5053,
            -0.4907,
            -0.4637,
            -0.6300,
            -0.5600,
            -0.6400,
            -0.4200,
            -0.2100,
            0.0500,
            0.3000,
            0.5400,
            0.7900,
            0.9000,
            0.9300,
            0.9200,
            0.9500,
            0.9900,
            1.0100,
            1.0200,
            1.0000,
            0.9400,
            0.8500,
            0.7000,
            0.6600,
            0.7010,
            0.7219,
            0.6864,
            0.5860,
            0.4264,
            0.2235,
            0.0000,
            -0.1565,
            -0.2985,
            -0.4102,
            -0.4805,
            -0.5053,
            -0.4907,
            -0.4597,
            -0.2299,
            0.0000,
        ]
        cd_extrap = [
            0.1770,
            0.2132,
            0.3173,
            0.4758,
            0.6686,
            0.8708,
            1.0560,
            1.1996,
            1.2818,
            1.2900,
            1.2818,
            1.1996,
            1.0560,
            0.8708,
            0.6686,
            0.4758,
            0.3158,
            0.0390,
            0.0233,
            0.0131,
            0.0134,
            0.0119,
            0.0122,
            0.0116,
            0.0144,
            0.0146,
            0.0162,
            0.0274,
            0.0303,
            0.0369,
            0.0509,
            0.0648,
            0.0776,
            0.0917,
            0.0994,
            0.2306,
            0.3142,
            0.3186,
            0.4758,
            0.6686,
            0.8708,
            1.0560,
            1.1996,
            1.2818,
            1.2900,
            1.2818,
            1.1996,
            1.0560,
            0.8708,
            0.6686,
            0.4758,
            0.3173,
            0.2132,
            0.1770,
        ]
        cm_extrap = [
            0.0000,
            0.4000,
            0.2431,
            0.2568,
            0.2865,
            0.3185,
            0.3458,
            0.3632,
            0.3672,
            0.3559,
            0.3443,
            0.3182,
            0.2808,
            0.2362,
            0.1886,
            0.1414,
            0.0942,
            -0.0044,
            -0.0051,
            0.0018,
            -0.0216,
            -0.0282,
            -0.0346,
            -0.0405,
            -0.0455,
            -0.0507,
            -0.0404,
            -0.0321,
            -0.0281,
            -0.0284,
            -0.0322,
            -0.0361,
            -0.0363,
            -0.0393,
            -0.0398,
            -0.0983,
            -0.1242,
            -0.1155,
            -0.1710,
            -0.2202,
            -0.2637,
            -0.3002,
            -0.3284,
            -0.3471,
            -0.3559,
            -0.3672,
            -0.3632,
            -0.3458,
            -0.3185,
            -0.2865,
            -0.2568,
            -0.2431,
            -0.5000,
            0.0000,
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)
        cm = np.interp(alpha_extrap, newpolar.alpha, newpolar.cm)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cm, cm_extrap, atol=5e-3)

    def test_extrap1_w_airfoil(self):

        cdmax = 1.29
        af = Airfoil([self.polar2])
        newaf = af.extrapolate(cdmax=cdmax)
        newpolar = newaf.polars[0]

        alpha_extrap = [
            -180,
            -170,
            -160,
            -150,
            -140,
            -130,
            -120,
            -110,
            -100,
            -90,
            -80,
            -70,
            -60,
            -50,
            -40,
            -30,
            -20,
            -10.1,
            -8.2,
            -6.1,
            -4.1,
            -2.1,
            0.1,
            2,
            4.1,
            6.2,
            8.1,
            10.2,
            11.3,
            12.1,
            13.2,
            14.2,
            15.3,
            16.3,
            17.1,
            18.1,
            19.1,
            20.1,
            30,
            40,
            50,
            60,
            70,
            80,
            90,
            100,
            110,
            120,
            130,
            140,
            150,
            160,
            170,
            180,
        ]
        cl_extrap = [
            0.0000,
            0.2299,
            0.4597,
            0.4907,
            0.5053,
            0.4805,
            0.4102,
            0.2985,
            0.1565,
            0.0000,
            -0.1565,
            -0.2985,
            -0.4102,
            -0.4805,
            -0.5053,
            -0.4907,
            -0.4637,
            -0.6300,
            -0.5600,
            -0.6400,
            -0.4200,
            -0.2100,
            0.0500,
            0.3000,
            0.5400,
            0.7900,
            0.9000,
            0.9300,
            0.9200,
            0.9500,
            0.9900,
            1.0100,
            1.0200,
            1.0000,
            0.9400,
            0.8500,
            0.7000,
            0.6600,
            0.7010,
            0.7219,
            0.6864,
            0.5860,
            0.4264,
            0.2235,
            0.0000,
            -0.1565,
            -0.2985,
            -0.4102,
            -0.4805,
            -0.5053,
            -0.4907,
            -0.4597,
            -0.2299,
            0.0000,
        ]
        cd_extrap = [
            0.1770,
            0.2132,
            0.3173,
            0.4758,
            0.6686,
            0.8708,
            1.0560,
            1.1996,
            1.2818,
            1.2900,
            1.2818,
            1.1996,
            1.0560,
            0.8708,
            0.6686,
            0.4758,
            0.3158,
            0.0390,
            0.0233,
            0.0131,
            0.0134,
            0.0119,
            0.0122,
            0.0116,
            0.0144,
            0.0146,
            0.0162,
            0.0274,
            0.0303,
            0.0369,
            0.0509,
            0.0648,
            0.0776,
            0.0917,
            0.0994,
            0.2306,
            0.3142,
            0.3186,
            0.4758,
            0.6686,
            0.8708,
            1.0560,
            1.1996,
            1.2818,
            1.2900,
            1.2818,
            1.1996,
            1.0560,
            0.8708,
            0.6686,
            0.4758,
            0.3173,
            0.2132,
            0.1770,
        ]
        cm_extrap = np.linspace(0, 0, len(cd_extrap))

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)
        cm = np.interp(alpha_extrap, newpolar.alpha, newpolar.cm)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cm, cm_extrap, atol=5e-3)

    def test_extrap2(self):

        cdmax = 1.0
        newpolar = self.polar.extrapolate(cdmax=cdmax)

        alpha_extrap = [
            -180,
            -170,
            -160,
            -150,
            -140,
            -130,
            -120,
            -110,
            -100,
            -90,
            -80,
            -70,
            -60,
            -50,
            -40,
            -30,
            -20,
            -10.1,
            -8.2,
            -6.1,
            -4.1,
            -2.1,
            0.1,
            2,
            4.1,
            6.2,
            8.1,
            10.2,
            11.3,
            12.1,
            13.2,
            14.2,
            15.3,
            16.3,
            17.1,
            18.1,
            19.1,
            20.1,
            30,
            40,
            50,
            60,
            70,
            80,
            90,
            100,
            110,
            120,
            130,
            140,
            150,
            160,
            170,
            180,
        ]
        cl_extrap = [
            0.0000,
            0.2299,
            0.4597,
            0.4411,
            0.4287,
            0.3943,
            0.3297,
            0.2364,
            0.1225,
            0.0000,
            -0.1225,
            -0.2364,
            -0.3297,
            -0.3943,
            -0.4287,
            -0.4411,
            -0.4637,
            -0.6300,
            -0.5600,
            -0.6400,
            -0.4200,
            -0.2100,
            0.0500,
            0.3000,
            0.5400,
            0.7900,
            0.9000,
            0.9300,
            0.9200,
            0.9500,
            0.9900,
            1.0100,
            1.0200,
            1.0000,
            0.9400,
            0.8500,
            0.7000,
            0.6600,
            0.6302,
            0.6124,
            0.5633,
            0.4710,
            0.3378,
            0.1750,
            0.0000,
            -0.1225,
            -0.2364,
            -0.3297,
            -0.3943,
            -0.4287,
            -0.4411,
            -0.4597,
            -0.2299,
            0.0000,
        ]
        cd_extrap = [
            0.2135,
            0.2404,
            0.3176,
            0.4349,
            0.5767,
            0.7241,
            0.8568,
            0.9560,
            1.0069,
            1.0000,
            1.0069,
            0.9560,
            0.8568,
            0.7241,
            0.5767,
            0.4349,
            0.3158,
            0.0390,
            0.0233,
            0.0131,
            0.0134,
            0.0119,
            0.0122,
            0.0116,
            0.0144,
            0.0146,
            0.0162,
            0.0274,
            0.0303,
            0.0369,
            0.0509,
            0.0648,
            0.0776,
            0.0917,
            0.0994,
            0.2306,
            0.3142,
            0.3186,
            0.4349,
            0.5767,
            0.7241,
            0.8568,
            0.9560,
            1.0069,
            1.0000,
            1.0069,
            0.9560,
            0.8568,
            0.7241,
            0.5767,
            0.4349,
            0.3176,
            0.2404,
            0.2135,
        ]
        cm_extrap = [
            0.0000,
            0.4000,
            0.2432,
            0.2354,
            0.2500,
            0.2695,
            0.2864,
            0.2961,
            0.2956,
            0.2834,
            0.2776,
            0.2603,
            0.2337,
            0.2013,
            0.1663,
            0.1310,
            0.0942,
            -0.0044,
            -0.0051,
            0.0018,
            -0.0216,
            -0.0282,
            -0.0346,
            -0.0405,
            -0.0455,
            -0.0507,
            -0.0404,
            -0.0321,
            -0.0281,
            -0.0284,
            -0.0322,
            -0.0361,
            -0.0363,
            -0.0393,
            -0.0398,
            -0.0983,
            -0.1242,
            -0.1155,
            -0.1577,
            -0.1930,
            -0.2239,
            -0.2494,
            -0.2683,
            -0.2798,
            -0.2834,
            -0.2956,
            -0.2961,
            -0.2864,
            -0.2695,
            -0.2500,
            -0.2354,
            -0.2432,
            -0.5000,
            0.0000,
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)
        cm = np.interp(alpha_extrap, newpolar.alpha, newpolar.cm)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cm, cm_extrap, atol=5e-3)

    def test_extrap3(self):

        cdmax = 1.5
        newpolar = self.polar.extrapolate(cdmax)

        alpha_extrap = [
            -180,
            -170,
            -160,
            -150,
            -140,
            -130,
            -120,
            -110,
            -100,
            -90,
            -80,
            -70,
            -60,
            -50,
            -40,
            -30,
            -20,
            -10.1,
            -8.2,
            -6.1,
            -4.1,
            -2.1,
            0.1,
            2,
            4.1,
            6.2,
            8.1,
            10.2,
            11.3,
            12.1,
            13.2,
            14.2,
            15.3,
            16.3,
            17.1,
            18.1,
            19.1,
            20.1,
            30,
            40,
            50,
            60,
            70,
            80,
            90,
            100,
            110,
            120,
            130,
            140,
            150,
            160,
            170,
            180,
        ]
        cl_extrap = [
            0.0000,
            0.2299,
            0.4597,
            0.5266,
            0.5608,
            0.5429,
            0.4685,
            0.3434,
            0.1810,
            0.0000,
            -0.1810,
            -0.3434,
            -0.4685,
            -0.5429,
            -0.5608,
            -0.5266,
            -0.4637,
            -0.6300,
            -0.5600,
            -0.6400,
            -0.4200,
            -0.2100,
            0.0500,
            0.3000,
            0.5400,
            0.7900,
            0.9000,
            0.9300,
            0.9200,
            0.9500,
            0.9900,
            1.0100,
            1.0200,
            1.0000,
            0.9400,
            0.8500,
            0.7000,
            0.6600,
            0.7523,
            0.8012,
            0.7756,
            0.6693,
            0.4906,
            0.2586,
            0.0000,
            -0.1810,
            -0.3434,
            -0.4685,
            -0.5429,
            -0.5608,
            -0.5266,
            -0.4597,
            -0.2299,
            0.0000,
        ]
        cd_extrap = [
            0.1506,
            0.1936,
            0.3170,
            0.5054,
            0.7351,
            0.9771,
            1.2003,
            1.3760,
            1.4809,
            1.5000,
            1.4809,
            1.3760,
            1.2003,
            0.9771,
            0.7351,
            0.5054,
            0.3158,
            0.0390,
            0.0233,
            0.0131,
            0.0134,
            0.0119,
            0.0122,
            0.0116,
            0.0144,
            0.0146,
            0.0162,
            0.0274,
            0.0303,
            0.0369,
            0.0509,
            0.0648,
            0.0776,
            0.0917,
            0.0994,
            0.2306,
            0.3142,
            0.3186,
            0.5054,
            0.7351,
            0.9771,
            1.2003,
            1.3760,
            1.4809,
            1.5000,
            1.4809,
            1.3760,
            1.2003,
            0.9771,
            0.7351,
            0.5054,
            0.3170,
            0.1936,
            0.1506,
        ]
        cm_extrap = [
            0.0000,
            0.4000,
            0.2431,
            0.2723,
            0.3130,
            0.3540,
            0.3888,
            0.4118,
            0.4190,
            0.4084,
            0.3926,
            0.3602,
            0.3148,
            0.2614,
            0.2049,
            0.1488,
            0.0942,
            -0.0044,
            -0.0051,
            0.0018,
            -0.0216,
            -0.0282,
            -0.0346,
            -0.0405,
            -0.0455,
            -0.0507,
            -0.0404,
            -0.0321,
            -0.0281,
            -0.0284,
            -0.0322,
            -0.0361,
            -0.0363,
            -0.0393,
            -0.0398,
            -0.0983,
            -0.1242,
            -0.1155,
            -0.1807,
            -0.2399,
            -0.2925,
            -0.3370,
            -0.3719,
            -0.3959,
            -0.4084,
            -0.4190,
            -0.4118,
            -0.3888,
            -0.3540,
            -0.3130,
            -0.2723,
            -0.2431,
            -0.5000,
            0.0000,
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)
        cm = np.interp(alpha_extrap, newpolar.alpha, newpolar.cm)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cm, cm_extrap, atol=5e-3)
class TestBlend(unittest.TestCase):
    def setUp(self):
        alpha = [
            -3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11, 6.13,
            7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18, 15.18, 16.17,
            17.14, 18.06, 19.06, 20.07, 25
        ]
        cl = [
            -0.071, 0.044, 0.144, 0.241, 0.338, 0.435, 0.535, 0.632, 0.728,
            0.813, 0.883, 0.946, 1.001, 1.054, 1.056, 1.095, 1.138, 1.114,
            1.073, 1.008, 0.95, 0.902, 0.795, 0.797, 0.8
        ]
        cd = [
            0.0122, 0.0106, 0.0114, 0.0134, 0.0136, 0.014, 0.0147, 0.0156,
            0.0162, 0.0173, 0.0191, 0.0215, 0.0248, 0.0339, 0.0544, 0.0452,
            0.0445, 0.067, 0.0748, 0.1028, 0.1473, 0.2819, 0.2819, 0.2819, 0.3
        ]
        Re = 1

        self.polar1 = Polar(Re, alpha, cl, cd)

        alpha = [
            -3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11, 6.13,
            7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18, 15.189, 16.17,
            17.14, 18.06, 19.06, 20.07, 21.08, 22.09, 23.1, 25
        ]
        cl = [
            -0.0852, 0.0528, 0.1728, 0.2892, 0.4056, 0.522, 0.642, 0.7584,
            0.8736, 0.9756, 1.0596, 1.1352, 1.2012, 1.2648, 1.2672, 1.314,
            1.3656, 1.3368, 1.2876, 1.2096, 1.14, 1.0824, 0.954, 0.9564, 1,
            1.2, 1.4, 1.6
        ]
        cd = [
            0.01464, 0.01272, 0.01368, 0.01608, 0.01632, 0.0168, 0.01764,
            0.01872, 0.01944, 0.02076, 0.02292, 0.0258, 0.02976, 0.04068,
            0.06528, 0.05424, 0.0534, 0.0804, 0.08976, 0.12336, 0.17676,
            0.33828, 0.33828, 0.33828, 0.35, 0.4, 0.45, 0.5
        ]

        self.polar2 = Polar(Re, alpha, cl, cd)

    def test_blend1(self):

        polar3 = self.polar1.blend(self.polar2, 0.5)

        alpha_blend = [
            -3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11, 6.13,
            7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18, 15.18, 16.17,
            17.14, 18.06, 19.06, 20.07, 25
        ]
        cl_blend = [
            -0.078, 0.048, 0.158, 0.265, 0.372, 0.479, 0.589, 0.695, 0.801,
            0.894, 0.971, 1.041, 1.101, 1.159, 1.162, 1.205, 1.252, 1.225,
            1.181, 1.109, 1.045, 0.992, 0.875, 0.877, 1.200
        ]
        cd_blend = [
            0.0134, 0.0117, 0.0125, 0.0147, 0.0150, 0.0154, 0.0162, 0.0172,
            0.0178, 0.0190, 0.0210, 0.0237, 0.0273, 0.0373, 0.0598, 0.0497,
            0.0490, 0.0737, 0.0822, 0.1131, 0.1620, 0.3101, 0.3101, 0.3101,
            0.4000
        ]

        # re-interpolate b/c angles of attack are different
        cl3 = np.interp(alpha_blend, polar3.alpha, polar3.cl)
        cd3 = np.interp(alpha_blend, polar3.alpha, polar3.cd)

        # should be within 1e-3
        np.testing.assert_allclose(cl3, cl_blend, atol=1e-3)
        np.testing.assert_allclose(cd3, cd_blend, atol=1e-3)

    def test_blend1_w_airfoil(self):

        af1 = Airfoil([self.polar1])
        af2 = Airfoil([self.polar2])
        af3 = af1.blend(af2, 0.5)
        polar3 = af3.polars[
            0]  # kind of bad practice for me to be accessing this

        alpha_blend = [
            -3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11, 6.13,
            7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18, 15.18, 16.17,
            17.14, 18.06, 19.06, 20.07, 25
        ]
        cl_blend = [
            -0.078, 0.048, 0.158, 0.265, 0.372, 0.479, 0.589, 0.695, 0.801,
            0.894, 0.971, 1.041, 1.101, 1.159, 1.162, 1.205, 1.252, 1.225,
            1.181, 1.109, 1.045, 0.992, 0.875, 0.877, 1.200
        ]
        cd_blend = [
            0.0134, 0.0117, 0.0125, 0.0147, 0.0150, 0.0154, 0.0162, 0.0172,
            0.0178, 0.0190, 0.0210, 0.0237, 0.0273, 0.0373, 0.0598, 0.0497,
            0.0490, 0.0737, 0.0822, 0.1131, 0.1620, 0.3101, 0.3101, 0.3101,
            0.4000
        ]

        # re-interpolate b/c angles of attack are different
        cl3 = np.interp(alpha_blend, polar3.alpha, polar3.cl)
        cd3 = np.interp(alpha_blend, polar3.alpha, polar3.cd)

        # should be within 1e-3
        np.testing.assert_allclose(cl3, cl_blend, atol=1e-3)
        np.testing.assert_allclose(cd3, cd_blend, atol=1e-3)

    def test_blend2(self):

        polar3 = self.polar1.blend(self.polar2, 0.7)

        alpha_blend = [
            -3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11, 6.13,
            7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18, 15.18, 16.17,
            17.14, 18.06, 19.06, 20.07, 25
        ]
        cl_blend = [
            -0.081, 0.050, 0.164, 0.275, 0.385, 0.496, 0.610, 0.720, 0.830,
            0.927, 1.007, 1.078, 1.141, 1.202, 1.204, 1.248, 1.297, 1.270,
            1.224, 1.149, 1.083, 1.028, 0.906, 0.909, 1.360
        ]
        cd_blend = [
            0.0139, 0.0121, 0.0130, 0.0153, 0.0155, 0.0160, 0.0168, 0.0178,
            0.0185, 0.0197, 0.0218, 0.0245, 0.0283, 0.0386, 0.0620, 0.0515,
            0.0507, 0.0764, 0.0852, 0.1172, 0.1679, 0.3214, 0.3214, 0.3214,
            0.4400
        ]

        # re-interpolate b/c angles of attack are different
        cl3 = np.interp(alpha_blend, polar3.alpha, polar3.cl)
        cd3 = np.interp(alpha_blend, polar3.alpha, polar3.cd)

        # should be within 1e-3
        np.testing.assert_allclose(cl3, cl_blend, atol=1e-3)
        np.testing.assert_allclose(cd3, cd_blend, atol=1e-3)

    def test_blend3(self):

        polar3 = self.polar1.blend(self.polar2, 0.2)

        alpha_blend = [
            -3.04, -2.03, -1.01, 0.01, 1.03, 2.05, 3.07, 4.09, 5.11, 6.13,
            7.14, 8.16, 9.17, 10.18, 11.18, 12.19, 13.18, 14.18, 15.18, 16.17,
            17.14, 18.06, 19.06, 20.07, 25
        ]
        cl_blend = [
            -0.074, 0.046, 0.150, 0.251, 0.352, 0.452, 0.556, 0.657, 0.757,
            0.846, 0.918, 0.984, 1.041, 1.096, 1.098, 1.139, 1.184, 1.159,
            1.116, 1.048, 0.988, 0.938, 0.827, 0.829, 0.960
        ]
        cd_blend = [
            0.0127, 0.0110, 0.0119, 0.0139, 0.0141, 0.0146, 0.0153, 0.0162,
            0.0168, 0.0180, 0.0199, 0.0224, 0.0258, 0.0353, 0.0566, 0.0470,
            0.0463, 0.0697, 0.0778, 0.1069, 0.1532, 0.2932, 0.2932, 0.2932,
            0.3400
        ]

        # re-interpolate b/c angles of attack are different
        cl3 = np.interp(alpha_blend, polar3.alpha, polar3.cl)
        cd3 = np.interp(alpha_blend, polar3.alpha, polar3.cd)

        # should be within 1e-3
        np.testing.assert_allclose(cl3, cl_blend, atol=1e-3)
        np.testing.assert_allclose(cd3, cd_blend, atol=1e-3)
Exemple #17
0
class TestExtrap(unittest.TestCase):
    def setUp(self):

        alpha = [
            -10.1, -8.2, -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2, 11.3,
            12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1
        ]
        cl = [
            -0.6300, -0.5600, -0.6400, -0.4200, -0.2100, 0.0500, 0.3000,
            0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100,
            1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600
        ]
        cd = [
            0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116, 0.0144,
            0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648, 0.0776,
            0.0917, 0.0994, 0.2306, 0.3142, 0.3186
        ]
        cm = [
            -0.0044, -0.0051, 0.0018, -0.0216, -0.0282, -0.0346, -0.0405,
            -0.0455, -0.0507, -0.0404, -0.0321, -0.0281, -0.0284, -0.0322,
            -0.0361, -0.0363, -0.0393, -0.0398, -0.0983, -0.1242, -0.1155
        ]
        cm_zeros = np.zeros(len(cm))
        Re = 1
        self.polar = Polar(Re, alpha, cl, cd, cm)
        self.polar2 = Polar(Re, alpha, cl, cd, cm_zeros)

    def test_extrap1(self):

        cdmax = 1.29
        newpolar = self.polar.extrapolate(cdmax=cdmax)

        alpha_extrap = [
            -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80,
            -70, -60, -50, -40, -30, -20, -10.1, -8.2, -6.1, -4.1, -2.1, 0.1,
            2, 4.1, 6.2, 8.1, 10.2, 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1,
            18.1, 19.1, 20.1, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130,
            140, 150, 160, 170, 180
        ]
        cl_extrap = [
            0.0000, 0.2299, 0.4597, 0.4907, 0.5053, 0.4805, 0.4102, 0.2985,
            0.1565, 0.0000, -0.1565, -0.2985, -0.4102, -0.4805, -0.5053,
            -0.4907, -0.4637, -0.6300, -0.5600, -0.6400, -0.4200, -0.2100,
            0.0500, 0.3000, 0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500,
            0.9900, 1.0100, 1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600,
            0.7010, 0.7219, 0.6864, 0.5860, 0.4264, 0.2235, 0.0000, -0.1565,
            -0.2985, -0.4102, -0.4805, -0.5053, -0.4907, -0.4597, -0.2299,
            0.0000
        ]
        cd_extrap = [
            0.1770, 0.2132, 0.3173, 0.4758, 0.6686, 0.8708, 1.0560, 1.1996,
            1.2818, 1.2900, 1.2818, 1.1996, 1.0560, 0.8708, 0.6686, 0.4758,
            0.3158, 0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116,
            0.0144, 0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648,
            0.0776, 0.0917, 0.0994, 0.2306, 0.3142, 0.3186, 0.4758, 0.6686,
            0.8708, 1.0560, 1.1996, 1.2818, 1.2900, 1.2818, 1.1996, 1.0560,
            0.8708, 0.6686, 0.4758, 0.3173, 0.2132, 0.1770
        ]
        cm_extrap = [
            0.0000, 0.4000, 0.2431, 0.2568, 0.2865, 0.3185, 0.3458, 0.3632,
            0.3672, 0.3559, 0.3443, 0.3182, 0.2808, 0.2362, 0.1886, 0.1414,
            0.0942, -0.0044, -0.0051, 0.0018, -0.0216, -0.0282, -0.0346,
            -0.0405, -0.0455, -0.0507, -0.0404, -0.0321, -0.0281, -0.0284,
            -0.0322, -0.0361, -0.0363, -0.0393, -0.0398, -0.0983, -0.1242,
            -0.1155, -0.1710, -0.2202, -0.2637, -0.3002, -0.3284, -0.3471,
            -0.3559, -0.3672, -0.3632, -0.3458, -0.3185, -0.2865, -0.2568,
            -0.2431, -0.5000, 0.0000
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)
        cm = np.interp(alpha_extrap, newpolar.alpha, newpolar.cm)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cm, cm_extrap, atol=5e-3)

    def test_extrap1_w_airfoil(self):

        cdmax = 1.29
        af = Airfoil([self.polar2])
        newaf = af.extrapolate(cdmax=cdmax)
        newpolar = newaf.polars[0]

        alpha_extrap = [
            -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80,
            -70, -60, -50, -40, -30, -20, -10.1, -8.2, -6.1, -4.1, -2.1, 0.1,
            2, 4.1, 6.2, 8.1, 10.2, 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1,
            18.1, 19.1, 20.1, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130,
            140, 150, 160, 170, 180
        ]
        cl_extrap = [
            0.0000, 0.2299, 0.4597, 0.4907, 0.5053, 0.4805, 0.4102, 0.2985,
            0.1565, 0.0000, -0.1565, -0.2985, -0.4102, -0.4805, -0.5053,
            -0.4907, -0.4637, -0.6300, -0.5600, -0.6400, -0.4200, -0.2100,
            0.0500, 0.3000, 0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500,
            0.9900, 1.0100, 1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600,
            0.7010, 0.7219, 0.6864, 0.5860, 0.4264, 0.2235, 0.0000, -0.1565,
            -0.2985, -0.4102, -0.4805, -0.5053, -0.4907, -0.4597, -0.2299,
            0.0000
        ]
        cd_extrap = [
            0.1770, 0.2132, 0.3173, 0.4758, 0.6686, 0.8708, 1.0560, 1.1996,
            1.2818, 1.2900, 1.2818, 1.1996, 1.0560, 0.8708, 0.6686, 0.4758,
            0.3158, 0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116,
            0.0144, 0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648,
            0.0776, 0.0917, 0.0994, 0.2306, 0.3142, 0.3186, 0.4758, 0.6686,
            0.8708, 1.0560, 1.1996, 1.2818, 1.2900, 1.2818, 1.1996, 1.0560,
            0.8708, 0.6686, 0.4758, 0.3173, 0.2132, 0.1770
        ]
        cm_extrap = np.linspace(0, 0, len(cd_extrap))

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)
        cm = np.interp(alpha_extrap, newpolar.alpha, newpolar.cm)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cm, cm_extrap, atol=5e-3)

    def test_extrap2(self):

        cdmax = 1.0
        newpolar = self.polar.extrapolate(cdmax=cdmax)

        alpha_extrap = [
            -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80,
            -70, -60, -50, -40, -30, -20, -10.1, -8.2, -6.1, -4.1, -2.1, 0.1,
            2, 4.1, 6.2, 8.1, 10.2, 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1,
            18.1, 19.1, 20.1, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130,
            140, 150, 160, 170, 180
        ]
        cl_extrap = [
            0.0000, 0.2299, 0.4597, 0.4411, 0.4287, 0.3943, 0.3297, 0.2364,
            0.1225, 0.0000, -0.1225, -0.2364, -0.3297, -0.3943, -0.4287,
            -0.4411, -0.4637, -0.6300, -0.5600, -0.6400, -0.4200, -0.2100,
            0.0500, 0.3000, 0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500,
            0.9900, 1.0100, 1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600,
            0.6302, 0.6124, 0.5633, 0.4710, 0.3378, 0.1750, 0.0000, -0.1225,
            -0.2364, -0.3297, -0.3943, -0.4287, -0.4411, -0.4597, -0.2299,
            0.0000
        ]
        cd_extrap = [
            0.2135, 0.2404, 0.3176, 0.4349, 0.5767, 0.7241, 0.8568, 0.9560,
            1.0069, 1.0000, 1.0069, 0.9560, 0.8568, 0.7241, 0.5767, 0.4349,
            0.3158, 0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116,
            0.0144, 0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648,
            0.0776, 0.0917, 0.0994, 0.2306, 0.3142, 0.3186, 0.4349, 0.5767,
            0.7241, 0.8568, 0.9560, 1.0069, 1.0000, 1.0069, 0.9560, 0.8568,
            0.7241, 0.5767, 0.4349, 0.3176, 0.2404, 0.2135
        ]
        cm_extrap = [
            0.0000, 0.4000, 0.2432, 0.2354, 0.2500, 0.2695, 0.2864, 0.2961,
            0.2956, 0.2834, 0.2776, 0.2603, 0.2337, 0.2013, 0.1663, 0.1310,
            0.0942, -0.0044, -0.0051, 0.0018, -0.0216, -0.0282, -0.0346,
            -0.0405, -0.0455, -0.0507, -0.0404, -0.0321, -0.0281, -0.0284,
            -0.0322, -0.0361, -0.0363, -0.0393, -0.0398, -0.0983, -0.1242,
            -0.1155, -0.1577, -0.1930, -0.2239, -0.2494, -0.2683, -0.2798,
            -0.2834, -0.2956, -0.2961, -0.2864, -0.2695, -0.2500, -0.2354,
            -0.2432, -0.5000, 0.0000
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)
        cm = np.interp(alpha_extrap, newpolar.alpha, newpolar.cm)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cm, cm_extrap, atol=5e-3)

    def test_extrap3(self):

        cdmax = 1.5
        newpolar = self.polar.extrapolate(cdmax)

        alpha_extrap = [
            -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80,
            -70, -60, -50, -40, -30, -20, -10.1, -8.2, -6.1, -4.1, -2.1, 0.1,
            2, 4.1, 6.2, 8.1, 10.2, 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1,
            18.1, 19.1, 20.1, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130,
            140, 150, 160, 170, 180
        ]
        cl_extrap = [
            0.0000, 0.2299, 0.4597, 0.5266, 0.5608, 0.5429, 0.4685, 0.3434,
            0.1810, 0.0000, -0.1810, -0.3434, -0.4685, -0.5429, -0.5608,
            -0.5266, -0.4637, -0.6300, -0.5600, -0.6400, -0.4200, -0.2100,
            0.0500, 0.3000, 0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500,
            0.9900, 1.0100, 1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600,
            0.7523, 0.8012, 0.7756, 0.6693, 0.4906, 0.2586, 0.0000, -0.1810,
            -0.3434, -0.4685, -0.5429, -0.5608, -0.5266, -0.4597, -0.2299,
            0.0000
        ]
        cd_extrap = [
            0.1506, 0.1936, 0.3170, 0.5054, 0.7351, 0.9771, 1.2003, 1.3760,
            1.4809, 1.5000, 1.4809, 1.3760, 1.2003, 0.9771, 0.7351, 0.5054,
            0.3158, 0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116,
            0.0144, 0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648,
            0.0776, 0.0917, 0.0994, 0.2306, 0.3142, 0.3186, 0.5054, 0.7351,
            0.9771, 1.2003, 1.3760, 1.4809, 1.5000, 1.4809, 1.3760, 1.2003,
            0.9771, 0.7351, 0.5054, 0.3170, 0.1936, 0.1506
        ]
        cm_extrap = [
            0.0000, 0.4000, 0.2431, 0.2723, 0.3130, 0.3540, 0.3888, 0.4118,
            0.4190, 0.4084, 0.3926, 0.3602, 0.3148, 0.2614, 0.2049, 0.1488,
            0.0942, -0.0044, -0.0051, 0.0018, -0.0216, -0.0282, -0.0346,
            -0.0405, -0.0455, -0.0507, -0.0404, -0.0321, -0.0281, -0.0284,
            -0.0322, -0.0361, -0.0363, -0.0393, -0.0398, -0.0983, -0.1242,
            -0.1155, -0.1807, -0.2399, -0.2925, -0.3370, -0.3719, -0.3959,
            -0.4084, -0.4190, -0.4118, -0.3888, -0.3540, -0.3130, -0.2723,
            -0.2431, -0.5000, 0.0000
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)
        cm = np.interp(alpha_extrap, newpolar.alpha, newpolar.cm)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cm, cm_extrap, atol=5e-3)
class TestExtrap(unittest.TestCase):
    def setUp(self):

        alpha = [
            -10.1, -8.2, -6.1, -4.1, -2.1, 0.1, 2, 4.1, 6.2, 8.1, 10.2, 11.3,
            12.1, 13.2, 14.2, 15.3, 16.3, 17.1, 18.1, 19.1, 20.1
        ]
        cl = [
            -0.6300, -0.5600, -0.6400, -0.4200, -0.2100, 0.0500, 0.3000,
            0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500, 0.9900, 1.0100,
            1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600
        ]
        cd = [
            0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116, 0.0144,
            0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648, 0.0776,
            0.0917, 0.0994, 0.2306, 0.3142, 0.3186
        ]
        Re = 1
        self.polar = Polar(Re, alpha, cl, cd)

    def test_extrap1(self):

        cdmax = 1.29
        newpolar = self.polar.extrapolate(cdmax=cdmax)

        alpha_extrap = [
            -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80,
            -70, -60, -50, -40, -30, -20, -10.1, -8.2, -6.1, -4.1, -2.1, 0.1,
            2, 4.1, 6.2, 8.1, 10.2, 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1,
            18.1, 19.1, 20.1, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130,
            140, 150, 160, 170, 180
        ]
        cl_extrap = [
            0.0000, 0.2299, 0.4597, 0.4907, 0.5053, 0.4805, 0.4102, 0.2985,
            0.1565, 0.0000, -0.1565, -0.2985, -0.4102, -0.4805, -0.5053,
            -0.4907, -0.4637, -0.6300, -0.5600, -0.6400, -0.4200, -0.2100,
            0.0500, 0.3000, 0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500,
            0.9900, 1.0100, 1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600,
            0.7010, 0.7219, 0.6864, 0.5860, 0.4264, 0.2235, 0.0000, -0.1565,
            -0.2985, -0.4102, -0.4805, -0.5053, -0.4907, -0.4597, -0.2299,
            0.0000
        ]
        cd_extrap = [
            0.1770, 0.2132, 0.3173, 0.4758, 0.6686, 0.8708, 1.0560, 1.1996,
            1.2818, 1.2900, 1.2818, 1.1996, 1.0560, 0.8708, 0.6686, 0.4758,
            0.3158, 0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116,
            0.0144, 0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648,
            0.0776, 0.0917, 0.0994, 0.2306, 0.3142, 0.3186, 0.4758, 0.6686,
            0.8708, 1.0560, 1.1996, 1.2818, 1.2900, 1.2818, 1.1996, 1.0560,
            0.8708, 0.6686, 0.4758, 0.3173, 0.2132, 0.1770
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)

    def test_extrap1_w_airfoil(self):

        cdmax = 1.29
        af = Airfoil([self.polar])
        newaf = af.extrapolate(cdmax=cdmax)
        newpolar = newaf.polars[0]

        alpha_extrap = [
            -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80,
            -70, -60, -50, -40, -30, -20, -10.1, -8.2, -6.1, -4.1, -2.1, 0.1,
            2, 4.1, 6.2, 8.1, 10.2, 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1,
            18.1, 19.1, 20.1, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130,
            140, 150, 160, 170, 180
        ]
        cl_extrap = [
            0.0000, 0.2299, 0.4597, 0.4907, 0.5053, 0.4805, 0.4102, 0.2985,
            0.1565, 0.0000, -0.1565, -0.2985, -0.4102, -0.4805, -0.5053,
            -0.4907, -0.4637, -0.6300, -0.5600, -0.6400, -0.4200, -0.2100,
            0.0500, 0.3000, 0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500,
            0.9900, 1.0100, 1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600,
            0.7010, 0.7219, 0.6864, 0.5860, 0.4264, 0.2235, 0.0000, -0.1565,
            -0.2985, -0.4102, -0.4805, -0.5053, -0.4907, -0.4597, -0.2299,
            0.0000
        ]
        cd_extrap = [
            0.1770, 0.2132, 0.3173, 0.4758, 0.6686, 0.8708, 1.0560, 1.1996,
            1.2818, 1.2900, 1.2818, 1.1996, 1.0560, 0.8708, 0.6686, 0.4758,
            0.3158, 0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116,
            0.0144, 0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648,
            0.0776, 0.0917, 0.0994, 0.2306, 0.3142, 0.3186, 0.4758, 0.6686,
            0.8708, 1.0560, 1.1996, 1.2818, 1.2900, 1.2818, 1.1996, 1.0560,
            0.8708, 0.6686, 0.4758, 0.3173, 0.2132, 0.1770
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)

    def test_extrap2(self):

        cdmax = 1.0
        newpolar = self.polar.extrapolate(cdmax=cdmax)

        alpha_extrap = [
            -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80,
            -70, -60, -50, -40, -30, -20, -10.1, -8.2, -6.1, -4.1, -2.1, 0.1,
            2, 4.1, 6.2, 8.1, 10.2, 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1,
            18.1, 19.1, 20.1, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130,
            140, 150, 160, 170, 180
        ]
        cl_extrap = [
            0.0000, 0.2299, 0.4597, 0.4411, 0.4287, 0.3943, 0.3297, 0.2364,
            0.1225, 0.0000, -0.1225, -0.2364, -0.3297, -0.3943, -0.4287,
            -0.4411, -0.4637, -0.6300, -0.5600, -0.6400, -0.4200, -0.2100,
            0.0500, 0.3000, 0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500,
            0.9900, 1.0100, 1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600,
            0.6302, 0.6124, 0.5633, 0.4710, 0.3378, 0.1750, 0.0000, -0.1225,
            -0.2364, -0.3297, -0.3943, -0.4287, -0.4411, -0.4597, -0.2299,
            0.0000
        ]
        cd_extrap = [
            0.2135, 0.2404, 0.3176, 0.4349, 0.5767, 0.7241, 0.8568, 0.9560,
            1.0069, 1.0000, 1.0069, 0.9560, 0.8568, 0.7241, 0.5767, 0.4349,
            0.3158, 0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116,
            0.0144, 0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648,
            0.0776, 0.0917, 0.0994, 0.2306, 0.3142, 0.3186, 0.4349, 0.5767,
            0.7241, 0.8568, 0.9560, 1.0069, 1.0000, 1.0069, 0.9560, 0.8568,
            0.7241, 0.5767, 0.4349, 0.3176, 0.2404, 0.2135
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)

    def test_extrap3(self):

        cdmax = 1.5
        newpolar = self.polar.extrapolate(cdmax)

        alpha_extrap = [
            -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80,
            -70, -60, -50, -40, -30, -20, -10.1, -8.2, -6.1, -4.1, -2.1, 0.1,
            2, 4.1, 6.2, 8.1, 10.2, 11.3, 12.1, 13.2, 14.2, 15.3, 16.3, 17.1,
            18.1, 19.1, 20.1, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130,
            140, 150, 160, 170, 180
        ]
        cl_extrap = [
            0.0000, 0.2299, 0.4597, 0.5266, 0.5608, 0.5429, 0.4685, 0.3434,
            0.1810, 0.0000, -0.1810, -0.3434, -0.4685, -0.5429, -0.5608,
            -0.5266, -0.4637, -0.6300, -0.5600, -0.6400, -0.4200, -0.2100,
            0.0500, 0.3000, 0.5400, 0.7900, 0.9000, 0.9300, 0.9200, 0.9500,
            0.9900, 1.0100, 1.0200, 1.0000, 0.9400, 0.8500, 0.7000, 0.6600,
            0.7523, 0.8012, 0.7756, 0.6693, 0.4906, 0.2586, 0.0000, -0.1810,
            -0.3434, -0.4685, -0.5429, -0.5608, -0.5266, -0.4597, -0.2299,
            0.0000
        ]
        cd_extrap = [
            0.1506, 0.1936, 0.3170, 0.5054, 0.7351, 0.9771, 1.2003, 1.3760,
            1.4809, 1.5000, 1.4809, 1.3760, 1.2003, 0.9771, 0.7351, 0.5054,
            0.3158, 0.0390, 0.0233, 0.0131, 0.0134, 0.0119, 0.0122, 0.0116,
            0.0144, 0.0146, 0.0162, 0.0274, 0.0303, 0.0369, 0.0509, 0.0648,
            0.0776, 0.0917, 0.0994, 0.2306, 0.3142, 0.3186, 0.5054, 0.7351,
            0.9771, 1.2003, 1.3760, 1.4809, 1.5000, 1.4809, 1.3760, 1.2003,
            0.9771, 0.7351, 0.5054, 0.3170, 0.1936, 0.1506
        ]

        # re-interpolate b/c angles of attack are different
        cl = np.interp(alpha_extrap, newpolar.alpha, newpolar.cl)
        cd = np.interp(alpha_extrap, newpolar.alpha, newpolar.cd)

        # test equality
        np.testing.assert_allclose(cl, cl_extrap, atol=1.5e-4)
        np.testing.assert_allclose(cd, cd_extrap, atol=1.5e-4)
class Test3DStall(unittest.TestCase):
    def setUp(self):
        alpha = [
            -9.000, -8.000, -7.000, -6.000, -5.000, -4.000, -3.000, -2.000,
            -1.000, 0.000, 1.000, 2.000, 3.000, 4.000, 5.000, 6.000, 7.000,
            8.000, 9.000, 10.000, 11.000, 12.000, 13.000, 14.000, 15.000,
            16.000, 17.000, 18.000, 19.000, 20.000, 30.000, 40.000, 50.000
        ]
        cl = [
            -0.802, -0.721, -0.611, -0.506, -0.408, -0.313, -0.220, -0.133,
            -0.060, 0.036, 0.227, 0.342, 0.436, 0.556, 0.692, 0.715, 0.761,
            0.830, 0.893, 0.954, 1.013, 1.042, 1.061, 1.083, 1.078, 0.882,
            0.811, 0.793, 0.793, 0.798, 0.772, 0.757, 0.700
        ]
        cd = [
            0.027, 0.025, 0.024, 0.023, 0.022, 0.022, 0.023, 0.025, 0.027,
            0.028, 0.024, 0.019, 0.017, 0.015, 0.017, 0.019, 0.021, 0.024,
            0.027, 0.031, 0.037, 0.046, 0.058, 0.074, 0.088, 0.101, 0.114,
            0.128, 0.142, 0.155, 0.321, 0.525, 0.742
        ]

        Re = 1

        self.polar = Polar(Re, alpha, cl, cd)

    def test_stall1(self):
        R = 2.4
        r = 0.25 * R
        chord = 0.18
        Omega = 200 * pi / 30
        Uinf = 10.0
        tsr = Omega * R / Uinf

        newpolar = self.polar.correction3D(r / R,
                                           chord / r,
                                           tsr,
                                           alpha_max_corr=30,
                                           alpha_linear_min=-4,
                                           alpha_linear_max=4)

        cl_3d = [
            -0.8466, -0.7523, -0.6420, -0.5342, -0.4302, -0.3284, -0.2276,
            -0.1303, -0.0404, 0.0618, 0.2191, 0.3321, 0.4336, 0.5501, 0.6755,
            0.7363, 0.8101, 0.8973, 0.9810, 1.0640, 1.1450, 1.2098, 1.2682,
            1.3281, 1.3731, 1.3088, 1.3159, 1.3534, 1.4010, 1.4515, 1.9140,
            1.8857, 1.6451
        ]
        cd_3d = [
            0.0399, 0.0334, 0.0316, 0.0293, 0.0269, 0.0254, 0.0246, 0.0246,
            0.0246, 0.0252, 0.0249, 0.0200, 0.0167, 0.0157, 0.0174, 0.0183,
            0.0212, 0.0255, 0.0303, 0.0367, 0.0465, 0.0615, 0.0800, 0.1047,
            0.1301, 0.1695, 0.2047, 0.2384, 0.2728, 0.3081, 0.8097, 1.2625,
            1.6280
        ]

        # test equality
        np.testing.assert_allclose(newpolar.cl, cl_3d, atol=1e-3)
        np.testing.assert_allclose(newpolar.cd, cd_3d, atol=1e-3)

    def test_stall1_w_airfoil(self):
        R = 2.4
        r = 0.25 * R
        chord = 0.18
        Omega = 200 * pi / 30
        Uinf = 10.0
        tsr = Omega * R / Uinf

        af = Airfoil([self.polar])
        newaf = af.correction3D(r / R,
                                chord / r,
                                tsr,
                                alpha_max_corr=30,
                                alpha_linear_min=-4,
                                alpha_linear_max=4)

        newpolar = newaf.polars[0]

        cl_3d = [
            -0.8466, -0.7523, -0.6420, -0.5342, -0.4302, -0.3284, -0.2276,
            -0.1303, -0.0404, 0.0618, 0.2191, 0.3321, 0.4336, 0.5501, 0.6755,
            0.7363, 0.8101, 0.8973, 0.9810, 1.0640, 1.1450, 1.2098, 1.2682,
            1.3281, 1.3731, 1.3088, 1.3159, 1.3534, 1.4010, 1.4515, 1.9140,
            1.8857, 1.6451
        ]
        cd_3d = [
            0.0399, 0.0334, 0.0316, 0.0293, 0.0269, 0.0254, 0.0246, 0.0246,
            0.0246, 0.0252, 0.0249, 0.0200, 0.0167, 0.0157, 0.0174, 0.0183,
            0.0212, 0.0255, 0.0303, 0.0367, 0.0465, 0.0615, 0.0800, 0.1047,
            0.1301, 0.1695, 0.2047, 0.2384, 0.2728, 0.3081, 0.8097, 1.2625,
            1.6280
        ]

        # test equality
        np.testing.assert_allclose(newpolar.cl, cl_3d, atol=1e-3)
        np.testing.assert_allclose(newpolar.cd, cd_3d, atol=1e-3)

    def test_stall2(self):
        R = 2.4
        r = 0.75 * R
        chord = 0.28
        Omega = 200 * pi / 30
        Uinf = 14.0
        tsr = Omega * R / Uinf

        newpolar = self.polar.correction3D(r / R,
                                           chord / r,
                                           tsr,
                                           alpha_max_corr=30,
                                           alpha_linear_min=-4,
                                           alpha_linear_max=4)

        cl_3d = [
            -0.81340155, -0.72876051, -0.61903798, -0.51322348, -0.41336822,
            -0.31696485, -0.22214149, -0.13269893, -0.05485453, 0.04222704,
            0.22525537, 0.33917483, 0.43518608, 0.55464051, 0.68785835,
            0.72023796, 0.77302335, 0.84665343, 0.91485674, 0.98191931,
            1.04592758, 1.08446883, 1.11313747, 1.14423161, 1.15194066,
            0.98921407, 0.93776667, 0.93384528, 0.94558296, 0.96199091,
            1.05910388, 1.04054486, 0.93735382
        ]
        cd_3d = [
            0.03050922, 0.02712935, 0.02589588, 0.02453937, 0.02341344,
            0.02320787, 0.02359745, 0.02497252, 0.02653913, 0.02751806,
            0.02430795, 0.01935093, 0.01663156, 0.01552516, 0.01698944,
            0.01853615, 0.02107760, 0.02443710, 0.02784230, 0.03217433,
            0.03929881, 0.05021192, 0.06322801, 0.08159739, 0.09837902,
            0.11798276, 0.13692472, 0.15565820, 0.17470667, 0.19368328,
            0.44408310, 0.71034295, 0.96437541
        ]

        # test equality
        np.testing.assert_allclose(newpolar.cl, cl_3d, atol=1e-3)
        np.testing.assert_allclose(newpolar.cd, cd_3d, atol=1e-3)

    def test_stall3(self):
        R = 5.0
        r = 0.5 * R
        chord = 0.5
        Omega = 100 * pi / 30
        Uinf = 10.0
        tsr = Omega * R / Uinf

        newpolar = self.polar.correction3D(r / R,
                                           chord / r,
                                           tsr,
                                           alpha_max_corr=30,
                                           alpha_linear_min=-4,
                                           alpha_linear_max=4)

        cl_3d = [
            -0.8240, -0.7363, -0.6264, -0.5199, -0.4188, -0.3206, -0.2239,
            -0.1319, -0.0502, 0.0485, 0.2233, 0.3369, 0.4347, 0.5532, 0.6839,
            0.7254, 0.7849, 0.8629, 0.9361, 1.0082, 1.0777, 1.1246, 1.1628,
            1.2031, 1.2228, 1.0916, 1.0589, 1.0682, 1.0914, 1.1188, 1.3329,
            1.3112, 1.1640
        ]
        cd_3d = [
            0.0335, 0.0291, 0.0277, 0.0261, 0.0245, 0.0239, 0.0239, 0.0249,
            0.0259, 0.0268, 0.0245, 0.0195, 0.0167, 0.0156, 0.0171, 0.0185,
            0.0211, 0.0248, 0.0286, 0.0336, 0.0416, 0.0538, 0.0686, 0.0890,
            0.1085, 0.1345, 0.1586, 0.1822, 0.2061, 0.2303, 0.5612, 0.8872,
            1.1769
        ]

        # test equality
        np.testing.assert_allclose(newpolar.cl, cl_3d, atol=1e-3)
        np.testing.assert_allclose(newpolar.cd, cd_3d, atol=1e-3)
Exemple #20
0
    0.996, 1.046, 1.095, 1.145, 1.192, 1.239, 1.283, 1.324, 1.358, 1.385,
    1.403, 1.401, 1.358, 1.313, 1.287, 1.274, 1.272, 1.273, 1.273, 1.273,
    1.272, 1.273, 1.275, 1.281, 1.284, 1.296, 1.306, 1.308, 1.308, 1.308,
    1.308, 1.307, 1.311, 1.325
]
cd = [
    0.0567, 0.0271, 0.0303, 0.0287, 0.0124, 0.0109, 0.0092, 0.0083, 0.0089,
    0.0082, 0.0074, 0.0069, 0.0065, 0.0063, 0.0061, 0.0058, 0.0057, 0.0057,
    0.0057, 0.0057, 0.0057, 0.0057, 0.0057, 0.0058, 0.0058, 0.0059, 0.0061,
    0.0063, 0.0066, 0.0071, 0.0079, 0.0090, 0.0103, 0.0113, 0.0122, 0.0131,
    0.0139, 0.0147, 0.0158, 0.0181, 0.0211, 0.0255, 0.0301, 0.0347, 0.0401,
    0.0468, 0.0545, 0.0633, 0.0722, 0.0806, 0.0900, 0.0987, 0.1075, 0.1170,
    0.1270, 0.1368, 0.1464, 0.1562, 0.1664, 0.1770, 0.1878, 0.1987, 0.2100
]

p1 = Polar(Re, alpha, cl, cd)

# second polar
Re = 9e6
alpha = [
    -14.24, -13.24, -12.22, -11.22, -10.19, -9.70, -9.18, -8.18, -7.19, -6.65,
    -6.13, -6.00, -5.50, -5.00, -4.50, -4.00, -3.50, -3.00, -2.50, -2.00,
    -1.50, -1.00, -0.50, 0.00, 0.50, 1.00, 1.50, 2.00, 2.50, 3.00, 3.50, 4.00,
    4.50, 5.00, 5.50, 6.00, 6.50, 7.00, 7.50, 8.00, 9.00, 9.50, 10.00, 10.50,
    11.00, 11.50, 12.00, 12.50, 13.00, 13.50, 14.00, 14.50, 15.00, 15.50,
    16.00, 16.50, 17.00, 17.50, 18.00, 18.50, 19.00
]
cl = [
    -1.229, -1.148, -1.052, -0.965, -0.867, -0.822, -0.769, -0.756, -0.690,
    -0.616, -0.542, -0.525, -0.451, -0.382, -0.314, -0.251, -0.189, -0.120,
    -0.051, 0.017, 0.085, 0.152, 0.219, 0.288, 0.354, 0.421, 0.487, 0.554,
    def solve_nonlinear(self, params, unknowns, resids):

        # determine aspect ratio = (rotor radius / chord_75% radius)\
        #    if provided, cdmax is computed from AR'
        bl = params['blade_length']
        dr = params['rotor_diameter']
        hr = 0.5 * dr - bl
        rotor_radius = 0.5 * dr
        chord = params['chord_st'] * bl
        s = params['s_st']
        r = (s * bl + hr) / rotor_radius
        chord_75 = np.interp(0.75, r, chord)
        AR = rotor_radius / chord_75

        # write aerodyn files
        af_name_base = 'cs_'
        af_name_suffix = '_aerodyn'
        tcs = params['cs_polars_tc']

        n_cs_alpha = params['n_cs_alpha']
        pol = params['cs_polars']
        nmet = 0
        # TODO: blend polars determined with different methods
        for i, tc in enumerate(self.blend_var):
            af_name = af_name_base + \
                '%03d_%04d' % (i, tc * 1000) + af_name_suffix
            re_polars = []
            for nre, re in enumerate(self.res):
                # create polar object
                p = Polar(re,
                          pol[:n_cs_alpha[i, nre, nmet], 0, i, nre, nmet],
                          pol[:n_cs_alpha[i, nre, nmet], 1, i, nre, nmet],
                          pol[:n_cs_alpha[i, nre, nmet], 2, i, nre, nmet],
                          pol[:n_cs_alpha[i, nre, nmet], 3, i, nre, nmet])

                # extrapolate polar
                if tc < self.tc_max:
                    p_extrap = p.extrapolate(self.cdmax,
                                             AR,
                                             self.cdmin,
                                             self.nalpha)
                else:
                    p_extrap = p.extrapolate_as_cylinder()
                p_extrap.useCM = self.useCM
                re_polars.append(p_extrap)

                # TODO: output as HAWC2/FAST format
                # See if HAWC can take several af tables with different Re
                # numbers
                '''
                unknowns['airfoildata:aoa%02d' % i] = p_extrap.alpha
                unknowns['airfoildata:cl%02d' % i] = p_extrap.cl
                unknowns['airfoildata:cd%02d' % i] = p_extrap.cd
                unknowns['airfoildata:cm%02d' % i] = p_extrap.cm
                '''

            # create airfoil object
            af = Airfoil(re_polars)
            af.interpToCommonAlpha()
            af.writeToAerodynFile(af_name + '.dat')

            if self.plot_polars:
                figs = af.plot(single_figure=True)
                titles = ['cl', 'cd', 'cm']
                for (fig, title) in zip(figs, titles):
                    fig.savefig(af_name + '_' + title + '.png', dpi=400)
                    fig.savefig(af_name + '_' + title + '.pdf')

        self._get_unknowns(unknowns)