モデルにランダムに作成されたジオメトリを含めたいと思ったことはありませんか? 例えば, 自然素材や, 寸法変化の統計分布が既知の部品配置をシミュレーションしたい場合などです. このような場合, COMSOL Multiphysics® ソフトウェアでランダムジオメトリを作成する必要があるかもしれません. バージョン 5.3 のリリースでは, メソッドを使用してランダムジオメトリを作成できるようになりました. 興味深い例を使って, その方法を見てみましょう.
スイスチーズのモデル構築
世界最高のチーズ を決めるのは激しい論争の的となっていますが, あえて私の意見を言えば, 良質な エメンタールチーズ に勝るものはありません. 熟練のチーズ職人 は “風味を加えるのは実は穴だ” と冗談を言うかもしれません. ですから, チーズホイールを COMSOL Multiphysics で良いモデルとして構築するには, チーズの穴も含める必要があります.

ランダムな位置とサイズの穴を持つエメンタールチーズのモデル.
スイスチーズに穴が開く理由 は非常に複雑なので, 穴の形成そのものをモデル化することはしません. 代わりに, 上の画像に示すように, チーズのモデルを作成します. チーズの中にランダムに分布した穴を配置し, その半径は上限と下限の間でランダムになるようにします. COMSOL Multiphysics バージョン 5.3 の新しい メソッド 機能を使用することで, このランダムな形状を作成できます. その方法を見てみましょう…
COMSOL Multiphysics® におけるメソッドの紹介
Windows® プラットフォームで COMSOL Multiphysics® バージョン 5.3 を実行し, モデルビルダーで作業している場合, 下のスクリーンショットに示すように, リボンに デベロッパー タブが表示されます. オプションの1つに メソッドを記録 があります. このオプションをクリックすると, 新しい メソッド名 と メソッドタイプ を入力するように求められます. メソッド名には任意の文字列を入力でき, メソッドタイプは アプリケーションメソッド または モデルメソッド のいずれかにすることができます.
アプリケーションメソッド は COMSOL アプリ内で使用できます. この チュートリアルビデオ では, その手順を紹介します. モデルメソッド は, 基盤となる COMSOL Multiphysics モデル内で使用でき, 既存のモデルデータに対して操作 (および情報の追加) を行うことができます.

デベロッパー タブには, メソッドを記録 ボタンと モデルメソッドを実行 ボタンが表示されています.
メソッドを記録 ダイアログボックスで OK ボタンをクリックすると, グラフィカルユーザーインターフェース全体が赤色でハイライト表示されます. 記録停止 ボタンをクリックするまで, 実行されたすべての操作はこのメソッドに記録されます. 記録を停止したら, アプリケーションビルダーに切り替えて, 記録したメソッドを確認できます. 下のスクリーンショットは, 1つのジオメトリオブジェクトの作成を記録した後のアプリケーションビルダーとメソッドを示しています. オブジェクトは, タグが cyl1 の円柱で, 半径は 40 cm, 高さは 20 cm です. これは, チーズホイールの概算値として適切な値です.

