Skip to content
Snippets Groups Projects
Commit 413fc6c4 authored by Mikkel Friis-Møller's avatar Mikkel Friis-Møller
Browse files

renamed recording to utils

new random initial positions feature that respects the boundaries and tries to respect the min spacing

animations now possible

added test-file to optimization recording testing and tests to the utility module
parent 84a9cc2d
No related branches found
No related tags found
1 merge request!38Animation
from topfarm.constraint_components.boundary_component import BoundaryComp,\
PolygonBoundaryComp
from topfarm.constraint_components.spacing_component import SpacingComp
from topfarm.plotting import PlotComp
from topfarm.utils import pos_from_case, latest_id
import os
import time
import numpy as np
......@@ -5,41 +10,38 @@ import warnings
with warnings.catch_warnings():
warnings.simplefilter('ignore', FutureWarning)
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.utils import pos_from_case, latest_id
class TopFarm(object):
"""Optimize wind farm layout in terms of
"""Optimize wind farm layout in terms of
- Position of turbines
[- Type of turbines: Not implemented yet]
[- Height of turbines: Not implemented yet]
[- Number of turbines: Not implemented yet]
"""
def __init__(self, turbines, cost_comp, min_spacing, boundary, boundary_type='convex_hull', plot_comp=None,
driver=ScipyOptimizeDriver(), record = False, case_recorder_dir = os.getcwd(),
rerun_case_id = None):
def __init__(self, turbines, cost_comp, min_spacing, boundary,
boundary_type='convex_hull', plot_comp=None,
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)
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)
self.initial_positions = turbines = pos_from_case(rerun_case_id)
n_wt = turbines.shape[0]
if boundary_type == 'polygon':
self.boundary_comp = PolygonBoundaryComp(boundary, n_wt)
else:
self.boundary_comp = BoundaryComp(boundary, n_wt, boundary_type)
self.problem = prob = Problem()
indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*'])
indeps = prob.model.add_subsystem('indeps', IndepVarComp(),
promotes=['*'])
min_x, min_y = self.boundary_comp.vertices.min(0)
mean_x, mean_y = self.boundary_comp.vertices.mean(0)
design_var_kwargs = {}
......@@ -69,8 +71,10 @@ class TopFarm(object):
prob.model.add_design_var('turbineY', **design_var_kwargs)
prob.model.add_objective('cost')
prob.model.add_subsystem('spacing_comp', SpacingComp(nTurbines=n_wt), promotes=['*'])
prob.model.add_subsystem('bound_comp', self.boundary_comp, promotes=['*'])
prob.model.add_subsystem('spacing_comp', SpacingComp(nTurbines=n_wt),
promotes=['*'])
prob.model.add_subsystem('bound_comp', self.boundary_comp,
promotes=['*'])
if plot_comp == "default":
plot_comp = PlotComp()
if plot_comp:
......@@ -85,8 +89,6 @@ 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()
......@@ -133,6 +135,14 @@ class TopFarm(object):
return np.array([self.problem['turbineX'], self.problem['turbineY']]).T
def post_process(self, anim_time=10, verbose=True):
if self.plot_comp.animate:
self.plot_comp.run_animate(anim_time, verbose)
for file in os.listdir(self.plot_comp.temp):
if file.startswith('plot_') and file.endswith('.png'):
os.remove(os.path.join(self.plot_comp.temp,file))
def try_me():
if __name__ == '__main__':
from topfarm.cost_models.dummy import DummyCostPlotComp, DummyCost
......@@ -145,12 +155,13 @@ def try_me():
turbines = np.array(optimal) + np.random.randint(-random_offset, random_offset, (n_wt, 2))
plot_comp = DummyCostPlotComp(optimal)
plot_comp.animate = True
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()
tf.post_process()
try_me()
......@@ -85,4 +85,3 @@ class SpacingComp(ExplicitComponent):
dSdy[k, i] = -2 * (turbineY[j] - turbineY[i])
# increment turbine pair counter
k += 1
return dSdx, dSdy
import time
import matplotlib
from openmdao.core.explicitcomponent import ExplicitComponent
import os
import matplotlib.pyplot as plt
import numpy as np
......@@ -23,13 +21,15 @@ def mypause(interval):
class PlotComp(ExplicitComponent):
colors = ['b', 'r', 'm', 'c', 'g', 'y', 'orange', 'indigo', 'grey'] * 100
def __init__(self, memory=10, delay=0.001, plot_initial=True):
def __init__(self, memory=10, delay=0.001, plot_initial=True,
animate=False):
ExplicitComponent.__init__(self)
self.memory = memory
self.delay = delay
self.plot_initial = plot_initial
self.history = []
self.counter = 0
self.animate = animate
def show(self):
plt.show()
......@@ -59,20 +59,29 @@ class PlotComp(ExplicitComponent):
cost = inputs['cost'][0]
if not hasattr(self, "initial"):
self.initial = np.array([x, y]).T, cost
self.history = [(x.copy(), y.copy())] + self.history[:self.memory]
boundary = inputs['boundary']
self.init_plot(boundary)
plt.title("%f (%.2f%%)"%(cost, (self.initial[1]-cost)/self.initial[1]*100))
plt.title("%f (%.2f%%)" % (cost,
(self.initial[1]-cost)/self.initial[1]*100))
history_arr = np.array(self.history)
for i, c, x_, y_ in zip(range(len(x)), self.colors, x, y):
if self.plot_initial:
plt.plot([self.initial[0][i, 0], x_], [self.initial[0][i, 1], y_], '-', color=c, lw=1)
plt.plot(history_arr[:, 0, i], history_arr[:, 1, i], '.--', color=c, lw=1)
plt.plot([self.initial[0][i, 0], x_],
[self.initial[0][i, 1], y_], '-', color=c, lw=1)
plt.plot(history_arr[:, 0, i], history_arr[:, 1, i], '.--',
color=c, lw=1)
plt.plot(x_, y_, 'o', color=c, ms=5)
plt.plot(x_, y_, 'x' + 'k', ms=4)
self.temp = '../__animations__'
if not os.path.exists(self.temp):
os.makedirs(self.temp)
if self.animate:
path = os.path.join(self.temp,
'plot_{:05d}.png'.format(self.counter))
plt.savefig(path)
if self.counter == 0:
plt.pause(.01)
......@@ -80,6 +89,16 @@ class PlotComp(ExplicitComponent):
self.counter += 1
def run_animate(self, anim_time=10, verbose=False):
N = anim_time/self.counter
string = 'ffmpeg -f image2 -r 1/'
string += '{} -i {}//plot_%05d.png'.format(N, self.temp)
string += ' -vcodec mpeg4 -y {}//animation.mp4'.format(self.temp)
if verbose:
print('\nCreating animation:')
print(string)
os.system(string)
class NoPlot(PlotComp):
def __init__(self, *args, **kwargs):
......
File added
# -*- coding: utf-8 -*-
from topfarm import TopFarm
import numpy as np
from topfarm.cost_models.cost_model_wrappers import CostModelComponent
import pytest
import os
from topfarm.utils import pos_from_case, latest_id
thisdir = os.path.dirname(os.path.abspath(__file__))
turbines = np.array([[ 2.4999377 , -2.99987763],
[ 6. , -6.99997496],
[ 4.49993771, -2.99985273],
[ 3.00004123, -6.9999519 ]])
def test_pos_from_case():
crf = "..\\test_files\\recordings\cases_20180621_111710.sql"
path = os.path.join(thisdir, crf)
np.testing.assert_allclose(turbines, pos_from_case(path))
def test_latest_id():
crd = "..\\test_files\\recordings"
path = os.path.join(thisdir, crd)
ref_path = os.path.join(path,'cases_20180621_111710.sql')
assert latest_id(path) == ref_path
if __name__ == '__main__':
test_pos_from_case()
test_latest_id()
# pass
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment