def find_distance(nt, a, diam, min_x, max_x, min_y, max_y):
     n = 0
     while n == 0:
         n = 1
         for i in range(nt):
             for j in range(nt):
                 if i != j and distance(a[i][0], a[i][1], a[j][0], a[j][1]) < 2.0 * diam:
                     # print 'counting'
                     a[j] = gen_turbine(min_x, max_x, min_y, max_y)
                     n = 0
     return a
def pso_horns():

    windrose = open('horns_rev_windrose2.dat', 'r')
    windrose_angle = []
    windrose_speed = []
    windrose_frequency = []
    for line in windrose:
        columns = line.split()
        windrose_angle.append(float(columns[0]))
        windrose_speed.append(float(columns[1]))
        windrose_frequency.append(float(columns[2]))

    windrose.close()

    data = open('pso7_layout_ainslie.dat', 'w', 1)
    data2 = open('pso7_random_layout_ainslie.dat', 'w', 1)
    data3 = open('pso7_best_global_fitness_ainslie.dat', 'w', 1)
    #  pso1 first run. Np 40 (max recommended). Ainslie model combination 30 from MCDA. 20 000 iterations to see what happens. 12.91 = 87.09% eff.
    #  pso2 Less particles down to 25. Ive changed the inertia and acceleration coefficients multiplied by 0.1. added e-1. For smaller movements and less chaos. Didnt work because of e-1 i think, it moves too slow so nothing changes. 13.46 = 86.54% eff.
    #  pso3 chagned e-1 to decimal notation of the accel. coefficients. 5 particles only to test.
    #  pso4     n_iter = 80    np = 25 ## Number of particles in swarm. 2000 function calls. 8 hrs
    #  pso5 same as pso4, with np = 15, n_iter = 134
    # pso 7 same as pso 5 more iter to 268.

    n_iter = 268
    np = 15 ## Number of particles in swarm
    nt = 80
    diam = 80.0
    particles = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])

    if random() < 0.5:
        sign1 = 1.0
    else:
        sign1 = - 1.0
    if random() < 0.5:
        sign2 = 1.0
    else:
        sign2 = - 1.0

    vel = array([[[sign1 * random(), sign2 * random()] for x in range(nt)] for x in range(np)])

    best_own_fitness = [100.0 for x in range(np)]
    best_global_fitness = 100.0

    def create():
        k = random()
        l = random()
        xt = 5457.0 * l
        if xt <= 412.0:
            yt = k * 3907.0 + (1.0 - k) * (- 3907.0 / 412.0 * xt + 3907.0)
        elif xt <= 5040.0:
            yt = k * 3907.0
        else:
            yt = k * (3907.0 / 417.0 * (- xt + 5457.0))
        return xt, yt

    ## Produce starting positions. Includes boundaries of Horns Rev
    for n in range(np):
        for tur in range(nt):
            particles[n][tur] = create()

    best_layout = particles[0]
    best_local = array(particles)

    for ite in range(n_iter):
    # while best_global_fitness > 0.001:
        start_time2 = time.time()

        for p in range(np):  # Can be parallelised in the future.
            # Solving Constrained Nonlinear Optimization Problems with Particle Swarm Optimization by Xiaohui Hu and Russell Eberhart. For 1.49445 learning coefficients.
            vel[p] = 0.72984 * vel[p] + 1.49617 * random() * (best_local[p] - particles[p]) + 1.49617 * random() * (best_layout - particles[p])
            particles[p] += vel[p]
            for t in range(nt):  # Reflect on boundary
                j = 1.0
                w = 1.0
                while particles[p][t][1] > 3907.0 or particles[p][t][1] < 0.0:
                    if particles[p][t][1] > 3907.0:
                        particles[p][t][1] = 3907.0 * 2.0 - particles[p][t][1]
                        j = random()
                    elif particles[p][t][1] < 0.0:
                        particles[p][t][1] = - particles[p][t][1]
                        j = random()
                while particles[p][t][1] < - 3907.0 / 412.0 * particles[p][t][0] + 3907.0 or particles[p][t][1] > 3907.0 / 417.0 * (- particles[p][t][0] + 5457.0):
                    if particles[p][t][0] < 412.0 / 3907.0 * (3907.0 - particles[p][t][1]):
                        particles[p][t][0] = 2.0 * (412.0 / 3907.0) * (3907.0 - particles[p][t][1]) - particles[p][t][0]
                        w = random()
                    elif particles[p][t][0] > 5457.0 - particles[p][t][0] * 417.0 / 3907.0:
                        particles[p][t][0] = 2.0 * (5457.0 - particles[p][t][0] * 417.0 / 3907.0) - particles[p][t][0]
                        w = random()
                vel[p][t] *= [- w, - j]

        # Find minimum distance between turbines, and if two are closer than 1D, then randomise one of them. TODO Must be 2D if used with Ainslie model, since it does not guarantee any data before 2D.
        for b in range(np):
            pp = 0
            while pp == 0:
                pp = 1
                for i in range(nt):
                    for j in range(nt):
                        if i != j and distance(particles[b][i][0], particles[b][i][1], particles[b][j][0], particles[b][j][1]) < 2.0 * diam:
                            particles[b][j] = create()
                            pp = 0

        # Fitness evaluation skipped if counter turbine is out of boundaries. following: BrattonKennedy07 PSO. Not used.
        # More 'repair' methods for particles out of boundaries shown in PhD thesis Helwig2010.
        # Chu2011 proves that the reflecting boundary method is better than random or absorbing boundary.

        fitness = Parallel(n_jobs=8)(delayed(fit)(particles[i], windrose_angle, windrose_speed, windrose_frequency) for i in range(np))

        for p in range(np):
            if fitness[p] < best_own_fitness[p]:
                best_own_fitness[p] = fitness[p]
                best_local[p] = copy.deepcopy(particles[p])
            if fitness[p] < best_global_fitness:
                best_global_fitness = fitness[p]
                best_layout = copy.deepcopy(particles[p])
                for i in range(nt):
                    data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
                data.write('\n')
                data3.write('{1:d} {0:f}\n'.format(best_global_fitness, ite))

        for i in range(nt):
            data2.write('{2:d} {0:f} {1:f}\n'.format(particles[4][i][0], particles[4][i][1], i))
        data2.write('\n')


        print(" --- %s seconds ---" % (time.time() - start_time2))
    data.close()
    data2.close()
    data3.close()
