1. 程式人生 > >TowerChain平臺開發日誌(2)

TowerChain平臺開發日誌(2)

TowerChain平臺開發日誌

  • 模型檔案的修正以及初始計算檔案的獲得

針對定製化專案,在選定機型之後,機組成本主要的區分點在於風資源的不同。風力發電機組在不同的風資源下的氣動特性存在一定的差異性,其中,空氣密度是影響較大的幾個因素之一。

  1. 空氣密度提取

風資源提供的定製化風電場風資源資料時應按照標準模板生成,其中首頁Site Condition第7列應為各機位點空氣密度,專案空氣密度取其中最大值進行計算。

風資原始檔需要進行格式篩查,檢查是否存在留空以及分組資訊缺失。

如果流程中包含自動格式篩查(),則風檔案不需要手動對上述資訊進行處理。

空氣密度模組同時應提供標準開發介面,即提供含有空氣密度的txt檔案。

風資原始檔將自動被平臺分配至計算目錄下的WindFile資料夾,資料夾下未檢索到風資原始檔時或風檔案數量異常時,應報錯,並終止程式。

# Function 空氣密度資訊提取 # Done
def get_airdensity(root_dir):

    wind_dir = os.path.join(root_dir, 'WindFile')
    windfile_dir = get_typefile(wind_dir, '.xlsx')
    isxlsx = 1

    if not windfile_dir:
        windfile_dir = get_typefile(wind_dir, 'txt')
        isxlsx = 0

    if len(windfile_dir) > 1:
        logging(root_dir, ' ERROR : 風檔案過多!')
        raise Exception('風檔案過多!')

    elif not windfile_dir:
        logging(root_dir, ' ERROR : 沒有風檔案資料!')
        raise Exception('沒有風檔案資料')

    if isxlsx:
        wind = xlrd.open_workbook(windfile_dir[0])
        site_condition = wind.sheet_by_name('Site Condition')
        airdensity = site_condition.col_values(6)
        airdensity = [i for i in airdensity if isinstance(i, float)]

    else:
        with open(windfile_dir[0], 'r') as wind:
            lines = wind.readlines()
            airdensity = float(lines[0])

    return max(airdensity)
  1. 初始IN檔案生成

風力發電機組的模擬通常利用Bladed(@DNV GL)進行。TowerChain平臺使用版本為 Bladed 4.6。Bladed的標準模型檔案格式為*.prj(後文稱為prj檔案),計算模型檔案格式為*.$PJ(後文稱為PJ檔案), 標準計算檔案格式為*.IN(後文稱為IN檔案)。三種檔案資料儲存格式均為xml格式,記錄機組模型資料及相關模擬設定。關於檔案的詳細格式與相關含義,將在後面的文章中詳細說明,這裡僅講解計算前的準備工作。

通常傳遞的機組模型為prj或PJ檔案。由於平臺需要進行大量的後臺計算,因此需要將得到的prj或PJ檔案轉化成求解器可以直接呼叫的IN檔案。關於Bladed的求解器將同計算檔案的格式一同說明。當前,在選擇機組模型時,上傳的模型檔案應統一為prj檔案。

prj檔案需要經過格式篩查,主要檢查模型是否存在模組缺失。此外,由於後期需要迭代機組塔架模型,如果機組模態資訊固定則會導致計算出錯,應選擇在模擬開始時依據模型自行計算模態資訊。因此要求上傳的prj檔案中不得包含機組模態資訊,處理方式為使用文字格式開啟prj檔案後,手動刪除如下欄位:

0RMODE

以及

MSTART RMODE
...
...
MEND

如果流程中包含自動格式篩查(),則prj檔案不需要手動對上述資訊進行處理

在生成IN檔案之前應使用獲得的空氣密度修正模型

在生成IN檔案之前,prj檔案中所引用的絕對路徑,如計算目錄及控制器路徑,應進行修正。

prj檔案生成IN檔案使用bat命令呼叫Bladed_m72.exe求解器執行

@echo off
cd %~dp0
setlocal EnableDelayedExpansion
for /f "delims=" %%i in ('"dir /aa/s/b/on *.prj"') do (
set file=%%~fi
set file=!file:/=/!
)

set apath=%~dp0

"D:\Program Files (x86)\DNV GL\Bladed 4.6\Bladed_m72.exe" -Prj !file! -RunDir !apath! -ResultPath !apath!

