dynamicsoar's log

主に研究関係のメモ

Rhinoceors 3D: Python script で「表示中のすべてのオブジェクトそれぞれに対してコマンドを実行」する

環境

Rhino 6 on Windows 10 Pro/Enterprise. だけど PythonScript は Mac でも動くらしい(RhinoScript は Win でしか動かないらしい)。

解きたい問題

現在画面に表示させているすべてのオブジェクト(今の場合は球だった)の体積中心に点を打ちたい、という状況があった。マウスクリックで球を選択してから VolumeCentroid を実行し、次の球を選択したら space キー(直前のコマンドの redo)、というのを延々と繰り返せばいいのだが、600個くらいあってちょっと手作業が嫌になった。こんな簡単な作業、スクリプトでできないはずがない、と思い、初めてスクリプトを使ってみようと思い立った。

参考リンク

主に以下を参考にした:

Developer とあるのでちょっと勘違いしていたが、スクリプトを使いたいユーザ向けでもあるよなこれ…

手順

まず Rhino のメニューから Tools > PythonScript > Edit... を選択しエディタを起動する。そこにスクリプトを書いて、エディタのツールバーにある緑の三角で実行。

スクリプト

import rhinoscriptsyntax as rs

rs.CurrentLayer("centroids")

obj = rs.FirstObject()
while obj:

    massprop= rs.SurfaceVolumeCentroid(obj)
    if massprop: rs.AddPoint( massprop[0] )
    
    obj = rs.NextObject(obj)

これにより、あるレイヤ(centroids という名前)をカレントレイヤに設定し、そこに VolumeCentroid*1の結果としての points を出力する。もちろん、VolumeCentroid のところを他のコマンドに変えれば色々応用できると思う。

おそらくこれくらいの簡単な作業なら旧来の RhinoScript でも問題なくできそうだが、どうも Python がこれからはスタンダードになっていくようなので Python にした。初めて書いたばかりなので syntax とかよくわかってない。公式によると

Rhino uses Python version 2.7 ( What is Rhino.Python? with Python )

ということでちょっとがっくり来たが、これはこの機能が実装され始めた時代的にしょうがなかったんだろうかな…

改良版(ロックされたレイヤを無視する)

毎回「見えてるレイヤだけ」処理するのが面倒で、「ロックされたレイヤは飛ばせないかなぁ」と思っていたが、下記でできた。

import rhinoscriptsyntax as rs

# This is optional. You can pre-select a layer and comment out this line instead.
rs.CurrentLayer("centroids")

obj = rs.FirstObject()
while obj:
    
    if rs.IsLayerLocked( rs.ObjectLayer(obj) ):
        pass
    else:
        massprop= rs.CurveAreaCentroid(obj)
        if massprop: rs.AddPoint( massprop[0] )
    
    obj = rs.NextObject(obj)

rs.ObjectLayer(obj) で「obj というIDのオブジェクトが属するレイヤ」のIDを返すっぽい。で、その結果を使って、rs.IsLayerLocked でロックされてるかどうかを調べる、ということ。

*1:なぜかスクリプトではコマンドと違って名前が SurfaceVolumeCentroid だが。

AutoDesk で middle drag(= pan)を rotation に変え、Ctrl+middle drag を pan にアサインする(X-Mouse Button Control利用)

概要

環境は Win 10.

AutoDesk Inventor を使い始めて、マウスの middle drag をデフォルトの pan でなく回転にしたかった。基本的には先人の知恵に習った:

Fusion 360で右クリックで視点を回転させる方法 - 画力がないなら立体を作ればいい

ただ、これだけやると逆に pan ができなくなったので、Ctrl + middle drag で pan するように少しだけ工夫した。具体的には以下の通り:

手順

  1. http://www.highrez.co.uk/downloads/XMouseButtonControl.htm をインストール(ポータブル版でもいいのかも)
  2. Fusion 360で右クリックで視点を回転させる方法 - 画力がないなら立体を作ればいい のとおりに middle drag を rotation に設定(Fusion のところは自分のアプリに置き換えて考える)
  3. 次に、Settings > Modifier Keys と進み、Enable modifier keys にチェック。さらに Layer Modifiers の Activate Layer 2 のところを None から Control に変えて、OK.
  4. メインウィンドウで Apply.

