Exemple #1
0
def farm_damage(turbineX, turbineY, windDirections, windFrequencies, atm_free,
                atm_close, atm_far):
    """
    calculate the damage of each turbine in the farm for every wind direction

    inputs:
    turbineX:       x locations of the turbines (in the wind frame)
    turbineY:       y locations of the turbines (in the wind frame)
    windDirections: the wind directions
    windFrequencies: the associated probabilities of the wind directions
    atm_free:       the freestream atmospheric loads as a function of time
    atm_close:      the 4D downstream fully waked atmospheric loads as a function of time
    atm_far:        the 10D downstream fully waked atmospheric loads as a function of time

    outputs:
    damage:         fatigue damage of the farm

    """

    damage = np.zeros_like(turbineX)
    nDirections = len(windDirections)
    nTurbines = len(turbineX)

    for j in range(nDirections):
        turbineXw, turbineYw = fast_calc_aep.windframe(windDirections[j],
                                                       turbineX, turbineY)
        for i in range(nTurbines):
            damage[i] += calc_damage(turbineXw, turbineYw, i,
                                     windFrequencies[j], atm_free, atm_close,
                                     atm_far)
    return damage
def farm_damage(turbineX,
                turbineY,
                windDirections,
                windFrequencies,
                atm_free,
                atm_close,
                atm_far,
                Omega_free,
                Omega_waked,
                free_speed,
                waked_speed,
                TI=0.11,
                N=24001):
    """
    calculate the damage of each turbine in the farm for every wind direction

    inputs:
    turbineX:       x locations of the turbines (in the wind frame)
    turbineY:       y locations of the turbines (in the wind frame)
    windDirections: the wind directions
    windFrequencies: the associated probabilities of the wind directions
    atm_free:       a function giving the freestream atmospheric loads as a function of time
    atm_close:      a function giving the 4D downstream fully waked atmospheric loads as a function of time
    atm_far:        a function giving the 10D downstream fully waked atmospheric loads as a function of time
    Omega_free:     the time average of the rotation rate for the freestream FAST file
    Omega_waked:    the time average of the rotation rate for the close waked FAST file
    free_speed:     the freestream wind speed
    waked_speed:    the fully waked close wind speed


    outputs:
    damage:         fatigue damage of the farm

    """

    damage = np.zeros_like(turbineX)
    nDirections = len(windDirections)
    nTurbines = len(turbineX)

    for i in range(nTurbines):
        for j in range(nDirections):
            turbineXw, turbineYw = fast_calc_aep.windframe(
                windDirections[j], turbineX, turbineY)
            # moments = get_loads_history(turbineXw,turbineYw,i,Omega_free,Omega_waked,free_speed,waked_speed,atm_free,atm_close,atm_far,TI=TI,N=N)
            # damage[i] += calc_damage(moments,windFrequencies[j])

            damage[i] += get_loads_history(turbineXw,
                                           turbineYw,
                                           i,
                                           Omega_free,
                                           Omega_waked,
                                           free_speed,
                                           waked_speed,
                                           atm_free,
                                           atm_close,
                                           atm_far,
                                           windFrequencies[j],
                                           TI=TI,
                                           N=N)
    return damage
def damage_farm_damage(turbineX,
                       turbineY,
                       windDirections,
                       windFrequencies,
                       damage_free,
                       damage_close,
                       damage_far,
                       recovery_dist,
                       wind_speed=8,
                       TI=0.11,
                       rotor_diameter=126.4):
    """
    calculate the damage of each turbine in the farm for every wind direction

    inputs:
    turbineX:       x locations of the turbines (in the wind frame)
    turbineY:       y locations of the turbines (in the wind frame)
    windDirections: the wind directions
    windFrequencies: the associated probabilities of the wind directions
    atm_free:       the freestream atmospheric loads as a function of time
    atm_close:      the 4D downstream fully waked atmospheric loads as a function of time
    atm_far:        the 10D downstream fully waked atmospheric loads as a function of time

    outputs:
    damage:         fatigue damage of the farm

    """

    damage = np.zeros_like(turbineX)
    nDirections = len(windDirections)
    nTurbines = len(turbineX)

    for j in range(nDirections):
        turbineXw, turbineYw = fast_calc_aep.windframe(windDirections[j],
                                                       turbineX, turbineY)
        ind = np.argsort(turbineXw)
        sortedX = np.zeros(nTurbines)
        sortedY = np.zeros(nTurbines)
        for k in range(nTurbines):
            sortedX[k] = turbineXw[ind[k]]
            sortedY[k] = turbineYw[ind[k]]
        _, sigma = get_speeds(sortedX,
                              sortedY,
                              np.array([0.]),
                              np.array([0.]),
                              np.array([0.]),
                              wind_speed,
                              TI=TI)
        wake_radius = sigma * 2.
        for i in range(nTurbines):
            # damage[i] += damage_calc.combine_damage(turbineXw,turbineYw,i,damage_free,damage_close,damage_far,rotor_diameter,wake_radius)*windFrequencies[j]
            damage[i] += damage_calc.combine_damage(
                sortedX, sortedY,
                np.where(ind == i)[0][0], damage_free, damage_close,
                damage_far, rotor_diameter, wake_radius,
                recovery_dist) * windFrequencies[j]
    return damage