アプリケーションビルダーには, ジオメトリを作成するために使用するメソッドのコードが表示されています.
モデルビルダーで作業している場合, デベロッパー タブの モデルメソッドを実行 ボタンを使用して, 他のモデルファイル内でこのメソッドを呼び出すことができます (ジオメトリシーケンス内にタグが cyl1 の既存のオブジェクトが存在しない限り). もちろん, この単純なメソッドは円柱を作成するだけです. 穴をモデリングしたい場合は, メソッドに少しランダム性を取り入れる必要があります. 次に, その点について見ていきましょう.
ランダムなジオメトリ特徴セットの作成
メソッド内では, 0.0 以上 1.0 未満の倍精度数値を返す Math.random class クラスなどの標準 Java® クラスを呼び出すことができます. このクラスと少しの追加コードを使用して, チーズホイールのモデル内に, 指定された数のランダムな位置とサイズの穴を設定します.
チーズ全体にランダムに1000個の穴をあけ, それぞれの半径を 0.1 cm から 1 cm の間でランダムに変化させたいとします. また, エメンタールチーズは 天然の皮 で覆われているため, 穴は形成されません. そのため, 1000個の穴が実際にチーズ内部にあることを確認するためのロジックを少し追加する必要があります. 以下の完全なメソッド (行番号を追加し, 文字列を赤字で表示) は, その方法を示しています.
1 int NUMBER_OF_HOLES = 1000; 2 int ind = 0; 3 double hx, hy, hz, hr = 0.0; 4 double CHEESE_HEIGHT = 20.0; 5 double CHEESE_RADIUS = 40.0; 6 double RIND_THICKNESS = 0.2; 7 double HOLE_MIN_RADIUS = 0.1; 8 double HOLE_MAX_RADIUS = 1.0; 9 model.component("comp1").geom("geom1").lengthUnit("cm"); 10 model.component("comp1").geom("geom1").selection().create("csel1", "CumulativeSelection"); 11 while (ind < NUMBER_OF_HOLES) { 12 hx = (2.0*Math.random()-1.0)*CHEESE_RADIUS; 13 hy = (2.0*Math.random()-1.0)*CHEESE_RADIUS; 14 hz = Math.random()*CHEESE_HEIGHT; 15 hr = Math.random()*(HOLE_MAX_RADIUS-HOLE_MIN_RADIUS)+HOLE_MIN_RADIUS; 16 if ((Math.sqrt(hx*hx+hy*hy)+hr) > CHEESE_RADIUS-RIND_THICKNESS) {continue; } 17 if (((hz-hr) < RIND_THICKNESS) || ((hz+hr) > CHEESE_HEIGHT-RIND_THICKNESS)) {continue; } 18 model.component("comp1").geom("geom1").create("sph"+ind, "Sphere"); 19 model.component("comp1").geom("geom1").feature("sph"+ind).set("r", hr); 20 model.component("comp1").geom("geom1").feature("sph"+ind).set("pos", new double[]{hx, hy, hz}); 21 model.component("comp1").geom("geom1").feature("sph"+ind).set("contributeto", "csel1"); 22 ind++; 23 } 24 model.component("comp1").geom("geom1").create("cyl1", "Cylinder"); 25 model.component("comp1").geom("geom1").feature("cyl1").set("r", CHEESE_RADIUS); 26 model.component("comp1").geom("geom1").feature("cyl1").set("h", CHEESE_HEIGHT); 27 model.component("comp1").geom("geom1").create("dif1", "Difference"); 28 model.component("comp1").geom("geom1").feature("dif1").selection("input").set("cyl1"); 29 model.component("comp1").geom("geom1").feature("dif1").selection("input2").named("csel1"); 30 model.component("comp1").geom("geom1").run();
このメソッドを1行ずつ見ていきましょう:
1. チーズに開ける穴の総数を初期化して定義します.
2. 後で使用するインデックスカウンターを初期化して定義します.
3. 各穴の xyz 位置と半径を保持する倍精度数値セットを初期化します.
4–8. チーズの高さ, 半径, リングの厚さ, そして穴の半径の最大値と最小値 (センチメートル単位) を定義する数値セットを初期化して定義します.
9. ジオメトリの長さの単位をセンチメートルに設定します.
10. タグ csel, 名前 CumulativeSelection の新しい選択セットを作成します. 既に同じ選択セットが存在する場合, メソッドはこの時点で失敗することに注意してください. 同じファイル内でメソッドを繰り返し実行したい場合は, この点を考慮してメソッドを変更することもできます.
11. 指定された数の穴を作成するための while ループを初期化します.
12–14. 穴の xyz 位置を定義します. そのためには, random メソッドを呼び出し, 出力をスケーリングして, 穴の xyz 位置がチーズの外側の直交座標境界内に収まるようにします.
15. 穴の半径が指定された範囲内になるように定義します.
16–17. 穴の位置とサイズが, 穴が実際にチーズの外側にあるかどうかを確認します. そうである場合は, ループ内の残りのコードを実行せずに, while ループの次の反復処理に進みます. この確認は, プログラミングスタイルの好みに応じて, 1行で実行することも, 3行に分割することもできます.
18. 現在のインデックス値に基づいて名前を付けた球体を作成します.
19–20. 新しく作成した球体の半径と位置を設定します. 半径は double 型として直接渡すことができますが, 位置は double 型の配列として指定する必要があります.
21. この球体が csel1 という選択セットの一部であることを指定します.
22–23. インデックスを反復処理し, 球体が作成されたことを示し, while ループを閉じます.
24–26. チーズホイールを表す円柱プリミティブを作成します.
27–29. ブール値の差演算を設定します. 加算するオブジェクトは円柱プリミティブで, 減算するオブジェクトはすべての球体の選択です.
30. ジオメトリシーケンス全体を実行し, 円柱からすべての球体を切り出してチーズホイールを形成します.
このメソッドを新しい (空の) モデルファイルで実行することで, チーズホイールのモデルを作成できます. メソッドを再実行するたびに, 異なるモデルが生成されます. モデルファイル内のジオメトリシーケンスには, すべての球体と円柱プリミティブ, およびブール演算が含まれています.
必要であれば, メソッドにコードを追加して, 最終的なジオメトリ (チーズ) のみのジオメトリファイルを書き出すこともできます. このジオメトリファイルは, COMSOL Multiphysics ネイティブまたは STL ファイル形式で書き出すことができます. また, Parasolid® ソフトウェアカーネルを含む オプションモジュール のいずれかを使用して, Parasolid® ソフトウェアまたは ACIS® ソフトウェアファイル形式に書き出すこともできます. エクスポートと再インポートを行った後, 最終的なジオメトリのみを扱う方が, 完全なジオメトリシーケンスを扱うよりも高速です.
以下は, 私たちの努力の最終結果です. おいしそう!

エメンタールチーズホイールのモデル. すぐに食べられます.
手法を用いたランダム形状の作成に関するまとめ
手法を用いて, ランダムな配置とサイズを持つ形状を作成する簡単な例を見てきました. 穴が重ならないようにする方法や, 最密充填配置 を実現する方法など, ここでは取り上げていない問題もありますが, これらはそれ自体が独立した分野である難しい数学的問題です.
もちろん, メソッドを使ってできることは他にもたくさんありますが, それについてはまた別の機会に説明します. また, パラメトリックにサーフェス を定義するなど, ランダムなジオメトリを作成する方法もあります.
関連リソース
- メソッドの別の活用方法について読む: 視覚と聴覚で確認できるシミュレーション結果の生成
- COMSOL Multiphysics® バージョン 5.3 の新機能については, リリースハイライトページ をご覧ください.
ACIS は Spatial Corporation の登録商標です. Oracle および Java は, Oracle および/またはその関連会社の登録商標です. Parasolid は, 米国およびその他の国における Siemens Product Lifecycle Management Software Inc. またはその子会社の商標または登録商標です. Microsoft および Windows は, 米国およびその他の国における Microsoft Corporation の登録商標または商標です

コメント (0)