diff --git a/wetb/prepost/hawcstab2.py b/wetb/prepost/hawcstab2.py index 5d630e929b31eab836a357f799c2c29642c18b9c..62f812f4b2002e50b1e6e6aa65af506da77611de 100644 --- a/wetb/prepost/hawcstab2.py +++ b/wetb/prepost/hawcstab2.py @@ -410,9 +410,16 @@ class ReadControlTuning(object): def __init__(self): """ """ - pass + self._aerogains = False def parse_line(self, line, controller): + """Parses the output lines with the controller tuning parameters. + Does not parse the aerodynamic gain lines. + """ + + if line.startswith('Aerodynamic gains'): + self._aerogains = True + return split1 = line.split('=') var1 = split1[0].strip() @@ -449,8 +456,21 @@ class ReadControlTuning(object): elif i == 10: controller = 'aero_damp' setattr(self, controller, dummy()) - else: + elif not self._aerogains: self.parse_line(line, controller) + # do not break since we want to see if aero gains are included + # elif self._aerogains: + # break + + self.aero_gains_units = ['[deg]', '[kNm/deg]', '[kNm/deg]', + '[kNm/(rad/s)]', '[kNm/(rad/s)]'] + self.aero_gains = pd.DataFrame() + # in case the gains are missing from the file, don't try to read it + if i > 17: + arr = np.loadtxt(fpath, skiprows=17) + columns = ['theta', 'dq/dtheta', 'dq/dtheta_fit', 'dq/domega', + 'dq/domega_fit'] + self.aero_gains = pd.DataFrame(arr, columns=columns) # set some parameters to zero for the linear case, or when aerodynamic # gain scheduling is not used diff --git a/wetb/prepost/tests/data/controller_input_quadratic.txt b/wetb/prepost/tests/data/controller_input_quadratic.txt index 062781f61b1750095b78c74865637282accd90ea..4b883b2a078f0bc3549bdace48445ea9a58b08c6 100644 --- a/wetb/prepost/tests/data/controller_input_quadratic.txt +++ b/wetb/prepost/tests/data/controller_input_quadratic.txt @@ -11,3 +11,22 @@ K1 = 7.30949 [deg], K2 = 1422.81187 [deg^2] (dq/dtheta = -176.489 Additional terms due to the Aerodynamic damping Kp2 = 0.240394E-01 [rad/(rad/s)] Ko1 = -1.69769 [deg], Ko2 = -15.02688 [deg^2] (dq/domega = 243.08924 kNm/(rad/s)) +******************************************** +Aerodynamic gains: +******************************************** + (1) theta [deg] (2) dq/dtheta [kNm/deg] (3) fit [kNm/deg] (4) dq/domega [kNm/(rad/s)] (5) fit [kNm/(rad/s)] + 0.00000 -1165.04860 -1182.80164 -393.03157 -950.85937 + 4.10000 -1665.72575 -1655.44826 -6919.03943 -6544.84749 + 6.69000 -2012.86015 -1998.12171 -13119.30826 -12659.67192 + 8.62000 -2290.61883 -2275.67536 -18911.31597 -18515.75425 + 10.26000 -2535.50152 -2526.42508 -24632.87239 -24364.04365 + 11.74000 -2757.11114 -2764.46364 -30186.31522 -30329.61030 + 13.10000 -2991.31463 -2993.03195 -36257.79933 -36386.82912 + 14.38000 -3213.58048 -3216.75546 -42410.93450 -42591.10977 + 15.59000 -3428.46978 -3435.91220 -48626.47812 -48904.89826 + 16.76000 -3642.91400 -3654.91116 -55070.40445 -55424.76312 + 17.88000 -3858.46084 -3871.07886 -61702.38984 -62048.05630 + 18.97000 -4075.53879 -4087.58722 -68581.71761 -68852.77188 + 20.03000 -4295.29300 -4303.93692 -75700.65394 -75809.68369 + 21.05000 -4524.66782 -4517.52214 -83045.36607 -82820.10608 + 22.05000 -4758.62680 -4732.06052 -90639.34883 -89993.97031 diff --git a/wetb/prepost/tests/test_hawcstab2.py b/wetb/prepost/tests/test_hawcstab2.py index f1fb229cf213a3e0a2499b2bd5127bf02acd3fe8..20c95d440c6c572e3af55e9c2b779aede464d63c 100644 --- a/wetb/prepost/tests/test_hawcstab2.py +++ b/wetb/prepost/tests/test_hawcstab2.py @@ -71,6 +71,8 @@ class Tests(unittest.TestCase): self.assertEqual(hs2.aero_damp.Ko1, -4.21472) self.assertEqual(hs2.aero_damp.Ko2, 0.0) + self.assertEqual(hs2.aero_gains.shape, (0, 0)) + def test_quadratic_file(self): hs2 = ReadControlTuning() @@ -91,6 +93,38 @@ class Tests(unittest.TestCase): self.assertEqual(hs2.aero_damp.Ko1, -1.69769) self.assertEqual(hs2.aero_damp.Ko2, -15.02688) + self.assertEqual(hs2.aero_gains.shape, (15, 5)) + cols = ['theta', 'dq/dtheta', 'dq/dtheta_fit', 'dq/domega', + 'dq/domega_fit'] + self.assertEqual(hs2.aero_gains.columns.tolist(), cols) + + tmp = np.array([0, 4.1, 6.69, 8.62, 10.26, 11.74, 13.1, 14.38, 15.59, + 16.76, 17.88, 18.97, 20.03, 21.05, 22.05]) + np.testing.assert_allclose(hs2.aero_gains['theta'].values, tmp) + + tmp = [-1165.0486, -1665.72575, -2012.86015, -2290.61883, + -2535.50152, -2757.11114, -2991.31463, -3213.58048, + -3428.46978, -3642.914, -3858.46084, -4075.53879, + -4295.293, -4524.66782, -4758.6268] + np.testing.assert_allclose(hs2.aero_gains['dq/dtheta'].values, tmp) + + tmp = [-1182.80164, -1655.44826, -1998.12171, -2275.67536, -2526.42508, + -2764.46364, -2993.03195, -3216.75546, -3435.9122, -3654.91116, + -3871.07886, -4087.58722, -4303.93692, -4517.52214, -4732.06052] + np.testing.assert_allclose(hs2.aero_gains['dq/dtheta_fit'].values, tmp) + + tmp = [-393.03157, -6919.03943, -13119.30826, -18911.31597, + -24632.87239, -30186.31522, -36257.79933, -42410.9345, + -48626.47812, -55070.40445, -61702.38984, -68581.71761, + -75700.65394, -83045.36607, -90639.34883] + np.testing.assert_allclose(hs2.aero_gains['dq/domega'].values, tmp) + + tmp = [-950.85937, -6544.84749, -12659.67192, -18515.75425, + -24364.04365, -30329.6103, -36386.82912, -42591.10977, + -48904.89826, -55424.76312, -62048.0563, -68852.77188, + -75809.68369, -82820.10608, -89993.97031] + np.testing.assert_allclose(hs2.aero_gains['dq/domega_fit'].values, tmp) + def test_ind_file(self): fnames = ['dtu10mw_nofull_defl_u10000.ind', 'dtu10mw_nofull_fext_u10000.ind', @@ -108,7 +142,7 @@ class Tests(unittest.TestCase): res = results() df_data = res.load_ind(fname) data = np.loadtxt(fname) - np.testing.assert_almost_equal(data, df_data.values) + np.testing.assert_allclose(data, df_data.values) def test_pwr_file(self): fnames = ['dtu10mw_nofull.pwr', @@ -121,19 +155,7 @@ class Tests(unittest.TestCase): df_data, units = res.load_pwr_df(fname) data = np.loadtxt(fname) self.assertEqual(data.shape, df_data.shape) - print(fname) - print(data.dtype) - print(df_data.values.dtype) - for i in range(data.shape[0]): - a = data[i,:] - b = df_data.values[i,:] - if not np.allclose(a,b): - print(i) - print(a-b) - print(a) - print(b) - np.testing.assert_almost_equal(a, b) - np.testing.assert_almost_equal(data, df_data.values, decimal=6) + np.testing.assert_allclose(data, df_data.values) if __name__ == "__main__":