これでどうなるかというと、

  • ミドルドラッグすると回転
  • Ctrl 押しながらミドルドラッグすると、もともとの挙動、つまり pan

になる。

最初は Rhinoceros のように右クリックを pan つまり middle drag に変えればいいじゃん、と思ったのだが、実際やってみると「Inventor 上でのすべての right mouse click」が「middle click」になってしまったようで、全然ダメだった。いや、なんか方法はありそうなんだけど、ちょっと思いつかないのでとりあえずこれで。

Fluent: VS Code で journal file の編集をする → Scheme の関連付けをする

journal file の拡張子をたとえば .jou などに統一しておいて、Scheme と関連付けすればよい。まずは Scheme の機能拡張を入れる(自分は適当に vscode-scheme を選んだ)。次に、settings.json に、

    "files.associations": {
        "*.jou": "scheme"
    },

を追加する(最後尾に追加するなら、最後のカンマは不要)。

これで、セミコロン ; がコメントと認識されて、syntax highlight がされるし、トグルコメントなども機能するようになる。

…今思ったけど、.set ファイルも関連付けしとくと見やすいだろうな。

Fluent: journal file を複数に分割して include するには→ file/read-journal を使う

まえがき

これ、できないと思いこんでたけど、よく見たら User's Guide に書いてあった。.set ファイルに頼らずに、なるべく journal file でやろうとすると、ファイルがどんどん長くなっていて、困っていたので、これができると非常に嬉しい。

方法

要は以下のコマンドで他の journal file(s) を read するというだけ:

file/read-journal "<path_to_another_jorunal_file>" ""

最後に2つのダブルクォーテーションを置くことを忘れないように(忘れると、なぜか次のコマンドがファイル名として認識されてエラーになる)。

ファイルパスは、同一ディレクトリで良ければ、ふつうに、

file/read-journal "./sub.jou" ""

って感じでOK.

もし複数の journal files を連続して読み込みたいなら、

file/read-journal "<path_to_1st_jorunal_file>" "<path_to_2nd_jorunal_file>" ""

みたいにいける。まぁ行数節約しなくていいなら複数行に分けて書いたほうが見やすい気もするが。

具体例

こんなのやろうって人は自分でいくらでも思いつくとは思うけど、たとえば、smoothing の方法を切り替えやすくなる。

つまり、以下のように、smoothing_common.jou, smoothing_spring.jou, smoothing_diffusion.jou, smoothing_linelast.jou というファイルを作っておいて、

smoothing_common.jou

;; ****************************************
;; COMMON settings for SPRING, DIFFUSION, or LIN-ELASTIC method (see below for method-specific settings)
;;; Hidden settings (not accessible from GUI)
;;;; Skewness smoothing on all deforming boundaries [yes]
;;;;   ? Enable/disable skewness smoothing for all deforming dynamic boundary zones. If disabled, only the deforming dynamic boundary zones are smoothed which have smoothing explicitly enabled or use local face remeshing.
define/dynamic-mesh/controls/smoothing-parameters/skew-smooth-all-deforming-boundaries?
yes
;;;; Skewness threshold for cell [0.9]
;;;;   ? Set the cell skewness threshold above which cells will be smoothed using the skewness method.
define/dynamic-mesh/controls/smoothing-parameters/skew-smooth-cell-skew-max
0.7
;;;; Skewness threshold for face [0.7]
;;;;   ? Set the face skewness threshold above which deforming boundary faces will be smoothed using the skewness method.
define/dynamic-mesh/controls/smoothing-parameters/skew-smooth-face-skew-max
0.5
;;;; Skewness-based smoothing number of iterations [4]
define/dynamic-mesh/controls/smoothing-parameters/skew-smooth-niter
4

smoothing_spring.jou