prj檔案將自動被平臺分配至計算目錄下的Model資料夾,資料夾下未檢索到模型檔案時或模型檔案數量異常時,應報錯,並終止程式。

# Function 基礎in檔案生成 # Done
# 修正空氣密度 #
# 修改控制器路徑 #
def gen_originalin(root_dir):
    global logfile

    model_dir = os.path.join(root_dir, 'Model')
    project_dir = get_typefile(model_dir, '.prj')

    if not project_dir:
        logging(root_dir, ' ERROR : 未找到模型檔案!')
        raise Exception('未找到模型檔案')

    control_dir = os.path.join(root_dir, 'Exctrl')
    dll_file_path = get_typefile(control_dir, '.dll')
    xml_file_path = get_typefile(control_dir, '.xml')

    change_xml(project_dir[0], 'ExternalController', 'Filepath', dll_file_path[0])
    change_xml(project_dir[0], 'ExternalController', 'AdditionalParameters', 'READ ' + xml_file_path[0])

    change_info(project_dir[0], 'CALCULATION', '2')
    run_bat(root_dir, 'Model')
    in_dir = get_typefile(model_dir, '.in')[0]
    eigen_b = catch_block(in_dir, 'EIGENB')
    eigen_b.append('\n')
    eigen_t = catch_block(in_dir, 'EIGENT')
    eigen_t.append('\n')

    change_info(project_dir[0], 'CALCULATION', '10')
    add_info(project_dir[0], '0RMASS', '0RMODE')
    change_block(project_dir[0], 'CONSTANTS', 'RHO', str(get_airdensity(root_dir)))
    run_bat(root_dir, 'Model')

    add_block(in_dir, 'RCON', eigen_b)
    add_block(in_dir, 'RCON', eigen_t)

    logging(root_dir, ' 初始in檔案生成成功')
    print('初始in檔案生成成功')

    return
  1. 功率係數與最小槳距角

風力發電機組的功率係數是表徵機組發電效能的主要因素,機組在不同槳距角下葉尖速比與功率係數的曲線不同,通常我們取功率係數最大時的槳距角作為最優槳距角,並記錄對應的葉尖速比,用於下節的Kopt計算。通常我們會讓機組的葉片一直保持在最優槳距角,以保證發電效能,直到風速上升至機組需要變槳(收槳,即槳距角增大)降載,因此最優槳距角通常也稱作最小槳距角。

依據葉片設計,通常我們尋找最優槳距角,需要從-2度到2度,以0.5度為一個間隔建立工作點分別進行計算(Bladed 4.4及以前版本),平臺採用的Bladed 4.6版本將多個計算整合成單個計算,可以只設置起止點及步長即可得到結果,簡化了計算步驟。

功率係數的計算在Bladed中的內部編號CALCN為5,主要引數模組為

MSTART PCOEFF
...
PITCH	-0.03490660
PITCH_END	0.03490660
PITCH_STEP	0.00872665
...
MEND

主要設定引數為槳距角起點(PITCH),終點(PITCH_END)以及步長(PITCH_STEP)。

功率係數的計算路徑將自動分配至當前目錄下的Performance資料夾,計算使用的IN檔案為從Model資料夾中複製的上步中生成的初始IN檔案。

功率係數的計算使用bat命令呼叫dtblade.exe求解器執行。

需要注意的地方是,功率係數計算需要將計算選項OPTN設定為0。

功率係數計算後,主要的計算結果儲存在*.%37檔案中。

# subFunction Cp計算in檔案生成並執行計算 # Done
# 修正槳距角為-2至2度,步長0.5度 #
def gen_performance(root_dir):
    global logfile
    gen_originalin(root_dir)

    ori_in_dir = os.path.join(root_dir, 'Model')
    ori_in_file_path = get_typefile(ori_in_dir, '.in')
    current_in_dir = os.path.join(root_dir, 'Performance')
    current_in_file_path = ori_in_file_path[0].replace(ori_in_dir, current_in_dir)
    shutil.copyfile(ori_in_file_path[0], current_in_file_path)

    change_info(current_in_file_path, 'CALCN', '5')
    change_info(current_in_file_path, 'PATH', current_in_dir)
    change_info(current_in_file_path, 'RUNNAME', 'pcoeffs')
    change_info(current_in_file_path, 'OPTNS', '0')
    change_block(current_in_file_path, 'PCOEFF', 'PITCH', '-0.03490660')
    change_block(current_in_file_path, 'PCOEFF', 'PITCH_END', '0.03490660')
    change_block(current_in_file_path, 'PCOEFF', 'PITCH_STEP', '0.00872665')

    print('開始計算最小槳距角')
    run_bat(root_dir, 'Performance')
    logging(root_dir, ' 最小槳距角計算完成')
    print('最小槳距角計算完成')

    return
  1. 最優增益計算

