From 5a51622ca943bb9f94d1e6e6e3ccfc2d5cdf72a0 Mon Sep 17 00:00:00 2001
From: mikf <mikf@dtu.dk>
Date: Fri, 19 Nov 2021 12:49:19 +0100
Subject: [PATCH 1/2] restructure

---
 edwin/__init__.py          |   4 +-
 edwin/c_mst_cables.py      |  44 +++++++------
 edwin/method.py            |  45 -------------
 edwin/wind_farm_network.py | 129 ++++++++++++++++++++++++++-----------
 4 files changed, 119 insertions(+), 103 deletions(-)
 delete mode 100644 edwin/method.py

diff --git a/edwin/__init__.py b/edwin/__init__.py
index 2198dce..b325f3b 100644
--- a/edwin/__init__.py
+++ b/edwin/__init__.py
@@ -1,3 +1,3 @@
 # 'filled_by_setup.py'
-__version__ = 'c6c857252e379ba76e90ff3f5bf58f9efe828ee'
-__release__ = 'c6c857252e379ba76e90ff3f5bf58f9efe828ee'
+__version__ = '0.0.0'
+__release__ = '0.0.0'
diff --git a/edwin/c_mst_cables.py b/edwin/c_mst_cables.py
index db18de6..bbf2852 100644
--- a/edwin/c_mst_cables.py
+++ b/edwin/c_mst_cables.py
@@ -12,7 +12,7 @@ from c_mst import capacitated_spanning_tree
 import time
 
 
