diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000000000000000000000000000000000000..4e1a67de478323f278a7e6f43449d3c8093d68bc --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +omit = */Colonel/* \ No newline at end of file diff --git a/topfarm/example_data/__init__.py b/tests/test_constraint/__init__.py similarity index 100% rename from topfarm/example_data/__init__.py rename to tests/test_constraint/__init__.py diff --git a/tests/test_constraint/test_PolygonBoundaryComp.py b/tests/test_constraint/test_PolygonBoundaryComp.py new file mode 100644 index 0000000000000000000000000000000000000000..76945f2ee5e7b0caf20dba8d2caf87a3f84e5470 --- /dev/null +++ b/tests/test_constraint/test_PolygonBoundaryComp.py @@ -0,0 +1,105 @@ +import unittest + +import numpy as np +from topfarm.cost_models.dummy import DummyCost, DummyCostPlotComp +from topfarm import TopFarm +from topfarm.constraint_components.boundary_component import PolygonBoundaryComp + + +class TestPolygonBoundaryComp(unittest.TestCase): + + def testPolygon(self): + boundary = [(0, 0), (1, 1), (2, 0), (2, 2), (0, 2)] + pbc = PolygonBoundaryComp(boundary, 1) + np.testing.assert_array_equal(pbc.vertices, [[0, 0], + [1, 1], + [2, 0], + [2, 2], + [0, 2]]) + + def testPolygon_StartEqEnd(self): + boundary = [(0, 0), (1, 1), (2, 0), (2, 2), (0, 2), (0, 0)] + pbc = PolygonBoundaryComp(boundary, 1) + np.testing.assert_array_equal(pbc.vertices, [[0, 0], + [1, 1], + [2, 0], + [2, 2], + [0, 2]]) + + def testPolygon_Clockwise(self): + boundary = [(0, 0), (0, 2), (2, 2), (2, 0), (1, 1)] + pbc = PolygonBoundaryComp(boundary, 1) + np.testing.assert_array_equal(pbc.vertices, [[0, 0], + [1, 1], + [2, 0], + [2, 2], + [0, 2]]) + + def testPolygon_StartEqEndClockwise(self): + boundary = [(0, 0), (0, 2), (2, 2), (2, 0), (1, 1), (0, 0)] + pbc = PolygonBoundaryComp(boundary, 1) + np.testing.assert_array_equal(pbc.vertices, [[0, 0], + [1, 1], + [2, 0], + [2, 2], + [0, 2]]) + + def check(self, boundary, points, distances): + pbc = PolygonBoundaryComp(boundary, 1) + d, dx, dy = pbc.calc_distance_and_gradients(points[:, 0], points[:, 1]) + np.testing.assert_array_almost_equal(d, distances) + eps = 1e-7 + d1, _, _ = pbc.calc_distance_and_gradients(points[:, 0] + eps, points[:, 1]) + np.testing.assert_array_almost_equal((d1 - d) / eps, dx) + d2, _, _ = pbc.calc_distance_and_gradients(points[:, 0], points[:, 1] + eps) + np.testing.assert_array_almost_equal((d2 - d) / eps, dy) + + def test_calc_distance_edge(self): + boundary = np.array([(0, 0), (1, 0), (2, 1), (0, 2), (0, 0)]) + points = np.array([(0.5, .2), (1, .5), (.5, 1.5), (.2, 1)]) + self.check(boundary, points, [0.2, np.sqrt(2 * .25**2), .5 * np.sin(np.arctan(.5)), 0.2]) + + def test_calc_distance_edge_outside(self): + boundary = np.array([(0, 0), (1, 0), (2, 1), (0, 2), (0, 0)]) + points = np.array([(0.5, -.2), (1.5, 0), (.5, 2), (-.2, 1)]) + self.check(boundary, points, [-0.2, -np.sqrt(2 * .25**2), -.5 * np.sin(np.arctan(.5)), -0.2]) + + def test_calc_distance_point_vertical(self): + boundary = np.array([(0, 0), (1, 1), (2, 0), (2, 2), (0, 2), (0, 0)]) + points = np.array([(.8, 1), (.8, 1.2), (1, 1.2), (1.1, 1.2), (1.2, 1.2), (1.2, 1)]) + self.check(boundary, points, [np.sqrt(.2**2 / 2), np.sqrt(2 * .2**2), .2, + np.sqrt(.1**2 + .2**2), np.sqrt(2 * .2**2), np.sqrt(.2**2 / 2)]) + + def test_calc_distance_point_vertical_outside(self): + boundary = np.array([(0, 0), (1, 1), (2, 0), (0, 0)]) + points = np.array([(.8, 1), (.8, 1.2), (1, 1.2), (1.1, 1.2), (1.2, 1.2), (1.2, 1)]) + + self.check(boundary, points, [-np.sqrt(.2**2 / 2), -np.sqrt(2 * .2**2), -.2, + -np.sqrt(.1**2 + .2**2), -np.sqrt(2 * .2**2), -np.sqrt(.2**2 / 2)]) + + def test_calc_distance_point_horizontal(self): + boundary = np.array([(0, 0), (2, 0), (1, 1), (2, 2), (0, 2), (0, 0)]) + points = np.array([(1, .8), (.8, .8), (.8, 1), (.8, 1.1), (.8, 1.2), (1, 1.2)]) + self.check(boundary, points, [np.sqrt(.2**2 / 2), np.sqrt(2 * .2**2), .2, + np.sqrt(.1**2 + .2**2), np.sqrt(2 * .2**2), np.sqrt(.2**2 / 2)]) + + def testPolygon_Line(self): + boundary = [(0, 0), (0, 2)] + self.assertRaisesRegex(AssertionError, "Area must be non-zero", PolygonBoundaryComp, boundary, 1) + + def test_calc_distance_U_shape(self): + boundary = np.array([(0, 0), (3, 0), (3, 2), (2, 2), (2, 1), (1, 1), (1, 2), (0, 2)]) + points = np.array([(-.1, 1.5), (.1, 1.5), (.9, 1.5), (1.1, 1.5), (1.5, 1.5), (1.9, 1.5), (2.1, 1.5), (2.9, 1.5), (3.1, 1.5)]) + self.check(boundary, points, [-.1, .1, .1, -.1, -.5, -.1, .1, .1, -.1]) + + def test_calc_distance_V_shape(self): + boundary = np.array([(0, 0), (1, 2), (2, 0), (2, 2), (1, 4), (0, 2)]) + points = np.array([(.8, 2), (.8, 2.2), (1, 2.2), (1.2, 2.2), (1.2, 2), (.8, 4), (.8, 4.2), (1, 4.2), (1.2, 4.2), (1.2, 4)]) + v1 = np.sqrt(.2**2 * 4 / 5) + v2 = np.sqrt(2 * .2**2) + self.check(boundary, points, [v1, v2, .2, v2, v1, -v1, -v2, -.2, -v2, -v1]) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() diff --git a/tests/test_constraint/test_boundary.py b/tests/test_constraint/test_boundary.py new file mode 100644 index 0000000000000000000000000000000000000000..665116027bdb2c76da8a63f0c5a927bad2b64f32 --- /dev/null +++ b/tests/test_constraint/test_boundary.py @@ -0,0 +1,48 @@ +import unittest + +import numpy as np +from topfarm.cost_models.dummy import DummyCost, DummyCostPlotComp +from topfarm import TopFarm + + +class TestBoundary(unittest.TestCase): + + def testSquare(self): + optimal = [(0, 0)] + boundary = [(0, 0), (1, 3)] + tf = TopFarm(optimal, DummyCost(optimal), 2, boundary=boundary, boundary_type='square') + np.testing.assert_array_equal(tf.boundary, [[-1, 0], + [2, 0], + [2, 3], + [-1, 3], + [-1, 0]]) + + def testRectangle(self): + optimal = [(0, 0)] + boundary = [(0, 0), (1, 3)] + tf = TopFarm(optimal, DummyCost(optimal), 2, boundary=boundary, boundary_type='rectangle') + np.testing.assert_array_equal(tf.boundary, [[0, 0], + [1, 0], + [1, 3], + [0, 3], + [0, 0]]) + + def testConvexHull(self): + optimal = [(0, 0)] + boundary = [(0, 0), (1, 1), (2, 0), (2, 2), (0, 2)] + tf = TopFarm(optimal, DummyCost(optimal), 2, boundary=boundary, boundary_type='convex_hull') + np.testing.assert_array_equal(tf.boundary, [[0, 0], + [2, 0], + [2, 2], + [0, 2], + [0, 0]]) + + def testNotImplemented(self): + optimal = [(0, 0)] + boundary = [(0, 0), (1, 1), (2, 0), (2, 2), (0, 2)] + self.assertRaisesRegex(NotImplementedError, "Boundary type 'Something' is not implemented", TopFarm, optimal, DummyCost(optimal), 2, boundary=boundary, boundary_type='Something') + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() diff --git a/tests/test_constraint/test_boundary_polygon.py b/tests/test_constraint/test_boundary_polygon.py new file mode 100644 index 0000000000000000000000000000000000000000..a94f6401c2d3e391b805010a590c7f3578aa844d --- /dev/null +++ b/tests/test_constraint/test_boundary_polygon.py @@ -0,0 +1,48 @@ +import unittest + +import numpy as np +from topfarm.cost_models.dummy import DummyCost, DummyCostPlotComp +from topfarm import TopFarm +from topfarm.constraint_components.boundary_component import PolygonBoundaryComp +from topfarm.plotting import NoPlot, PlotComp + + +class TestBoundaryPolygon(unittest.TestCase): + + def testPolygon(self): + optimal = [(0, 0)] + boundary = [(0, 0), (1, 1), (2, 0), (2, 2), (0, 2)] + tf = TopFarm(optimal, DummyCost(optimal), 2, boundary=boundary, boundary_type='polygon') + np.testing.assert_array_equal(tf.boundary, [[0, 0], + [1, 1], + [2, 0], + [2, 2], + [0, 2], + [0, 0]]) + + def testPolygonConcave(self): + optimal = [(1.5, 1.3), (4, 1)] + boundary = [(0, 0), (5, 0), (5, 2), (3, 2), (3, 1), (2, 1), (2, 2), (0, 2), (0, 0)] + plot_comp = NoPlot() # DummyCostPlotComp(optimal) + initial = [(-0, .1), (4, 1.5)][::-1] + tf = TopFarm(initial, DummyCost(optimal), 0, boundary=boundary, boundary_type='polygon', plot_comp=plot_comp) + tf.evaluate() + tf.optimize() + np.testing.assert_array_almost_equal(tf.turbine_positions, optimal, 4) + plot_comp.show() + + def testPolygonTwoRegionsStartInWrong(self): + optimal = [(1, 1), (4, 1)] + boundary = [(0, 0), (5, 0), (5, 2), (3, 2), (3, 0), (2, 0), (2, 2), (0, 2), (0, 0)] + plot_comp = NoPlot() # DummyCostPlotComp(optimal, delay=.1) + initial = [(3.5, 1.5), (2, 1)] + tf = TopFarm(initial, DummyCost(optimal), 0, boundary=boundary, boundary_type='polygon', plot_comp=plot_comp) + tf.evaluate() + tf.optimize() + plot_comp.show() + np.testing.assert_array_almost_equal(tf.turbine_positions, optimal, 4) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() diff --git a/tests/test_costmodel_utils/__init__.py b/tests/test_costmodel_utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/test_costmodel_utils/test_aep_calculator.py b/tests/test_costmodel_utils/test_aep_calculator.py new file mode 100644 index 0000000000000000000000000000000000000000..88823c6e569e524309b438e335887e7a7f72743d --- /dev/null +++ b/tests/test_costmodel_utils/test_aep_calculator.py @@ -0,0 +1,31 @@ +''' +Created on 17. maj 2018 + +@author: mmpe +''' +import unittest + +import numpy as np +from topfarm.cost_models.utils.wind_resource import WindResource +from tests.test_files import testfilepath +from topfarm.cost_models.fused_wake_wrappers import FusedWakeGCLWakeModel +from topfarm.cost_models.utils.aep_calculator import AEPCalculator + + +class TestAEPCalculator(unittest.TestCase): + + def test_AEPCalculator(self): + f = [1,0,0,0] + A = [9.176929,10,10,10] + k = [2.392578,2,2,2] + wr = WindResource(np.array(f), A, k, ti=np.zeros_like(f) + .1) + wf_3tb = testfilepath + "wind_farms/3tb.yml" + wm = FusedWakeGCLWakeModel(wf_3tb) + aep_calc = AEPCalculator(wr, wm) + + self.assertAlmostEqual(aep_calc(np.array([[-1600, 0, 1600], [0, 0, 0]]).T), 22.3178800761) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() diff --git a/tests/test_costmodel_utils/test_cost_model_wrappers.py b/tests/test_costmodel_utils/test_cost_model_wrappers.py new file mode 100644 index 0000000000000000000000000000000000000000..26ed94ee99da93777f3fed1b7189e6ba2c95ff35 --- /dev/null +++ b/tests/test_costmodel_utils/test_cost_model_wrappers.py @@ -0,0 +1,59 @@ +''' +Created on 17. maj 2018 + +@author: mmpe +''' +import unittest +import numpy as np +from topfarm.cost_models.dummy import DummyCost +from topfarm.cost_models.cost_model_wrappers import CostModelComponent,\ + AEPCostModelComponent +from topfarm import TopFarm + + +class TestCostModelWrappers(unittest.TestCase): + def setUp(self): + unittest.TestCase.setUp(self) + self.boundary = [(0, 0), (6, 0), (6, -10), (0, -10)] # turbine boundaries + self.initial = [[6, 0], [6, -8], [1, 1], [-1, -8]] # initial turbine layouts + self.optimal_with_constraints = np.array([[2.5, -3], [6, -7], [4.5, -3], [3, -7]]) # optimal turbine layout + self.min_spacing = 2 # min distance between turbines + self.optimal = np.array([[3, -3], [7, -7], [4, -3], [3, -7]]) # desired turbine layouts + + def cost(self, pos): + x, y = pos.T + opt_x, opt_y = self.optimal.T + return np.sum((x - opt_x)**2 + (y - opt_y)**2) + + def aep_cost(self, pos): + x, y = pos.T + opt_x, opt_y = self.optimal.T + return -np.sum((x - opt_x)**2 + (y - opt_y)**2) + + def gradients(self, pos): + x, y = pos.T + return (2 * x - 2 * self.optimal[:, 0]), (2 * y - 2 * self.optimal[:, 1]) + + def aep_gradients(self, pos): + x, y = pos.T + return -(2 * x - 2 * self.optimal[:, 0]), -(2 * y - 2 * self.optimal[:, 1]) + + def testCostModelComponent(self): + tf = TopFarm(self.initial, CostModelComponent(4, self.cost, self.gradients), self.min_spacing, boundary=self.boundary) + tf.optimize() + np.testing.assert_array_almost_equal(tf.turbine_positions, self.optimal_with_constraints, 5) + + def testCostModelComponent_no_gradients(self): + tf = TopFarm(self.initial, CostModelComponent(4, self.cost), self.min_spacing, boundary=self.boundary) + tf.optimize() + np.testing.assert_array_almost_equal(tf.turbine_positions, self.optimal_with_constraints, 5) + + def testAEPCostModelComponent(self): + tf = TopFarm(self.initial, AEPCostModelComponent(4, self.aep_cost, self.aep_gradients), self.min_spacing, boundary=self.boundary) + tf.optimize() + np.testing.assert_array_almost_equal(tf.turbine_positions, self.optimal_with_constraints, 5) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() diff --git a/tests/test_costmodel_utils/test_wind_resource.py b/tests/test_costmodel_utils/test_wind_resource.py new file mode 100644 index 0000000000000000000000000000000000000000..c4341609610594088e26ca73ba60f3fc045e82a8 --- /dev/null +++ b/tests/test_costmodel_utils/test_wind_resource.py @@ -0,0 +1,26 @@ +''' +Created on 17. maj 2018 + +@author: mmpe +''' +import unittest +import numpy as np +from topfarm.cost_models.utils.wind_resource import WindResource + + +class TestWindResource(unittest.TestCase): + + def test_WindResource(self): + f = [0.035972, 0.039487, 0.051674, 0.070002, 0.083645, 0.064348, 0.086432, 0.117705, 0.151576, 0.147379, 0.10012, 0.05166] + A = [9.176929, 9.782334, 9.531809, 9.909545, 10.04269, 9.593921, 9.584007, 10.51499, 11.39895, 11.68746, 11.63732, 10.08803] + k = [2.392578, 2.447266, 2.412109, 2.591797, 2.755859, 2.595703, 2.583984, 2.548828, 2.470703, 2.607422, 2.626953, 2.326172] + ti = np.zeros_like(f) + .1 + wr = WindResource(f, A, k, ti) + + wdir, ws, ti, weight = wr([0], [0], [4, 5]) + np.testing.assert_array_almost_equal(weight, np.array([[0.071381703], [0.088361194]]) * 0.035972 * (12 / 360)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testWindResource'] + unittest.main() diff --git a/tests/test_files/wind_farms/3tb.yml b/tests/test_files/wind_farms/3tb.yml new file mode 100644 index 0000000000000000000000000000000000000000..0da0d247ac528b3c91e0e310ef48abbfe96a965b --- /dev/null +++ b/tests/test_files/wind_farms/3tb.yml @@ -0,0 +1,143 @@ +layout: + - name: WT01 + row: 1 + position: [0, 160] + turbine_type: V80 + - name: WT02 + row: 2 + position: [0, 0] + turbine_type: V80 + - name: WT03 + row: 3 + position: [0, -160] + turbine_type: V80 + +metmasts: + - name: M2 + position: [423412, 6153342] # <- wrong location!! please find the right one and make a pull request + - name: M6 + position: [431255, 6149504] + - name: M7 + position: [435252, 6149494] + +plant_data: + utm: + code: 32 + letter: U + name: Horns Rev + owner: DONG Energy, Vattenfall + +turbine_types: + # Sources: + # [1] https://windbench.net/system/files/hornsrev_v80_0.pdf + # [2] http://www.thewindpower.net/turbine_en_30_vestas_2000.php + # [3] http://en.wind-turbine-models.com/turbines/668-vestas-v-80-offshore + # [4] WAsP wind turbine library (distributed as part of the WAsP software) + - name: V80 + hub_height: 70.0 # [1] + rotor_diameter: 80.0 # [1] + rated_power: 2000.0 # [1] + cut_in_wind_speed: 4.0 # [1] + cut_out_wind_speed: 25.0 # [1] + rated_wind_speed: 16.0 # [1] + wind_class: IEC Ia (DIBt III) # [2] + air_density: 1.225 # guess + gear_box: + speed_number: 3 + ratio: 1:100,5 # [2] + type: spur/planetary # [3] + nacelle: # [2] + weight: 68000.0 # kg [2], 69000.0 kg according to [3] + rotor: # [2, 3] + weight: 37000.0 # kg [2] + tip_speed: 80.0 # m/s [3] + min_speed: 9 # rd/min [2] + max_speed: 19 # rd/min [2] + manufacturer: Vestas + hub: + weight: 18000 # kg [3] + tower: # [2] + weight: 198000.0 #kg [2], max 148000.0 kg according to [3] + material: steel + manufacturer: Welcon + control: # [1] + type: Active Pitch, Variable Speed + generator: # [2] + type: ASYNC + number: 1 + max_output_speed: 1909 #rounds/minute + output_voltage: 690 #V + grid_frequency: 50/60 # Hz + power_curve: # [1] + - [3.0, 0.0] + - [4.0, 66.6] + - [5.0, 154.0] + - [6.0, 282.0] + - [7.0, 460.0] + - [8.0, 696.0] + - [9.0, 996.0] + - [10.0, 1341.0] + - [11.0, 1661.0] + - [12.0, 1866.0] + - [13.0, 1958.0] + - [14.0, 1988.0] + - [15.0, 1997.0] + - [16.0, 1999.0] + - [17.0, 2000.0] + - [18.0, 2000.0] + - [19.0, 2000.0] + - [20.0, 2000.0] + - [21.0, 2000.0] + - [22.0, 2000.0] + - [23.0, 2000.0] + - [24.0, 2000.0] + - [25.0, 2000.0] + c_t_curve: + - [3.0, 0.00] + - [4.0, 0.818] + - [5.0, 0.806] + - [6.0, 0.804] + - [7.0, 0.805] + - [8.0, 0.806] + - [9.0, 0.807] + - [10.0, 0.793] + - [11.0, 0.739] + - [12.0, 0.709] + - [13.0, 0.409] + - [14.0, 0.314] + - [15.0, 0.249] + - [16.0, 0.202] + - [17.0, 0.167] + - [18.0, 0.140] + - [19.0, 0.119] + - [20.0, 0.102] + - [21.0, 0.088] + - [22.0, 0.077] + - [23.0, 0.067] + - [24.0, 0.060] + - [25.0, 0.053] + c_t_idle: 0.053 # [4] + blade: + geometry: # [1] + # [radius [m], c [m], twist [deg], airfoil ] + - [2.563, 2.004, 9.50, 'Cylinder 1'] + - [4.389, 2.523, 9.50, 'Cylinder 1'] + - [6.216, 3.015, 9.50, 'FFA W3-301'] + - [8.042, 3.278, 9.50, 'FFA W3-301'] + - [9.868, 3.309, 9.50, 'FFA W3-301'] + - [11.694, 3.195, 9.50, 'FFA W3-301'] + - [13.520, 3.039, 9.22, 'FFA W3-241'] + - [15.346, 2.863, 7.81, 'FFA W3-211'] + - [17.173, 2.687, 6.40, 'FFA W3-211'] + - [18.999, 2.511, 5.11, 'FFA W3-211'] + - [20.825, 2.334, 3.83, 'FFA W3-211'] + - [22.651, 2.158, 2.61, 'NACA 63-221'] + - [24.477, 1.982, 1.48, 'NACA 63-221'] + - [26.304, 1.806, 0.42, 'NACA 63-221'] + - [28.130, 1.630, 0.49, 'NACA 63-221'] + - [29.956, 1.454, 1.23, 'NACA 63-218'] + - [31.782, 1.278, 1.79, 'NACA 63-218'] + - [33.608, 1.102, 2.24, 'NACA 63-218'] + - [35.435, 0.926, 2.61, 'NACA 63-218'] + - [37.261, 0.749, 2.84, 'NACA 63-218'] + - [39.087, 0.573, 2.97, 'NACA 63-218'] \ No newline at end of file diff --git a/tests/test_fuga/test_pyfuga.py b/tests/test_fuga/test_pyfuga.py index dd4cb10ab1b44f6bda36d85fc0d72f8472f9364c..a388cdd4e3170b6dde605fa7b6ebc6ffb6081018 100644 --- a/tests/test_fuga/test_pyfuga.py +++ b/tests/test_fuga/test_pyfuga.py @@ -15,6 +15,7 @@ from topfarm.cost_models.fuga.py_fuga import PyFuga import os from topfarm.cost_models.fuga import py_fuga import sys +from topfarm._topfarm import TopFarm fuga_path = os.path.abspath(os.path.dirname(py_fuga.__file__)) + '/Colonel/' @@ -38,10 +39,10 @@ class Test(unittest.TestCase): def lib_missing(self): lib_path = os.path.dirname(py_fuga.__file__) + "/Colonel/FugaLib/FugaLib.%s" % ('so', 'dll')[os.name == 'nt'] - + if os.path.isfile(lib_path) is False: pytest.xfail("Fugalib missing") - raise Warning("Fugalib '%s' not found\n"%lib_path) + raise Warning("Fugalib '%s' not found\n" % lib_path) return False def get_fuga(self, tb_x=[423974, 424033], tb_y=[6151447, 6150889]): @@ -97,6 +98,23 @@ class Test(unittest.TestCase): [0.000000e+00, 0.000000e+00]]) pyFuga.cleanup() + def testAEP_topfarm(self): + if self.lib_missing(): + return + pyFuga = self.get_fuga() + init_pos = [[0, 0], [200, 0]] + tf = TopFarm(init_pos, pyFuga.get_TopFarm_cost_component(), 160, init_pos, boundary_type='square') + tf.evaluate() + np.testing.assert_array_almost_equal(tf.get_cost(), -14.866138) + + def test_pyfuga_cmd(self): + if self.lib_missing(): + return + pyFuga = PyFuga() + pyFuga.execute(r'echo "ColonelInit"') + self.assertEqual(pyFuga.log.strip().split("\n")[-1], 'ColonelInit') + + # def test_parallel(self): # from multiprocessing import Pool # diff --git a/tests/test_fusedwake_models/__init__.py b/tests/test_fusedwake_models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/test_fusedwake_models/test_gcl.py b/tests/test_fusedwake_models/test_gcl.py new file mode 100644 index 0000000000000000000000000000000000000000..c393bd18295780c1f09100dbbf08c56b4d8e70fd --- /dev/null +++ b/tests/test_fusedwake_models/test_gcl.py @@ -0,0 +1,43 @@ +import os +import unittest + +import numpy as np +from topfarm.cost_models.fused_wake_wrappers import FusedWakeGCLWakeModel +from topfarm.cost_models.utils.aep_calculator import AEPCalculator +from topfarm.cost_models.utils.wind_resource import WindResource +from tests.test_files import tfp +from topfarm._topfarm import TopFarm + + +class TestFusedWakeModels(unittest.TestCase): # unittest version + + def test_GCL(self): + # f, A, k = read_lib(fuga_path + 'LUT/Farms/Horns Rev 1\hornsrev_north_only_pm45.lib') + f = [1.0, 0.0, 0.0, 0.0] + A = [9.176929, 9.782334, 9.531809, 9.909545] + k = [2.392578, 2.447266, 2.412109, 2.591797] + + wr = WindResource(f, A, k, ti=np.zeros_like(f) + .1) + wm = FusedWakeGCLWakeModel(tfp + "wind_farms/3tb.yml") + aep_calc = AEPCalculator(wr, wm) + init_pos = wm.windFarm.pos.T + self.assertEqual(aep_calc(init_pos), 19.85973533524627) + self.assertEqual(aep_calc(np.array([[-500, 0, 500], [0, 0, 0]]).T), 22.31788007605505) + + def test_GCL_Topfarm(self): + # f, A, k = read_lib(fuga_path + 'LUT/Farms/Horns Rev 1\hornsrev_north_only_pm45.lib') + f = [1.0, 0.0, 0.0, 0.0] + A = [9.176929, 9.782334, 9.531809, 9.909545] + k = [2.392578, 2.447266, 2.412109, 2.591797] + + wr = WindResource(f, A, k, ti=np.zeros_like(f) + .1) + wm = FusedWakeGCLWakeModel(tfp + "wind_farms/3tb.yml") + aep_calc = AEPCalculator(wr, wm) + init_pos = wm.windFarm.pos.T + tf = TopFarm(init_pos, aep_calc.get_TopFarm_cost_component(), 160, init_pos, boundary_type='square') + tf.evaluate() + self.assertEqual(tf.get_cost(), -19.85973533524627) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_topfarm.py b/tests/test_topfarm.py new file mode 100644 index 0000000000000000000000000000000000000000..dde9a1f5cf89dfd004f3b793ac874d91a4f2057b --- /dev/null +++ b/tests/test_topfarm.py @@ -0,0 +1,49 @@ +''' +Created on 17. maj 2018 + +@author: mmpe +''' +from topfarm import TopFarm +import unittest + +import numpy as np +from topfarm.cost_models.dummy import DummyCost +from topfarm.cost_models.cost_model_wrappers import CostModelComponent + + +class TestTopFarm(unittest.TestCase): + def setUp(self): + unittest.TestCase.setUp(self) + self.boundary = [(0, 0), (6, 0), (6, -10), (0, -10)] # turbine boundaries + self.initial = [[6, 0], [6, -8], [1, 1], [-1, -8]] # initial turbine layouts + self.optimal_with_constraints = np.array([[2.5, -3], [6, -7], [4.5, -3], [3, -7]]) # optimal turbine layout + self.min_spacing = 2 # min distance between turbines + self.optimal = np.array([[3, -3], [7, -7], [4, -3], [3, -7]]) # desired turbine layouts + + def cost(self, pos): + x, y = pos.T + opt_x, opt_y = self.optimal.T + return np.sum((x - opt_x)**2 + (y - opt_y)**2) + + def gradients(self, pos): + x, y = pos.T + return (2 * x - 2 * self.optimal[:, 0]), (2 * y - 2 * self.optimal[:, 1]) + + def wrong_gradients(self, pos): + x, y = pos.T + return (2 * x - 2 * self.optimal[:, 0] + 1), (2 * y - 2 * self.optimal[:, 1]) + + def testTopFarm_default_plotcomp(self): + tf = TopFarm(self.initial, CostModelComponent(4, self.cost, self.gradients), self.min_spacing, boundary=self.boundary, plot_comp='default') + + def testTopFarm_check_gradients(self): + tf = TopFarm(self.initial, CostModelComponent(4, self.cost, self.gradients), self.min_spacing, boundary=self.boundary) + tf.check(True) + + tf = TopFarm(self.initial, CostModelComponent(4, self.cost, self.wrong_gradients), self.min_spacing, boundary=self.boundary) + self.assertRaisesRegex(Warning, "Mismatch between finite difference derivative of 'cost' wrt. 'turbineX' and derivative computed in 'cost_comp' is", tf.check) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() diff --git a/tests/test_try_me.py b/tests/test_try_me.py new file mode 100644 index 0000000000000000000000000000000000000000..47a059e4e4287528a2af0665e79c318bd29aa042 --- /dev/null +++ b/tests/test_try_me.py @@ -0,0 +1,38 @@ +''' +Created on 17. maj 2018 + +@author: mmpe +''' +import unittest +import topfarm +import pkgutil +import importlib +import inspect +import ast +import warnings +from topfarm.cost_models.fuga import lib_reader +import mock +import pytest +import os + + +class TestTryMe(unittest.TestCase): + + + def test_try_me(self): + if os.name == 'posix' and "DISPLAY" not in os.environ: + pytest.xfail("No display") + package = topfarm + for _, modname, _ in pkgutil.walk_packages(package.__path__, package.__name__ + '.'): + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + m = importlib.import_module(modname) + if 'try_me' in dir(m): + print("Checking %s.try_me" % modname) + with mock.patch.object(m, "__name__", "__main__"): + getattr(m, 'try_me')() + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() diff --git a/tests/test_with_dummy.py b/tests/test_with_dummy.py index 2efbafb82f5972a87967269fe089234566390b6f..c0e08ebaa423c524e8fba484cbbc39fb29abe224 100644 --- a/tests/test_with_dummy.py +++ b/tests/test_with_dummy.py @@ -1,7 +1,7 @@ """Tests for TOPFARM """ import os -from topfarm.topfarm import TopFarm +from topfarm import TopFarm import unittest import warnings diff --git a/topfarm/__init__.py b/topfarm/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f700fd731544e18c0bd412898f0defd3dac14f8e 100644 --- a/topfarm/__init__.py +++ b/topfarm/__init__.py @@ -0,0 +1 @@ +from ._topfarm import * \ No newline at end of file diff --git a/topfarm/topfarm.py b/topfarm/_topfarm.py similarity index 80% rename from topfarm/topfarm.py rename to topfarm/_topfarm.py index 5aa08aef57e35d6489e45efd904b4a5fe39ff6d0..ac2a8a034602861d5072c266d04be5220e2b7d94 100644 --- a/topfarm/topfarm.py +++ b/topfarm/_topfarm.py @@ -6,6 +6,7 @@ import numpy as np from topfarm.constraint_components.boundary_component import BoundaryComp,\ PolygonBoundaryComp from topfarm.constraint_components.spacing_component import SpacingComp +from topfarm.plotting import PlotComp import warnings @@ -59,14 +60,14 @@ class TopFarm(object): def check(self, all=False, tol=1e-3): """Check gradient computations""" comp_name_lst = [comp.pathname for comp in self.problem.model.system_iter() - if (comp._has_compute_partials and - comp.pathname not in ['spacing_comp', 'bound_comp', 'plot_comp'] or all)] + if comp._has_compute_partials and + (comp.pathname not in ['spacing_comp', 'bound_comp', 'plot_comp'] or (all and comp.pathname != 'plot_comp'))] print("checking %s" % ", ".join(comp_name_lst)) res = self.problem.check_partials(comps=comp_name_lst, compact_print=True) for comp in comp_name_lst: var_pair = list(res[comp].keys()) worst = var_pair[np.argmax([res[comp][k]['rel error'].forward for k in var_pair])] - err = res['cost_comp'][worst]['rel error'].forward + err = res[comp][worst]['rel error'].forward if err > tol: raise Warning("Mismatch between finite difference derivative of '%s' wrt. '%s' and derivative computed in '%s' is: %f" % (worst[0], worst[1], comp, err)) @@ -98,21 +99,24 @@ class TopFarm(object): return np.array([self.problem['turbineX'], self.problem['turbineY']]).T -if __name__ == '__main__': - from topfarm.cost_models.dummy import DummyCostPlotComp, DummyCost - from topfarm.plotting import PlotComp +def try_me(): + if __name__ == '__main__': + from topfarm.cost_models.dummy import DummyCostPlotComp, DummyCost - n_wt = 4 - random_offset = 5 - optimal = [(3, -3), (7, -7), (4, -3), (3, -7), (-3, -3), (-7, -7), (-4, -3), (-3, -7)][:n_wt] - rotorDiameter = 1.0 - minSpacing = 2.0 + n_wt = 4 + random_offset = 5 + optimal = [(3, -3), (7, -7), (4, -3), (3, -7), (-3, -3), (-7, -7), (-4, -3), (-3, -7)][:n_wt] + rotorDiameter = 1.0 + minSpacing = 2.0 - turbines = np.array(optimal) + np.random.randint(-random_offset, random_offset, (n_wt, 2)) - plot_comp = DummyCostPlotComp(optimal) + turbines = np.array(optimal) + np.random.randint(-random_offset, random_offset, (n_wt, 2)) + plot_comp = DummyCostPlotComp(optimal) - boundary = [(0, 0), (6, 0), (6, -10), (0, -10)] - tf = TopFarm(turbines, DummyCost(optimal), minSpacing * rotorDiameter, boundary=boundary, plot_comp=plot_comp) - # tf.check() - tf.optimize() - plot_comp.show() + boundary = [(0, 0), (6, 0), (6, -10), (0, -10)] + tf = TopFarm(turbines, DummyCost(optimal), minSpacing * rotorDiameter, boundary=boundary, plot_comp=plot_comp) + # tf.check() + tf.optimize() + # plot_comp.show() + + +try_me() diff --git a/topfarm/cost_models/dummy.py b/topfarm/cost_models/dummy.py index 449d4601d69d341b953c3cff1f6fb93bc74bd791..777b77f80e09eddd43d4f210541731aead66c4df 100644 --- a/topfarm/cost_models/dummy.py +++ b/topfarm/cost_models/dummy.py @@ -3,7 +3,7 @@ from openmdao.core.explicitcomponent import ExplicitComponent import matplotlib.pyplot as plt import numpy as np from topfarm.plotting import PlotComp -from topfarm.topfarm import TopFarm +from topfarm import TopFarm class DummyCost(ExplicitComponent): diff --git a/topfarm/cost_models/fuga/Colonel b/topfarm/cost_models/fuga/Colonel index 100b7842bbeb29ba6f51556fbc24d01cf153efe1..01e2b99aa8f7f40d7a020710f9a0374bcfa7f26c 160000 --- a/topfarm/cost_models/fuga/Colonel +++ b/topfarm/cost_models/fuga/Colonel @@ -1 +1 @@ -Subproject commit 100b7842bbeb29ba6f51556fbc24d01cf153efe1 +Subproject commit 01e2b99aa8f7f40d7a020710f9a0374bcfa7f26c diff --git a/topfarm/cost_models/fuga/py_fuga.py b/topfarm/cost_models/fuga/py_fuga.py index 6a8de07b72e42bec1025a037c43e65b1267f15d0..cd8816439cee4ed1090594e6ac84b8e1c356614c 100644 --- a/topfarm/cost_models/fuga/py_fuga.py +++ b/topfarm/cost_models/fuga/py_fuga.py @@ -78,7 +78,7 @@ class PyFuga(object): return no_turbines_p.contents.value def move_turbines(self, tb_x, tb_y): - assert len(tb_x) == len(tb_y) == self.get_no_tubines(), (len(tb_x) ,len(tb_y), self.get_no_tubines()) + assert len(tb_x) == len(tb_y) == self.get_no_tubines(), (len(tb_x), len(tb_y), self.get_no_tubines()) tb_x_ctype = np.array(tb_x, dtype=np.float).ctypes tb_y_ctype = np.array(tb_y, dtype=np.float).ctypes @@ -144,19 +144,19 @@ class PyFuga(object): print("#" + str(res) + "#") -if __name__ == '__main__': +def try_me(): + if __name__ == '__main__': + pyFuga = PyFuga() + pyFuga.setup(farm_name='Horns Rev 1', + turbine_model_path=fuga_path + 'LUT/', turbine_model_name='Vestas_V80_(2_MW_offshore)[h=67.00]', + tb_x=[423974, 424033], tb_y=[6151447, 6150889], + mast_position=(0, 0, 70), z0=0.0001, zi=400, zeta0=0, + farms_dir=fuga_path + 'LUT/Farms/', wind_atlas_path='Horns Rev 1\hornsrev.lib') - fuga_path = os.path.abspath(".") + '/Colonel/' - pyFuga = PyFuga(farm_name='Horns Rev 1', - turbine_model_path=fuga_path + 'LUT/', turbine_model_name='Vestas_V80_(2_MW_offshore)[h=67.00]', - tb_x=[423974, 424033], tb_y=[6151447, 6150889], - mast_position=(0, 0, 70), z0=0.0001, zi=400, zeta0=0, - farms_dir=fuga_path + 'LUT/Farms/', wind_atlas_path='Horns Rev 1\hornsrev.lib') + print(pyFuga.get_no_tubines()) + print(pyFuga.get_aep(np.array([[0, 0], [0, 1000]]))) + print(pyFuga.get_aep(np.array([[0, 1000], [0, 0]]))) + print(pyFuga.get_aep_gradients(np.array([[0, 0], [0, 100]]))) - print(pyFuga.get_no_tubines()) - print(pyFuga.get_aep([0, 0], [0, 1000])) - print(pyFuga.get_aep([0, 1000], [0, 0])) - print(pyFuga.get_aep_gradients([0, 0], [0, 100])) - print(pyFuga.get_aep([0, 0], [0, 100])) - print(pyFuga.get_aep([0, 0], [0, 101])) - print(pyFuga.get_aep_gradients([0, 0], [0, 200])) + +try_me() diff --git a/topfarm/cost_models/fused_wake_wrappers.py b/topfarm/cost_models/fused_wake_wrappers.py index 2ed053f2080bb5b6bdcbaf5d0610501f4c4ff66a..e19e958f50466f61a875d4bd4104dc051d763e30 100644 --- a/topfarm/cost_models/fused_wake_wrappers.py +++ b/topfarm/cost_models/fused_wake_wrappers.py @@ -32,20 +32,22 @@ class FusedWakeGCLWakeModel(object): return p.sum(2) # sum over all turbines +def try_me(): + if __name__ == '__main__': + from fusedwake import fusedwake + import os -if __name__ == '__main__': - from fusedwake import fusedwake - import os + hornsrev_yml = os.path.dirname(fusedwake.__file__) + "/../examples/hornsrev.yml" + wm = FusedWakeGCLWakeModel(hornsrev_yml) + tb_pos = wm.windFarm.pos - hornsrev_yml = os.path.dirname(fusedwake.__file__) + "/../examples/hornsrev.yml" - wm = FusedWakeGCLWakeModel(hornsrev_yml) - tb_pos = wm.windFarm.pos + print(wm(tb_pos.T, no_wake_wdir=270, no_wake_wsp=8, no_wake_ti=0.1)) - print(wm(tb_pos, no_wake_wdir=270, no_wake_wsp=8, no_wake_ti=0.1).shape) + WS_cases = np.arange(4, 12) + WD_cases = np.arange(0, 360, 10) + WS_ms, WD_ms = np.meshgrid(WS_cases, WD_cases) + p = wm(tb_pos.T, WD_ms, WS_ms, np.zeros_like(WS_ms) + .1) + print(p) - WS_cases = np.arange(4, 12) - WD_cases = np.arange(0, 360, 10) - WS_ms, WD_ms = np.meshgrid(WS_cases, WD_cases) - p = wm(tb_pos, WD_ms, WS_ms, np.zeros_like(WS_ms) + .1) - print(p.shape) - print(p) + +try_me() diff --git a/topfarm/cost_models/utils/aep_calculator.py b/topfarm/cost_models/utils/aep_calculator.py index fbbc28cf4c261b4b3a379d30669060a8dd8eb695..e7f7059a2f7b16f86a87e4813bcd274136868c94 100644 --- a/topfarm/cost_models/utils/aep_calculator.py +++ b/topfarm/cost_models/utils/aep_calculator.py @@ -10,6 +10,7 @@ import numpy as np from topfarm.cost_models.fused_wake_wrappers import FusedWakeGCLWakeModel from topfarm.cost_models.utils.wind_resource import WindResource from topfarm.cost_models.cost_model_wrappers import AEPCostModelComponent +from tests.test_files import testfilepath class AEPCalculator(object): @@ -34,14 +35,17 @@ class AEPCalculator(object): return AEPCostModelComponent(n_wt, lambda *args: self(*args)) -if __name__ == '__main__': - f = [0.035972, 0.039487, 0.051674, 0.070002, 0.083645, 0.064348, 0.086432, 0.117705, 0.151576, 0.147379, 0.10012, 0.05166] - A = [9.176929, 9.782334, 9.531809, 9.909545, 10.04269, 9.593921, 9.584007, 10.51499, 11.39895, 11.68746, 11.63732, 10.08803] - k = [2.392578, 2.447266, 2.412109, 2.591797, 2.755859, 2.595703, 2.583984, 2.548828, 2.470703, 2.607422, 2.626953, 2.326172] - wr = WindResource(f / 100, A, k, ti=np.zeros_like(f) + .1) - hornsrev_yml = os.path.dirname(fusedwake.__file__) + "/../examples/hornsrev.yml" - hornsrev_yml_2tb = "../../example_data/hornsrev_2tb.yml" - wm = FusedWakeGCLWakeModel(hornsrev_yml) - aep_calc = AEPCalculator(wr, wm) +def try_me(): + if __name__ == '__main__': + f = [0.035972, 0.039487, 0.051674, 0.070002, 0.083645, 0.064348, 0.086432, 0.117705, 0.151576, 0.147379, 0.10012, 0.05166] + A = [9.176929, 9.782334, 9.531809, 9.909545, 10.04269, 9.593921, 9.584007, 10.51499, 11.39895, 11.68746, 11.63732, 10.08803] + k = [2.392578, 2.447266, 2.412109, 2.591797, 2.755859, 2.595703, 2.583984, 2.548828, 2.470703, 2.607422, 2.626953, 2.326172] + wr = WindResource(np.array(f) / 100, A, k, ti=np.zeros_like(f) + .1) + wf_3tb = testfilepath + "wind_farms/3tb.yml" + wm = FusedWakeGCLWakeModel(wf_3tb) + aep_calc = AEPCalculator(wr, wm) - print(aep_calc(wm.wf.pos)) + print(aep_calc(wm.windFarm.pos.T)) + + +try_me() diff --git a/topfarm/cost_models/utils/turbine_model.py b/topfarm/cost_models/utils/turbine_model.py deleted file mode 100644 index 071dfa161e35ec9a9b144d8b13a37adabcf07e2c..0000000000000000000000000000000000000000 --- a/topfarm/cost_models/utils/turbine_model.py +++ /dev/null @@ -1,22 +0,0 @@ -''' -Created on 17/04/2018 - -@author: Mads -''' - - -class TurbineModel(object): - def __init__(self, wsp, power, ct): - self.wsp = wsp - self.power = power - self.ct = ct - - -class Vestas_V80_2_MW_offshore(TurbineModel): - def __init__(self): - wsp = (4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0) - power = (66600.0, 154000.0, 282000.0, 460000.0, 696000.0, 996000.0, 1341000.0, 1661000.0, 1866000.0, 1958000.0, 1988000.0, 1997000.0, 1999000.0, 2000000.0, 2000000.0, 2000000.0, 2000000.0, 2000000.0, 2000000.0, 2000000.0, 2000000.0, 2000000.0), - ct = (0.818, 0.806, 0.804, 0.805, 0.806, 0.807, 0.793, 0.739, 0.709, 0.409, 0.314, 0.249, 0.202, 0.167, 0.14, 0.119, 0.102, 0.088, 0.077, 0.067, 0.06, 0.053) - TurbineModel.__init__(self, wsp, power, ct) - - \ No newline at end of file diff --git a/topfarm/cost_models/utils/wind_resource.py b/topfarm/cost_models/utils/wind_resource.py index 705f7fa0ad897d5c076a2605879f88235d40eeed..53994e4f978a1228f58996ba60da39b34b169901 100644 --- a/topfarm/cost_models/utils/wind_resource.py +++ b/topfarm/cost_models/utils/wind_resource.py @@ -9,14 +9,15 @@ import numpy as np class WindResource(object): def __init__(self, f, a, k, ti): wdir = np.linspace(0, 360, len(f), endpoint=False) - indexes = np.argmin((np.tile(np.arange(360),(len(f),1)).T - wdir + (360/len(f)/2)) % 360, 1) + indexes = np.argmin((np.tile(np.arange(360), (len(f), 1)).T - wdir + (360 / len(f) / 2)) % 360, 1) self.f = np.array(f)[indexes] / (360 / len(f)) self.a = np.array(a)[indexes] self.k = np.array(k)[indexes] self.ti = np.array(ti)[indexes] def weibull_weight(self, WS, A, k): - cdf = lambda ws, A=A, k=k: 1 - np.exp(-(ws / A) ** k) + def cdf(ws, A=A, k=k): + return 1 - np.exp(-(ws / A) ** k) dWS = np.diff(WS[:2], 1, 0) / 2 return cdf(WS + dWS) - cdf(WS - dWS) @@ -24,15 +25,19 @@ class WindResource(object): # f(turbine_positions, wdir, wsp) -> WS[nWT,nWdir,nWsp], TI[nWT,nWdir,nWsp), Weight[nWdir,nWsp] WD, WS = np.meshgrid(wdir, wsp) weight = self.weibull_weight(WS, self.a[WD], self.k[WD]) * self.f[wdir] - WD,WS = np.tile(WD,(len(turbine_positions),1,1)), np.tile(WS,(len(turbine_positions),1,1)) + WD, WS = np.tile(WD, (len(turbine_positions), 1, 1)), np.tile(WS, (len(turbine_positions), 1, 1)) return WD, WS, self.ti[WD], weight -if __name__ == '__main__': - f = np.array("3.597152 3.948682 5.167395 7.000154 8.364547 6.43485 8.643194 11.77051 15.15757 14.73792 10.01205 5.165975".split(), dtype=np.float) - A = np.array("9.176929 9.782334 9.531809 9.909545 10.04269 9.593921 9.584007 10.51499 11.39895 11.68746 11.63732 10.08803".split(), dtype=np.float) - k = np.array("2.392578 2.447266 2.412109 2.591797 2.755859 2.595703 2.583984 2.548828 2.470703 2.607422 2.626953 2.326172".split(), dtype=np.float) - ti = np.zeros_like(f) + .1 - wr = WindResource(f, A, k, ti) +def try_me(): + if __name__ == '__main__': + f = [0.035972, 0.039487, 0.051674, 0.070002, 0.083645, 0.064348, 0.086432, 0.117705, 0.151576, 0.147379, 0.10012, 0.05166] + A = [9.176929, 9.782334, 9.531809, 9.909545, 10.04269, 9.593921, 9.584007, 10.51499, 11.39895, 11.68746, 11.63732, 10.08803] + k = [2.392578, 2.447266, 2.412109, 2.591797, 2.755859, 2.595703, 2.583984, 2.548828, 2.470703, 2.607422, 2.626953, 2.326172] + ti = np.zeros_like(f) + .1 + wr = WindResource(f, A, k, ti) - print(wr((0, 0), [0, 30, 60], [4, 5])) + print(wr((0, 0), [0, 30, 60], [4, 5])) + + +try_me() diff --git a/topfarm/example_data/hornsrev1.py b/topfarm/example_data/hornsrev1.py deleted file mode 100644 index 39a98bd1a919dec6088bc58806780310101f33b3..0000000000000000000000000000000000000000 --- a/topfarm/example_data/hornsrev1.py +++ /dev/null @@ -1,6 +0,0 @@ -import numpy as np -id = [1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28, 31, 32, 33, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 56, 57, 58, 61, 62, 63, 64, 65, 66, 67, 68, 71, 72, 73, 74, 75, 76, 77, 78, 81, 82, 83, 84, 85, 86, 87, 88, 91, 92, 93, 94, 95, 96, 97, 98] -turbine_x = [423974.0, 424033.0, 424092.0, 424151.0, 424210.0, 424268.0, 424327.0, 424386.0, 424534.0, 424593.0, 424652.0, 424711.0, 424770.0, 424829.0, 424888.0, 424947.0, 425094.0, 425153.0, 425212.0, 425271.0, 425330.0, 425389.0, 425448.0, 425507.0, 425654.0, 425713.0, 425772.0, 425831.0, 425890.0, 425950.0, 426009.0, 426068.0, 426214.0, 426273.0, 426332.0, 426392.0, 426451.0, 426510.0, 426569.0, 426628.0, 426774.0, 426833.0, 426892.0, 426952.0, 427011.0, 427070.0, 427129.0, 427189.0, 427334.0, 427393.0, 427453.0, 427512.0, 427571.0, 427631.0, 427690.0, 427749.0, 427894.0, 427953.0, 428013.0, 428072.0, 428132.0, 428191.0, 428250.0, 428310.0, 428454.0, 428513.0, 428573.0, 428632.0, 428692.0, 428751.0, 428811.0, 428870.0, 429014.0, 429074.0, 429133.0, 429193.0, 429252.0, 429312.0, 429371.0, 429431.0] -turbine_y = [6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148658.0, 6148101.0, 6147543.0, 6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148658.0, 6148101.0, 6147543.0, 6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148658.0, 6148101.0, 6147543.0, 6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148659.0, 6148101.0, 6147543.0, 6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148659.0, 6148101.0, 6147543.0, 6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148659.0, 6148101.0, 6147543.0, 6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148659.0, 6148101.0, 6147543.0, 6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148659.0, 6148101.0, 6147543.0, 6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148659.0, 6148101.0, 6147543.0, 6151447.0, 6150889.0, 6150332.0, 6149774.0, 6149216.0, 6148659.0, 6148101.0, 6147543.0] -height = [67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0, 67.0] -turbine_pos = np.array([turbine_x, turbine_y]).T \ No newline at end of file