はじめに
ここではpreCICE
の設定(概略)を見ていきます。ソースはこちらのページです。
(未完なところもあり、順次、加筆していく予定です)
preCICE
preCICEは上図にあるように2つのソルバーを弱連成させることができます。
<precice-configuration>
<solver-interface dimensions="3">
<data .../>
<mesh .../>
<participant .../>
<m2n .../>
<coupling-scheme .../>
</solver-interface>
</precice-configuration>
preCICEの設定は大きく5つのパートから構成されています。以下では、各パートを見ていきます。
0. Dimension
preCICEの設定にある次元は、シミュレーションの次元と一致させておく必要があります(setMeshVertexが持つ座標の次元と一致させる必要があります)。
OpenFOAMやCalculiXなど、3Dシミュレーションしかサポートしていないソルバーもあります。この場合、preCICEの次元が2Dであれば、アダプタは3Dから2Dにマッピングします。これはz方向に1層のセルを持つ準2次元のシミュレーションする場合に有効な設定方法になります。
1. Coupling data
カップリングさせる変数を設定します。多くの場合は、変位(Displacement)、力(Force)、温度(Temperature)などを指定することになると思います。
<data:scalar name="Temperature"/>
<data:vector name="Forces"/>
preCICE APIを使用してデータにアクセスする場合は、以下のようにします。
int temperatureID = precice.getDataID("Temperature", meshID);
2. Coupling meshes
ソルバー間の境界メッシュを指定します。
<mesh name="MyMesh1">
<use-data name="Temperature"/>
<use-data name="Forces"/>
</mesh>
preCICE APIでメッシュIDをアクセスする場合は,以下のようにします。
int meshID = precice.getMeshID("MyMesh1");
3. Coupling participants
participant
では マッピングをする2つのメッシュを設定します。
<participant name="MySolver1">
<use-mesh name="MyMesh1" provide="yes"/>
<use-mesh name="MyMesh2" from="MySolver2"/>
<write-data name="Forces" mesh="MyMesh1"/>
<read-data name="Temperature" mesh="MyMesh1"/>
<mapping:nearest-neighbor direction="read" from="MyMesh2" to="MyMesh1" constraint="consistent"/>
<mapping:nearest-neighbor direction="write" from="MyMesh1" to="MyMesh2" constraint="conservative"/>
</participant>
マッピングでは2つのdirection
であるread
、write
を定義します。
read
マッピングは、メッシュからデータを読み込む前に実施します。例えば、上の例では、Templerature
をMyMesh2
にて読み込み、次いでMyMesh2
からMyMesh1
にマッピングを行っています。
他方、write
マッピングは、データ書き込み後に実行されます。
その上で、マッピングにはconsistent
、conservative
の2つの拘束条件が用意されています。
conservative mapping
conservative
mappingでは、粗さが異なるメッシュ間のマッピングを、力(Force)や質量(mass)などの示量変数(extensive value)に対して適用されます。
例えば力のマッピングをnearest-neighbor mapping
(詳細は後述)で行う場合は、下図のようにマッピングされます。
f=2 f=1 f=2 f=1 f=1
------+------+------+------+------+------
\ | / | /
-------------+-------------+-------------
f=(2+1+2) f=(1+1)
consistent mapping
温度(temperature)や圧力(pressure)などのマッピングを行うときは、consistent mapping
を用います。
nearest-neighbor mapping
を用いてマッピングする場合は、下図のように取り扱われます。
T=2 T=1 T=2 T=1 T=1
------+------+------+------+------+------
| |
-------------+-------------+-------------
T=1 T=1
timing
マッピングのオプションパラメーターとしてtiming
があります。
-
initial
(the default): このメソッドではマッピングを、最初に、一度だけ行います。静止したメッシュ(stationary mesh)を対象とするときは、このオプションで十分機能します。 -
onadvance
: このオプションでは、カップリングをおこなう度にマッピングを新規に計算します。計算コストが高いため、使用に際してはこのオプションが自身の問題に適しているか、検討するのが好ましいです。 -
ondemand
: データはinitialize
,initializeData
,advance
ではマッピングされず、mapReadDataTo
mapWriteDataFrom
を用いてマニュアルで操作された場合のみマッピングを行います。また、このオプション使用には、アダプタがこれらのメソッドに対応している必要があります。
mapping method
preCICE では、2つのマッピング方法が用意されています;
-
nearest-neighbor
: first-oderのマッピング法であり、手っ取り早く、簡単に使用可能ですが、数値誤差を伴います。 -
nearest-projection
: second-orderのマッピング法であり、まずメッシュ要素にデータを投影し、その後、線形補間を行います(下図参照)。本手法はnearest-neighbor
よりも精度良く、かつ比較的高速です。 -
Radial-basis function mapping
: 詳細は別節にて。
Radial-basis function mapping
Radial-basis function
(放射基底関数)マッピングとは、一方のメッシュでグローバルな補間量を計算し、他方のメッシュで評価する手法です。グローバルな補間量は、放射基底関数の線形結合で表されます。
その他、詳細に関してはこちらを参照ください。
thin-plate-splines
thin-plate-splinesは、使用される基底関数のタイプです。
preCICEは、グローバルとローカルをサポートする基底関数を提供します。
グローバルサポートの基底関数(thin-plate-splinesなど)は、追加のパラメータを設定する必要がないため、設定が簡単です。しかし、大きなメッシュでは、このような関数は、アルゴリズムの複雑さ、数値条件、スケーラビリティの面で性能の問題を引き起こします。
ローカルサポートを持つ基底関数は、サポート半径の定義(rbf-compact-tps-c2など)または形状パラメータ(gaussianなど)のいずれかが必要です。精度と効率の良いトレードオフを実現するために、各基底関数のサポートは、各方向に3〜5個の頂点をカバーする必要があります。rbfShape.pyを使用すると、形状パラメータの良い推定値を得ることができます。
4. Communication
FSIでは流体計算と構造計算との組み合わせになりますが、この流体、構造の両者間のデータ交換(m2n communication
)について、例えば以下のような設定を行います。
<m2n:sockets from="MySolver1" to="MySolver2" exchange-directory="../"/>
分散システム上で計算をする場合(例えば流体側はM個のプロセッサーで計算し、個体側はN個のプロセッサーで計算していて、この両者をTCP/IPでつないでいるなど)は、ネットワークについての設定を行う必要があります(が、ここでは割愛させてもらいます)。
5. Coupling scheme
カップリングスキームはpreCICEの設定の重要な部分です。これは、2つ以上の連成に際し、論理的な実行順序を記述するものです。以降ではどのようにカップリングするのか、その方法を概説します。
結合方式にはSerial
(シリアル)とParallel
(パラレル)、Explicit
(陽的)とImplicit
(陰的)とがあります。シリアルとは、一方の計算が他方の計算の後に、時間をずらして実行することを指します。パラレルとは、両計算が同時に実行されることを指します。Explicit
では、両計算が同じ時間窓に一度だけ実行されます。他方、Implicit
では、両計算は収束するまで複数回実行されます。
Explicit-coupling schemes
<coupling-scheme:serial-explicit>
<participants first="MySolver1" second="MySolver2"/>
<max-time-windows value="20"/>
<time-window-size value="1e-3"/>
<exchange data="Forces" mesh="MyMesh2" from="MySolver1" to="MySolver2"/>
<exchange data="Temperature" mesh="MyMesh2" from="MySolver2" to="MySolver1"/>
</coupling-scheme:serial-explicit>
Implicit-coupling schemes
<coupling-scheme:parallel-implicit>
<participants first="MySolver1" second="MySolver2"/>
...
<exchange data="Temperature" mesh="MyMesh2" from="MySolver2" to="MySolver1"/>
<max-iterations value="100"/>
<relative-convergence-measure limit="1e-4" data="Displacements" mesh="MyMesh2"/>
<relative-convergence-measure limit="1e-4" data="Forces" mesh="MyMesh2"/>
<acceleration:IQN-ILS>
...
</acceleration:IQN-ILS>
</coupling-scheme:parallel-implicit>
まとめ
以上、preCICEの設定について、簡単ですがまとめてみました。
詳細等は本文中のリンクを参照ください。