-def cmst_cables(X=[], Y=[], T=[], Cables=[], plot=True):
+def cmst_cables(X=[], Y=[], T=[], Cables=[], plot=False):
     """
     Assigns cables to the obtained C-MST in previous stage
 
@@ -63,26 +63,30 @@ def cmst_cables(X=[], Y=[], T=[], Cables=[], plot=True):
         for k in range(T_d.shape[0]):
             T_d[k, 4] = (T_d[k, 2] / 1000) * Cables[T_d.astype(int)[k, 3], 2]
     if plot:
-        plt.figure()
-        plt.plot(X[1:], Y[1:], 'r+', markersize=10, label='Turbines')
-        plt.plot(X[0], Y[0], 'ro', markersize=10, label='OSS')
-        for i in range(len(X)):
-            plt.text(X[i] + 50, Y[i] + 50, str(i + 1))
-        colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'bg', 'gr', 'rc', 'cm']
-        for i in range(Cables.shape[0]):
-            index = T_d[:, 3] == i
-            if index.any():
-                n1xs = X[T_d[index, 0].astype(int) - 1].ravel().T
-                n2xs = X[T_d[index, 1].astype(int) - 1].ravel().T
-                n1ys = Y[T_d[index, 0].astype(int) - 1].ravel().T
-                n2ys = Y[T_d[index, 1].astype(int) - 1].ravel().T
-                xs = np.vstack([n1xs, n2xs])
-                ys = np.vstack([n1ys, n2ys])
-                plt.plot(xs, ys, '{}'.format(colors[i]))
-                plt.plot([], [], '{}'.format(colors[i]), label='Cable: {} mm2'.format(Cables[i, 0]))
-        plt.legend()
+        plot_network(X, Y, Cables, T_d)
     return T_d
 
+def plot_network(X, Y, Cables, T_d):
+    plt.figure()
+    plt.plot(X[1:], Y[1:], 'r+', markersize=10, label='Turbines')
+    plt.plot(X[0], Y[0], 'ro', markersize=10, label='OSS')
+    for i in range(len(X)):
+        plt.text(X[i] + 50, Y[i] + 50, str(i + 1))
+    colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'bg', 'gr', 'rc', 'cm']
+    for i in range(Cables.shape[0]):
+        index = T_d[:, 3] == i
+        if index.any():
+            n1xs = X[T_d[index, 0].astype(int) - 1].ravel().T
+            n2xs = X[T_d[index, 1].astype(int) - 1].ravel().T
+            n1ys = Y[T_d[index, 0].astype(int) - 1].ravel().T
+            n2ys = Y[T_d[index, 1].astype(int) - 1].ravel().T
+            xs = np.vstack([n1xs, n2xs])
+            ys = np.vstack([n1ys, n2ys])
+            plt.plot(xs, ys, '{}'.format(colors[i]))
+            plt.plot([], [], '{}'.format(colors[i]), label='Cable: {} mm2'.format(Cables[i, 0]))
+    plt.legend()
+    
+
 
 if __name__ == "__main__":
     t = time.time()
@@ -102,7 +106,7 @@ if __name__ == "__main__":
     print("Feasibility: {feasible1}".format(feasible1=feasible))
 
     if feasible:
-        T_cables = cmst_cables(X, Y, T, Cables)
+        T_cables = cmst_cables(X, Y, T, Cables, plot=True)
         print("The total cost of the system is {value:.2f} Euros".format(value=T_cables[:, -1].sum()))
     elapsed = time.time() - t
     print("The total time is {timep: .2f} s".format(timep=elapsed))
diff --git a/edwin/method.py b/edwin/method.py
deleted file mode 100644
index e255c05..0000000
--- a/edwin/method.py
+++ /dev/null
@@ -1,45 +0,0 @@
-from abc import ABC, abstractmethod
-
-
-class Method(ABC):
-    def __init__(self, **kwargs):
-        return
-
-    @abstractmethod
-    def _design(geometry, financial, electrical, contraints, **settings):
-        '''
-
-        Parameters
-        ----------
-        **settings : dict
-            Configuration of algorithm.
-
-        Returns
-        -------
-        dictionary of connections.
-
-        '''
-
-
-class HeuristicMethod(Method):
-    def __init__(self, **kwargs):
-        Method.__init__(self)
-
-    def _design(self, geometry, financial, electrical, contraints, **settings):
-        return {'hello from': 'HeuristicMethod'}
-
-
-class MetaHeuristicMethod(Method):
-    def __init__(self, **kwargs):
-        Method.__init__(self)
-
-    def _design(self, geometry, financial, electrical, contraints, **settings):
-        return {'hello from': 'MetaHeuristicMethod'}
-
-
-class GlobalMethod(Method):
-    def __init__(self, **kwargs):
-        Method.__init__(self)
-
-    def _design(self, geometry, financial, electrical, contraints, **settings):
-        return {'hello from': 'GlobalMethod'}
diff --git a/edwin/wind_farm_network.py b/edwin/wind_farm_network.py
index 0ee2626..883fe6a 100644
--- a/edwin/wind_farm_network.py
+++ b/edwin/wind_farm_network.py
@@ -1,48 +1,105 @@
-import matplotlib.pyplot as plt
+from abc import ABC, abstractmethod
+from edwin.collection_system import collection_system
+from edwin.c_mst_cables import plot_network
+import pandas as pd
+import numpy as np
+
+
+class Driver(ABC):
+    @abstractmethod
+    def run():
+        '''
+
+        '''
+
+
+class HeuristicDriver(Driver):
+    def __init__(self, option=3, Inters_const=True, max_it=20000):
+        self.option = option
+        self.Inters_const = Inters_const
+        self.max_it = max_it
+        Driver.__init__(self)
+
+    def run(self):
+        T, cables_cost = collection_system(self.wfn.x,
+                                           self.wfn.y,
+                                           self.option,
+                                           self.Inters_const,
+                                           self.max_it,
+                                           self.wfn.cables)
+        return T, cables_cost
 
 
 class WindFarmNetwork():
-    def __init__(self, method, geometry, financial, electrical, constraints):
-        self.method = method
-        self.geometry = geometry
-        self.financial = financial
-        self.electrical = electrical
-        self.constraints = constraints
-
-    def design(self, settings):
-        self.settings = settings
-        return self.method._design(self.geometry, self.financial, self.electrical,
-                                   self.constraints, **settings)
+    def __init__(self, layout, driver=HeuristicDriver(), cables=[]):
+        self.layout = layout
+        for k, v in layout.items():
+            setattr(self, k, v)
+        self.driver = driver
+        self.cables = cables
+        self.state = None
+        self.T = None
+        self.columns = ['from_node', 'to_node', 'cable_length', 'cable_type', 'cable_cost']
+        self.setup()
+
+    def setup(self):
+        setattr(self.driver, 'wfn', self)
+
+    def design(self):
+        T, cost = self.driver.run()
+        state = pd.DataFrame(T, columns=self.columns)
+        state = state.astype({'from_node': int,
+                              'to_node': int,
+                              'cable_type': int})
+        self.T = T
+        self.cost = cost
+        self.state = state
+        return cost, state
 
     def plot(self):
-        x = self.geometry['turbine_coordinates']['x']
-        y = self.geometry['turbine_coordinates']['y']
-        xss = self.geometry['sub_station_coordinates']['x']
-        yss = self.geometry['sub_station_coordinates']['y']
-        plt.plot(x, y, '.')
-        plt.plot(xss, yss, 'or', label='Sub station')
-        plt.legend()
+        if self.state is not None:
+            self.design()
+        plot_network(self.x, self.y, self.cables, self.T)
+
+
+class Constraints(dict):
+    def __init__(self, **kwargs):
+        dict.__init__(self, {'crossing': False,
+                             'tree': False,
+                             'thermal_capacity': False,
+                             'number_of_main_feeders': False})
+        self.update(kwargs)
 
 
 def main():
     if __name__ == '__main__':
-        from edwin.method import MetaHeuristicMethod
-        method = MetaHeuristicMethod()
-        geometry = {'turbine_coordinates': {'x': [1, 1, 1, 2, 2, 2, 3, 3, 3],
-                                            'y': [1, 2, 3, 2, 3, 4, 3, 4, 5], },
-                    'sub_station_coordinates': {'x': [2.5],
-                                                'y': [3.5], }}
-        financial = {}
-        electrical = {}
-        constraints = {'crossing': False,
-                       'tree': False,
-                       'thermal capacity': False,
-                       'number of main feeders': False}
-        settings = {}
-        wfn = WindFarmNetwork(method=method, geometry=geometry, financial=financial,
-                              electrical=electrical, constraints=constraints)
-        result_dict = wfn.design(settings)
-        print(result_dict)
+        # layout = {'x': [473095,471790,471394,470998,470602,470207,469811,472523,469415,472132,471742,471351,470960,470569,470179,469788,472866,472480,472094,471708,471322,470937,470551,473594,473213,472833,472452,472071,471691,471310,470929],
+        #           'y': [5992345,5991544,5991899,5992252,5992607,5992960,5993315,5991874,5993668,5992236,5992598,5992960,5993322,5993684,5994047,5994409,5992565,5992935,5993306,5993675,5994045,5994416,5994786,5992885,5993264,5993643,5994021,5994400,5994779,5995156,5995535]}
+        layout = dict(x=np.array([0., 2000., 4000., 6000.,
+                                  8000., 498.65600569, 2498.65600569, 4498.65600569,
+                                  6498.65600569, 8498.65600569, 997.31201137, 2997.31201137,
+                                  4997.31201137, 11336.25662483, 8997.31201137, 1495.96801706,
+                                  3495.96801706, 5495.96801706, 10011.39514341, 11426.89538545,
+                                  1994.62402275, 3994.62402275, 5994.62402275, 7994.62402275,
+                                  10588.90471566]),
+                      y=np.array([0., 0., 0., 0.,
+                                  0., 2000., 2000., 2000.,
+                                  2000., 2000., 4000., 4000.,
+                                  4000., 6877.42528387, 4000., 6000.,
+                                  6000., 6000., 3179.76530545, 5953.63051694,
+                                  8000., 8000., 8000., 8000.,
+                                  4734.32972738]))
+        # layout = {'x': [387100, 383400, 383400, 383900, 383200, 383200, 383200, 383200, 383200, 383200, 383200, 383200, 383300, 384200, 384200, 384100, 384000, 383800, 383700, 383600, 383500, 383400, 383600, 384600, 385400, 386000, 386100, 386200, 386300, 386500, 386600, 386700, 386800, 386900, 387000, 387100, 387200, 383900, 387400, 387500, 387600, 387800, 387900, 388000, 387600, 386800, 385900, 385000, 384100, 384500, 384800, 385000, 385100, 385200, 385400, 385500, 385700, 385800, 385900, 385900, 385500, 385500, 386000, 386200, 386200, 384500, 386200, 386700, 386700, 386700, 384300, 384400, 384500, 384600, 384300, 384700, 384700, 384700, 385500, 384300, 384300],
+        #           'y': [6109500, 6103800, 6104700, 6105500, 6106700, 6107800, 6108600, 6109500, 6110500, 6111500, 6112400, 6113400, 6114000, 6114200, 6115100, 6115900, 6116700, 6118400, 6119200, 6120000, 6120800, 6121800, 6122400, 6122000, 6121700, 6121000, 6120000, 6119100, 6118100, 6117200, 6116200, 6115300, 6114300, 6113400, 6112400, 6111500, 6110700, 6117600, 6108900, 6108100, 6107400, 6106300, 6105200, 6104400, 6103600, 6103600, 6103500, 6103400, 6103400, 6104400, 6120400, 6119500, 6118400, 6117400, 6116500, 6115500, 6114600, 6113500, 6112500, 6111500, 6105400, 6104200, 6110400, 6109400, 6108400, 6121300, 6107500, 6106400, 6105300, 6104400, 6113300, 6112500, 6111600, 6110800, 6110100, 6109200, 6108400, 6107600, 6106500, 6106600, 6105000]}
+
+        settings = {'option': 3,
+                    'Inters_const': True,
+                    'max_it': 20000}
+        cables = np.array([[500, 3, 100000], [800, 5, 150000], [1000, 10, 250000]])
+        wfn = WindFarmNetwork(layout=layout,
+                              driver=HeuristicDriver(**settings),
+                              cables=cables)
+        cost, state = wfn.design()
         wfn.plot()
 
 
-- 
GitLab


From aaba90e3c8f9d0e712e66091471e7331a52d6f7f Mon Sep 17 00:00:00 2001
From: mikf <mikf@dtu.dk>
Date: Fri, 19 Nov 2021 13:47:47 +0100
Subject: [PATCH 2/2] updated test

---
 edwin/c_mst.py                        |  2 +-
 edwin/c_mst_cables.py                 |  4 +-
 edwin/collection_system.py            |  4 +-
 edwin/intersection_checker.py         |  2 +-
 edwin/tests/test_wind_farm_network.py | 94 ++++++++++++++++++++++-----
 5 files changed, 82 insertions(+), 24 deletions(-)

diff --git a/edwin/c_mst.py b/edwin/c_mst.py
index f32405d..23720f8 100644
--- a/edwin/c_mst.py
+++ b/edwin/c_mst.py
@@ -5,8 +5,8 @@ Created on Thu May 28 08:12:54 2020
 @author: juru
 """
 import numpy as np
