Skip to content
Snippets Groups Projects
constrained_generator.py 3.82 KiB
Newer Older
Mads M. Pedersen's avatar
Mads M. Pedersen committed
from openmdao.drivers.doe_generators import DOEGenerator, ListGenerator
import numpy as np



class ConstrainedDiscardXYZGenerator(DOEGenerator):
    def __init__(self, generator):
        DOEGenerator.__init__(self)
        if isinstance(generator, list):
            generator = ListGenerator(generator)
        self.generator = generator
        
    def __call__(self, design_vars, model=None):
        xy_boundary_comp = model._get_subsystem('xy_bound_comp')
        spacing_comp = model._get_subsystem('spacing_comp')
        for xyz_tuple_lst in self.generator(design_vars, model=model):
            x, y, z = ([np.array(t[1]) for t in xyz_tuple_lst] + [0])[:3]
            if spacing_comp:
                dist = spacing_comp._compute(x, y)
                if np.any(dist < spacing_comp.min_spacing**2):
                    continue
                 
            if xy_boundary_comp:
                dist_to_boundary =xy_boundary_comp.distances(x,y)
                if np.any(dist_to_boundary<0):
                    continue
            yield xyz_tuple_lst

Mads M. Pedersen's avatar
Mads M. Pedersen committed
class ConstrainedXYZGenerator(DOEGenerator):
    def __init__(self, generator, n_iter=1000, step_size=0.1, offset=0.5, verbose=False):
        DOEGenerator.__init__(self)
        self.n_iter = n_iter
        self.step_size = step_size
        self.offset = offset
        if isinstance(generator, list):
            generator = ListGenerator(generator)
        self.generator = generator
        self.verbose = verbose

    def __call__(self, design_vars, model=None):
        xy_boundary_comp = model._get_subsystem('xy_bound_comp')
        spacing_comp = model._get_subsystem('spacing_comp')
        for xyz_tuple_lst in self.generator(design_vars, model=model):
            x, y, z = ([np.array(t[1]).astype(np.float) for t in xyz_tuple_lst] + [0])[:3]
Mads M. Pedersen's avatar
Mads M. Pedersen committed
            if spacing_comp:
                for j in range(self.n_iter):
                    dist = spacing_comp._compute(x, y)
                    dx, dy = spacing_comp._compute_partials(x, y)
Mads M. Pedersen's avatar
Mads M. Pedersen committed
                    if dist[index] < spacing_comp.min_spacing**2 or j == 0:
                        x += dx[index] * self.step_size
                        y += dy[index] * self.step_size
Mads M. Pedersen's avatar
Mads M. Pedersen committed
                        if xy_boundary_comp:
                            x, y, z = xy_boundary_comp.move_inside(x, y, z)
                    else:
                        if self.verbose:
                            print('Obtained required spacing after %d iterations' % j)
                        xyz = np.array([x, y, z])
                        break

            elif xy_boundary_comp:
                xyz = xy_boundary_comp.move_inside(x, y, z)
            xyz_tuple_lst = [(t[0], xyz) for t, xyz in zip(xyz_tuple_lst, xyz)]
            yield xyz_tuple_lst
#
#
# class shuffle_generator(DOEGenerator):
#     def __init__(self, turbineXYZOptimizationProblem, N=10, shuffle_type='rel', n_iter=1000,
#                  step_size=0.1, pad=1.1, offset=5, plot=False,
#                  verbose=False):
#         self.N = N
#         self.shuffle_type = shuffle_type
#         self.n_iter = n_iter
#         self.step_size = step_size
#         self.pad = pad
#         self.offset = offset
#         self.plot = plot
#         self.verbose = verbose
#         DOEGenerator.__init__(self)
#         self.turbineXYZOptimizationProblem = turbineXYZOptimizationProblem
#
#     def __call__(self, *args, **kwargs):
#         for _ in range(self.N):
#             p = self.turbineXYZOptimizationProblem
#             turbines = spos(p.xy_boundary, p.n_wt, p.min_spacing,
#                             p.turbine_positions, self.shuffle_type, self.n_iter,
#                             self.step_size, self.pad, self.offset, self.plot, self.verbose)
#             x, y = turbines.T
#             yield np.array([x, y, self.initialXYZOptimizationProblem['turbineZ']])