风电场SCADA风速手算理论发电量和K值

背景分析

有时候需要根据一条功率曲线,手算scada速度序列的发电量

  1. 设计功率曲线
  2. scada风速序列
import pandas as pd
import numpy as np

## Yandun
#powerlaw=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\power12.csv')
## Dongping
#powerlaw=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\my89_12.csv')
powerlaw=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\SL3000_121.pws.csv')

cpVs = powerlaw.iloc[:, 0]
cpPs = powerlaw.iloc[:, 1]
#velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\nacWindsim2.csv')
#velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\lidar.csv')
# velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\nac1.csv',skiprows=1)

# nac1= velocitySet.iloc[:,0]
# nac2= velocitySet.iloc[:,1]
# nac4= velocitySet.iloc[:,2]
# nac7= velocitySet.iloc[:,3]
# nac8= velocitySet.iloc[:,4]
# nac12= velocitySet.iloc[:,5]

def find(vel, cpVs):
    count=0
    for cpV in cpVs:
        if(cpV > vel):
            return count
        count=count+1

def getMean(cpVs,cpPs,vel):
    if(vel<=2):
        rePower= 0
        return rePower
    index = find(vel, cpVs)
    v1= cpVs[index-1]
    v2= cpVs[index]
    p1= cpPs[index-1]
    p2= cpPs[index]
    rePower = p1+(p2-p1)/(v2-v1)*(vel-v1)
    return rePower
def modify(vel):
    return (vel+0.7081)/0.9869

############################################################
##  Velocity linear interpolation Method ####################################
############################################################
def getPower(nac,i):
    calPower=np.zeros(len(nac),dtype=float)
    calVel=np.zeros(len(nac),dtype=float)
    count=0
    for vel in nac:
        calPower[count]=getMean(cpVs,cpPs,modify(vel))
        #calPower[count]=getMean(cpVs,cpPs,vel)
        #calPower[count]=getMean(cpVs,cpPs,vel)
        calVel[count]=modify(vel)
        count=count+1
    calPowerSeries=pd.DataFrame([calVel,calPower]).T
    calPowerSeries.to_csv(str(i)+"-power.csv")
    return np.sum(calPower)/6000
############################################################
##  Velocity Bin Method ####################################
############################################################
def powerLawIntoZones(zones):
    velocityZones=np.linspace(0,25,zones)
    powerZones=np.zeros(velocityZones.__len__())
    velocityBinMag= 25/zones
    for i in range(zones):
        velocityZones[i]=i*velocityBinMag
        powerZones[i]=getMean(cpVs,cpPs,i*velocityBinMag)
    return velocityZones,powerZones

def whichZones(vel,velocityZones,powerZones,zones):
    velocityMagnitude=25.0/zones
    for i in range(zones):
        if(0==i):
            if(vel>=0 and vel <velocityMagnitude/2.0):
                power=0
        else:
            if(vel>=(velocityZones[i]-velocityMagnitude/2.0)  and
                    vel<(velocityZones[i]+velocityMagnitude/2.0) ):
                power = powerZones[i]
    return power


def getPowerVelocityBin(nac,i,zones=50):
    calPower=np.zeros(len(nac),dtype=float)
    calVel=np.zeros(len(nac),dtype=float)
    count=0
    [velocityZones,powerZones]=powerLawIntoZones(zones)
    cps=pd.DataFrame([velocityZones,powerZones]).T
    cps.to_excel(f"powerVelocityBin{zones}.xlsx")
    for vel in nac:
        #calPower[count]=getMean(cpVs,cpPs,vel)
        calVel[count]=vel
        calPower[count]=whichZones(modify(vel),velocityZones,powerZones,zones)
        count=count+1
    calPowerSeries=pd.DataFrame([calVel,calPower]).T
    calPowerSeries.to_csv(str(i)+"-powerBin.csv")
    return np.sum(calPower)/6000
# nac8 = velocitySet.iloc[:, 0]
# power1 = getPower(nac8,0)
# print(power1)
# 烟墩6台机组 :0-6
#velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\nacVelocity.csv',skiprows=1)
velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\nacVelocity220.csv',skiprows=1)
# 东平10台机组 : 0-10
#velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\VP.csv',skiprows=1)

