2025/09/13公開
物体後方の流れを解析する例題
前回の解析で羽根を有するモデルは微細なグリッド解像度が必要であり、PCスペック的に困難なことが分かりました。
羽根に限らず、薄い形状や細かい形状を有するモデルは解析が難しくなると思われます。
比較的に容易に行えそうな解析としては、大雑把な形状の後方の流れを見るものが挙げられそうです。
main_setup()のサンプルの中に、3Dモデルのサンプルとしてよく見かける牛を使用したものがあります。
牛の後方の流れを見る目的は良く分かりませんが、おそらくソフト紹介のデモ用に目を引く題材として扱ったのだと思われます。
この例題を少し修正して、独自に物体後方の流れを解析する例題を作成してみます。
3Dモデルの準備
少しは工学的に意味のある解析を行いたいので、オープンカーの周囲の流れを解析してみます。
3Dモデルは適当なものを用意しました。
モデルを置き換えるだけで解析が行えるかと思いきや、またグリッド解像度の問題に直面しました。。
オープンカーの3Dモデルをそのまま使用するとフロントガラスが認識されないのです。
3Dモデルは実物を結構精度良くモデル化したものらしく、フロントガラスの厚さも実物通りに作っているようでした。
つまり、流体グリッドサイズよりも厚さが小さかったので認識されなかったようです。
仕方がないので、3Dモデルエディターでフロントガラスを十分な厚さを有する物に置き換えました。
この流体解析においては強度等を評価することではないので、この修正は結果にさほど影響を与えないと思われます。
流れのスピードについては実際のものを再現するような考慮はしていません。
とりあえず渦が観測できるスピードに調整をしました。
main_setup()内の設定
解析の設定はsetup.cpp内の関数main_setup()内で行います。
aerodynamics of a cowの解析をコピーして、必要箇所を修正していきます。
関数main_setup()を以下に示します。
------
void main_setup() { // custom4 aerodynamics of a open car; required extensions in defines.hpp: FP16S, EQUILIBRIUM_BOUNDARIES, SUBGRID, INTERACTIVE_GRAPHICS or GRAPHICS
// ### define simulation box size, viscosity and volume force ###
const uint3 lbm_N = resolution(float3(1.0f, 2.0f, 0.6f), 5000u); // input: simulation box aspect ratio and VRAM occupation in MB, output: grid resolution
const float si_u = 3.0f; //1.0f;
const float si_length = 2.4f;
const float si_T = 10.0f;
const float si_nu = 1.48E-5f, si_rho = 1.225f;
const float lbm_length = 0.65f * (float)lbm_N.y;
const float lbm_u = 0.075f;
units.set_m_kg_s(lbm_length, lbm_u, 1.0f, si_length, si_u, si_rho);
const float lbm_nu = units.nu(si_nu);
const ulong lbm_T = units.t(si_T);
print_info("Re = " + to_string(to_uint(units.si_Re(si_length, si_u, si_nu))));
LBM lbm(lbm_N, lbm_nu);
// ### define geometry ###
const float3x3 rotation = float3x3(float3(0, 0, 1), radians(-90.0f)); // *float3x3(float3(0, 0, 1), radians(180.0f));
Mesh* mesh = read_stl(get_exe_path() + "../stl/carbonizzare_gta_v_b_mdf.stl", lbm.size(), lbm.center(), rotation, lbm_length * 1.0f); // https://www.thingiverse.com/thing:182114/files
mesh->translate(float3(0.0f, 1.0f - mesh->pmin.y + 0.4f * lbm_length, 1.0f - mesh->pmin.z)); // move mesh forward a bit and to simulation box bottom, keep in mind 1 cell thick box boundaries
lbm.voxelize_mesh_on_device(mesh);
const uint Nx = lbm.get_Nx(), Ny = lbm.get_Ny(), Nz = lbm.get_Nz();
parallel_for(lbm.get_N(), [&](ulong n) { uint x = 0u, y = 0u, z = 0u; lbm.coordinates(n, x, y, z);
if (z == 0u) lbm.flags[n] = TYPE_S; // solid floor
if (lbm.flags[n] != TYPE_S) lbm.u.y[n] = -lbm_u; // initialize y-velocity everywhere except in solid cells
if (x == 0u || x == Nx - 1u || y == 0u || y == Ny - 1u || z == Nz - 1u) lbm.flags[n] = TYPE_E; // all other simulation box boundaries are inflow/outflow
}); // ### run simulation, export images and data ###
lbm.graphics.visualization_modes = VIS_FLAG_SURFACE | VIS_Q_CRITERION;
#if defined(GRAPHICS) && !defined(INTERACTIVE_GRAPHICS)
lbm.graphics.set_camera_centered(-40.0f, 20.0f, 78.0f, 1.25f);
lbm.run(0u, lbm_T); // initialize simulation
while (lbm.get_t() <= lbm_T) { // main simulation loop
if (lbm.graphics.next_frame(lbm_T, 10.0f)) lbm.graphics.write_frame();
lbm.run(1u, lbm_T);
}
#else // GRAPHICS && !INTERACTIVE_GRAPHICS
lbm.run();
#endif // GRAPHICS && !INTERACTIVE_GRAPHICS
}
------要点のみ解説すると
Mesh* mesh = read_stl(get_exe_path() + "../stl/carbonizzare_gta_v_b_mdf.stl", lbm.size(), lbm.center(), rotation, lbm_length * 1.0f);
の所で、オープンカーの3D形状を読み込んでいます。
効率よく解析するために、車体の周りの余分な空間をなるべく小さくするように調整しました。
解析結果アニメーション
以下よりYouTube動画を視聴できます。
それらしい結果が得られました。
オープンカーは真冬でもそれほど寒くないと聞きますが、座席の部分にはあまり渦が発生していないようなので、ドライバーには直接風が当たらないようです。
また、ミラーの部分でかなり渦が発生しているので、高速走行時はミラー部分の空力抵抗は結構大きいことが推測されます。
改めてFluidX3dの渦の可視化の凄さを感じました。