風力發電機組的最優增益通常用於扭矩控制環節,即機組滿發前,的扭矩設定值計算,使得機組一直保持在最優的功率係數附近運轉,保證機組能夠最大出力,發電效能最優。

最優增益通常使用符號Kopt進行代指。相同機型的情況下,Kopt通常與空氣密度直接相關,計算公式如下:

                  Kopt = π* ρ * R^5 * Cpmax / (2 * λ^3)

其中ρ為提取的空氣密度,R為機組葉輪半徑,Cpmax為上步中計算得出最優功率係數,λ為最優功率係數對應的葉尖速比。

為了計算Kopt,需要從上步中生成的*.%37中提取最優的功率係數,以及對應的最小槳距角以及葉尖速比(其中最優槳距角為生成模板IN檔案時使用)。

# subFunction 提取最優Cp及對應的葉尖速比與最小槳距角 # Done
def get_cpinfo(root_dir):
    cpinfo = []
    cp_path = os.path.join(root_dir, 'Performance')
    data_path = get_typefile(cp_path, '.%37')
    with open(data_path[0], 'r') as msg:
        lines = msg.readlines()
        for j in range(len(lines)):
            if 'ULOADS' in lines[j]:
                cpinfo.append(do_split(lines[j], '  ', 1))     # 提取Cp
                cpinfo.append(do_split(lines[j], '  ', 2))     # 提取λ
            elif 'MAXTIME'in lines[j]:
                cpinfo.append(do_split(lines[j], '  ', 1))     # 提取最小槳距角
    return cpinfo

除了從功率係數結果檔案中提取的資料外,機組的葉輪半徑需要從prj檔案中讀取葉輪直徑(DIAM)資料除二後使用。需要注意的是,提取的資料均為字串形式,需要轉換成浮點數後方可使用。

# subFunction Kopt計算 # Done
def get_optmodegain(root_dir):
    global logfile

    cpinfo = get_cpinfo(root_dir)
    cp_max = float(cpinfo[0].strip())
    lamda = float(cpinfo[1].strip())

    model_dir = os.path.join(root_dir, 'Model')
    project_dir = get_typefile(model_dir, '.prj')
    radius = 0.5 * get_block(project_dir[0], 'RCON', 'DIAM')

    pho = get_airdensity(root_dir)

    k_opt = math.pi * pho * math.pow(radius, 5) * cp_max / (2 * math.pow(lamda, 3))
    logging(root_dir, ' Kopt計算完成')
    print('Kopt計算完成')
    return int(k_opt)
  1. 生成模板IN檔案

在依據專案風參,得到基本的風機引數後,應對初始的IN檔案進行修正,得到的IN檔案將作為標準的IN檔案模板向後面的計算傳遞。後續的線性化計算以及載荷計算都將以該檔案作為模板進行對應的修正。

在從初始IN檔案生成模板IN檔案時,主要進行修正的模組為CONTROL。

MSTART CONTROL
...
GAIN_TSR	 1365796
...
PITMIN	 0
...
MEND

主要進行修正的引數為最優增益(GAIN_TSR)與最小槳距角(PITMIN)。

# Function 模板In檔案生成 # Done
# 修改最小槳距角及Kopt #
# 不執行計算 #
def gen_standard(root_dir):
    global logfile
    gen_performance(root_dir)

    ori_in_dir = os.path.join(root_dir, 'Model')
    ori_in_file_path = get_typefile(ori_in_dir, '.in')

    change_block(ori_in_file_path[0], 'CONTROL', 'GAIN_TSR', str(get_optmodegain(root_dir)))
    change_block(ori_in_file_path[0], 'CONTROL', 'PITMIN', get_cpinfo(root_dir)[2])

    logging(root_dir, ' 修正in檔案完成')
    print('修正in檔案完成')

    return

到這裡為止,計算的準備工作就完成了,然後就可以對機組進行線性化計算,從而得到機組的線性化模型,進行控制器整定。

那麼在下一篇文章,就會詳細的介紹如何實現機組的線性化,じゃね~