for i in range(0, 6):
#for i in range(0,10):
    nac8 = velocitySet.iloc[:, i]
    power1 = getPower(nac8,i)
    #power1 = getPowerVelocityBin(nac8,i,50)
    print(power1)

速度分仓

  1. 设计功率曲线按照分仓个数bin,进行分仓
  2. 按照分仓大小,设置速度范围多少归入一个仓中,比如50个分仓,仓大小为0.5, 那么第二个分仓也就是0.5,得满足所有大于等于0.25 小于0.75的速度序列术语第二个分仓
  3. 结果发现速度分仓超过25仓之后,对功率曲线计算结果基本上和线性插值类似。

悟空[条件]

注意判断中大于号和小于号都不能写错,涉及到判断、抉择、条件、空的时候一定得注意 思考对,曾经我就犯过错误!

if(vel>=(velocityZones[i]-velocityMagnitude/2.0)  and
        vel<(velocityZones[i]+velocityMagnitude/2.0) ):

手算两条功率的k值

实际功率曲线[一般是scada的风速和功率的散点图]和设计功率曲线之比如果达到1,也就是k值,那么认为是最好的,如果大点也可以,但是最好不要少于,为了计算这个k值,简单编写了下面代码

核心的地方在于比较提取的过程,即

  1. scada的风速-功率关系散点图
  2. 设计功率曲线
for vel in range(nac.__len__()):
    for j in range(zones):
        if(0==j and nac[vel]>=0 and nac[vel] <velocityMagnitude/2.0):
            counts[j]=counts[j]+1
            velocitySum[j]=velocitySum[j]+nac[vel]
            powerSum[j]=powerSum[j]+power[vel]
            break
        elif(nac[vel]>=(velocityZones[j]-velocityMagnitude/2.0)  and
            nac[vel]<(velocityZones[j]+velocityMagnitude/2.0)):
            counts[j]=counts[j]+1
            velocitySum[j]=velocitySum[j]+nac[vel]
            powerSum[j]=powerSum[j]+power[vel]
            break

全部代码如下:

import pandas as pd
import numpy as np

### 规定风速范围从0-25 不能少于25
powerlaw=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\my89_12.csv')

cpVs = powerlaw.iloc[:, 0]
cpPs = powerlaw.iloc[:, 1]
#velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\nacWindsim2.csv')
#velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\lidar.csv')
# velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\nac1.csv',skiprows=1)

# nac1= velocitySet.iloc[:,0]
# nac2= velocitySet.iloc[:,1]
# nac4= velocitySet.iloc[:,2]
# nac7= velocitySet.iloc[:,3]
# nac8= velocitySet.iloc[:,4]
# nac12= velocitySet.iloc[:,5]

def find(vel, cpVs):
    count=0
    for cpV in cpVs:
        if(cpV > vel):
            return count
        count=count+1

def getMean(cpVs,cpPs,vel):
    if(vel<=2):
        rePower= 0
        return rePower
    index = find(vel, cpVs)
    v1= cpVs[index-1]
    v2= cpVs[index]
    p1= cpPs[index-1]
    p2= cpPs[index]
    rePower = p1+(p2-p1)/(v2-v1)*(vel-v1)
    return rePower

def modify(vel):
    return (vel+0.7081)/0.9869

############################################################
##  Velocity linear interpolation Method ####################################
############################################################
def getPower(nac,i):
    calPower=np.zeros(len(nac),dtype=float)
    calVel=np.zeros(len(nac),dtype=float)
    count=0
    for vel in nac:
        calPower[count]=getMean(cpVs,cpPs,modify(vel))
        #calPower[count]=getMean(cpVs,cpPs,vel)
        calVel[count]=vel
        count=count+1
    calPowerSeries=pd.DataFrame([calVel,calPower]).T
    calPowerSeries.to_csv(str(i)+"-power.csv")
    return np.sum(calPower)/6000
############################################################
##  Velocity Bin Method ####################################
############################################################
def powerLawIntoZones(zones):
    velocityZones=np.linspace(0,25,zones)
    powerZones=np.zeros(velocityZones.__len__())
    velocityBinMag= 25/zones
    for i in range(zones):
        velocityZones[i]=i*velocityBinMag
        powerZones[i]=getMean(cpVs,cpPs,i*velocityBinMag)
    return velocityZones,powerZones