Exemple #4
0
def farm_damage(turbineX,turbineY,windDirections,windFrequencies,atm_free,atm_close,atm_far,Omega_free,Omega_waked,free_speed,waked_speed,TI=0.11,N=24001):

    damage = np.zeros_like(turbineX)
    nDirections = len(windDirections)
    nTurbines = len(turbineX)
    # for i in range(nDirections):
    #     turbineXw, turbineYw = fast_calc_aep.windframe(windDirections[i], turbineX, turbineY)
    #     for j in range(nTurbines):
    #         moments = get_loads_history(turbineXw,turbineYw,j,Omega_free,Omega_waked,free_speed,waked_speed,f_atm_free,f_atm_close,f_atm_far,N=N)
    #         calc_damage(moments,windFrequencies[i])
    for i in range(nTurbines):
        for j in range(nDirections):
            # print '____________'
            s = Time.time()
            turbineXw, turbineYw = fast_calc_aep.windframe(windDirections[j], turbineX, turbineY)
            # print Time.time()-s
            s = Time.time()
            # moments = get_loads_history(turbineXw,turbineYw,i,Omega_free,Omega_waked,free_speed,waked_speed,f_atm_free,f_atm_close,f_atm_far,N=N)
            moments = get_loads_history(turbineX,turbineY,i,Omega_free,Omega_waked,free_speed,waked_speed,atm_free,atm_close,atm_far,TI=TI,N=N)
            # print Time.time()-s
            s = Time.time()
            damage[i] += calc_damage(moments,windFrequencies[j])
            # print Time.time()-s
    return damage