;; ****************************************
;; SPRING method
;;    As boundary layer deformation smoothing can only be used with SPRING, this might be the one we should use.
;;; Smoothing method [spring] (spring, diffusion, linelast)
define/dynamic-mesh/controls/smoothing-parameters/smoothing-method
spring
;;; Normal settings (accessible from GUI)
;;;; <SPRING> Max iterations [20]
define/dynamic-mesh/controls/smoothing-parameters/max-iter
100
;;;; <SPRING> Spring constant factor [1]
define/dynamic-mesh/controls/smoothing-parameters/constant-factor
1
;;;; <SPRING> Convergence Tolorance [0.001]
define/dynamic-mesh/controls/smoothing-parameters/convergence-tolerance
0.0001
;;;; <SPRING> Laplace Node Relaxation factor [1]
define/dynamic-mesh/controls/smoothing-parameters/laplace-node-relaxation
1
;;;; <SPRING> Enable/disable spring-based smoothing for all cell shapes [no]
define/dynamic-mesh/controls/smoothing-parameters/spring-on-all-elements?
no
;;;; <SPRING> Enable/disable spring-based smoothing for tri/tet elements in mixed element zones [no]
define/dynamic-mesh/controls/smoothing-parameters/spring-on-simplex-elements?
no
;;; Hidden settings (not accessible from GUI)
;;;; <SPRING> Set the spring boundary node relaxation factor [1]
;;;;   ? The boundary node relaxation is used by spring smoothing. The boundary node relaxation allows you to relax the update of the node positions at deforming boundaries. A value of 0 prevents deforming boundary nodes from moving and a value of 1 indicates no under-relaxation.
define/dynamic-mesh/controls/smoothing-parameters/bnd-node-relaxation
1
;;;; <SPRING> Set the stiffness factor for springs connected to boundary nodes [1]
define/dynamic-mesh/controls/smoothing-parameters/bnd-stiffness-factor
1

smoothing_spring.jou

;; ****************************************
;; DIFFUSION method
define/dynamic-mesh/controls/smoothing-parameters/smoothing-method
diffusion
;;; Normal settings (accessible from GUI)
;;;; <DIFFUSION> Specify whether the diffusion coefficient is based on the boundary distance or the cell volume [boundary-distance] (boundary-distance, cell-volume)
define/dynamic-mesh/controls/smoothing-parameters/diffusion-coeff-function
boundary-distance
;;;; <DIFFUSION> Set the diffusion coefficient parameter used for diffusion-based smoothing [0] (0.0 -- 3.0)
define/dynamic-mesh/controls/smoothing-parameters/diffusion-coeff-parameter
1.5
;;; Hidden settings (not accessible from GUI)
;;;; <DIFFUSION> Set the numerical method used for diffusion-based smoothing [no] (no=FEM; yes=FVM)
;;;;   ? Answering yes at the prompt changes the diffusion-based smoothing method to the cell based finite volume approach that was the default in releases prior to Fluent 15.0. Answering no at the prompt changes the diffusion-based smoothing method to the default node-based finite element method.
define/dynamic-mesh/controls/smoothing-parameters/diffusion-fvm?
no
;;;; <DIFFUSION> Set the method used to evaluate the boundary distance for the diffusion coefficient calculation [no] (no=standard wall distance; yes=generalized boundary distance)
define/dynamic-mesh/controls/smoothing-parameters/boundary-distance-method
no
;;;; <DIFFUSION/LIN-ELAST> maximum number of iterations for mesh smoothing (FEM) [30]
define/dynamic-mesh/controls/smoothing-parameters/max-iter
30
;;;; <DIFFUSION/LIN-ELAST> Set the relative convergence tolerance for mesh smoothing (FEM) [1e-10]
define/dynamic-mesh/controls/smoothing-parameters/relative-convergence-tolerance
1e-15
;;;; <DIFFUSION/LIN-ELAST> Enable smoothing from reference position [no]
;;;;   ? Enables/disables smoothing from a reference position. Such smoothing may produce greater mesh quality consistency for cases with periodic or quasi-periodic motion, and is only available when the smoothing method is based on diffusion or the linearly elastic solid model.
define/dynamic-mesh/controls/smoothing-parameters/smooth-from-reference-position?
no
;;;; <DIFFUSION/LIN-ELAST> Set the verbosity for mesh smoothing (FEM) [0] (0 -- 1)
;;;;   ? Setting this to 1 will cause smoothing residuals to be printed to the text console. The default value of 0 suppresses this output.
define/dynamic-mesh/controls/smoothing-parameters/verbosity
1

smoothing_linelast.jou

