PR

OpenVSPのPythonAPIで地面効果を計算する

OpenVSPのPythonAPIで地面効果を計算する

スポンサーリンク

はじめに

OpenVSPのPythonAPIで地面効果を計算する

OpenVSPはVLM(Vortex Lattice Method / 渦格子法)を用いた解析ソフトなので、地面効果を計算するために鏡像法を用いている

↓参考

最終的にはこんな感じになる

それでは行ってみよう

ソースコード

↓ソースコードはこれ

def vsp_sweep_wig(vsp, alpha, mach, reynolds, height, AnalysisMethod=0, verbose=1):
    # wig : wing in ground effect

    if verbose:
        print('\n-> Calculate alpha & mach sweep analysis\n')

    # //==== Analysis: VSPAero Compute Geometry to Create Vortex Lattice DegenGeom File ====//
    
    # Set defaults
    compgeom_name = 'VSPAEROComputeGeometry'
    vsp.SetAnalysisInputDefaults(compgeom_name)
    if AnalysisMethod:
        vsp.SetIntAnalysisInput(compgeom_name, 'AnalysisMethod', [AnalysisMethod], 0)

    # List inputs, type, and current values
    if verbose:
        print(compgeom_name)
        vsp.PrintAnalysisInputs(compgeom_name)
        print('')

    # Execute
    if verbose:
        print('\tExecuting...')
    compgeom_resid = vsp.ExecAnalysis(compgeom_name)
    if verbose:
        print('\tCOMPLETE')

    # Get & Display Results
    if verbose:
        vsp.PrintResults(compgeom_resid)
        print('')

    # //==== Analysis: VSPAero Sweep ====//

    # Set defaults
    analysis_name = 'VSPAEROSweep'
    vsp.SetAnalysisInputDefaults(analysis_name)

    # Reference geometry set
    geom_set = [0]
    vsp.SetIntAnalysisInput(analysis_name, 'GeomSet', geom_set, 0)
    ref_flag = [1]
    vsp.SetIntAnalysisInput(analysis_name, 'RefFlag', ref_flag, 0)
    wid = vsp.FindGeomsWithName('WingGeom')
    vsp.SetStringAnalysisInput(analysis_name, 'WingID', wid, 0)

    df = pd.DataFrame()
    for re in reynolds:
        for ma in mach:
            for he in height:
                for al in alpha:
                    # Freestream Parameters
                    vsp.SetDoubleAnalysisInput(analysis_name, "AlphaStart", [al], 0)
                    vsp.SetIntAnalysisInput(analysis_name, "AlphaNpts", [1], 0)
                    vsp.SetDoubleAnalysisInput(analysis_name, 'MachStart', [ma], 0)
                    vsp.SetIntAnalysisInput(analysis_name, 'MachNpts', [1], 0)
                    vsp.SetDoubleAnalysisInput(analysis_name, 'ReCref', [re], 0)
                    vsp.SetIntAnalysisInput(analysis_name, 'ReCrefNpts', [1], 0)
                    vsp.Update()

                    # Ground Effect
                    vsp.SetIntAnalysisInput(analysis_name, 'GroundEffectToggle', [1], 0)
                    vsp.SetDoubleAnalysisInput(analysis_name, 'GroundEffect', [he], 0)

                    # List inputs, type, and current values
                    if verbose:
                        print(analysis_name)
                        vsp.PrintAnalysisInputs(analysis_name)
                        print('')

                    # Execute
                    if verbose:
                        print('\tExecuting...')
                        rid = vsp.ExecAnalysis(analysis_name)
                        print('\tCOMPLETE')
                    else:
                        with suppress_stdout():
                            rid = vsp.ExecAnalysis('VSPAEROSweep')
                    
                    tmp = get_polar_result(rid)
                    bref = vsp.GetDoubleAnalysisInput('VSPAEROSweep', 'bref')[0] # [m]
                    tmp['Alpha'], tmp['Height'], tmp['H_bref'] = al, he, he/bref
                    df = pd.concat([df, tmp])

    return df

地面効果を含めたスイープ計算をする関数

引数
vsp:OpenVSPのオブジェクト
alpha:迎角(deg) [list of float]
mach:マッハ数 [list of float]
reynolds:Re数 [list of float]
height:高度(m) [list of float]
AnalysisMethod=0:解析手法 (0: VLM, 1: Panel Method) [int]

返値
df:解析結果のデータフレーム [pd.DataFrame]

↓使い方の例はこれ

import sys
import os

import numpy as np
import pandas as pd

# ../bin/AnalysisVSPAERO.py をモジュールとしてインポート
sys.path.append(os.path.join('..')) # 親ディレクトリをモジュール探索パスに追加
from bin.AnalysisVSPAERO import *
from bin.AnalysisVSPAERO import *

import openvsp as vsp