Ejemplo n.º 3
0
def pso_horns():
    data = open('3horns_pso.dat', 'w')
    data2 = open('3swarm_horns.dat', 'w')
    data3 = open('3globalfit.dat', 'w')

    np = 20
    nt = 45
    diam = 80.0
    particles = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])

    if random() < 0.5:
        sign1 = 1.0
    else:
        sign1 = - 1.0
    if random() < 0.5:
        sign2 = 1.0
    else:
        sign2 = - 1.0
    vel = array([[[sign1 * random(), sign2 * random()] for x in range(nt)] for x in range(np)])
    best_local = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])
    best_own_fitness = [0.0 for x in range(np)]
    best_global_fitness = 0.0

    def create():
        k = random()
        l = random()
        xt = 400.0 * l
        yt = 3600 * k
        return xt, yt

    ## Produce starting positions. Includes boundaries of Horns Rev
    for n in range(np):
        for tur in range(nt):
            particles[n][tur] = create()

    best_layout = particles[0]

    for i in range(nt):
        data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
    data.write('\n')

    for iter in range(2000):

        start_time2 = time.time()

        fitness = Parallel(n_jobs=8)(delayed(fit)(particles[i], nt, diam / 2.0) for i in range(np))
        # for p in range(np):
        #     fitness[p] = fit(particles[p], nt, diam / 2.0)
        for p in range(np):
            if fitness[p] > best_own_fitness[p]:
                best_own_fitness[p] = fitness[p]
                best_local[p] = particles[p]
            if fitness[p] > best_global_fitness:
                best_global_fitness = fitness[p]
                best_layout = particles[p]

        for i in range(nt):
            data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
            data2.write('{2:d} {0:f} {1:f}\n'.format(particles[10][i][0], particles[10][i][1], i))
        data2.write('\n')
        data.write('\n')
        data3.write('{0:f}\n'.format(best_global_fitness))

        for p in range(np):
            ## Solving Constrained Nonlinear Optimization Problems with Particle Swarm Optimization by Xiaohui Hu and Russell Eberhart. For 1.49445 learning coefficients.
            vel[p] = (0.5 + random() / 2.0) * vel[p] + 2.0 * random() * (best_local[p] - particles[p]) + 2.0 * random() * (best_layout - particles[p])
            for t in range(nt):
                if vel[p][t][0] > 400.0:
                    vel[p][t][0] = 400.0
                if vel[p][t][0] < - 400.0:
                    vel[p][t][0] = - 400.0
                if vel[p][t][1] > 3600.0:
                    vel[p][t][1] = 3600.0
                if vel[p][t][1] < - 3600.0:
                    vel[p][t][1] = - 3600.0
            particles[p] = particles[p] + vel[p]
            for tur in range(nt):
                if particles[p][tur][1] > 3600.0:
                    particles[p][tur][1] = random() * 3600.0
                elif particles[p][tur][1] < 0.0:
                    particles[p][tur][1] = random() * 3600.0
                if particles[p][tur][0] > 400.0:
                    particles[p][tur][0] = random() * 400.0
                elif particles[p][tur][0] < 0.0:
                    particles[p][tur][0] = random() * 400.0

        # Find minimum distance between turbines, and if two are closer than 1D, then randomise one of them.
        for b in range(np):
            pp = 0
            while pp == 0:
                pp = 1
                for i in range(nt):
                    for j in range(nt):
                        if i != j and distance(particles[b][i][0], particles[b][i][1], particles[b][j][0], particles[b][j][1]) < diam:
                            particles[b][j] = create()
                            pp = 0

        print best_global_fitness
        if iter % 50 == 0:
            sys.stdout.flush()

        print("Iteration --- %s seconds ---" % (time.time() - start_time2))
    data.close()
    data2.close()
    data3.close()
Ejemplo n.º 4
0
def pso_horns():

    windrose = open('horns_rev_windrose2.dat', 'r')
    windrose_angle = []
    windrose_speed = []
    windrose_frequency = []
    for line in windrose:
        columns = line.split()
        windrose_angle.append(float(columns[0]))
        windrose_speed.append(float(columns[1]))
        windrose_frequency.append(float(columns[2]))

    windrose.close()

    data = open('try_best_layout_jensen.dat', 'w')
    data2 = open('try_random_layout_jensen.dat', 'w')
    data3 = open('try_best_global_fitness_jensen.dat', 'w', 1)

    np = 20 ## Number of particles in swarm
    nt = 80
    diam = 80.0
    particles = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])

    if random() < 0.5:
        sign1 = 1.0
    else:
        sign1 = - 1.0
    if random() < 0.5:
        sign2 = 1.0
    else:
        sign2 = - 1.0

    vel = array([[[sign1 * random(), sign2 * random()] for x in range(nt)] for x in range(np)])
    best_local = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])
    best_own_fitness = [0.0 for x in range(np)]
    best_global_fitness = 0.0

    def create():
        k = random()
        l = random()
        xt = 5457.0 * l
        if xt <= 412.0:
            yt = k * 3907.0 + (1.0 - k) * (- 3907.0 / 412.0 * xt + 3907.0)
        elif xt <= 5040.0:
            yt = random() * 3907.0
        else:
            yt = k * (3907.0 / 417.0 * (- xt + 5457.0))
        return xt, yt

    ## Produce starting positions. Includes boundaries of Horns Rev
    for n in range(np):
        for tur in range(nt):
            particles[n][tur] = create()

    best_layout = particles[0]

    for i in range(nt):
        data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
    data.write('\n')

    # Velocity limiting to 10% to start with, for convergence, and then increase speed.s
    k = 0.1

    for iter in range(2000):

        start_time2 = time.time()
        # fitness = Parallel(n_jobs=8)(delayed(fit)(particles[i], windrose_angle, windrose_speed, windrose_frequency) for i in range(np))
        fitness = [0.0 for x in range(np)]

        # Fitness evaluation skipped if a turbine is out of boundaries. following: BrattonKennedy07 PSO.
        for p in range(np):  # Can be parallelised in the future.
            check = True
            for tur in range(nt):
                if particles[p][tur][1] > 3907.0:
                    check = False
                    break
                elif particles[p][tur][1] < 0.0:
                    check = False
                    break
                elif particles[p][tur][1] > 3907.0 / 417.0 * (- particles[p][tur][0] + 5457.0):
                    check = False
                    break
                elif particles[p][tur][1] < - 3907.0 / 412.0 * particles[p][tur][0] + 3907.0:
                    check = False
                    break
            if check:
                fitness[p] = fit(particles[p], windrose_angle, windrose_speed, windrose_frequency)
                if fitness[p] > best_own_fitness[p]:
                    best_own_fitness[p] = fitness[p]
                    best_local[p] = particles[p]
                if fitness[p] > best_global_fitness:
                    best_global_fitness = fitness[p]
                    best_layout = particles[p]

        for i in range(nt):
            data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
            data2.write('{2:d} {0:f} {1:f}\n'.format(particles[10][i][0], particles[10][i][1], i))
        data2.write('\n')
        data.write('\n')
        data3.write('{0:f}\n'.format(best_global_fitness))

        for p in range(np):  # Can be parallelised in the future.
            ## Solving Constrained Nonlinear Optimization Problems with Particle Swarm Optimization by Xiaohui Hu and Russell Eberhart. For 1.49445 learning coefficients.
            vel[p] = (0.5 + random() / 2.0) * vel[p] + 2.0 * random() * (best_local[p] - particles[p]) + 2.0 * random() * (best_layout - particles[p])
            for t in range(nt): # Velocity half the maximum distance between boundaries. following: Particle Swarm Optimization: A Tutorial by James Blondin PSO
                if vel[p][t][0] > k * 2728.5:
                    vel[p][t][0] = k * 2728.5
                if vel[p][t][0] < - k * 2728.5:
                    vel[p][t][0] = - k * 2728.5
                if vel[p][t][1] > k * 1953.5:
                    vel[p][t][1] = k * 1953.5
                if vel[p][t][1] < - k * 1953.5:
                    vel[p][t][1] = - k * 1953.5
            particles[p] = particles[p] + vel[p]

        # Find minimum distance between turbines, and if two are closer than 1D, then randomise one of them.
        for b in range(np):
            pp = 0
            while pp == 0:
                pp = 1
                for i in range(nt):
                    for j in range(nt):
                        if i != j and distance(particles[b][i][0], particles[b][i][1], particles[b][j][0], particles[b][j][1]) < diam:
                            particles[b][j] = create()
                            pp = 0

        print("Iteration --- %s seconds ---" % (time.time() - start_time2))
    data.close()
    data2.close()
    data3.close()