;; ****************************************
;; LIN-ELAST method (linearly elastic solid based)
define/dynamic-mesh/controls/smoothing-parameters/smoothing-method
linelast
;;; Normal setting (accessible from GUI)
;;;; Poission ratio [0.45] (-1.0 -- 0.5)
define/dynamic-mesh/controls/smoothing-parameters/poisson-ratio
0.45
;;; Hidden settings (not accessible from GUI)
;;;; <DIFFUSION/LIN-ELAST> maximum number of iterations for mesh smoothing (FEM) [30]
define/dynamic-mesh/controls/smoothing-parameters/max-iter
30
;;;; <DIFFUSION/LIN-ELAST> Set the relative convergence tolerance for mesh smoothing (FEM) [1e-10]
define/dynamic-mesh/controls/smoothing-parameters/relative-convergence-tolerance
1e-4
;;;; <DIFFUSION/LIN-ELAST> Enable smoothing from reference position [no]
;;;;   ? Enables/disables smoothing from a reference position. Such smoothing may produce greater mesh quality consistency for cases with periodic or quasi-periodic motion, and is only available when the smoothing method is based on diffusion or the linearly elastic solid model.
define/dynamic-mesh/controls/smoothing-parameters/smooth-from-reference-position?
no
;;;; <DIFFUSION/LIN-ELAST> Set the verbosity for mesh smoothing (FEM) [0] (0 -- 1)
;;;;   ? Setting this to 1 will cause smoothing residuals to be printed to the text console. The default value of 0 suppresses this output.
define/dynamic-mesh/controls/smoothing-parameters/verbosity
1

main.jou

メインとなる journal では以下のように、必要ないものをコメントアウトすればよい:

<略>
;; Enable smoothing
define/dynamic-mesh/controls/smoothing?
yes
;
file/read-journal "./smoothing_common.jou" ""
file/read-journal "./smoothing_spring.jou" ""
; file/read-journal "./smoothing_diffusion.jou" ""
; file/read-journal "./smoothing_linelast.jou" ""
;
<略>

他にも、たとえば display/views/camera の設定をいろいろと保存しておいて、見たい角度などに応じて呼び出しを切り替える、といったこともできるだろう。

UDF: cell thread に含まれる face thread にアクセスする

UDF において、ある cell thread tc(たとえば翼を含む空間)に含まれる face thread tf(たとえば翼表面)を求めるのに、次のようなことができた:

begin_c_loop(c,tc);
c_face_loop(c,tc,i)
{
  if(C_FACE_THREAD(c,tc,i)==tf)
  {
    f=C_FACE(c,tc,i);
    f_node_loop(f,tf,n)
    {
       np=F_NODE(f,tf,n);
       if( NODE_POS_NEED_UPDATE(np) )
      {
         NODE_POS_UPDATED(np);
         do something;
      }
    }
  }
}
end_c_loop(c,tc);

if(C_FACE_THREAD(c,tc,i)==tf) のところ、UDFマニュアルのサンプルだと if( THREAD_ID(C_FACE_THREAD(c,tc,i)) == THREAD_ID(tf) ) のように書いてるんだけど、Thread ポインタのままで比較しても特に問題はなさそうだった。

…あれ?でもなんかこれあまり有意義ではないかも・・・

Fluent UDF: マクロ末尾の _M1 は「ひとつ前の時刻」の意味だった

UDF マニュアルより

The _M1 suffix can be applied to some of the cell variable macros in Table 3.8: Macros for Cell Flow Variables Defined in mem.h or sg_mem.h (p. 262) to allow access to the value of the variable at the previous time step (that is, t - \Delta t).

同様に、_M2 は「2つ前の時刻 (t - 2 \Delta t)」の意味だった。

ペンギン遊泳・フリッパー関連の先行研究

論文リスト

  • Kinematics of swimming of penguins at the Detroit Zoo (1979)
  • The energetics of 'flying' and 'paddling' in water: locomotion in penguins and ducks (1985)
  • Penguin Swimming. I. Hydrodynamics (1988)
  • Penguin Swimming. II. Energetics and Behavior (1988)
  • Functional anatomy of the penguin flipper (1992)
  • The potential costs of flipper-bands to penguins (2002)
  • Lovvorn, J., Liggins, G. A., Borstad, M. H., Calisal, S. M. & Mikkelsen, J. 2001 Hydrodynamic drag of diving birds: effects of body size, body shape and feathers at steady speeds. J. Exp. Biol. 204, 1547–1557.
  • Shufeldt, 1901
  • Meister, 1962
  • (Dablow, 1925; Neu, 1931; Kooyman et al., 1971).