def velocitySeriesSplitIntoZones(nac,power,zones=50):
    [velocityZones,powerZones]=powerLawIntoZones(zones)
    velocityMagnitude=25.0/zones
    counts=np.zeros(zones)
    probability=np.zeros(zones)
    velocitySum=np.zeros(zones)
    velocityMean=np.zeros(zones)
    powerSum=np.zeros(zones)
    powerMean=np.zeros(zones)
    powerTheory=np.zeros(zones)

    AEPActual=np.zeros(zones)
    AEPTheory=np.zeros(zones)
    for vel in range(nac.__len__()):
        for j in range(zones):
            if(0==j and nac[vel]>=0 and nac[vel] <velocityMagnitude/2.0):
                counts[j]=counts[j]+1
                velocitySum[j]=velocitySum[j]+nac[vel]
                powerSum[j]=powerSum[j]+power[vel]
                break
            elif(nac[vel]>=(velocityZones[j]-velocityMagnitude/2.0)  and
                 nac[vel]<(velocityZones[j]+velocityMagnitude/2.0)):
                counts[j]=counts[j]+1
                velocitySum[j]=velocitySum[j]+nac[vel]
                powerSum[j]=powerSum[j]+power[vel]
                break
    for i in range(counts.__len__()):
        if(0==counts[i]):
            continue
        else:
            probability[i]=counts[i]/nac.__len__()
            velocityMean[i]=velocitySum[i]/counts[i]
            powerMean[i]=powerSum[i]/counts[i]
            powerTheory[i]=getMean(cpVs,cpPs,velocityMean[i])
            AEPActual[i]=probability[i]*powerMean[i]*8760
            AEPTheory[i]=probability[i]*powerTheory[i]*8760


    k=np.sum(AEPActual)/np.sum(AEPTheory)

    return probability,velocityMean,powerMean,k




def whichZones(vel,velocityZones,powerZones,zones):
    velocityMagnitude=25.0/zones
    for i in range(zones):
        if(0==i):
            if(vel>=0 and vel <velocityMagnitude/2.0):
                power=0
        else:
            if(vel>=(velocityZones[i]-velocityMagnitude/2.0)  and
                    vel<(velocityZones[i]+velocityMagnitude/2.0) ):
                power = powerZones[i]
    return power

def getPowerVelocityBin(nac,i,zones=50):
    calPower=np.zeros(len(nac),dtype=float)
    calVel=np.zeros(len(nac),dtype=float)
    count=0
    [velocityZones,powerZones]=powerLawIntoZones(zones)
    cps=pd.DataFrame([velocityZones,powerZones]).T
    cps.to_excel(f"powerVelocityBin{zones}.xlsx")
    for vel in nac:
        #calPower[count]=getMean(cpVs,cpPs,vel)
        calVel[count]=vel
        calPower[count]=whichZones(modify(vel),velocityZones,powerZones,zones)
        count=count+1
    calPowerSeries=pd.DataFrame([calVel,calPower]).T
    calPowerSeries.to_csv(str(i)+"-powerBin.csv")
    return np.sum(calPower)/6000
# nac8 = velocitySet.iloc[:, 0]
# power1 = getPower(nac8,0)
# print(power1)
velocitySet=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\nacVelocity.csv',skiprows=1)
velocityPowerSeries=pd.read_csv(r'C:\Users\yezhaoliang\Desktop\vp.csv')

kvalues=np.zeros(10)
for i in range(0,10):
    # nac8 = velocitySet.iloc[:, i]
    nac8 = velocityPowerSeries.iloc[:, i]
    power8 = velocityPowerSeries.iloc[:, i+10]
    [probability,velocitySet,PowerSet,k] = velocitySeriesSplitIntoZones(nac8,power8,50)
    kvalues[i] = k
    print(np.sum(probability))
    print(f"k value is {k}")
    #power1 = getPower(nac8,i)
#    power1 = getPowerVelocityBin(nac8,i,125)
#    print(power1)
kset=pd.Series(kvalues)
kset.to_csv("kvalues.csv")
Related
叶昭良
叶昭良
Engineer of offshore wind turbine technique research

My research interests include distributed energy, wind turbine power generation technique , Computational fluid dynamic and programmable matter.