Ejemplo n.º 5
0
def Jensen(a, Nt, rad):
    from math import sqrt, log
    import wake
    from power_curve5MW import power5MW_kW as power  # Power curve 5 MW NREL

    windrose = open('horns_rev_windrose.dat', 'r')
    nt = Nt
    layout_x = [0.0 for x in range(nt)]
    layout_y = [0.0 for x in range(nt)]
    for x in range(nt):
        layout_x[x] = float(a[x][0])
        layout_y[x] = float(a[x][1])

    windrose_angle = []
    windrose_speed = []
    windrose_frequency = []
    for line in windrose:
        columns = line.split()
        windrose_angle.append(float(columns[0]))
        windrose_speed.append(float(columns[1]))
        windrose_frequency.append(float(columns[2]))

    windrose.close()
    summation = 0.0

    ## Power curve 2 MW Siemens.
    # def power(U0):
    #     if U0 < 4.0:
    #         return 0.0
    #     elif U0 >= 4.0:
    #         return 19.7907842158 * U0 ** 2.0 - 74.9080669331 * U0 + 37.257967033  # From 4 to 11 m/s

    # for wind in range(0, len(windrose_speed)):
    for wind in range(0, 1):
        U1 = windrose_speed[wind]  # Free stream wind speed
        U0 = U1 * (90.0 / 10.0) ** 0.11  # Power or log law for wind shear profile
        # U0 = U1 * log(70.0 / 0.005) / log(10.0 / 0.005)
        k = 0.04  # Decay constant
        r0 = rad  # Turbine rotor radius
        angle = windrose_angle[wind]
        angle3 = angle + 180.0
        wake_deficit_matrix = [[0.0 for x in range(nt)] for x in range(nt)]
        for turbine in range(nt):
            flag = [False for x in range(nt)]
            proportion = [0.0 for x in range(nt)]
            for i in range(nt):
                try:
                    proportion[i], flag[i] = wake.determine_if_in_wake(layout_x[turbine], layout_y[turbine], layout_x[i], layout_y[i], k, r0, angle3)
                except TypeError:
                    print layout_x[turbine], layout_y[turbine], layout_x[i], layout_y[i], k, r0, angle3

            # Matrix with effect of each turbine <i = turbine> on every other turbine <j> of the farm
            for j in range(nt):
                if turbine != j and flag[j] is True:
                    wake_deficit_matrix[turbine][j] = proportion[j] * wake.wake_deficit(0.46, k, wake.distance(layout_x[turbine], layout_y[turbine], layout_x[j], layout_y[j]), r0)
                elif turbine == j:
                    wake_deficit_matrix[turbine][j] = 0.0

        total_deficit = [0.0 for x in range(nt)]
        total_speed = [0.0 for x in range(nt)]
        for j in range(nt):
            for i in range(nt):
                total_deficit[j] += wake_deficit_matrix[i][j] ** 2.0
            total_deficit[j] = sqrt(total_deficit[j])
            total_speed[j] = U0 * (1.0 - total_deficit[j])

        # Farm efficiency
        profit = 0.0
        efficiency_proportion = [0.0 for x in range(0, len(windrose_frequency))]
        efficiency = 0.0
        for l in range(nt):
            profit += power(total_speed[l])
        efficiency = profit * 100.0 / (float(nt) * power(U0))
        efficiency_proportion[wind] = efficiency * windrose_frequency[wind] / 100.0
        summation += efficiency_proportion[wind]
    return summation  # Farm efficiency

# if __name__ == '__main__':
#     start_time = time.time()
#     Jensen()
# print("--- %s seconds ---" % (time.time() - start_time))
Ejemplo n.º 6
0
def jensen(a, windrose_angle, windrose_speed, windrose_frequency):
    import wake
    from math import sqrt, log, tan, cos
    from numpy import deg2rad

    nt = len(a)
    layout_x = [0.0 for x in range(nt)]
    layout_y = [0.0 for x in range(nt)]
    for x in range(nt):
        layout_x[x] = float(a[x][0])
        layout_y[x] = float(a[x][1])


        # Ct curves.
        # Polynomials 6th, 4th 3rd
        # - 3.10224672352816e-5 * U0 ** 4.0 + 0.0021367624 * U0 ** 3.0 - 0.0495873986 * U0 ** 2.0 + 0.3976324804 * U0 - 0.1608576035
        # 3.374593e-4 * U0 ** 3.0 - 0.0136412226 * U0 ** 2.0 + 0.1118003309 * U0 + 0.5782039288

        # Ct look-up table for linear interpolation
        # def thrust_table(v):
            #     if v == 4: return 0.82
            #     if v == 5: return 0.81
            #     if v == 6: return 0.8
            #     if v == 7: return 0.81
            #     if v == 8: return 0.81
            #     if v == 9: return 0.78
            #     if v == 10: return 0.74
            #     if v == 11: return 0.65
            #     if v == 12: return 0.57
            #     if v == 13: return 0.41
            #     if v == 14: return 0.31
            #     if v == 15: return 0.25
            #     if v == 16: return 0.2
            #     if v == 17: return 0.17
            #     if v == 18: return 0.14
            #     if v == 19: return 0.12
            #     if v == 20: return 0.1
            #     if v == 21: return 0.09
            #     if v == 22: return 0.08
            #     if v == 23: return 0.07
            #     if v == 24: return 0.06
            #     if v == 25: return 0.05

        # 2 step thrust curve:
        # 0.80 if U0 in 4 - 9 m/s
        # 0.250625 if U0 in 10 - 25 m/s


    def Ct(U0):
        if U0 < 4.0:
            return 0.1
        elif U0 <= 25.0:
            return 7.3139922126945e-7 * U0 ** 6.0 - 6.68905596915255e-5 * U0 ** 5.0 + 2.3937885e-3 * U0 ** 4.0 + - 0.0420283143 * U0 ** 3.0 + 0.3716111285 * U0 ** 2.0 - 1.5686969749 * U0 + 3.2991094727
        else:
            return 0.0

    def power(U0):
        if U0 < 4.0:
            return 0.0
        elif U0 <= 25.0:
            return 3.234808e-4 * U0 ** 7.0 - 0.0331940121 * U0 ** 6.0 + 1.3883148012 * U0 ** 5.0 - 30.3162345004 * U0 ** 4.0 + 367.6835557011 * U0 ** 3.0 - 2441.6860655008 * U0 ** 2.0 + 8345.6777042343 * U0 - 11352.9366182805
        else:
            return 0.0

            # Power curve polynomials.
        # elif U0 <= 25.0
            # - 0.0110778061 * U0 ** 5.0 + 0.8986075613 * U0 ** 4.0 - 27.2165513154 * U0 ** 3.0 + 368.8877606215 * U0 ** 2.0 - 1994.1905079276 * U0 + 3712.3986113386 #  5th degree
            # - 0.5308414162 * U0 ** 3.0 - 15.4948143381 * U0 ** 2.0 + 13.1508234816 * U0  # 3rd degree

        #  Interpolation
            #table:
    # def power_table(v):
    #     if v == 4: return 66.3
    #     if v == 5: return 152
    #     if v == 6: return 280
    #     if v == 7: return 457
    #     if v == 8: return 690
    #     if v == 9: return 978
    #     if v == 10: return 1296
    #     if v == 11: return 1598
    #     if v == 12: return 1818
    #     if v == 13: return 1935
    #     if v == 14: return 1980
    #     if v == 15: return 1995
    #     if v == 16: return 1999
    #     if v == 17: return 2000
    #     if v == 18: return 2000
    #     if v == 19: return 2000
    #     if v == 20: return 2000
    #     if v == 21: return 2000
    #     if v == 22: return 2000
    #     if v == 23: return 2000
    #     if v == 24: return 2000
    #     if v == 25: return 2000
