> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ionworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# シミュレーション設定

> モデルまたはパラメータ化モデルにメッシュとソルバーの永続設定を紐付け、パラメータが必要とするグリッドで毎回シミュレーションを実行します。

**シミュレーション設定 (Simulation settings)** は、PyBaMM の `Simulation`
に渡すキーワード引数（`var_pts`、`submesh_types`、`spatial_methods`、
`solver`）を [モデル](/ja/build/models) または
[パラメータ化モデル](/ja/build/parameterized-models) に永続的に保存する
オプションの設定バッグです。モデルが実行されるたびに Ionworks がこれらを
自動的に再適用します。

モデルの方程式自体はメッシュやソルバーに依存しませんが、フィット済みの
パラメータセットが *必要とする* 設定は依存する場合があります。例えば、
表面近傍で急峻な勾配を持つ固相拡散係数をフィットすると、粒子メッシュを
表面付近で細かくクラスタリングした細かいメッシュが必要になります。PyBaMM
の粗いデフォルトに戻ってしまうと電圧が正しく再現されません。シミュレーション
設定を使うと、こうした要件をモデルまたはパラメータセットに一度だけ紐付け、
下流のすべてのシミュレーションがそのグリッドとソルバーで実行されるように
できます。

## 使いどころ

以下のいずれかに該当する場合にシミュレーション設定を付与します:

* パラメータが非デフォルトのメッシュ（例: `Chebyshev1DSubMesh` を使った
  細かい粒子メッシュ）でフィットされていて、そのメッシュを対応する
  パラメータ化モデルの実行時に必ず適用したい場合。
* 特定のモデル構成が数値的な安定性のために特定のソルバーやソルバー許容誤差
  を必要とする場合。

モデルが PyBaMM のデフォルト設定で正しく動く場合は何も設定する必要は
ありません。`simulation_settings` を未設定（または `None`）のままに
しておけば、PyBaMM 側の `default_var_pts` / `default_submesh_types` /
`default_spatial_methods` / `default_solver` が使われます。

## 設定できる項目

すべてのフィールドはオプションで、省略した項目はモデルのデフォルトに
フォールバックします。

| フィールド             | 型                               | 用途                                                                       |
| ----------------- | ------------------------------- | ------------------------------------------------------------------------ |
| `var_pts`         | `{空間変数: int}`                   | 空間変数ごとのメッシュ点数（例: `{"r_n": 16, "r_p": 16}`）。                              |
| `submesh_types`   | `{ドメイン: submesh config}`        | ドメイン（例: `"negative particle"`）ごとにシリアライズした `pybamm.MeshGenerator`。        |
| `spatial_methods` | `{ドメイン: spatial method config}` | ドメインごとにシリアライズした `pybamm.SpatialMethod`。                                  |
| `solver`          | `dict` または `pybamm.BaseSolver`  | シリアライズした `pybamm.BaseSolver.to_config()` ペイロード（ソルバークラス名 + 許容誤差 / オプション）。 |

保存されるブロックに含まれるクラス名は書き込み時に静的な許可リストと
照合されます。下記に挙げられていないクラスは保存されずに `BAD_REQUEST`
として拒否されます。

`var_pts` で許可される空間変数: `x_n`、`x_s`、`x_p`、`r_n`、`r_p`、`R_n`、
`R_p`、`y`、`z`、および複合電極用の `_prim` / `_sec` バリアント。値は正の
整数でなければなりません。

許可されている submesh クラス: `Uniform1DSubMesh`、`Exponential1DSubMesh`、
`Chebyshev1DSubMesh`、`UserSupplied1DSubMesh`、`SpectralVolume1DSubMesh`、
`SymbolicUniform1DSubMesh`、`SubMesh0D`。

許可されている spatial method クラス: `FiniteVolume`、`SpectralVolume`、
`ZeroDimensionalSpatialMethod`。

許可されているソルバークラス: `IDAKLUSolver`、`AlgebraicSolver`、
`NonlinearSolver`。`CasadiSolver` と `ScipySolver` は PyBaMM で非推奨に
なっており、永続化できません。`ionworkspipeline.Simulation` の背後で使われる
高速なデフォルトソルバーについては
[Ionworks DAE ソルバー](/ja/guide/modeling/ionworks-solver) を参照してください。

<Warning>
  `geometry` は永続化できません。ジオメトリのオーバーライドを保存しようと
  すると、書き込み時に `simulation_settings.geometry is not supported` として
  拒否されます。ジオメトリのデシリアライズは JSON から任意の PyBaMM 式ツリー
  シンボルを再構築するため、上記のクラス許可リストでは境界を定められないから
  です。代わりに `var_pts` / `submesh_types` / `spatial_methods` / `solver` を
  永続化し、ジオメトリのオーバーライドが必要な場合は実行時に
  `simulation_kwargs` で渡してください。
</Warning>

## 優先順位

シミュレーション時、Ionworks は次の固定された優先順位で永続化された設定を
マージします。上位のレイヤーがキー単位で優先されます:

```
runtime simulation_kwargs  >  parameterized model  >  model  >  pybamm defaults
```

* **メッシュ系のキー**（`var_pts`、`submesh_types`、`spatial_methods`）は
  キー単位でマージされます。さらにモデル自身の PyBaMM デフォルトの上に
  キー単位で重ねられるため、`Simulation` に渡されるマップは常に完全な形に
  なります。したがってパラメータ化モデルはグリッド全体を再指定せずに `r_n`
  と `r_p` だけを細かくでき、実行時の `simulation_kwargs` が `r_p` のみを
  指定した場合も、永続化された `r_n` が失われることはなくその 1 エントリだけ
  が上書きされます。