if __name__=='__main__':
    
    # Clear the current VSP model and read the new VSP file
    vsp.ClearVSPModel()
    vsp.Update()
    vsp.ReadVSPFile('G103A.vsp3')
    vsp.Update()

    # Define the list of alpha angles, the Mach number and Reynolds number for the sweep
    alpha = [2]
    mach = [0.1]
    reynolds = [1e6]

    # Define the list of height
    bref = 17.536552870371967
    height = list((1-np.cos(np.linspace(0,1,12)*np.pi/2))*bref)[1:] + [999]
    
    df = vsp_sweep_wig(vsp, alpha, mach, reynolds, height, AnalysisMethod=0, verbose=1)
    df = make_CDo_correction(vsp, df, Weight=580, xTr=(0.5, 0.7), CDpCL=0.0016, thickness=0.19, interference_factor=1.14, altitude=0, dT=0)
    
    # Output the results to file
    df.to_csv('G103A_DegenGeom.polar', sep='\t')

解析結果をG103A_DegenGeom.polarに書き出す前に、有害抗力に対する補正↓を行っている

それでは説明していく

プログラムの解説

↓基本的には、これをベースにして地面効果の設定を追加しているだけである

# Ground Effect
vsp.SetIntAnalysisInput(analysis_name, 'GroundEffectToggle', [1], 0)
vsp.SetDoubleAnalysisInput(analysis_name, 'GroundEffect', [he], 0)
vsp.SetIntAnalysisInput( analysis, name, indata, index=0)

実行する解析に整数の入力値を設定する関数

引数
analysis:実行する解析の名前 [str]
name:入力の名前 [str]
indata:整数の入力値の配列 [list <int>]
index:データのインデックス [int]

↓使い方の例

Build software better, together
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over...

↓今回はGUIでいうところのこれを設定している

「From Model」の部分
右側の「Npts」の部分

vsp.SetDoubleAnalysisInput(analysis_name, name, indata, index)

特定の解析に対してDouble型の入力の値を設定する関数

引数
analysis_name:特定の解析の名前 [str]
name:入力名 [str]
indata:入力の値の配列 [Array of double]
index:データのインデックス [int]

↓使い方の例

Build software better, together
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over...

↓今回はGUIでいうところのこれを設定している

右側の「Alpha Start」「End」「Mach Start」の部分

↓参考

ただし、VSPAEROSweepで地面効果の計算を有効にしたことで、以下の変更を加えた

  • α、Mach、Re数のスイープ計算ができなくなってしまう仕様なので、α、Mach、Re数のリストを1つずつfor文で回して解析し、結果を1つのデータフレームに結合している(なので普通のスイープ計算よりも時間がかかる)
  • 書き出された結果のαが必ずゼロになってしまう仕様なので、αの値を上書きしている
  • 高度の情報が書き出されないので、追加で書き出している
df = pd.DataFrame()
for re in reynolds:
    for ma in mach:
        for he in height:
            for al in alpha:
                  :
                rid = vsp.ExecAnalysis(analysis_name)
                  :
                tmp = get_polar_result(rid)
                bref = vsp.GetDoubleAnalysisInput('VSPAEROSweep', 'bref')[0] # [m]
                tmp['Alpha'], tmp['Height'], tmp['H_bref'] = al, he, he/bref
                df = pd.concat([df, tmp])
def get_polar_result(result_ids):

    # Loop through the results associated with the given result_ids
    for result_id in vsp.GetStringResults(result_ids, 'ResultsVec'):
        # Check if the result name is 'VSPAERO_Polar'
        if vsp.GetResultsName(result_id) == 'VSPAERO_Polar':
            data, columns = [], []
            # Loop through all available data names for this result_id
            for data_name in vsp.GetAllDataNames(result_id):
                # Get double results for the data_name and append if available
                double_results = vsp.GetDoubleResults(result_id, data_name, 0)
                if double_results:
                    data.append(double_results)
                    columns.append(data_name)
            # If data was found, return it as a pandas DataFrame
            if data:
                return pd.DataFrame(np.array(data).T, columns=columns)
    
    # Return an empty DataFrame if no data is found
    return pd.DataFrame()

OpenVSPの解析IDからスイープ計算の結果を取得する関数

引数
result_ids:OpenVSPの解析ID(vsp.ExecAnalysisの返値)[list of str]

返値
data:スイープ計算の結果 [pd.DataFrame]

VSPAEROの解析が失敗したときは空のデータフレームを返す

結果の比較

解析した結果をみんな大好きHoerner and Boostの式(1)と今回初めて知ったTorenbeekの式(2)と比較してみる

\begin{align}
\frac{(C_{D_{i}}/C_{L}^{2})_{h}}{(C_{D_{i}}/C_{L}^{2})_{\infty}}
&=\frac{33(h/b)^{1.5}}{1+33(h/b)^{1.5}} \tag{1} \\\\
\frac{(C_{D_{i}}/C_{L}^{2})_{h}}{(C_{D_{i}}/C_{L}^{2})_{\infty}}
&=1-\exp{\left[-2.48 \left(\frac{2h}{b}\right)^{0.768}\right]} \tag{2} \\\\
\end{align}

Hoerner and Borstの式(1)もTorenbeekの式(2)も、高度5m以上の範囲ではよく一致するが,5m以下では誘導抗力が小さくなりすぎ,高度0mで誘導抗力が0になってしまう仕様である

↓参考

Handle Redirect

グラフで比較するとこんな感じ

VSPAEROの地面効果はきちんと計算できてそうである

おわりに

OpenVSPのPythonAPIで地面効果を計算した

水平尾翼や胴体も含めて地面効果を計算できるのがOpenVSPの良いところだと思う

↓関連記事

コメント