# interpolation function
    # def interpolate(minx, miny, maxx, maxy, valx):
        # return miny + (maxy - miny) * ((valx - minx) / (maxx - minx))

        # 2 step Power curve
        # 815.0333333 kw from 4 to 13 m/s, 2000 from 13-25 m/s


    # for U0 in range(4, 20):
    summation = 0.0

    def distance_to_front(x, y, theta, r):
        theta = deg2rad(theta)
        return abs(x + tan(theta) * y - r / cos(theta)) / sqrt(1.0 + tan(theta) ** 2.0)

    # for wind in range(0, 1):
    for wind in range(0, len(windrose_angle)):
        U1 = windrose_speed[wind]  # Free stream wind speed
        U0 = U1 * (70.0 / 10.0) ** 0.11 # Power or log law for wind shear profile
        # U0 = 8.5
        k = 0.04  # Decay constant
        r0 = 40.0  # Turbine rotor radius
        angle = windrose_angle[wind]
        angle3 = angle + 180.0
        deficit_matrix = [[0.0 for x in range(nt)] for x in range(nt)]
        proportion = [[0.0 for x in range(nt)] for x in range(nt)]
        distance = [[0.0 for x in range(2)] for x in range(nt)]

        U = [U0 for x in range(nt)]
        total_deficit = [0.0 for x in range(nt)]

        for tur in range(nt):
            distance[tur] = [distance_to_front(layout_x[tur], layout_y[tur], angle, 100000000.0), tur]
        distance.sort()

        for turbine in range(nt):
            for num in range(turbine):
                total_deficit[distance[turbine][1]] += deficit_matrix[distance[turbine][1]][distance[num][1]] ** 2.0
            total_deficit[distance[turbine][1]] = sqrt(total_deficit[distance[turbine][1]])
            U[distance[turbine][1]] = U0 * (1.0 - total_deficit[distance[turbine][1]])
            for i in range(turbine + 1, nt):
                proportion[distance[turbine][1]][distance[i][1]] = wake.determine_if_in_wake(layout_x[distance[turbine][1]], layout_y[distance[turbine][1]], layout_x[distance[i][1]], layout_y[distance[i][1]], k, r0, angle3)
                deficit_matrix[distance[i][1]][distance[turbine][1]] = proportion[distance[turbine][1]][distance[i][1]] * wake.wake_deficit(Ct(U[distance[turbine][1]]), k, wake.distance(layout_x[distance[turbine][1]], layout_y[distance[turbine][1]], layout_x[distance[i][1]], layout_y[distance[i][1]]), r0)

        # Farm efficiency
        profit = 0.0
        efficiency_proportion = [0.0 for x in range(0, len(windrose_frequency))]
        for l in range(nt):
            profit += power(U[l])
        efficiency = profit * 100.0 / (float(nt) * power(U[distance[0][1]]))
        efficiency_proportion[wind] = efficiency * windrose_frequency[wind] / 100.0

        # print 'Farm efficiency with wind direction = {0:d} deg: {1:2.2f}%'.format(int(angle), efficiency)
        summation += efficiency_proportion[wind]

    return 100.0 - summation
