From 4b5de449422a9b7b90cfab478530be92ea2bd3d9 Mon Sep 17 00:00:00 2001
From: mikf <mikf@dtu.dk>
Date: Thu, 21 Jun 2018 11:23:25 +0200
Subject: [PATCH] added option to record/resume optimizaton. record
 optimization by setting: record = True chose directory of recording by
 setting: case_recorder_dir = [your dir] resume optimization by setting:
 rerun_case_id = [your case_id] or 'latest' for resuming most recent run

---
 topfarm/_topfarm.py  | 35 ++++++++++++++++++++++++++++++-----
 topfarm/recording.py | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 5 deletions(-)
 create mode 100644 topfarm/recording.py

diff --git a/topfarm/_topfarm.py b/topfarm/_topfarm.py
index 1e0e75d8..e789c274 100644
--- a/topfarm/_topfarm.py
+++ b/topfarm/_topfarm.py
@@ -1,13 +1,16 @@
+import os
 import time
 import numpy as np
 import warnings
 with warnings.catch_warnings():
     warnings.simplefilter('ignore', FutureWarning)
-    from openmdao.api import Problem, ScipyOptimizeDriver, IndepVarComp
+    from openmdao.api import Problem, ScipyOptimizeDriver, IndepVarComp, \
+    SqliteRecorder
 from topfarm.constraint_components.boundary_component import BoundaryComp,\
     PolygonBoundaryComp
 from topfarm.constraint_components.spacing_component import SpacingComp
 from topfarm.plotting import PlotComp
+from topfarm.recording import pos_from_case, latest_id
 
 
 class TopFarm(object):
@@ -19,10 +22,18 @@ class TopFarm(object):
     """
 
     def __init__(self, turbines, cost_comp, min_spacing, boundary, boundary_type='convex_hull', plot_comp=None,
-                 driver=ScipyOptimizeDriver()):
-
-        self.initial_positions = turbines = np.array(turbines)
-
+                 driver=ScipyOptimizeDriver(), record = False, case_recorder_dir = os.getcwd(),
+                 rerun_case_id = None):
+        if rerun_case_id is None:
+            self.initial_positions = turbines = np.array(turbines)
+        elif rerun_case_id is 'latest':
+            rerun_case_id = latest_id(case_recorder_dir)
+            self.initial_positions = turbines = pos_from_case(rerun_case_id) 
+            print('*Initial positions loaded from file: {}\n'.format(
+                    rerun_case_id))
+        else:
+            self.initial_positions = turbines = pos_from_case(rerun_case_id) 
+        print(turbines)
         n_wt = turbines.shape[0]
         if boundary_type == 'polygon':
             self.boundary_comp = PolygonBoundaryComp(boundary, n_wt)
@@ -44,6 +55,17 @@ class TopFarm(object):
         prob.model.add_subsystem('cost_comp', cost_comp, promotes=['*'])
         prob.driver = driver
 
+        if record:
+            timestr = time.strftime("%Y%m%d_%H%M%S")
+            filename = 'cases_{}.sql'.format(timestr)
+            case_recorder_filename = os.path.join(case_recorder_dir, filename)
+            recorder = SqliteRecorder(case_recorder_filename)
+            prob.driver.add_recorder(recorder)
+            prob.driver.recording_options['record_desvars'] = True
+            prob.driver.recording_options['record_responses'] = True
+            prob.driver.recording_options['record_objectives'] = True
+            prob.driver.recording_options['record_constraints'] = True
+
         prob.model.add_design_var('turbineX', **design_var_kwargs)
         prob.model.add_design_var('turbineY', **design_var_kwargs)
         prob.model.add_objective('cost')
@@ -63,6 +85,9 @@ class TopFarm(object):
 
         prob.setup(check=True, mode='fwd')
 
+
+        
+        
     def check(self, all=False, tol=1e-3):
         """Check gradient computations"""
         comp_name_lst = [comp.pathname for comp in self.problem.model.system_iter()
diff --git a/topfarm/recording.py b/topfarm/recording.py
new file mode 100644
index 00000000..3b367276
--- /dev/null
+++ b/topfarm/recording.py
@@ -0,0 +1,39 @@
+import os
+import numpy as np
+from openmdao.api import CaseReader
+
+
+def pos_from_case(case_recorder_filename):
+    cr = CaseReader(case_recorder_filename)
+    case_list = cr.driver_cases.list_cases()
+    case_len = len(case_list)
+    case_arg = 'rank0:SLSQP|{:d}'.format(case_len-1)
+    case = cr.driver_cases.get_case(case_arg)
+    x = np.array(case.desvars['turbineX'])
+    y = np.array(case.desvars['turbineY'])
+    turbines = np.column_stack((x, y))
+    return turbines
+
+
+def latest_id(case_recorder_dir):
+    files = os.listdir(case_recorder_dir)
+    files = [x for x in files if x.startswith('cases_') and x.endswith('.sql')]
+    if len(files) == 0:
+        string = 'No recorded files found in the specified directory: '
+        string += case_recorder_dir + '\n' + 9*' '
+        string += 'Start a new optimization or specify another directory '
+        string += 'for resumed optimization'
+        raise Warning(string)
+    latest = max(files)
+    latest = os.path.join(case_recorder_dir,latest)
+    return latest
+    
+if __name__ == '__main__':
+    crf = r"C:\Sandbox\Git\TopFarm2\topfarm\cases_20180621_104446.sql"
+    case_recorder_filename = crf
+    turbines = pos_from_case(case_recorder_filename)
+    print(turbines)
+
+    case_recorder_dir = r'C:\Sandbox\Git\TopFarm2\topfarm'
+    latest_id = latest_id(case_recorder_dir)
+    print(latest_id)
-- 
GitLab