Skip to content
Snippets Groups Projects
Commit 2c501cdd authored by Jenni Rinker's avatar Jenni Rinker
Browse files

Merge branch 'rnd_init_pos' into 'master'

new random initial positions feature

See merge request !37
parents edd39f00 78e39b30
No related branches found
No related tags found
1 merge request!94Handle disabled mpi
......@@ -10,7 +10,7 @@ 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
from topfarm.utils import pos_from_case, latest_id
class TopFarm(object):
......
......@@ -33,34 +33,39 @@ class SpacingComp(ExplicitComponent):
self.declare_partials('wtSeparationSquared', ['turbineX', 'turbineY'])
def compute(self, inputs, outputs):
# print 'in dist const'
turbineX = inputs['turbineX']
turbineY = inputs['turbineY']
separation_squared = self._compute(turbineX, turbineY)
outputs['wtSeparationSquared'] = separation_squared
def _compute(self, turbineX, turbineY):
nTurbines = self.nTurbines
separation_squared = np.zeros(int((nTurbines - 1) * nTurbines / 2))
k = 0
for i in range(0, nTurbines):
for j in range(i + 1, nTurbines):
separation_squared[k] = (turbineX[j] - turbineX[i])**2 + (turbineY[j] - turbineY[i])**2
k += 1
outputs['wtSeparationSquared'] = separation_squared
# print("wt sep")
# print(separation_squared)
# print()
return separation_squared
def compute_partials(self, inputs, J):
# obtain necessary inputs
turbineX = inputs['turbineX']
turbineY = inputs['turbineY']
dSdx, dSdy = self._compute_partials(turbineX, turbineY)
# populate Jacobian dict
J['wtSeparationSquared', 'turbineX'] = dSdx
J['wtSeparationSquared', 'turbineY'] = dSdy
def _compute_partials(self, turbineX, turbineY):
# get number of turbines
nTurbines = self.nTurbines
# initialize gradient calculation array
dS = np.zeros((int((nTurbines - 1.) * nTurbines / 2.), 2 * nTurbines))
dSdx = np.zeros((int((nTurbines - 1.) * nTurbines / 2.), nTurbines)) #col: dx_1-dx_n, row: d12, d13,..,d1n, d23..d2n,..
dSdy = np.zeros((int((nTurbines - 1.) * nTurbines / 2.), nTurbines))
......@@ -71,20 +76,13 @@ class SpacingComp(ExplicitComponent):
for i in range(0, nTurbines):
for j in range(i + 1, nTurbines):
# separation wrt Xj
dS[k, j] = 2 * (turbineX[j] - turbineX[i])
dSdx[k,j]= 2 * (turbineX[j] - turbineX[i])
# separation wrt Xi
dS[k, i] = -2 * (turbineX[j] - turbineX[i])
dSdx[k, i] = -2 * (turbineX[j] - turbineX[i])
# separation wrt Yj
dS[k, j + nTurbines] = 2 * (turbineY[j] - turbineY[i])
dSdy[k, j] = 2 * (turbineY[j] - turbineY[i])
# separation wrt Yi
dS[k, i + nTurbines] = -2 * (turbineY[j] - turbineY[i])
dSdy[k, i] = -2 * (turbineY[j] - turbineY[i])
# increment turbine pair counter
k += 1
# populate Jacobian dict
J['wtSeparationSquared', 'turbineX'] = dS[:, :nTurbines]
J['wtSeparationSquared', 'turbineY'] = dS[:, nTurbines:]
return dSdx, dSdy
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)
from topfarm.constraint_components.boundary_component import \
PolygonBoundaryComp
from topfarm.constraint_components.spacing_component import SpacingComp
import os
from copy import copy
import numpy as np
from openmdao.api import CaseReader
import matplotlib.pyplot as plt
def pos_from_case(case_recorder_filename):
'''
Input: a recorded optimization case
Returns the positions at the last step of that optimization
'''
if not os.path.exists(case_recorder_filename):
string = 'The specified optimization recording does not exists: '
string += case_recorder_filename
raise Warning(string)
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):
'''
Input: path to the directory of recorded optimizations
Returns the absolute path to the most recent recording in that directory
'''
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
def random_positions(boundary, n_wt, n_iter, step_size, min_space,
pad = 1.1, plot=False, verbose=True):
'''
Input:
boundary: list of tuples, e.g.: [(0, 0), (6, 1), (7, -11), (-1, -10)]
n_wt: number of wind turbines
n_iter: number of iterations allowed to try and satisfy the minimum
spacing constraint
step_size: the multiplier on the spacing gradient that the turbines
are moved in each step
min_space: the minimum spacing between turbines
pad: the multiplier on the boundary gradient
plot: plot the generated random layout
verbose: print helpful text to the console
Returns an array of xy coordinates of the wind turbines
'''
x, y = map(_random, np.array(boundary).T)
turbines = _random_positions(x, y, boundary, n_wt, n_iter, step_size,
min_space, pad, plot, verbose)
return turbines
def _random_positions(x, y, boundary, n_wt, n_iter, step_size, min_space,
pad, plot, verbose):
boundary_comp = PolygonBoundaryComp(boundary, n_wt)
spacing_comp = SpacingComp(nTurbines=n_wt)
turbineX = copy(x)
turbineY = copy(y)
min_space2 = min_space**2
ba = np.array(boundary).T
bx = np.append(ba[0], ba[0][0])
by = np.append(ba[1], ba[1][0])
if plot:
plt.cla()
plt.plot(bx, by)
plt.plot(x, y, '.')
for j in range(n_iter):
dist = spacing_comp._compute(turbineX, turbineY)
dx, dy = spacing_comp._compute_partials(turbineX, turbineY)
index = np.argmin(dist)
if dist[index] < min_space2:
turbineX += dx[index]*step_size
turbineY += dy[index]*step_size
turbineX, turbineY = _contain(n_wt, turbineX, turbineY,
boundary_comp, pad)
else:
if verbose:
print('Obtained required spacing after {} iterations'.format(
j))
break
if plot:
plt.plot(turbineX, turbineY, 'o')
dist = spacing_comp._compute(turbineX, turbineY)
index = np.argmin(dist)
if verbose:
print('Spacing obtained: {}'.format(dist[index]**0.5))
print('Spacing required: {}'.format(min_space))
turbines = np.array([turbineX, turbineY]).T
return turbines
def _random(b):
return np.random.rand(n_wt) * (max(b) - min(b)) + min(b)
def _contain(n_wt, turbineX, turbineY, boundary_comp, pad):
for i in range(0, n_wt):
dng = boundary_comp.calc_distance_and_gradients(turbineX,
turbineY)
dist = dng[0][i]
if dist < 0:
dx = dng[1][i]
dy = dng[2][i]
turbineX[i] -= dx*dist*pad
turbineY[i] -= dy*dist*pad
return turbineX, turbineY
if __name__ == '__main__':
# this_dir = os.path.dirname(os.path.abspath(__file__))
# crf = r"C:\Sandbox\Git\TopFarm2\topfarm\cases_20180621_111710.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)
boundary = [(0, 0), (6, 1), (7, -11), (-1, -10)]
n_wt = 20
n_iter = 1000
step_size = 0.1
min_space = 2.1
plot = True
verbose = True
turbines = random_positions(boundary, n_wt, n_iter, step_size, min_space,
plot, verbose)
print(turbines)
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