Ejemplo n.º 7
0
def jensen(a, windrose_angle, windrose_speed, windrose_frequency):
    import wake
    from math import sqrt, log, tan, cos
    from numpy import deg2rad

    nt = len(a)
    layout_x = [0.0 for x in range(nt)]
    layout_y = [0.0 for x in range(nt)]
    for x in range(nt):
        layout_x[x] = float(a[x][0])
        layout_y[x] = float(a[x][1])

    def Ct(U0):
        if U0 < 4.0:
            return 0.1
        elif U0 <= 25.0:
            return 0.00000073139922126945 * U0 ** 6.0 - 0.0000668905596915255 * U0 ** 5.0 + 0.0023937885 * U0 ** 4.0 + - 0.0420283143 * U0 ** 3.0 + 0.3716111285 * U0 ** 2.0 - 1.5686969749 * U0 + 3.2991094727
        else:
            return 0.0

    def power(U0):
        if U0 < 4.0:
            return 0.0
        elif U0 <= 25.0:
            return 0.0003234808 * U0 ** 7.0 - 0.0331940121 * U0 ** 6.0 + 1.3883148012 * U0 ** 5.0 - 30.3162345004 * U0 ** 4.0 + 367.6835557011 * U0 ** 3.0 - 2441.6860655008 * U0 ** 2.0 + 8345.6777042343 * U0 - 11352.9366182805
        else:
            return 0.0

    # for U0 in range(4, 20):
    nt = 80  # Number of turbines
    summation = 0.0

    def distance_to_front(x, y, theta, r):
        theta = deg2rad(theta)
        return abs(x + tan(theta) * y - r / cos(theta)) / sqrt(1.0 + tan(theta) ** 2.0)

    for wind in range(0, len(windrose_angle)):
        U1 = windrose_speed[wind]  # Free stream wind speed
        U0 = U1 * (70.0 / 10.0) ** 0.11 # Power or log law for wind shear profile
        k = 0.04  # Decay constant
        r0 = 40.0  # Turbine rotor radius
        angle = windrose_angle[wind]
        angle3 = angle + 180.0
        deficit_matrix = [[0.0 for x in range(nt)] for x in range(nt)]
        proportion = [[0.0 for x in range(nt)] for x in range(nt)]
        distance = [[0.0 for x in range(2)] for x in range(nt)]

        U = [U0 for x in range(nt)]
        total_deficit = [0.0 for x in range(nt)]

        for tur in range(nt):
            distance[tur] = [distance_to_front(layout_x[tur], layout_y[tur], angle, 100000000.0), tur]
        distance.sort()

        for turbine in range(nt):
            for num in range(turbine):
                total_deficit[distance[turbine][1]] += deficit_matrix[distance[turbine][1]][distance[num][1]] ** 2.0
            total_deficit[distance[turbine][1]] = sqrt(total_deficit[distance[turbine][1]])
            U[distance[turbine][1]] = U0 * (1.0 - total_deficit[distance[turbine][1]])
            for i in range(turbine + 1, nt):
                proportion[distance[turbine][1]][distance[i][1]] = wake.determine_if_in_wake(layout_x[distance[turbine][1]], layout_y[distance[turbine][1]], layout_x[distance[i][1]], layout_y[distance[i][1]], k, r0, angle3)
                deficit_matrix[distance[i][1]][distance[turbine][1]] = proportion[distance[turbine][1]][distance[i][1]] * wake.wake_deficit(Ct(U[distance[turbine][1]]), k, wake.distance(layout_x[distance[turbine][1]], layout_y[distance[turbine][1]], layout_x[distance[i][1]], layout_y[distance[i][1]]), r0)

        # Farm efficiency
        profit = 0.0
        efficiency_proportion = [0.0 for x in range(0, len(windrose_frequency))]
        for l in range(nt):
            profit += power(U[l])
        efficiency = profit * 100.0 / (float(nt) * power(U[distance[0][1]]))
        efficiency_proportion[wind] = efficiency * windrose_frequency[wind] / 100.0
        # print 'Farm efficiency with wind direction = {0:d} deg: {1:2.2f}%'.format(int(angle), efficiency)
        summation += efficiency_proportion[wind]

    return summation
                def analysis():

                    # Random layout to test, since optimiser will always be dealing with random layouts.
                    layout_x = []
                    layout_y = []
                    nt = 80
                    for xx in range(nt):
                        l = random()
                        k = random()
                        layout_x.append(5457.0 * l)
                        if layout_x[-1] <= 412.0:
                            layout_y.append(k * 3907.0 + (1.0 - k) * (- 3907.0 / 412.0 * layout_x[-1] + 3907.0))
                        elif layout_x[-1] <= 5040.0:
                            layout_y.append(k * 3907.0)
                        else:
                            layout_y.append(k * (3907.0 / 417.0 * (- layout_x[-1] + 5457.0)))

                        nt = len(layout_y)  # Number of turbines ## Length of layout list
                        summation = 0.0

                    def distance_to_front(x, y, theta, r): ## TODO: Calculate distance to any front and use negative distances to order.
                        theta = deg2rad(theta)
                        return abs(x + tan(theta) * y - r / cos(theta)) / sqrt(1.0 + tan(theta) ** 2.0)

                    for wind in range(0, len(windrose_angle)):
                    # for wind in range(90, 91):
                        # if wind in [100, 133, 271, 280, 313]:
                        #     continue
                        U1 = windrose_speed[wind]  # Free stream wind speed
                        U0 = U1 * (70.0 / 10.0) ** 0.11 # Power or log law for wind shear profile
                        # U0 = U1 * log(70.0 / 0.005) / log(10.0 / 0.005)
                        # U0 = 8.5
                        k = 0.04  # Decay constant
                        r0 = 40.0  # Turbine rotor radius
                        angle = windrose_angle[wind]
                        angle3 = angle + 180.0
                        deficit_matrix = [[0.0 for x in range(nt)] for x in range(nt)]
                        proportion = [[0.0 for x in range(nt)] for x in range(nt)]
                        distance = [[0.0 for x in range(2)] for x in range(nt)]

                        U = [U0 for x in range(nt)]
                        total_deficit = [0.0 for x in range(nt)]

                        for tur in range(nt):
                            distance[tur] = [distance_to_front(layout_x[tur], layout_y[tur], angle, 100000000.0), tur]
                        distance.sort()

                        for turbine in range(nt):
                            for num in range(turbine):
                                total_deficit[distance[turbine][1]] += deficit_matrix[distance[turbine][1]][distance[num][1]] ** 2.0
                            total_deficit[distance[turbine][1]] = sqrt(total_deficit[distance[turbine][1]])
                            U[distance[turbine][1]] = U0 * (1.0 - total_deficit[distance[turbine][1]])
                            for i in range(turbine + 1, nt):
                                proportion[distance[turbine][1]][distance[i][1]] = wake.determine_if_in_wake(layout_x[distance[turbine][1]], layout_y[distance[turbine][1]], layout_x[distance[i][1]], layout_y[distance[i][1]], k, r0, angle3)
                                # If statement for proportion = 0
                                deficit_matrix[distance[i][1]][distance[turbine][1]] = proportion[distance[turbine][1]][distance[i][1]] * wake.wake_deficit(Ct(U[distance[turbine][1]]), k, wake.distance(layout_x[distance[turbine][1]], layout_y[distance[turbine][1]], layout_x[distance[i][1]], layout_y[distance[i][1]]), r0)

                        # for turb in range(nt):
                        #     for i in range(nt):
                        #         output.write('{0:f}\t'.format(deficit_matrix[turb][i]))
                        #     output.write('\n')
                        #     output2.write('{0:d}\t{1:.1f}\t{2:.1f}\t{3:f}\t{4:f}\t{5:d}\t{6:f}\n'.format(turb, layout_x[turb], layout_y[turb], total_deficit[turb], U[turb], int(angle), power(U[turb])))
                        # output2.write('\n')

                        # for n in range(nt):
                        #     aver[n] += power(U[n]) / 360.0
                        # ---------------------------------------TODO UNCOMMENT -----------------------------------------
                        if withdata:
                            turb_data.write('{0:f} {1:f}\n'.format(angle, power(U[14])))

                        # Farm efficiency
                        profit = 0.0
                        efficiency_proportion = [0.0 for x in range(0, len(windrose_frequency))]
                        for l in range(nt):
                            profit += power(U[l])
                        efficiency = profit * 100.0 / (float(nt) * power(U[distance[0][1]])) # same as using U0
                        efficiency_proportion[wind] = efficiency * windrose_frequency[wind] / 100.0
                        # print 'Farm efficiency with wind direction = {0:d} deg: {1:2.2f}%'.format(int(angle), efficiency)
                    # ---------------------------------------TODO UNCOMMENT ------------------------------------------
                        if withdata:
                            direction.write('{0:f} {1:f}\n'.format(angle, profit))
                        summation += efficiency_proportion[wind]
                    return summation
