コンテンツにスキップ

場ソルバーと境界条件

やりたいこと推奨設定注意
小さいメッシュで動作確認field_solver = "auto" または "direct"direct は厳密だが O(nelem)
要素数が多い通常計算field_solver = "fmm"FMM の詳細は Coulomb FMM コア詳細
2軸周期境界を使うfield_bc_mode = "periodic2"field_solver = "fmm"ちょうど 2 軸を periodic にする
精度確認・デバッグ小ケースで directfmm を比較同じ mesh / particle 条件で比較する

periodic2 は現行実装では FMM 専用です。autofield_bc_mode="free" の小・中規模ケース向けと考えてください。

4. 境界要素電荷による Coulomb 場

Section titled “4. 境界要素電荷による Coulomb 場”

Source: bem_field_solver, bem_field_solver_config, bem_field_solver_eval

direct mode では、評価点 r に対して全要素を直接足し込みます。

E(r)=kci=1Nqirci(rci2+ϵ2)3/2\mathbf{E}(\mathbf{r}) = k_c \sum_{i=1}^{N} q_i \frac{\mathbf{r} - \mathbf{c}_i} {\left(\lVert\mathbf{r} - \mathbf{c}_i\rVert^2 + \epsilon^2\right)^{3/2}}

計算量は 1 評価点あたり O(nelem) です。 粒子 step 数と粒子数が増えると支配的になるため、要素数が大きいケースでは treecode または FMM を使います。

sim.field_normalization により、内部計算の長さスケール L0 を選べます。

L0
si1 m
lengthsim.field_length_scale
boxmax(box_max - box_min)
meshmesh bounding box の最大幅

内部では

x=xx0L0,ϵ=ϵL0\mathbf{x}' = \frac{\mathbf{x} - \mathbf{x}_0}{L_0}, \quad \epsilon' = \frac{\epsilon}{L_0}

として評価し、電場は k_c / L0^2、電位は k_c / L0 を掛けて SI 単位へ戻します。 入力設定と出力 CSV は SI 単位のままです。


Source: init_field_solver, refresh_field_solver, eval_e_field_solver, Coulomb FMM コア詳細

sim.field_solver は次を受けます。

挙動
direct常に direct 和
treecodeoctree + monopole 近似
fmmCoulomb FMM core
autonelem >= tree_min_nelem なら treecode、それ以外は direct

periodic2 は現行実装では field_solver="fmm" が必要です。

treecode は要素重心を octree に分割します。

  1. elem_order に全要素 index を並べる。
  2. node 内の要素重心 AABB を求める。
  3. 要素数が leaf_max 以下、または分割不能なら leaf とする。
  4. そうでなければ中心で 8 octant に分類し、子 node を再帰構築する。

refresh_field_solver は bottom-up に各 node の monopole を再集計します。

Qn=inqiQ_n = \sum_{i \in n} q_i cQ,n={Qn1inqici,Qn>0,cnode,Qn0\mathbf{c}_{Q,n} = \begin{cases} Q_n^{-1}\sum_{i \in n} q_i \mathbf{c}_i, & |Q_n| > 0, \\ \mathbf{c}_{\mathrm{node}}, & Q_n \approx 0 \end{cases}

評価時には node 半径 R と評価点までの距離 d から遠方採用を判定し、採用できる node は monopole として評価します。 採用できない node は子へ降り、leaf では direct 和を行います。 電荷打ち消しが大きい node は monopole 誤差が出やすいため、abs(Q) < charge_cancellation_tol * sum(abs(q_i)) の場合は遠方採用を抑制します。

FMM mode は simulator 非依存の Coulomb FMM core を呼びます。 field solver adapter は次を担当します。

  1. メッシュ重心を source 座標 src_pos(3, nelem) に変換する。
  2. build_plan(plan, src_pos, options) で幾何依存 plan を作る。
  3. update_state(plan, state, q_elem) で電荷依存 state を更新する。
  4. 粒子位置ごとに eval_point(plan, state, r, e) を呼ぶ。

FMM core の P2M / M2M / M2L / L2L / L2P の詳細は Coulomb FMM コア詳細 を参照してください。


Source: bem_field_solver_config, bem_coulomb_fmm_periodic, bem_collision

sim.field_bc_mode="periodic2" は、3 軸のうちちょうど 2 軸を周期軸として扱います。 周期軸は bc_low(axis) == bc_high(axis) == periodic で判定されます。 第三軸は開放方向です。

periodic2 では次が必須です。

  • sim.use_box = true
  • ちょうど 2 軸が periodic
  • 各周期軸の box_max - box_min > 0
  • sim.field_solver = "fmm"

field_periodic_far_correctionauto, none, m2l_root_oracle を受けます。 現行実装では auto は互換用に none へ正規化されます。 m2l_root_oracle は明示指定時だけ有効になる診断的な遠方補正です。

field_periodic_image_layers = N は、周期 2 軸の近傍画像を

(i,j)[N,N]2(i, j) \in [-N, N]^2

で列挙します。FMM core は primary cell source と画像 source を組み合わせて近傍寄与を扱います。 m2l_root_oracle を選ぶと、build 時に Ewald residual を使って root local 補正を fit し、runtime では root local へ注入します。

衝突判定側の periodic2 は、場計算の FMM とは別に処理されます。 find_first_hit_periodic2 は粒子線分と canonical mesh AABB から必要な image shift 範囲を計算し、shift した線分で base mesh との交差を調べます。 同じ t に複数候補がある場合は、要素 index と image shift で deterministic に tie-break します。