Exemple #5
0
    ax2 = plt.subplot(122)

    from yy_calc_fatigue import *
    filename_free = '/Users/ningrsrch/Dropbox/Projects/waked-loads/BYU/BYU/C680_W8_T11.0_P0.0_m2D_L0/Model.out'
    filename_close = '/Users/ningrsrch/Dropbox/Projects/waked-loads/BYU/BYU/C653_W8_T11.0_P0.0_4D_L0/Model.out'
    filename_far = '/Users/ningrsrch/Dropbox/Projects/waked-loads/BYU/BYU/C671_W8_T11.0_P0.0_10D_L0/Model.out'

    TI = 0.11
    Omega_free, free_speed, Omega_close, close_speed, Omega_far, far_speed = find_omega(
        filename_free, filename_close, filename_far, TI=TI)
    Rhub, r, chord, theta, af, Rtip, B, rho, mu, precone, hubHt, nSector, pitch, yaw_deg = setup_airfoil(
    )
    print Omega_free, free_speed, Omega_close, close_speed, Omega_far, far_speed

    dir = 270.
    turbineXw, turbineYw = fast_calc_aep.windframe(dir, turbineX, turbineY)

    ws_array, wake_diameters = gaus.porteagel_visualize(
        turbineXw, sorted_x_idx, turbineYw, turbineZ, rotorDiameter, Ct,
        wind_speed, yaw, ky, kz, alpha, beta, I, RotorPointsY, RotorPointsZ,
        z_ref, z_0, shear_exp, velX, velY, velZ, wake_combination_method,
        ti_calculation_method, calc_k_star, wec_factor, wake_model_version,
        interp_type, use_ct_curve, ct_curve_wind_speed, ct_curve_ct,
        sm_smoothing)

    damage270 = farm_damage(turbineXw,
                            turbineYw,
                            np.array([270.]),
                            np.array([0.5]),
                            Omega_free,
                            free_speed,
def new_farm_damage(turbineX,
                    turbineY,
                    windDirections,
                    windFrequencies,
                    atm_free,
                    atm_close,
                    atm_far,
                    Omega_free,
                    Omega_waked,
                    free_speed,
                    waked_speed,
                    TI=0.11):
    """
    calculate the damage of each turbine in the farm for every wind direction

    inputs:
    turbineX:       x locations of the turbines (in the wind frame)
    turbineY:       y locations of the turbines (in the wind frame)
    windDirections: the wind directions
    windFrequencies: the associated probabilities of the wind directions
    atm_free:       a function giving the freestream atmospheric loads as a function of time
    atm_close:      a function giving the 4D downstream fully waked atmospheric loads as a function of time
    atm_far:        a function giving the 10D downstream fully waked atmospheric loads as a function of time
    Omega_free:     the time average of the rotation rate for the freestream FAST file
    Omega_waked:    the time average of the rotation rate for the close waked FAST file
    free_speed:     the freestream wind speed
    waked_speed:    the fully waked close wind speed


    outputs:
    damage:         fatigue damage of the farm

    """

    damage = np.zeros_like(turbineX)
    nDirections = len(windDirections)
    nTurbines = len(turbineX)

    for j in range(nDirections):
        turbineXw, turbineYw = fast_calc_aep.windframe(windDirections[j],
                                                       turbineX, turbineY)
        for i in range(nTurbines):
            cc_moments = new_get_cc_loads(turbineXw,
                                          turbineYw,
                                          i,
                                          Omega_free,
                                          Omega_waked,
                                          free_speed,
                                          waked_speed,
                                          len(atm_free),
                                          TI=0.11,
                                          wind_speed=8.)
            for k in range(len(cc_moments)):
                cc_moments[k] = round(cc_moments[k], 4)
            damage_cc = calc_damage(cc_moments, windFrequencies[j], fos=3)
            damage_atm = new_damage_atm(turbineXw,
                                        turbineYw,
                                        i,
                                        atm_free,
                                        atm_close,
                                        atm_far,
                                        np.mean(cc_moments),
                                        windFrequencies[j],
                                        TI=0.11,
                                        wind_speed=8.,
                                        rotor_diameter=126.4)
            damage[i] += damage_cc * 2.
            damage[i] += damage_atm
    return damage
def calcAEP(turbineX,turbineY,windDirections,windSpeeds,windFrequencies,TI=0.11,relaxationFactor=1.0):

    nTurbines = len(turbineX)
    turbineZ = np.ones(nTurbines)*90.
    yaw = np.zeros(nTurbines)
    rotorDiameter = np.ones(nTurbines)*126.4
    ky = 0.022
    kz = 0.022
    alpha = 2.32
    beta = 0.154
    z_ref = 50.
    z_0 = 0.
    # RotorPointsY = np.array([0.])
    # RotorPointsZ = np.array([0.])
    nRotorPoints = 20
    RotorPointsY, RotorPointsZ = sunflower_points(nRotorPoints)

    sorted_x_idx = np.argsort(turbineX)

    use_ct_curve = True
    interp_type = 1.
    Ct = np.ones(nTurbines)*8./9.

    ct_curve_ct = np.array([0.000000000000000000e+00,1.926046656751827513e-01,2.304704215057909733e-01,2.625801650211371241e-01,2.897988824025847787e-01,3.128715534101859097e-01,3.325197358991970331e-01,3.493848361140217129e-01,
        3.640088009445398010e-01,3.768126783817991599e-01,3.876023690081823458e-01,3.972631433719887584e-01,4.056700381028983671e-01,4.130674880647284830e-01,4.196235247518781408e-01,4.254417392565709721e-01,
        4.305404786433919551e-01,4.352952842627632046e-01,4.392221404869978141e-01,4.429120876801027618e-01,4.462733349122694482e-01,4.489563239069855882e-01,4.514849682878421255e-01,4.538698830206908674e-01,
        4.556616377445937838e-01,4.571609267936883603e-01,4.585773528364238683e-01,4.599161818549730718e-01,4.609826078311411446e-01,4.615522686688521281e-01,4.620913641318648013e-01,4.626017054828027719e-01,
        4.630849686797392506e-01,4.635427067073090157e-01,4.637089016217447179e-01,4.635678487000876591e-01,4.634341695706203357e-01,4.633074665079051635e-01,4.631873685982802469e-01,4.631607703567138801e-01,
        4.631607703567138801e-01,4.631607703567138801e-01,4.631607703567137690e-01,4.631607703567138801e-01,4.631607703567138801e-01,4.631607703567137690e-01,4.631607703567138801e-01,4.631607703567138801e-01,
        4.631607703567137690e-01,4.631607703567138801e-01,4.631607703567137690e-01,4.631607703567138801e-01,4.631607703567138801e-01,4.631607703567138801e-01,4.631607703567138801e-01,4.631607703567138801e-01,
        4.631607703567138801e-01,4.631607703567138801e-01,4.631607703567138801e-01,4.631607703567138801e-01,4.629944322154941894e-01,4.628064174063633018e-01,4.619912099228598024e-01,4.609688430800724657e-01,
        4.599702722417739476e-01,4.589946761727181079e-01,4.580412709972682683e-01,4.602779942453900097e-01,4.601593442651156773e-01,4.522311128900888266e-01,4.444394795294665523e-01,4.367820906927074032e-01,
        4.292566334383077220e-01,4.218608346751668847e-01,4.145924604759902432e-01,4.074493154025272679e-01,4.004292418424294508e-01,3.935301193575363454e-01,3.867498640433883472e-01,3.800864278997781454e-01,
        3.735377982121443341e-01,3.671019969436217778e-01,3.607770801375717595e-01,3.545611373304012326e-01,3.484522909744995345e-01,3.424486958711209228e-01,3.365485386130337986e-01,3.307500370367759124e-01,
        3.250514396843435794e-01,3.194510252741598055e-01,3.139471021811547913e-01,3.085380079258019381e-01,3.032221086719636416e-01,2.979977987333838341e-01,2.928635000886827267e-01,2.878176619047133067e-01,
        2.828587600681249370e-01,2.779852967249981099e-01,2.731957998284155198e-01,2.684888226938225708e-01,2.638629435620525876e-01,2.593167651698772835e-01,2.548489143279616398e-01,2.504580415060849163e-01,
        2.461428204255101670e-01,2.419019476583784412e-01,2.377341422340028820e-01,2.336381452519474267e-01,2.296127195017700351e-01,2.256566490893210097e-01,2.217687390694769445e-01,2.179478150852021401e-01,
        2.141927230128318482e-01,2.105023286134643790e-01,2.068755171903588486e-01,2.033111932522393972e-01,1.998082801823969634e-01,1.963657199134924980e-01,1.929824726079658326e-01,1.896575163439477851e-01,
        1.863898468065857128e-01,1.831784769846854788e-01,1.800224368725827362e-01,1.769207731771487158e-01,1.738725490298434206e-01,1.708768437037334609e-01,1.679327523353813245e-01,1.650393856515293134e-01,
        1.621958697004900751e-01,1.594013455881682639e-01,1.566549692186263998e-01,1.539559110391245933e-01,1.513033557895500647e-01,1.486965022561654304e-01,1.461345630295985409e-01,1.436167642670038713e-01,
        1.411423454583196901e-01,1.387105591965529239e-01,1.363206709520234095e-01,1.339719588504956205e-01,1.316637134551348065e-01,1.293952375522178233e-01,1.271658459405384245e-01,1.249748652244396241e-01,
        1.228216336104114015e-01,1.207055007071945740e-01,1.186258273293273463e-01,1.165819853040765686e-01,1.145733572816970275e-01,1.125993365489582620e-01,1.106593268458838930e-01,1.087527421856505916e-01,
        1.068790066775877345e-01,1.050375543532279521e-01,1.032278289953537237e-01,1.014492839699910887e-01,9.970138206129613989e-02,9.798359530928681116e-02,9.629540485037166309e-02,9.463630076062452823e-02,
        9.300578190176048143e-02,9.140335576976474363e-02,8.982853834613112320e-02,8.828085395166129778e-02,8.675983510278516275e-02,8.526502237035533949e-02,8.379596424087515372e-02,8.235221698011675751e-02,
        8.093334449909067585e-02,7.953891822232299347e-02,7.816851695840211500e-02,7.682172677275747597e-02,7.549814086262850166e-02,7.419735943418842572e-02,7.291898958178492929e-02,7.166264516926239281e-02,
        7.042794671332706924e-02,6.921452126892356504e-02,6.802200231658521445e-02,6.685002965172548439e-02,6.569824927583710339e-02,6.456631328956505267e-02,6.345387978762324910e-02,6.236061275551976757e-02,
        6.128618196806329826e-02,6.023026288961717128e-02,5.919253657607215918e-02,5.817268957850805361e-02,5.717041384851592745e-02,5.618540664515054434e-02,5.521737044348627721e-02,5.426601284474912718e-02,
        5.333104648799626146e-02,5.241218896331780591e-02,5.150916272653360134e-02,5.062169501536060989e-02,4.974951776702336154e-02,4.889236753728529172e-02,4.804998542087406121e-02,4.722211697327857727e-02,
        4.640851213389269453e-02,4.640294355792866365e-02])

    ct_curve_wind_speed = np.array([2.990000000000000213e+00,3.000000000000000000e+00,3.130846633912168553e+00,3.261693267824336662e+00,3.392539901736505215e+00,3.523386535648673323e+00,3.654233169560841876e+00,3.785079803473010429e+00,
        3.915926437385178538e+00,4.046773071297346647e+00,4.177619705209515644e+00,4.308466339121683752e+00,4.439312973033851861e+00,4.570159606946020858e+00,4.701006240858188967e+00,4.831852874770357076e+00,
        4.962699508682526073e+00,5.093546142594694182e+00,5.224392776506862290e+00,5.355239410419031287e+00,5.486086044331199396e+00,5.616932678243367505e+00,5.747779312155536502e+00,5.878625946067704611e+00,
        6.009472579979872719e+00,6.140319213892041716e+00,6.271165847804209825e+00,6.402012481716377934e+00,6.532859115628546931e+00,6.663705749540715040e+00,6.794552383452883149e+00,6.925399017365052146e+00,
        7.056245651277220254e+00,7.187092285189388363e+00,7.317938919101556472e+00,7.448785553013725469e+00,7.579632186925893578e+00,7.710478820838061687e+00,7.841325454750230683e+00,7.972172088662398792e+00,
        8.103018722574567789e+00,8.233865356486735010e+00,8.364711990398904007e+00,8.495558624311073004e+00,8.626405258223240224e+00,8.757251892135409221e+00,8.888098526047578218e+00,9.018945159959745439e+00,
        9.149791793871914436e+00,9.280638427784083433e+00,9.411485061696250654e+00,9.542331695608419651e+00,9.673178329520588647e+00,9.804024963432755868e+00,9.934871597344924865e+00,1.006571823125709386e+01,
        1.019656486516926108e+01,1.032741149908143008e+01,1.045825813299359908e+01,1.058910476690576630e+01,1.071995140081793352e+01,1.085079803473010429e+01,1.098164466864227151e+01,1.111249130255444051e+01,
        1.124333793646660773e+01,1.137418457037877673e+01,1.150503120429094572e+01,1.163587783820311294e+01,1.163687783820311239e+01,1.170448773987094526e+01,1.177249045298416696e+01,1.184088825976518677e+01,
        1.190968345569603315e+01,1.197887834959541564e+01,1.204847526369622734e+01,1.211847653372344524e+01,1.218888450897254216e+01,1.225970155238831971e+01,1.233093004064423148e+01,1.240257236422211662e+01,
        1.247463092749243785e+01,1.254710814879499381e+01,1.262000646052004527e+01,1.269332830918996713e+01,1.276707615554136943e+01,1.284125247460764818e+01,1.291585975580207624e+01,1.299090050300133115e+01,
        1.306637723462955591e+01,1.314229248374284609e+01,1.321864879811426619e+01,1.329544874031939194e+01,1.337269488782226112e+01,1.345038983306189451e+01,1.352853618353932852e+01,1.360713656190508125e+01,
        1.368619360604718338e+01,1.376570996917974021e+01,1.384568831993192539e+01,1.392613134243757322e+01,1.400704173642524530e+01,1.408842221730886735e+01,1.417027551627881010e+01,1.425260438039358135e+01,
        1.433541157267203126e+01,1.441869987218604443e+01,1.450247207415383777e+01,1.458673099003374496e+01,1.467147944761861744e+01,1.475672029113066763e+01,1.484245638131695166e+01,1.492869059554540279e+01,
        1.501542582790134972e+01,1.510266498928466561e+01,1.519041100750748896e+01,1.527866682739243132e+01,1.536743541087143328e+01,1.545671973708519076e+01,1.554652280248309282e+01,1.563684762092381852e+01,
        1.572769722377645785e+01,1.581907466002229157e+01,1.591098299635705970e+01,1.600342531729391382e+01,1.609640472526695731e+01,1.618992434073530617e+01,1.628398730228786917e+01,1.637859676674863962e+01,
        1.647375590928269418e+01,1.656946792350268183e+01,1.666573602157608036e+01,1.676256343433293594e+01,1.685995341137432391e+01,1.695790922118139576e+01,1.705643415122510120e+01,1.715553150807646787e+01,
        1.725520461751760237e+01,1.735545682465332717e+01,1.745629149402339664e+01,1.755771200971544843e+01,1.765972177547854471e+01,1.776232421483745938e+01,1.786552277120751953e+01,1.796932090801018234e+01,
        1.807372210878929764e+01,1.817872987732797796e+01,1.828434773776621114e+01,1.839057923471915146e+01,1.849742793339603253e+01,1.860489741971984046e+01,1.871299130044769754e+01,1.882171320329183928e+01,
        1.893106677704140850e+01,1.904105569168489609e+01,1.915168363853333844e+01,1.926295433034414017e+01,1.937487150144572112e+01,1.948743890786286315e+01,1.960066032744270004e+01,1.971453955998155294e+01,
        1.982908042735243725e+01,1.994428677363336178e+01,2.006016246523626378e+01,2.017671139103686073e+01,2.029393746250508812e+01,2.041184461383640780e+01,2.053043680208382682e+01,2.064971800729074403e+01,
        2.076969223262445041e+01,2.089036350451051405e+01,2.101173587276795374e+01,2.113381341074506992e+01,2.125660021545620282e+01,2.138010040771921538e+01,2.150431813229382527e+01,2.162925755802062611e+01,
        2.175492287796109636e+01,2.188131830953824419e+01,2.200844809467817598e+01,2.213631649995246775e+01,2.226492781672132537e+01,2.239428636127766836e+01,2.252439647499188879e+01,2.265526252445766175e+01,
        2.278688890163840242e+01,2.291928002401470010e+01,2.305244033473256593e+01,2.318637430275259348e+01,2.332108642299984780e+01,2.345658121651478467e+01,2.359286323060499768e+01,2.372993703899775753e+01,
        2.386780724199356385e+01,2.400647846662051066e+01,2.414595536678961807e+01,2.428624262345093143e+01,2.442734494475072893e+01,2.456926706618942902e+01,2.471201375078058504e+01,2.485558978921068274e+01,
        2.500000000000000711e+01,2.500100000000000122e+01])


    wake_model_version=2016
    sm_smoothing=700.
    calc_k_star=True
    ti_calculation_method=2
    wake_combination_method=1
    print_ti = False

    shear_exp=0.
    TI=0.11

    nDirections = len(windDirections)

    dir_powers = np.zeros(nDirections)

    for i in range(nDirections):

        turbineXw, turbineYw = fast_calc_aep.windframe(windDirections[i], turbineX, turbineY)
        wtVelocity = gaus.porteagel_analyze(turbineX,sorted_x_idx,turbineY,
                            turbineZ,rotorDiameter,Ct,windSpeeds[i],yaw,ky,kz,alpha,beta,
                            TI,RotorPointsY,RotorPointsZ,z_ref,z_0,shear_exp,wake_combination_method,
                            ti_calculation_method,calc_k_star,relaxationFactor,print_ti,wake_model_version,
                            interp_type,use_ct_curve,ct_curve_wind_speed,ct_curve_ct,sm_smoothing)

        _,dir_powers[i] = WindDirectionPower(wtVelocity)

    AEP = np.sum(dir_powers*windFrequencies*3600.*24.*365.)

    return AEP
Exemple #8
0
def calcAEP(turbineX,
            turbineY,
            windDirections,
            windSpeeds,
            windFrequencies,
            TI=0.11,
            relaxationFactor=1.0):

    nTurbines = len(turbineX)
    turbineZ = np.ones(nTurbines) * 90.
    yaw = np.zeros(nTurbines)
    rotorDiameter = np.ones(nTurbines) * 126.4
    ky = 0.022
    kz = 0.022
    alpha = 2.32
    beta = 0.154
    z_ref = 50.
    z_0 = 0.
    # RotorPointsY = np.array([0.])
    # RotorPointsZ = np.array([0.])
    # nRotorPoints = 20
    # RotorPointsY, RotorPointsZ = sunflower_points(nRotorPoints)
    RotorPointsY = np.array([0., 0., 0.69, -0.69])
    RotorPointsZ = np.array([0.69, -0.69, 0., 0.])

    sorted_x_idx = np.argsort(turbineX)

    use_ct_curve = False
    interp_type = 1.
    Ct = np.ones(nTurbines) * 8. / 9.

    ct_curve_ct = Ct

    wake_model_version = 2016
    sm_smoothing = 700.
    calc_k_star = True
    ti_calculation_method = 2
    wake_combination_method = 1
    print_ti = False

    shear_exp = 0.
    TI = 0.11

    nDirections = len(windDirections)

    dir_powers = np.zeros(nDirections)

    for i in range(nDirections):
        ct_curve_wind_speed = np.ones_like(Ct) * windSpeeds[i]

        turbineXw, turbineYw = fast_calc_aep.windframe(windDirections[i],
                                                       turbineX, turbineY)
        wtVelocity = gaus.porteagel_analyze(
            turbineX, sorted_x_idx, turbineY, turbineZ, rotorDiameter, Ct,
            windSpeeds[i], yaw, ky, kz, alpha, beta, TI, RotorPointsY,
            RotorPointsZ, z_ref, z_0, shear_exp, wake_combination_method,
            ti_calculation_method, calc_k_star, relaxationFactor, print_ti,
            wake_model_version, interp_type, use_ct_curve, ct_curve_wind_speed,
            ct_curve_ct, sm_smoothing)

        _, dir_powers[i] = WindDirectionPower(wtVelocity)

    AEP = np.sum(dir_powers * windFrequencies * 3600. * 24. * 365.)

    return AEP
def farm_damage(turbineX,
                turbineY,
                windDirections,
                windFrequencies,
                Omega_free,
                free_speed,
                Omega_close,
                close_speed,
                Omega_far,
                far_speed,
                Rhub,
                r,
                chord,
                theta,
                af,
                Rtip,
                B,
                rho,
                mu,
                precone,
                hubHt,
                nSector,
                pitch,
                yaw_deg,
                TI=0.11):
    """
    calculate the damage of each turbine in the farm for every wind direction

    inputs:
    turbineX:       x locations of the turbines (in the wind frame)
    turbineY:       y locations of the turbines (in the wind frame)
    windDirections: the wind directions
    windFrequencies: the associated probabilities of the wind directions
    atm_free:       a function giving the freestream atmospheric loads as a function of time
    atm_close:      a function giving the 4D downstream fully waked atmospheric loads as a function of time
    atm_far:        a function giving the 10D downstream fully waked atmospheric loads as a function of time
    Omega_free:     the time average of the rotation rate for the freestream FAST file
    Omega_waked:    the time average of the rotation rate for the close waked FAST file
    free_speed:     the freestream wind speed
    waked_speed:    the fully waked close wind speed


    outputs:
    damage:         fatigue damage of the farm

    """

    damage = np.zeros_like(turbineX)
    nDirections = len(windDirections)
    nTurbines = len(turbineX)

    for j in range(nDirections):
        turbineXw, turbineYw = fast_calc_aep.windframe(windDirections[j],
                                                       turbineX, turbineY)
        for i in range(nTurbines):
            damage[i] += get_edgewise_damage(turbineXw,
                                             turbineYw,
                                             i,
                                             Omega_free,
                                             free_speed,
                                             Omega_close,
                                             close_speed,
                                             Omega_far,
                                             far_speed,
                                             Rhub,
                                             r,
                                             chord,
                                             theta,
                                             af,
                                             Rtip,
                                             B,
                                             rho,
                                             mu,
                                             precone,
                                             hubHt,
                                             nSector,
                                             pitch,
                                             yaw_deg,
                                             TI=TI) * windFrequencies[j]
    return damage