-from intersection_checker import intersection_checker
 import matplotlib.pyplot as plt
+from edwin.intersection_checker import intersection_checker
 
 
 def capacitated_spanning_tree(X=[], Y=[], option=3, UL=100, Inters_const=True, max_it=20000):
diff --git a/edwin/c_mst_cables.py b/edwin/c_mst_cables.py
index bbf2852..a34aa34 100644
--- a/edwin/c_mst_cables.py
+++ b/edwin/c_mst_cables.py
@@ -8,8 +8,8 @@ Created on Thu Jun  4 08:07:37 2020
 import numpy as np
 import networkx as nx
 import matplotlib.pyplot as plt
-from c_mst import capacitated_spanning_tree
 import time
+from edwin.c_mst import capacitated_spanning_tree
 
 
 def cmst_cables(X=[], Y=[], T=[], Cables=[], plot=False):
@@ -66,6 +66,7 @@ def cmst_cables(X=[], Y=[], T=[], Cables=[], plot=False):
         plot_network(X, Y, Cables, T_d)
     return T_d
 
+
 def plot_network(X, Y, Cables, T_d):
     plt.figure()
     plt.plot(X[1:], Y[1:], 'r+', markersize=10, label='Turbines')
@@ -85,7 +86,6 @@ def plot_network(X, Y, Cables, T_d):
             plt.plot(xs, ys, '{}'.format(colors[i]))
             plt.plot([], [], '{}'.format(colors[i]), label='Cable: {} mm2'.format(Cables[i, 0]))
     plt.legend()
