外部 Mesh Morphing 連携#

外部のmesh morphingツールへ体積メッシュを渡し、変形後の節点座標をEMSolutionへ返すための 連携機能です。Python APIの一般一覧とは分離して、このページでデータ契約、実行順序、制約を 説明します。

警告

この機能はschema version 1/2のPoC段階です。外部ツールとの結合試験および互換性方針が 確定するまでは、安定APIとしては扱いません。外部ツール側はschema versionを確認し、 未対応のversionを受け取った場合は処理を中止してください。

概要#

EMSolutionは、DEFORM領域について、外部ツールが必要とする静的な体積メッシュと、各ステップの 節点状態をPythonへ渡します。外部ツールはRIGID運動を反映済みの**グローバル絶対座標**を返します。 EMSolutionはその座標を使って変形行列を組み立てます。

  • 座標単位は常に m。

  • 座標はグローバル直交XYZ座標系。

  • 返却値は基準座標からの変位量ではなく、変形後の絶対座標。

  • 外部payloadを渡したstepでは、既存の set_deformed_node_position() は重ねて適用されません。

実行の流れ#

初期化直後に静的トポロジーを一度だけ取得して外部ツール側でキャッシュし、各stepでは現在の 変形状態を取得してpayloadを返します。ライフサイクル管理のため、module-level関数ではなく CoupledSession を使用してください。

import pyemsol

with pyemsol.CoupledSession(input_json, str(run_directory)) as session:
    # セッション中に変わらない体積メッシュ。最初のstepより前に1回だけ取得する。
    topology = session.describe_deformation_mesh()

    for end_time, delta_time, motion_state in time_steps:
        description = session.describe_deformation()
        deformation = morph_deformation(
            description, topology, motion_state, time=end_time
        )
        result = session.step(
            time=end_time,
            delta_time=delta_time,
            deformation=deformation,
        )

describe_deformation() の current_coordinates はstep後に更新されます。静的な topology は immutable_during_session が True であれば、セッション終了まで 再取得する必要はありません。

利用するPython API#

class CoupledSession(inputJson, run_directory)#

外部step解析のセッションです。with 文を使用すると、終了時に close() が呼ばれます。 同一プロセスで複数のactiveな解析を実行することはサポートしません。

CoupledSession.describe_deformation() → dict#

各DEFORM領域の参照座標、既存線形変形の目標座標、現在座標を返します。schema versionは現在 1 です。

CoupledSession.describe_deformation_mesh() → dict#

外部morphing用の静的体積メッシュと境界roleを返します。schema versionは現在 2 です。

CoupledSession.step(time, delta_time, inputs={}, deformation=None) → dict#

1つの過渡stepを実行します。time は直前終了時刻 + delta_time、delta_time は 正の有限値でなければなりません。電気連携を併用する場合は inputs にポート入力を指定します。

linear_deformation(description, position, *, mesh_revision=None) → dict#

既存の線形変形規則と同じabsolute-coordinate payloadを作る参照helperです。外部ツールへの 接続確認には利用できますが、一般のmesh morphingでは外部ツールのadapterに置き換えます。 領域が1つなら position は数値、複数なら {deform_id: position} を渡します。

静的メッシュトポロジー(schema version 2)#

describe_deformation_mesh() のトップレベル構造です。

{
    "schema_version": 2,
    "enabled": True,
    "mesh_revision": 0,
    "unit": "m",
    "coordinate_frame": "global",
    "immutable_during_session": True,
    "regions": [...],
}
  • regions の各要素は deform_id、motion_id、基準・目標motion位置、 return_node_ids、mesh を持ちます。

  • return_node_ids はstep payloadへ返す節点IDです。describe_deformation() の 同じ領域の node_ids と同じ順序です。

  • mesh.nodes は ids、reference_coordinates、roles を持ち、同じ添字が 同じ節点を表します。

  • mesh.volume_elements は element_id、element_type_id、element_type、 material_id、role、node_ids を持ちます。node_ids はEMSolutionの局所節点順を 保持します。

節点roleは次の3種類です。

  • deformable: 変形する体積領域(内部の MOTION_DEFORM)。

  • rigid: 形状を保って移動する領域(内部の MOTION_RIGID)。

  • fixed: 外側の固定領域と共有するため既存処理で動かさない境界節点。