def pso_horns():

    windrose = open('horns_rev_windrose.dat', 'r')
    windrose_angle = []
    windrose_speed = []
    windrose_frequency = []
    for line in windrose:
        columns = line.split()
        windrose_angle.append(float(columns[0]))
        windrose_speed.append(float(columns[1]))
        windrose_frequency.append(float(columns[2]))

    windrose.close()

    data = open('ref3_layout.dat', 'w', 1)
    data2 = open('ref3_random_layout.dat', 'w', 1)
    data3 = open('ref3_best_global_fitness.dat', 'w', 1)
    allfit = open('ref3_all_fitnesses.dat', 'w', 1)
    #  pso1 first run. Np 40 (max recommended). Ainslie model combination 30 from MCDA. 20 000 iterations to see what happens. 12.91 = 87.09% eff.
    #  pso2 Less particles down to 25. Ive changed the inertia and acceleration coefficients multiplied by 0.1. added e-1. For smaller movements and less chaos. Didnt work because of e-1 i think, it moves too slow so nothing changes. 13.46 = 86.54% eff.
    #  pso3 chagned e-1 to decimal notation of the accel. coefficients. 5 particles only to test.
    #  pso4     n_iter = 80    np = 25 ## Number of particles in swarm. 2000 function calls. 8 hrs
    # pso6 same as pso 4 more iterations to  160.
    #  pso8 includes one particle as the original horns rev. 10 particles to test.
    #  ref1 reflecting, 10 particles. Changed vel and particles update with one operation per dimension. 138 seconds per iteration.
    #  ref2 10 particles, changed windrose to 30 degrees for speed. 3.5 seconds per iteration. 200 iterations.
    #  ref3 same as ref2, 2000 iterations.
    n_iter = 2000
    np = 10 ## Number of particles in swarm
    nt = 80
    diam = 80.0
    particles = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])

    # if random() < 0.5:
    #     sign1 = 1.0
    # else:
    #     sign1 = - 1.0
    # if random() < 0.5:
    #     sign2 = 1.0
    # else:
    #     sign2 = - 1.0

    vel = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])

    best_own_fitness = [100.0 for x in range(np)]
    best_global_fitness = 100.0

    def create():
        k = random()
        l = random()
        xt = 5457.0 * l
        if xt <= 412.0:
            yt = k * 3907.0 + (1.0 - k) * (- 3907.0 / 412.0 * xt + 3907.0)
        elif xt <= 5040.0:
            yt = k * 3907.0
        else:
            yt = k * (3907.0 / 417.0 * (- xt + 5457.0))
        return xt, yt

    ## Produce starting positions. Includes boundaries of Horns Rev
    for n in range(np):
        for tur in range(nt):
            particles[n][tur] = create()
    # layout = open('horns_rev.dat', 'r')
    # ll = 0
    # horns = array([[0, 0] for gf in range(nt)])
    # for line in layout:
    #     columns = line.split()
    #     horns[ll] = [float(columns[0]) - 423974.0, float(columns[1]) - 6147543.0]
    #     ll += 1
    # layout.close()
    # particles[np - 1] = horns
    fitness = Parallel(n_jobs=-1)(delayed(fit)(particles[i], windrose_angle, windrose_speed, windrose_frequency) for i in range(np))
    # fitness = Parallel(n_jobs=-1)(delayed(fit)(particles[i], nt) for i in range(np))
    best_layout = copy.deepcopy(particles[fitness.index(min(fitness))])
    best_local = copy.deepcopy(particles)

    for ite in range(n_iter):
        start_time2 = time.time()

        for p in range(np):  # Can be parallelised in the future.
            # Solving Constrained Nonlinear Optimization Problems with Particle Swarm Optimization by Xiaohui Hu and Russell Eberhart. For 1.49445 learning coefficients.
            for t in range(nt):
                for coord in range(2):
                    vel[p][t][coord] = 0.72984 * vel[p][t][coord] + 1.49617 * random() * (best_local[p][t][coord] - particles[p][t][coord]) + 1.49617 * random() * (best_layout[t][coord] - particles[p][t][coord])
                    particles[p][t][coord] += vel[p][t][coord]
                j = 1.0
                w = 1.0
                while particles[p][t][1] > 3907.0 or particles[p][t][1] < 0.0:
                    if particles[p][t][1] > 3907.0:
                        particles[p][t][1] = 3907.0 * 2.0 - particles[p][t][1]
                        j = random()
                    elif particles[p][t][1] < 0.0:
                        particles[p][t][1] = - particles[p][t][1]
                        j = random()
                while particles[p][t][1] < - 3907.0 / 412.0 * (particles[p][t][0]+10.) + 3907.0 or particles[p][t][1] > 3907.0 / 417.0 * (- particles[p][t][0] + 5457.0+10.):
                    if particles[p][t][1] < - 3907.0 / 412.0 * (particles[p][t][0]+10.) + 3907.0:
                        particles[p][t][0] = 2.0 * (412.0 / 3907.0) * (3907.0 - particles[p][t][1]) - particles[p][t][0]
                        w = random()
                    elif particles[p][t][1] > 3907.0 / 417.0 * (- particles[p][t][0] + 5457.0+10.):
                        particles[p][t][0] = 2.0 * (5457.0 - particles[p][t][0] * 417.0 / 3907.0) - particles[p][t][0]
                        w = random()
                vel[p][t] *= [- w, - j]
        # Find minimum distance between turbines, and if two are closer than 1D, then randomise one of them. TODO Must be 2D if used with Ainslie model, since it does not guarantee any data before 2D.
        for b in range(np):
            pp = 0
            while pp == 0:
                pp = 1
                for i in range(nt):
                    for j in range(nt):
                        if i != j and distance(particles[b][i][0], particles[b][i][1], particles[b][j][0], particles[b][j][1]) < 2.0 * diam:
                            particles[b][j] = create()
                            pp = 0


        # More 'repair' methods for particles out of boundaries shown in PhD thesis Helwig2010.
        # Chu2011 proves that the reflecting boundary method is better than random or absorbing boundary.

        for fg in range(np):
            allfit.write('{0:f}\n'.format(fitness[fg]))
        allfit.write('\n')

        fitness = Parallel(n_jobs=-1)(delayed(fit)(particles[i], windrose_angle, windrose_speed, windrose_frequency) for i in range(np))
        # fitness = Parallel(n_jobs=-1)(delayed(fit)(particles[i], nt) for i in range(np))

        for p in range(np):
            if fitness[p] < best_own_fitness[p]:
                best_own_fitness[p] = fitness[p]
                best_local[p] = copy.deepcopy(particles[p])
            if fitness[p] < best_global_fitness:
                best_global_fitness = fitness[p]
                best_layout = copy.deepcopy(particles[p])
                for i in range(nt):
                    data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
                data.write('\n')
                data3.write('{1:d} {0:f}\n'.format(best_global_fitness, ite))

        for i in range(nt):
            data2.write('{2:d} {0:f} {1:f}\n'.format(particles[2][i][0], particles[2][i][1], i))
        data2.write('\n')

        print(" --- %s seconds ---" % (time.time() - start_time2))
    data.close()
    data2.close()
    data3.close()
    allfit.close()