-    
 
 
 if __name__ == "__main__":
diff --git a/edwin/collection_system.py b/edwin/collection_system.py
index 06a55d2..ee30985 100644
--- a/edwin/collection_system.py
+++ b/edwin/collection_system.py
@@ -5,8 +5,8 @@ Created on Mon Jun 22 10:59:47 2020
 @author: juru
 """
 import numpy as np
-from c_mst import capacitated_spanning_tree
-from c_mst_cables import cmst_cables
+from edwin.c_mst import capacitated_spanning_tree
+from edwin.c_mst_cables import cmst_cables
 
 
 def collection_system(X=[], Y=[], option=3, Inters_const=True, max_it=20000, Cables=[], plot=False):
diff --git a/edwin/intersection_checker.py b/edwin/intersection_checker.py
index c70dc51..54adefa 100644
--- a/edwin/intersection_checker.py
+++ b/edwin/intersection_checker.py
@@ -6,7 +6,7 @@ Created on Fri May 29 10:08:54 2020
 """
 
 import numpy as np
-from two_lines_intersecting import two_lines_intersecting
+from edwin.two_lines_intersecting import two_lines_intersecting
 
 
 def intersection_checker(pos_potential_edge, edges_tot, mst_edges, X, Y, Inters_const):
diff --git a/edwin/tests/test_wind_farm_network.py b/edwin/tests/test_wind_farm_network.py
index d663ed6..bc45abd 100644
--- a/edwin/tests/test_wind_farm_network.py
+++ b/edwin/tests/test_wind_farm_network.py
@@ -1,22 +1,80 @@
-from edwin.wind_farm_network import WindFarmNetwork
-from edwin.method import MetaHeuristicMethod
+import numpy as np
+from edwin.wind_farm_network import WindFarmNetwork, HeuristicDriver
+import numpy.testing as npt
 