要素には deformable と rigid だけを含めます。モデル全体のfixed要素は渡しません。 ただし、外部ツールが固定条件を認識できるよう、共有境界節点は fixed roleとして含まれます。 element_type はEMSolutionの短縮名(例: H1、PR1)です。外部ツール固有の要素種別へ 変換する場合は、element_type_id、節点数、局所節点順を合わせてadapter内で対応付けてください。

動的な変形記述(schema version 1)#

describe_deformation() は各stepで利用する節点状態を返します。

{
    "schema_version": 1,
    "enabled": True,
    "mode": "absolute",
    "unit": "m",
    "coordinate_frame": "global_after_rigid",
    "regions": [
        {
            "deform_id": 1,
            "motion_id": 1,
            "position_pre_geom": 0.0,
            "position_deform_mesh": 0.24,
            "node_ids": [10, 11, 12],
            "reference_coordinates": [[...], [...], [...]],
            "target_coordinates": [[...], [...], [...]],
            "current_coordinates": [[...], [...], [...]],
        },
    ],
}

node_ids、reference_coordinates、target_coordinates、current_coordinates は、 同じ添字が同じ節点を表します。target_coordinates は既存 deform_mesh による線形変形の 目標値であり、全節点の拘束条件ではありません。motion位置は外部solver、Pythonで評価した 時間関数、または上位の連成制御コードから外部ツールへ渡してください。

外部ツールから返すpayload#

外部ツールは、全DEFORM領域を1回ずつ含む regions 形式を返します。

deformation = {
    "mode": "absolute",
    "unit": "m",
    "coordinate_frame": "global_after_rigid",
    "mesh_revision": 25,  # 任意。結果へそのまま返される。
    "regions": [
        {
            "deform_id": 1,
            "node_ids": [10, 11, 12],
            "coordinates": [
                [-0.15, 0.50, 0.00],
                [-0.09, 0.51, 0.00],
                [-0.03, 0.50, 0.00],
            ],
        },
    ],
}

coordinates は (N, 3) のグローバル絶対座標です。node_ids[i] と coordinates[i] は同じ節点を表します。入力順序は任意ですが、デバッグ性と互換性のため description が返した順序を維持してください。部分更新、節点IDの振り直し、変位量の返却は サポートしていません。

NumPyを内部で利用しても、pyemsolへ渡す直前にPython組み込み型へ変換してください。

region_payload = {
    "deform_id": int(deform_id),
    "node_ids": node_ids.astype(int).tolist(),
    "coordinates": coordinates.astype(float).tolist(),
}

結果と検証#

成功時、step() の戻り値には次のような変形情報が含まれます。

result["deformation"] == {
    "mode": "absolute",
    "coordinate_frame": "global_after_rigid",
    "region_count": 1,
    "node_count": 548,
    "mesh_revision": 25,
}

EMSolutionは全領域を検証してから節点座標を更新します。以下の場合は座標および解析時刻を進めずに 例外を返します。

  • DEFORM領域がない、または領域数・deform_id が一致しない。

  • mode、unit、coordinate_frame が指定値と異なる。

  • node_ids または coordinates の長さ、対象ID、XYZ成分数が正しくない。

  • 節点IDの重複・不足・不明ID、NaN/Infを含む座標、Python組み込み型以外の値。

  • gap要素を含むモデル、またはSlide motionと外部Deformを同時に使用するモデル。

外部ツールの受け入れ確認#

adapter実装では、少なくとも次を確認してください。

  1. 受け取った description / topology を破壊的に変更しない。

  2. 全 deform_id について、全 return_node_ids を欠落・重複なく返す。

  3. 座標は有限な m 単位のグローバル絶対座標で、RIGID運動後の境界と固定境界を満たす。

  4. 同じ入力に対して決定的な結果を返す。

  5. 基準状態で期待する形状を返し、Deform_sample による40stepの結合試験を完走する。

step後にもう一度 describe_deformation() を呼び、current_coordinates と送信した coordinates を比較すると、座標の受け渡しを確認できます。

現在の制約#

  • 表面要素、周期境界・スライド面、要素品質指標はトポロジーAPIに含まれません。

  • 外部座標について、要素反転・負Jacobian・体積変化は検査しません。

  • solver計算失敗時の完全rollback、および非線形morphingの後処理再生用座標履歴は未実装です。

  • 毎step、対象となる全節点の座標を返す必要があります。