* **`solver`** は最上位のレイヤーで丸ごと置き換えられます。部分的な solver
  は解釈が曖昧なためです。
* 実行時に明示的に渡された `simulation_kwargs` は常に優先されます。
  1 回の実行をデバッグするために永続化された設定を書き換える必要は
  ありません。

<Note>
  パイプラインの **design objective（設計目的関数）** のみ例外です。ここでは
  解決後の `var_pts` と `solver` だけが適用されます。design objective は
  design-optimization コンバータが組み込むシンボリックな submesh を必要とする
  ため、永続化された `submesh_types` / `spatial_methods` は意図的に適用され
  ません。プロトコルシミュレーションおよびモデル / パラメータ化モデルの
  シミュレーション経路では 4 つのキーすべてが適用されます。
</Note>

## API から設定を紐付ける

`client.model` と `client.parameterized_model` はどちらも create と update で
`simulation_settings` フィールドを受け付けます。サブクライアントの詳細は
[Python API リファレンス](/ja/build/api) を参照してください。

### モデルに紐付ける

```python theme={null}
from ionworks import Ionworks

client = Ionworks()

model = client.model.create({
    "name": "DFN with refined particle mesh",
    "config": {"type": "DFN"},
    "simulation_settings": {
        "var_pts": {"r_n": 20, "r_p": 20},
    },
})
```

### パラメータ化モデルに紐付ける

パラメータ固有の設定はベースモデルの設定より優先されるため、フィット済み
パラメータのメッシュ細分化はここに置くのが一般的です:

```python theme={null}
param_model = client.parameterized_model.create("your-cell-spec-id", {
    "name": "NMC622 fitted parameters",
    "model_id": model.id,
    "parameters": {
        "Negative electrode diffusivity [m2.s-1]": 3.3e-14,
    },
    "simulation_settings": {
        "var_pts": {"r_n": 32, "r_p": 32},
        "solver": {
            "type": "IDAKLUSolver",
            "atol": 1e-8,
            "rtol": 1e-6,
        },
    },
})
```

後から設定を更新できます:

```python theme={null}
client.parameterized_model.update(
    "your-cell-spec-id",
    param_model.id,
    {"simulation_settings": {"var_pts": {"r_n": 40, "r_p": 40}}},
)
```

<Warning>
  部分更新は *フィールド* 単位であり、`simulation_settings` の内部ではあり
  ません。送信した内容が**保存済みブロック全体を置き換えます**。上記の呼び出し
  では、create 時に永続化した `solver` が破棄されます。1 つのキーだけを変更
  したい場合は、現在の設定を取得してローカルでマージし、ブロック全体を送信
  してください:

  ```python theme={null}
  current = client.parameterized_model.get(param_model.id).simulation_settings or {}

  client.parameterized_model.update(
      "your-cell-spec-id",
      param_model.id,
      {"simulation_settings": {**current, "var_pts": {"r_n": 40, "r_p": 40}}},
  )
  ```

  [優先順位](#優先順位) で説明したキー単位のマージは、シミュレーション時に
  モデル / パラメータ化モデル / 実行時という *レイヤー* 間で適用されるもので、
  書き込み対象の行に対して更新内容をマージするものではありません。
</Warning>

`"simulation_settings": None` を渡すとフィールドがクリアされ、ベースモデルの
設定（ベースモデルにも無い場合は PyBaMM のデフォルト）を継承します。

## パイプラインから設定を紐付ける

[`ionworks_schema`](/ja/pipelines/overview) のモデルクラス
（`GITTModel`、`MSMRFullCellModel`、`MSMRHalfCellModel`、`LumpedSPMR`、
`LumpedSPMeR`、`ECM` など）は `simulation_settings` 引数を受け付け、
パイプライン投入時にモデル設定と一緒にシリアライズされます:

```python theme={null}
import pybamm
import ionworks_schema as iws

model = iws.models.GITTModel(
    options={"working electrode": "positive"},
    simulation_settings=iws.models.SimulationSettings(
        var_pts={"r_p": 32},
        submesh_types={
            "positive particle": pybamm.MeshGenerator(
                pybamm.Chebyshev1DSubMesh,
            ),
        },
    ),
)
```

生の `MeshGenerator` / `BaseSolver` オブジェクトはパイプライン側で正規化
された JSON 形式に自動的にシリアライズされるので、同じ設定が API を経由
しても保持されます。

## シリアライズされた形式

内部的にはシミュレーション設定はフラットな JSON dict として保存されます。
これは `client.model.get(...).simulation_settings` が返す形式でもあり、
データベース列に保存されている形式でもあります。典型的なブロックは
次のようになります:

```json theme={null}
{
  "var_pts": {"r_n": 20, "r_p": 20},
  "submesh_types": {
    "negative particle": {
      "$type": "type",
      "class": "pybamm.meshes.one_dimensional_submeshes.Chebyshev1DSubMesh",
      "submesh_params": {}
    }
  },
  "solver": {
    "type": "IDAKLUSolver",
    "atol": 1e-8,
    "rtol": 1e-6
  }
}
```

この dict をそのまま渡すこともできますし、`SimulationSettings` スキーマ
クラスから `to_config()` を呼んで同じペイロードを生成させることもできます。