-method = MetaHeuristicMethod()
-geometry = {'turbine_coordinates': {'x': [1, 1, 1, 2, 2, 2, 3, 3, 3],
-                                    'y': [1, 2, 3, 2, 3, 4, 3, 4, 5], },
-            'sub_station_coordinates': {'x': [2.5],
-                                        'y': [3.5], }}
-financial = {}
-electrical = {}
-constraints = {'crossing': False,
-               'tree': False,
-               'thermal capacity': False,
-               'number of main feeders': False}
-settings = {}
-wfn = WindFarmNetwork(method=method, geometry=geometry, financial=financial,
-                      electrical=electrical, constraints=constraints)
+layout = dict(x=np.array([0., 2000., 4000., 6000.,
+                          8000., 498.65600569, 2498.65600569, 4498.65600569,
+                          6498.65600569, 8498.65600569, 997.31201137, 2997.31201137,
+                          4997.31201137, 11336.25662483, 8997.31201137, 1495.96801706,
+                          3495.96801706, 5495.96801706, 10011.39514341, 11426.89538545,
+                          1994.62402275, 3994.62402275, 5994.62402275, 7994.62402275,
+                          10588.90471566]),
+              y=np.array([0., 0., 0., 0.,
+                          0., 2000., 2000., 2000.,
+                          2000., 2000., 4000., 4000.,
+                          4000., 6877.42528387, 4000., 6000.,
+                          6000., 6000., 3179.76530545, 5953.63051694,
+                          8000., 8000., 8000., 8000.,
+                          4734.32972738]))
+settings = {'option': 3,
+            'Inters_const': True,
+            'max_it': 20000}
+cables = np.array([[500, 3, 100000], [800, 5, 150000], [1000, 10, 250000]])
+wfn = WindFarmNetwork(layout=layout,
+                      driver=HeuristicDriver(**settings),
+                      cables=cables)
+
+T_ref = np.asarray([[1.00000000e+00, 2.00000000e+00, 2.00000000e+03, 1.00000000e+00,
+                     3.00000000e+05],
+                    [2.00000000e+00, 3.00000000e+00, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05],
+                    [3.00000000e+00, 4.00000000e+00, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05],
+                    [4.00000000e+00, 5.00000000e+00, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05],
+                    [1.00000000e+00, 6.00000000e+00, 2.06122726e+03, 2.00000000e+00,
+                     5.15306815e+05],
+                    [6.00000000e+00, 7.00000000e+00, 2.00000000e+03, 2.00000000e+00,
+                     5.00000000e+05],
+                    [7.00000000e+00, 8.00000000e+00, 2.00000000e+03, 2.00000000e+00,
+                     5.00000000e+05],
+                    [8.00000000e+00, 9.00000000e+00, 2.00000000e+03, 2.00000000e+00,
+                     5.00000000e+05],
+                    [9.00000000e+00, 1.00000000e+01, 2.00000000e+03, 2.00000000e+00,
+                     5.00000000e+05],
+                    [1.00000000e+01, 1.90000000e+01, 1.91839148e+03, 1.00000000e+00,
+                     2.87758722e+05],
+                    [1.90000000e+01, 1.50000000e+01, 1.30428124e+03, 0.00000000e+00,
+                     1.30428124e+05],
+                    [1.90000000e+01, 2.50000000e+01, 1.65836903e+03, 0.00000000e+00,
+                     1.65836903e+05],
+                    [2.50000000e+01, 2.00000000e+01, 1.47950085e+03, 0.00000000e+00,
+                     1.47950085e+05],
+                    [2.00000000e+01, 1.40000000e+01, 9.28230659e+02, 0.00000000e+00,
+                     9.28230659e+04],
+                    [1.00000000e+00, 1.10000000e+01, 4.12245452e+03, 2.00000000e+00,
+                     1.03061363e+06],
+                    [1.10000000e+01, 1.20000000e+01, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05],
+                    [1.20000000e+01, 1.30000000e+01, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05],
+                    [1.10000000e+01, 1.60000000e+01, 2.06122726e+03, 2.00000000e+00,
+                     5.15306815e+05],
+                    [1.60000000e+01, 1.70000000e+01, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05],
+                    [1.70000000e+01, 1.80000000e+01, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05],
+                    [1.60000000e+01, 2.10000000e+01, 2.06122726e+03, 1.00000000e+00,
+                     3.09184089e+05],
+                    [2.10000000e+01, 2.20000000e+01, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05],
+                    [2.20000000e+01, 2.30000000e+01, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05],
+                    [2.30000000e+01, 2.40000000e+01, 2.00000000e+03, 0.00000000e+00,
+                     2.00000000e+05]])
 
 
 def test_wind_farm_network():
-    result_dict = wfn.design(settings)
-    assert result_dict == {'hello from': 'MetaHeuristicMethod'}
+    cost, state = wfn.design()
+    assert 7495208.24825092 == cost
+    npt.assert_allclose(wfn.T, T_ref)
-- 
GitLab