def pso_horns():

    windrose = open('horns_rev_windrose2.dat', 'r')
    windrose_angle = []
    windrose_speed = []
    windrose_frequency = []
    for line in windrose:
        columns = line.split()
        windrose_angle.append(float(columns[0]))
        windrose_speed.append(float(columns[1]))
        windrose_frequency.append(float(columns[2]))

    windrose.close()

    data = open('refpar_layout_jensen.dat', 'w')
    data2 = open('refpar_random_layout_jensen.dat', 'w')
    data3 = open('refpar_best_global_fitness_jensen.dat', 'w', 1)

    np = 5 ## Number of particles in swarm
    nt = 21
    diam = 80.0
    particles = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])

    if random() < 0.5:
        sign1 = 1.0
    else:
        sign1 = - 1.0
    if random() < 0.5:
        sign2 = 1.0
    else:
        sign2 = - 1.0

    vel = array([[[sign1 * random(), sign2 * random()] for x in range(nt)] for x in range(np)])
    best_local = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])
    best_own_fitness = [0.0 for x in range(np)]
    best_global_fitness = 0.0

    def create():
        k = random()
        l = random()
        xt = 5457.0 * l
        if xt <= 412.0:
            yt = k * 3907.0 + (1.0 - k) * (- 3907.0 / 412.0 * xt + 3907.0)
        elif xt <= 5040.0:
            yt = random() * 3907.0
        else:
            yt = k * (3907.0 / 417.0 * (- xt + 5457.0))
        return xt, yt

    ## Produce starting positions. Includes boundaries of Horns Rev
    for n in range(np):
        for tur in range(nt):
            particles[n][tur] = create()

    # best_layout = particles[0]

    # for i in range(nt):
    #     data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
    # data.write('\n')

    # Velocity limiting to 10% to start with, for convergence, and then increase speed.
    k = 1.0

    for ite in range(100):

        start_time2 = time.time()

        # Fitness evaluation skipped if counter turbine is out of boundaries. following: BrattonKennedy07 PSO.
        # More 'repair' methods for particles out of boundaries shown in PhD thesis Helwig2010.
        # Chu2011 proves that the reflecting boundary method is better than random or absorbing boundary. TODO implement

        fitness = Parallel(n_jobs=8)(delayed(fit)(particles[i], windrose_angle, windrose_speed, windrose_frequency) for i in range(np))

        for p in range(np):
            if fitness[p] >= best_own_fitness[p]:
                best_own_fitness[p] = fitness[p]
                best_local[p] = particles[p]
            if fitness[p] >= best_global_fitness:
                best_global_fitness = fitness[p]
                best_layout = particles[p]
                for i in range(nt):
                    data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
                data.write('\n')

        for i in range(nt):
            data2.write('{2:d} {0:f} {1:f}\n'.format(particles[4][i][0], particles[4][i][1], i))
        data2.write('\n')
        data3.write('{0:f}\n'.format(best_global_fitness))

        move = Parallel(n_jobs=8)(delayed(repair)(particles[i], vel[i], best_local[i], best_layout, nt) for i in range(np))
        particles = move[:][0]
        vel = move[:][1]

        # Find minimum distance between turbines, and if two are closer than 1D, then randomise one of them.
        for b in range(np):
            pp = 0
            while pp == 0:
                pp = 1
                for i in range(nt):
                    for j in range(nt):
                        if i != j and distance(particles[b][i][0], particles[b][i][1], particles[b][j][0], particles[b][j][1]) < diam:
                            particles[b][j] = create()
                            pp = 0

        print("Iteration --- %s seconds ---" % (time.time() - start_time2))
    data.close()
    data2.close()
    data3.close()
Ejemplo n.º 11
0
def Jensen(a, Nt, rad):
    from math import sqrt, log
    import wake
    # from power_curve5MW import power5MW_kW as power  # Power curve 5 MW NREL

    windrose = open('horns_rev_windrose2.dat', 'r')
    nt = Nt
    layout_x = [0.0 for x in range(nt)]
    layout_y = [0.0 for x in range(nt)]
    for x in range(nt):
        layout_x[x] = float(a[x][0])
        layout_y[x] = float(a[x][1])

    windrose_angle = []
    windrose_speed = []
    windrose_frequency = []
    for line in windrose:
        columns = line.split()
        windrose_angle.append(float(columns[0]))
        windrose_speed.append(float(columns[1]))
        windrose_frequency.append(float(columns[2]))

    windrose.close()
    summation = 0.0

    # Power curve 2 MW Siemens.
    def power(U0):
        if U0 < 4.0:
            return 0.0
        elif U0 <= 25.0:
            return 0.0003234808 * U0 ** 7.0 - 0.0331940121 * U0 ** 6.0 + 1.3883148012 * U0 **5.0 - 30.3162345004 * U0 **4.0 + 367.6835557011 * U0 ** 3.0 - 2441.6860655008 * U0 ** 2.0 + 8345.6777042343 * U0 - 11352.9366182805
        else:
            return 0.0

    # for wind in range(0, len(windrose_speed)):
    for wind in range(0, 1):
        # U1 = windrose_speed[wind]  # Free stream wind speed
        # U0 = U1 * (90.0 / 10.0) ** 0.11  # Power or log law for wind shear profile
        # U0 = U1 * log(70.0 / 0.005) / log(10.0 / 0.005)
        U0 = 8.5
        k = 0.04  # Decay constant
        r0 = rad  # Turbine rotor radius
        angle = windrose_angle[wind]
        angle3 = angle + 180.0
        wake_deficit_matrix = [[0.0 for x in range(nt)] for x in range(nt)]
        for turbine in range(nt):
            flag = [False for x in range(nt)]
            proportion = [0.0 for x in range(nt)]
            for i in range(nt):
                try:
                    proportion[i], flag[i] = wake.determine_if_in_wake(layout_x[turbine], layout_y[turbine], layout_x[i], layout_y[i], k, r0, angle3)
                except TypeError:
                    print layout_x[turbine], layout_y[turbine], layout_x[i], layout_y[i], k, r0, angle3

            # Matrix with effect of each turbine <i = turbine> on every other turbine <j> of the farm
            for j in range(nt):
                if turbine != j and flag[j] is True:
                    wake_deficit_matrix[turbine][j] = proportion[j] * wake.wake_deficit(0.81, k, wake.distance(layout_x[turbine], layout_y[turbine], layout_x[j], layout_y[j]), r0)
                elif turbine == j:
                    wake_deficit_matrix[turbine][j] = 0.0

        total_deficit = [0.0 for x in range(nt)]
        total_speed = [0.0 for x in range(nt)]
        for j in range(nt):
            for i in range(nt):
                total_deficit[j] += wake_deficit_matrix[i][j] ** 2.0
            total_deficit[j] = sqrt(total_deficit[j])
            total_speed[j] = U0 * (1.0 - total_deficit[j])

        # Farm efficiency
        profit = 0.0
        efficiency_proportion = [0.0 for x in range(0, len(windrose_frequency))]
        efficiency = 0.0
        for l in range(nt):
            profit += power(total_speed[l])
        efficiency = profit * 100.0 / (float(nt) * power(U0))
        efficiency_proportion[wind] = efficiency * windrose_frequency[wind] / 100.0
        summation += efficiency_proportion[wind]
    return efficiency  # Farm efficiency