Kinematics of swimming of penguins at the Detroit Zoo

  • 計測はいくつかの手法で行っている。
    1. 時間計測
    2. 2台のSony 3210カメラ(情報が出てこないがおそらくアナログフィルム)により60 fpsで水路の中を泳ぐペンギンを撮影。2台使っているがこれはステレオ撮影のためではなく、単に広い領域を撮影するためのようだ。calibration とか three-dimension とかいう言葉は全く出てこないし、結果もない。また、水路の外から撮影しているにもかかわらず、ガラスと水による屈折の影響を全く考慮していない。
    3. 1台のカメラによる撮影から、体長で割った速度と、羽ばたき周波数を計測。
    4. 24 fps で?撮影。ちょっとここは自分のアナログ機器の知識不足で、何を言ってるのかよくわからない…。Fig. 2 はこの結果のようだが、羽ばたき1周期がたったの8フレーム・6フレームしかないので、24 fps というのは妥当に思える。
  • 種は色々いるが、撮影できたのは主に African penguin(論文中での呼称は blackfoot penguin).
  • 連続羽ばたきのみを解析の対象とし、間欠的な羽ばたき⇔滑空は解析から除いている。
  • 翼の迎え角は当然計測できていない。というか羽ばたき振幅も画像の解像度不足で計測できていない。これらは率直に書いてあって、印象が良い。
  • やたらと stride length の利用を推しているが、この方法で整理することでなにが嬉しいのかわからない。
  • アデリーで、gliding 直前の downstroke duration (0.35 s) は連続羽ばたき中のそれ (0.54 s) よりも短い、つまりストロークが速い。これはちょっと興味深い。つまり、glide する前には1回だけ、ただし強めに羽ばたいておく、ということをやっている可能性がある。
  • エンペラーが姿勢を変えずに 2.18 m 滑空したケースがあり、ここから抗力係数を推算している。体重すら計測せずに文献値なのか…水族館あまり協力的じゃなかったのかな…。"This force is assumed to be exclusively friction drag (D)" は意味がわからない。別に pressure drag 成分を除く根拠はないだろうに。普通に total drag でいい。Discussion の最後の記述とか見ると流体力学わかってないという感じではないので、なにか勘違いしてたのかな…。
    • また、結果としての抗力係数は 0.0021 から 0.003 とあるがさすがに小さすぎる。これは代表面積のとり方が表面積だからというだけでは説明がつかない。Lovvorn et al., 2001 によると little penguin (LIPEと略記)の模型・冷凍死骸とも、同等の Re(約100万)で最小でも 0.02 程度(代表面積を表面積にした場合。前面投影面積にすると1桁増える)。つまり、計測誤差が大きいというのもあり得るし、and/or 実際にはわずかに羽ばたくとか胴体を揺するとかして、このエンペラーはわずかでも推進力を生み出していた、ということもありそうに思える。
  • Neu (1931) では、水面付近を泳ぐペンギンの羽ばたき運動を調べていたが、これは今回の結果と異なる。水面付近ならではの制約があったのではと推測している。

The energetics of 'flying' and 'paddling' in water: locomotion in penguins and ducks

  • 体重が同じくらいのアヒルとリトルペンギンを比較。アヒルは足漕ぎ遊泳 (paddling) の代表、ペンギンは翼での遊泳 (flying) の代表という設定。
  • メインは酸素(正確には体積流量 $\dot{V}_{O_2}$)の計測。
  • 水面を遊泳中のペンギンを 200 fps のカメラ1台で横から撮影し、周波数を取得(アヒルは足漕ぎ、ペンギンは羽ばたきの周波数)。カメラは Milliken DBH-5 というアナログフィルムの高速度カメラ。
  • 死骸を使って水面での抗力を計測(水中にすると不安定で計測不能だった)。

The potential costs of flipper-bands to penguins

フリッパーバンドはコストを増大させる、という話。