preCICEの設定について（概説）

# はじめに
ここでは`preCICE`の設定（概略）を見ていきます。ソースは[こちらのページ](https://precice.org/configuration-introduction.html)です。
（未完なところもあり、順次、加筆していく予定です）

# preCICE

![doc-base.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/35d7ec83-c999-0635-e9cc-a2891dea90d8.png)

preCICEは上図にあるように2つのソルバーを弱連成させることができます。


```xml:precice-config.xml
<precice-configuration>
  <solver-interface dimensions="3">
   <data .../>
   <mesh .../>
   <participant .../>
   <m2n .../>
   <coupling-scheme .../>
 </solver-interface>
</precice-configuration>
```

preCICEの設定は大きく５つのパートから構成されています。以下では、各パートを見ていきます。

# 0. Dimension

preCICEの設定にある次元は、シミュレーションの次元と一致させておく必要があります（setMeshVertexが持つ座標の次元と一致させる必要があります）。
OpenFOAMやCalculiXなど、3Dシミュレーションしかサポートしていないソルバーもあります。この場合、preCICEの次元が2Dであれば、アダプタは3Dから2Dにマッピングします。これはz方向に1層のセルを持つ準2次元のシミュレーションする場合に有効な設定方法になります。

# 1. Coupling data
カップリングさせる変数を設定します。多くの場合は、変位(Displacement)、力(Force)、温度(Temperature)などを指定することになると思います。

```xml
<data:scalar name="Temperature"/>
<data:vector name="Forces"/>
```

preCICE APIを使用してデータにアクセスする場合は、以下のようにします。

```xml
int temperatureID = precice.getDataID("Temperature", meshID);
```

# 2. Coupling meshes

ソルバー間の境界メッシュを指定します。

```xml
<mesh name="MyMesh1"> 
  <use-data name="Temperature"/> 
  <use-data name="Forces"/> 
</mesh> 
```

preCICE APIでメッシュIDをアクセスする場合は，以下のようにします。

```xml
int meshID = precice.getMeshID("MyMesh1");
```

# 3. [Coupling participants](https://precice.org/configuration-mapping.html)

`participant`では マッピングをする2つのメッシュを設定します。

![doc-participants.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/0886cd03-b76f-fdfa-b745-44f14ac3d4c0.png)


```xml:Example of participant section
<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`(詳細は後述）で行う場合は、下図のようにマッピングされます。

```console
     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`を用いてマッピングする場合は、下図のように取り扱われます。

```console
     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 では、２つのマッピング方法が用意されています；

- **`nearest-neighbor`** : first-oderのマッピング法であり、手っ取り早く、簡単に使用可能ですが、数値誤差を伴います。
- **`nearest-projection`** : second-orderのマッピング法であり、まずメッシュ要素にデータを投影し、その後、線形補間を行います（下図参照）。本手法は`nearest-neighbor`よりも精度良く、かつ比較的高速です。
- **`Radial-basis function mapping`** : 詳細は別節にて。

![configuration-mapping-variants.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/424d03f2-069c-d680-e736-9007017a3848.png)

#### **`Radial-basis function mapping`**
`Radial-basis function`(放射基底関数)マッピングとは、一方のメッシュでグローバルな補間量を計算し、他方のメッシュで評価する手法です。グローバルな補間量は、放射基底関数の線形結合で表されます。
その他、詳細に関しては[こちら](https://precice.org/configuration-mapping.html#radial-basis-function-mapping)を参照ください。

##### thin-plate-splines
thin-plate-splinesは、使用される基底関数のタイプです。
preCICEは、グローバルとローカルをサポートする基底関数を提供します。

グローバルサポートの基底関数（thin-plate-splinesなど）は、追加のパラメータを設定する必要がないため、設定が簡単です。しかし、大きなメッシュでは、このような関数は、アルゴリズムの複雑さ、数値条件、スケーラビリティの面で性能の問題を引き起こします。

ローカルサポートを持つ基底関数は、サポート半径の定義（rbf-compact-tps-c2など）または形状パラメータ（gaussianなど）のいずれかが必要です。精度と効率の良いトレードオフを実現するために、各基底関数のサポートは、各方向に3〜5個の頂点をカバーする必要があります。rbfShape.pyを使用すると、形状パラメータの良い推定値を得ることができます。

# 4. Communication

FSIでは流体計算と構造計算との組み合わせになりますが、この流体、構造の両者間のデータ交換(`m2n communication`)について、例えば以下のような設定を行います。

```xml:m2n communication setting
<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](https://precice.org/configuration-coupling.html#explicit-coupling-schemes)

```xml:Example of explicit-coupling
<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](https://precice.org/configuration-coupling.html#implicit-coupling-schemes)

```xml:Example of implicit-coupling
<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の設定について、簡単ですがまとめてみました。
詳細等は本文中のリンクを参照ください。