# if __name__ == '__main__':
#     start_time = time.time()
#     Jensen()
# print("--- %s seconds ---" % (time.time() - start_time))
    def solve_nonlinear(self, params, unknowns, resids):

        a = params['a']

        from math import sqrt, log
        import wake
        windrose = open('horns_rev_windrose2.dat', 'r')
        nt = 80
        layout_x = [0.0 for x in range(nt)]
        layout_y = [0.0 for x in range(nt)]
        for x in range(nt):
            layout_x[x] = float(a[x][0])
            layout_y[x] = float(a[x][1])

        windrose_angle = []
        windrose_speed = []
        windrose_frequency = []
        for line in windrose:
            columns = line.split()
            windrose_angle.append(float(columns[0]))
            windrose_speed.append(float(columns[1]))
            windrose_frequency.append(float(columns[2]))

        windrose.close()
        summation = 0.0

        def Ct(U0):
            return 0.0001923077 * U0 ** 4.0 + -0.0075407925 * U0 ** 3.0 + 0.096462704 * U0 ** 2.0 - 0.5012354312 * U0 + 1.7184749184

        def power(U0):
            if U0 < 4.0:
                return 0.0
            elif U0 >= 4.0:
                return 19.7907842158 * U0 ** 2.0 - 74.9080669331 * U0 + 37.257967033  # From 4 to 11 m/s

        for wind in range(0, len(windrose_speed)):
        # for wind in range(0, 1):
            U1 = windrose_speed[wind]  # Free stream wind speed
            U0 = U1 * (70.0 / 10.0) ** 0.11  # Power or log law for wind shear profile
            # U0 = U1 * log(70.0 / 0.005) / log(10.0 / 0.005)
            k = 0.04  # Decay constant
            r0 = 40.0  # Turbine rotor radius
            angle = windrose_angle[wind]
            angle3 = angle + 180.0
            wake_deficit_matrix = [[0.0 for x in range(nt)] for x in range(nt)]
            for turbine in range(nt):
                flag = [False for x in range(nt)]
                proportion = [0.0 for x in range(nt)]
                for i in range(nt):
                    try:
                        proportion[i], flag[i] = wake.determine_if_in_wake(layout_x[turbine], layout_y[turbine], layout_x[i], layout_y[i], k, r0, angle3)
                    except TypeError:
                        print(layout_x[turbine], layout_y[turbine], layout_x[i], layout_y[i], k, r0, angle3)

                # Matrix with effect of each turbine <i = turbine> on every other turbine <j> of the farm
                for j in range(nt):
                    if turbine != j and flag[j] is True:
                        wake_deficit_matrix[turbine][j] = proportion[j] * wake.wake_deficit(0.81, k, wake.distance(layout_x[turbine], layout_y[turbine], layout_x[j], layout_y[j]), r0)
                    elif turbine == j:
                        wake_deficit_matrix[turbine][j] = 0.0

            total_deficit = [0.0 for x in range(nt)]
            total_speed = [0.0 for x in range(nt)]
            for j in range(nt):
                for i in range(nt):
                    total_deficit[j] += wake_deficit_matrix[i][j] ** 2.0
                total_deficit[j] = sqrt(total_deficit[j])
                total_speed[j] = U0 * (1.0 - total_deficit[j])

            # Farm efficiency
            profit = 0.0
            efficiency_proportion = [0.0 for x in range(0, len(windrose_frequency))]
            for l in range(nt):
                profit += power(total_speed[l])
            efficiency = profit * 100.0 / (float(nt) * power(U0))
            efficiency_proportion[wind] = efficiency * windrose_frequency[wind] / 100.0
            summation += efficiency_proportion[wind]
        unknowns['eff'] = summation  # Farm efficiency
def pso_horns():
    time4 = time.time()
    windrose = open('horns_rev_windrose2.dat', 'r')
    windrose_angle = []
    windrose_speed = []
    windrose_frequency = []
    for line in windrose:
        columns = line.split()
        windrose_angle.append(float(columns[0]))
        windrose_speed.append(float(columns[1]))
        windrose_frequency.append(float(columns[2]))

    windrose.close()

    data = open('try6_layout_jensen.dat', 'w')
    data2 = open('try6_random_layout_jensen.dat', 'w')
    data3 = open('try6_best_global_fitness_jensen.dat', 'w', 1)
    allfit = open('try6_all_fitnesses.dat', 'w', 1)

    np = 10 ## Number of particles in swarm
    nt = 80
    diam = 80.0
    particles = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])

    vel = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])
    best_own_fitness = [100.0 for x in range(np)]

    def create():
        kk = random()
        l = random()
        xt = 5457.0 * l
        if xt <= 412.0:
            yt = kk * 3907.0 + (1.0 - kk) * (- 3907.0 / 412.0 * (xt + 10.0) + 3907.0)
        elif xt <= 5040.0:
            yt = kk * 3907.0
        else:
            yt = kk * (3907.0 / 417.0 * (- xt + 5457.0 + 10.0))
        return xt, yt

    ## Produce starting positions. Includes boundaries of Horns Rev
    for n in range(np):
        for tur in range(nt):
            particles[n][tur] = create()

    # layout = open('horns_rev.dat', 'r')
    # ll = 0
    # horns = array([[0, 0] for gf in range(nt)])
    # for line in layout:
    #     columns = line.split()
    #     horns[ll] = [float(columns[0]) - 423974.0, float(columns[1]) - 6147543.0]
    #     ll += 1
    # layout.close()

    # particles[np - 1] = deepcopy(horns)

    best_local = array([[[0.0, 0.0] for x in range(nt)] for x in range(np)])
    # Fitness evaluation skipped if a turbine is out of boundaries. following: BrattonKennedy07 PSO.
    # More 'repair' methods for particles out of boundaries shown in PhD thesis Helwig2010.
    # Chu2011 proves that the reflecting boundary method is better than random or absorbing boundary. TODO implement
    fitness = Parallel(n_jobs=-1)(delayed(efficiency)(particles[i], windrose_angle, windrose_speed, windrose_frequency, nt) for i in range(np))
    print fitness
    for fg in range(np):
        allfit.write('{0:f}\n'.format(fitness[fg]))
    allfit.write('\n')

    for p in range(np):
        best_own_fitness[p] = deepcopy(fitness[p])
        best_local[p] = deepcopy(particles[p])
    best_global_fitness = min(fitness)
    print best_global_fitness
    print best_own_fitness
    best_layout = deepcopy(particles[fitness.index(min(fitness))])
    print best_local[5][54][1] - particles[5][54][1]
    # for i in range(nt):
    #     data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
    # data.write('\n')

    # Velocity limiting to 10% to start with, for convergence, and then increase speed.
    k = 1.0
    for ite in range(200):

        start_time2 = time.time()

        particles = Parallel(n_jobs=-1)(delayed(movement)(vel[i], best_local[i], particles[i], best_layout, k, nt) for i in range(np))

        # Find minimum distance between turbines, and if two are closer than 1D, then randomise one of them.
        for b in range(np):
            pp = 0
            while pp == 0:
                pp = 1
                for i in range(nt):
                    for j in range(nt):
                        if i != j and distance(particles[b][i][0], particles[b][i][1], particles[b][j][0], particles[b][j][1]) < 2.0 * diam:
                            particles[b][j] = create()
                            pp = 0

        # Fitness evaluation skipped if a turbine is out of boundaries. following: BrattonKennedy07 PSO.
        # More 'repair' methods for particles out of boundaries shown in PhD thesis Helwig2010.
        # Chu2011 proves that the reflecting boundary method is better than random or absorbing boundary. TODO implement
        fitness = Parallel(n_jobs=-1)(delayed(efficiency)(particles[i], windrose_angle, windrose_speed, windrose_frequency, nt) for i in range(np))

        for fg in range(np):
            allfit.write('{0:f}\n'.format(fitness[fg]))
        allfit.write('\n')

        for p in range(np):
            if fitness[p] < best_own_fitness[p]:
                best_own_fitness[p] = deepcopy(fitness[p])
                best_local[p] = deepcopy(particles[p])
            if fitness[p] < best_global_fitness:
                best_global_fitness = deepcopy(fitness[p])
                best_layout = deepcopy(particles[p])

        for i in range(nt):
            data.write('{2:d} {0:f} {1:f}\n'.format(best_layout[i][0], best_layout[i][1], i))
            data2.write('{2:d} {0:f} {1:f}\n'.format(particles[1][i][0], particles[1][i][1], i))
        data2.write('\n')
        data.write('\n')
        data3.write('{0:f}\n'.format(best_global_fitness))


        print("Iteration --- %s seconds ---" % (time.time() - start_time2))
    data.close()
    data2.close()
    data3.close()
    allfit.close()