外部 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実装では、少なくとも次を確認してください。
受け取った
description/topologyを破壊的に変更しない。全
deform_idについて、全return_node_idsを欠落・重複なく返す。座標は有限な
m単位のグローバル絶対座標で、RIGID運動後の境界と固定境界を満たす。同じ入力に対して決定的な結果を返す。
基準状態で期待する形状を返し、
Deform_sampleによる40stepの結合試験を完走する。
step後にもう一度 describe_deformation() を呼び、current_coordinates と送信した
coordinates を比較すると、座標の受け渡しを確認できます。
現在の制約#
表面要素、周期境界・スライド面、要素品質指標はトポロジーAPIに含まれません。
外部座標について、要素反転・負Jacobian・体積変化は検査しません。
solver計算失敗時の完全rollback、および非線形morphingの後処理再生用座標履歴は未実装です。
毎step、対象となる全節点の座標を返す必要があります。