開発者向けアーキテクチャ
BEACH の Fortran 実装を初めて変更する開発者が、実行入口から変更対象と直接 test まで移動するための概要です。 通常の物理・数値サイクルはBEACH の計算サイクル、build と test の選び方は 開発ワークフローを参照してください。このページは全 module の一覧を再掲せず、runtime の 制御フロー、主要 state の所有者、subsystem の境界だけを扱います。
ディレクトリの責務を判断する
Section titled “ディレクトリの責務を判断する”配置は扱う対象と処理の責務で決めます。mesh/ は形状と離散化、physics/ は物理モデルと数値解法、
runtime/ はそれらを結ぶ実行制御です。たとえば三角形の面積や求積点は mesh、面電荷が作る電場の積分は
field solver に属します。
ディレクトリ(src/ 以下) | 担当 |
|---|---|
core/ | 共通の型・定数・文字列処理・MPI 基盤 |
mesh/ | 形状の生成・読み込み、三角形幾何、面の向き、求積、衝突検索用の幾何 |
particles/ | 粒子配列の管理と注入分布のサンプリング |
physics/ | 電場・粒子運動・境界・表面・シースの物理モデルと数値解法 |
config/ | 設定型、TOML の読取、座標・単位の正規化、実行前検証 |
runtime/ | 設定からの実行データ構築、バッチ制御、モデル間の連成、出力、再開 |
tools/ | 通常のバッチ計算から独立した表生成・診断ツール |
照射実験の前提は irradiation_cell_contract_type が持ちます。
resolve_irradiation_cell_contract は実行開始時に設定から壁の面・軸・外向き法線・座標、周期軸、下端モデルを
一度解決します。粒子追跡、外部シース、壁電位の診断はこの契約へ問い合わせ、mesh・注入分布・pusher・collision・
direct / FMM の汎用 kernel は契約型に依存しません。壁は現行の製品構成では z_high で、公開設定は増やしません。
表面電流モデルを単独で呼ぶ場合は入口で解決し、simulator から呼ぶ場合は実行中の契約を渡します。
実行フローを追う
Section titled “実行フローを追う”flowchart TD cli["app/main.f90\nCLI / MPI 初期化"] config["config parser / runtime configuration\napp_config と mesh を構築"] restart["restart または初期 state\nq_elem / stats / residual / ledger"] loop["run_absorption_insulator\naccepted batch / trial loop"] field["electrostatic snapshot\ncommit 済み q_elem から refresh"] inject["source plan / injection\ntrial の particles_soa を生成"] step["particle step / events\nBoris → 最初の mesh / box event"] commit["closure / MPI reduce / commit\ndq を q_elem へ一度反映"] record["stats / history / checkpoint\naccepted state だけを記録"] final["main の最終出力\nsummary / CSV / checkpoint"]
cli --> config --> restart --> loop loop --> field --> inject --> step --> commit --> record record -->|次の accepted batch| field record -->|batch_count 到達| finalapp/main.f90は CLI option を処理します。--check-configは設定検証で終了し、 通常実行では MPI と performance profile を初期化して設定 path を解決します。load_or_init_run_stateが設定を読み、mesh と初期 state または restart state を用意します。bem_app_config_parser.f90は TOML をapp_configへ読みます。authoring の正規化と領域別 preflight が派生値・参照と最小のモデル成立条件を確認します。bem_app_config_mesh_runtime.f90が template または OBJ からmesh_typeを構築します。mainはopen_run_outputsで history と終了時 mesh 電位の出力先をrun_outputs_typeにまとめて開き(その前に root rank が出力先を今回の run の世代にそろえる。新規実行は前の run の checkpoint を無効化して任意出力を消し、再開は history を checkpoint の batch まで切り戻す)、run_absorption_insulatorに 1 引数で 渡します(unit = -1 の history は書かない)。interface はbem_simulator.f90、主 loop はbem_simulator_loop.f90、 粒子生成・追跡はbem_simulator_particles.f90、 電荷反映・電流補正・台帳はbem_simulator_charge.f90が担当します。 統計と履歴はbem_simulator_stats.f90とbem_simulator_io.f90の submodule に分かれます。- simulator は commit 済み
mesh%q_elemからelectrostatic_snapshot_typeを refresh します。 同じ trial の粒子追跡中はこの snapshot を固定し、accepted commit の電荷は次の batch の refresh で初めて場へ入ります。 build_particle_source_planとprepare_batch_stateが、source 設定とrun.batch.duration_sから trial 用のparticles_soaを作ります。設定からの粒子構築はbem_app_config_particle_runtime.f90、分布 sampling はsrc/particles/が担当します。process_particle_batchはbem_particle_stepper.f90を通して 予測中点場、Boris 更新、候補軌道を作ります。bem_collision.f90とbem_boundary.f90が最初の mesh hit または box event を確定し、吸収、escape、reflect、periodic wrap 後の再積分へ分岐します。- hit 電荷と放出反作用電荷は
simulator_batch_workspace_typeの thread-localdqに蓄積します。surface / current closure と MPI reduce が成功した accepted trial だけをcommit_batch_chargeがmesh%q_elemへ一度加え、必要なら conductor 電荷を再配分します。 - commit 後に
sim_statsとcharge_ledger_typeを更新し、履歴と定期 checkpoint を書きます。mainは最終的にbem_output_writer.f90から summary、CSV、最終 checkpoint を公開します。
外部シースの根を観測 PE 流出で更新する場合は、
bem_zhao_outflow_refresh.f90 が accepted batch の
H 通過モーメントを窓に集め、窓が満ちたら根を解き直して次の batch の closure と z-high 電位基準を返します。
主ループはこの内部状態を直接変更せず、commit 後に一度だけ呼び出します。
adaptive batch-duration は手順 5—7 を同じ batch 開始 state から再生します。棄却 trial の候補電荷、粒子 outcome、
RNG、macro 粒子端数は accepted state にしません。受理・rollback の詳細は
run.batch.duration_s の理論を参照してください。
主要 state の所有者を確認する
Section titled “主要 state の所有者を確認する”| State | 所有者と lifetime | 更新規則 |
|---|---|---|
app_config | main が構築し、run 全体で保持 | parser / runtime resolution 後は simulator へ read-only で渡す |
mesh_type geometry | main が構築し、run 全体で保持 | 頂点、panel geometry、collision index は原則不変 |
mesh%q_elem | mesh_type が持つ canonical な表面電荷 | run 前に初期化または復元し、その後は accepted trial の commit_batch_charge だけが更新する |
electrostatic_snapshot_type | simulator が run 中に保持する派生 cache | commit 済み q_elem から refresh し、粒子追跡中は固定する。正本の電荷ではない |
particles_soa | 1 trial の粒子 batch | source から生成し、吸収・escape・上限到達まで追跡した後に破棄する |
simulator_batch_workspace_type | simulator が再利用する作業領域 | thread-local dq、候補電荷、outcome flag を保持する。commit 前は canonical state ではない |
injection_state と RNG | accepted batch 間で継続し、restart で復元 | macro 粒子端数と乱数列を継続する。trial 棄却時は batch 開始 state へ戻す |
sim_stats | main と simulator が保持する累積統計 | accepted trial だけを加算し、summary / checkpoint へ保存する |
charge_ledger_type | run 全体の signed charge stock / flux | accepted batch の移送だけを累積し、保存残差と未解決量を別々に保持する |
| output / checkpoint files | writer が committed state から作る serialized copy | file 自体を runtime state の所有者にせず、loader が契約検査後に復元する |
この区別により、変更時には「候補値を作る場所」と「accepted state を確定する場所」を分けて確認できます。 trial-local 配列を更新しただけで、統計、ledger、履歴、checkpoint まで更新したとみなしてはいけません。
公開入口から責務の担当へ進む
Section titled “公開入口から責務の担当へ進む”公開入口は呼び出し順とデータの受け渡しを管理し、個別の形式や物理分野の処理を次の実装へ委譲します。
| 処理 | 公開入口 | 実装の担当 |
|---|---|---|
| 場の評価 | bem_field_solver.f90 | _config は設定解決、_tree は treecode の木とモーメント、_fmm は FMM core のパネル幾何・電荷状態、_eval は評価方式の切り替え |
| Fortran の結果出力 | bem_output_writer.f90 | _history submodule は履歴の生成・追記、_summary はサマリ、_files はメッシュ・電荷・台帳 CSV |
| チェックポイントの再開 | bem_restart.f90 | _contract は再開条件の検証、_records は統計・電荷・台帳の読み込み、_injection は乱数・マクロ粒子端数の保存と復元 |
| 設定から粒子を生成 | bem_app_config_particle_runtime.f90 | 親 module は粒子源計画、_batch は MPI 配分とバッチ構築、_sampling は種別ごとのサンプリングと注入速度補正 |
| Python の設定処理 | beach/config/core.py | 読み込み・正規化・schema 検査の順序を持つ。schema.py は同梱 JSON Schema による key・型・範囲の検査、_layout.py は grouped / runtime layout の変換、_authoring.py は空間指定の展開を担当する。組合せと派生値の検査は Fortran の beach --check-config(beachx lint)が持つ |
| Python の結果読み込み | beach/io/results.py | 基本のメッシュ・電荷を読み、_matching_plane_io.py と _field_reconstruction_io.py に外部シース状態・場の再構築メタデータを委譲する |
FMM の木構造・相互作用リストは field_solver_type%fmm_core_plan、電荷から計算する作業状態は
%fmm_core_state が保持します。旧 FMM の複製 view と未使用の局所展開配列は削除しました。
診断時は core plan / state を参照し、treecode 用配列から FMM の状態を読まないでください。
init は既存の FMM 作業状態を解放してから再構築します。たとえば、同じ solver に対して
call solver%init(mesh, sim) を再度呼び、sim%field_solver を切り替えられます。
refresh(mesh) は電荷更新に用い、FMM では空メッシュまたは要素数の変更にも対応します。
同じ要素数で頂点座標を変更した場合は init で幾何を再構築してください。
設定の読取・正規化と実行データ構築を分ける
Section titled “設定の読取・正規化と実行データ構築を分ける”src/config/ は TOML を読み、既定値・座標変換・派生値・参照を解決し、実行に必要な最小条件を確認します。
その設定からメッシュ、粒子、境界電位を作る処理は src/runtime/configuration/ に置きます。
beach --check-config beach.toml は通常実行と同じ設定読込を使い、MPI 初期化と実行データ構築の前に終了します。
外部境界の基底契約は preflight が app_config%boundary_contract に解決し、粒子生成・run 制御・summary 出力が
同じ値を参照します。種別の動的な kinetic barrier は、その基底契約に面別の上書きを重ねます。
particle_source_plan_type は粒子源を整数の種別に解決して保持し、バッチの slot 構築は文字列を解釈しません。
sim_config は入力表現と run 制御を保持し、粒子追跡・衝突・境界 event は親型 particle_domain_config の
箱・面別条件・乱数 seed・場境界だけを受け取ります。photo ray は、それに解決済みバッチ幅と反射回数上限を加えた
photo_raycast_config を使います。runtime は種別の領域設定を一度作り、入力の has_* や外部場の角度指定を
粒子追跡の内部へ渡しません。設定を Fortran から直接組み立てる場合、基底契約も解決済みの値として設定します。
| 担当 | 実装 | 境界 |
|---|---|---|
| TOML の基本値 | bem_config_toml.f90 | 型、整数の格納範囲、実数の有限性、配列長、文字列の格納長を確認して値を返す |
| Table ごとの読取 | bem_app_config_parser.f90 と _read_sim / _read_particles / _read_mesh / _read_surface | キーを設定型と authoring overlay に対応付ける |
| 座標・配置の展開 | bem_app_config_authoring.f90 と _types / _domain / _sources / _geometry | 型と既定値、領域、注入面、mesh group・anchor を分離。親は配列管理と変換順序を持つ |
| 派生値とモデル成立条件 | parser の _finalize、_preflight_sim / _preflight_particles / _preflight_surface、_validate、bem_physics_config_types | finalize は処理順、_validate は粒子源の派生量、bem_physics_config_types は場のモデルの組合せ、他の preflight は各領域の参照解決と必要条件を担当する |
| 実行データの構築 | runtime/configuration/ | bem_app_config は既存の公開入口。mesh、粒子源計画・batch・sampling、境界電位を担当別に構築する |
| Python の schema 検査 | beach/config/core.py と schema.py | 読取、schema、authoring 展開を一つの経路で実行する。組合せ制約は持たず、lint が beach --check-config を呼ぶ |
Python の load_config_file、normalize_config_document、lint は共通の基本型・整数の格納範囲・有限値・未知キー検査を使います。
lint は TOML を再読込しません。
列挙された識別値の大文字小文字を正規化し、path や自由文字列を一律に小文字化しません。
Python は schema のキー・型・列挙値・値域を検査し、Fortran preflight が設定の組合せと派生量を検査します。
make test-config-contract は正常・不正入力の両方で lint と beach --check-config の採否を照合します。
この gate は L2 に含まれます。beach.tooling.workload は、正規化済みの設定から粒子数を見積もり、
重みやバッチ幅を一意に計算できない場合を検出します。放出方向・境界作用・一様外部場など、粒子数に使わない
物理条件の検証は preflight が担当します。追加する検証の判断は
開発ワークフローに従います。
電場ソルバーと三角形幾何の担当
Section titled “電場ソルバーと三角形幾何の担当”src/physics/field_solver/ は最終的な静電場の合成まで担当します。
bem_field_solver は Direct / Treecode / FMM の評価を切り替え、bem_electrostatic_snapshot は
周期場の平均成分と非ゼロ成分、指定一様場を合成してバッチ中に固定する場を提供します。
ディレクトリ(src/ 以下) | 担当 |
|---|---|
mesh/panel/ | 三角形の幾何・モーメント・面の向き、幾何だけから求める求積点と重み |
physics/field_solver/ | snapshot による場の合成、Direct / Treecode / FMM の切り替え、C API |
physics/field_solver/panel/ | 三角形面電荷の Coulomb 積分、面上の自己項、求積による電場の検証用実装 |
physics/field_solver/periodic/ | 平面平均場の解法、非ゼロ Fourier 成分の参照評価、上部真空域での Fourier 評価 |
physics/field_solver/fmm/ | FMM の公開 API と内部の木・展開・相互作用・Ewald 遠方演算子・cache |
zero mode は x/y 波数がゼロの平面平均場で、電場ソルバーの一部です。高さごとの累積電荷と下側境界条件から
Gauss 則を積分します。非ゼロ成分を Fourier 参照計算で求める場合と FMM の cached_kneq0 で求める場合に
同じ実装を使うため、periodic/ に置きます。合成時の重複除去と式は
periodic2 静電場を参照してください。
共有する Fourier 評価もこのディレクトリに置き、FMM 固有の演算子生成・cache は fmm/internal/periodic/ が持ちます。
メッシュ構築は bem_triangle_quadrature の fill_panel_quadrature を直接使い、電場評価に依存しません。
bem_panel_quadrature は電場の検証用積分を持ち、既存の求積 API も公開して従来の呼び出し元を維持します。
幾何の準備を共有しても、Coulomb kernel の検証用積分は解析 kernel と別の式で評価します。
シースと外部応答の担当
Section titled “シースと外部応答の担当”src/physics/sheath/ は境界契約を持ち、app_config、MPI、ファイルシステム、simulator には依存しません。
Zhao シースの零電流根、成立条件の検査、根が z-high 面に課す条件(壁電位、電子・イオンが越える電位、
上流の貯留部、放出電子の脱出・帰還)、観測スペクトルからの放出源の構築、更新間で引き継ぐ根は、外部ライブラリ
sheath-model の結合 API(sheath_matching_iteration、evaluate_matching_conditions、observed_outflow_source)が担当します。
粒子種との対応、面積、固定電流 target、PE と SEE の分割、summary による再開は src/runtime/sheath/ が担当します。
flowchart LR simulator["simulator: バッチ制御"] --> refresh["runtime/sheath: 外部根の更新"] simulator --> model["runtime/sheath: 設定から closure へ"] refresh --> model refresh --> zhao model --> zhao["sheath-model(外部依存): 零電流根、面上の条件、外部根の更新"] model --> contract["physics/sheath: 境界契約"]ディレクトリ(src/ 以下) | ファイル | 担当 |
|---|---|---|
physics/sheath/ | bem_surface_closure_contract.f90 | simulator が受け取る電流 target、流入写像、外向き障壁、z-high 電位基準のデータ型。モデル固有の解法は持たない |
runtime/sheath/ | bem_surface_current_model.f90 | 設定から sheath-model の上流状態と放出源を作り、外部根の面上条件を、表面放出と外部放出源を分けた species 別の電流 target と境界写像へ変換 |
runtime/sheath/ | bem_zhao_outflow_refresh.f90 | 観測 PE・SEE 流出の窓集計から外部の放出源を作って sheath-model の外部根を更新し、外部状態を stats へ保存。再開時の根の再構成 |
src/physics/bem_surface_models*.f90 は物体側の電荷再配分・導体条件などを担当し、外部シース応答とは別です。
粒子配列を直接生成する
Section titled “粒子配列を直接生成する”bem_particles の allocate_particles(pcls, n) が非負の粒子数 n に一致する配列の確保を担当します。
位置・速度・電荷・質量は呼び出し元が埋めます。重みは 1、粒子種 ID は 0、放出元要素は -1、
alive は true で初期化されます。n=0 でも長さゼロの配列を確保し、既存の粒子群を置き換えます。
たとえば、静止粒子を直接生成する場合は次のように書けます。
use bem_kinds, only: dp, i32use bem_types, only: particles_soause bem_particles, only: allocate_particles
type(particles_soa) :: pcls
call allocate_particles(pcls, 100_i32)pcls%x = 0.0_dppcls%v = 0.0_dppcls%q = -1.602176634e-19_dppcls%m = 9.1093837015e-31_dp既存の配列を検証してコピーする用途は引き続き init_particles が担当します。
注入時は分布サンプラーが生成先へ直接書き込み、バッチ構築では種別ごとの必要数だけを一時保持し、
従来の種別交互順で完成した SoA へ詰めます。乱数の消費順と放出元要素の対応を維持します。
mesh の幾何更新は bem_panel_geometry が計算した重心・法線・面積を利用します。
fill_panel_quadrature(panel, position, weight) は確保済みの position(3,7) と weight(7) に
積分点と重みを書き込みます。mesh はこの入口を使い、三角形ごとの一時配列の確保・コピーを省きます。
積分計画を新しく構築する既存の build_panel_quadrature も、この計算を共有します。
mesh 更新では次のように要素 i の配列へ書き込みます。
call fill_panel_quadrature(panel, mesh%panel_quad_position(:, :, i), mesh%panel_quad_weight(:, i))積分対象から除外する細長い三角形も、衝突判定用の幾何情報は保持します。
Subsystem から実装と test へ移動する
Section titled “Subsystem から実装と test へ移動する”表の test は変更直後に使う直接 test です。必要な累積 gate は開発ワークフローで 選びます。
| Subsystem | 主な source | 直接 test | 正本・解説 |
|---|---|---|---|
| CLI、config、runtime resolution | app/main.f90、src/config/、src/runtime/configuration/ | test_app_config_parser.f90、test_physics_config_types.f90、tests/python/config/、tests/python/cli/test_config_commands.py、make test-config-contract | 設定を編集する、設定パラメータ |
| mesh、template、OBJ、panel geometry | src/mesh/ | test_templates_importers_runtime.f90、test_panel_geometry_near.f90、test_panel_moments.f90 | 設定レシピ、Direct |
| batch orchestration | src/runtime/simulator/bem_simulator*.f90 | test_simulator_loop.f90、test_simulator_failure_context.f90(停止時の診断文)、test_soft_discard.f90、test_particle_pool.f90(batch の生成と共有 pool)、test_dynamics_basic.f90 | SPEC.md、BEACH の計算サイクル |
| field snapshot、Direct / Treecode / FMM、periodic2 | src/physics/field_solver/ | test_electrostatic_snapshot.f90、test_dynamics_field_solver.f90、test_panel_kernel.f90、test_dynamics_fmm、test_periodic_zero_mode、test_periodic2_cached_snapshot、test_periodic2_adaptive_batch(adaptive batch) | 場の評価、FMM、periodic2 静電場 |
| particle source と injection | bem_app_config_particle_runtime.f90、src/particles/ | test_injection_sampling.f90、test_reservoir_injection.f90 | 粒子をどこから入れるか、境界から粒子を流入させる、光電子放出 |
| Boris、collision、box event | bem_particle_stepper.f90、bem_pusher.f90、bem_collision.f90、bem_boundary.f90 | test_particle_stepper.f90、test_boundary.f90、test_dynamics_basic | 粒子更新、Boris、粒子 event |
| surface charge、closure、ledger | bem_surface_models*.f90、src/physics/sheath/、src/runtime/sheath/、bem_simulator_charge.f90、bem_charge_ledger.f90 | test_surface_models.f90、test_surface_current_model.f90、test_charge_ledger.f90、test_surface_charge_closure.f90、test_zhao_outflow_refresh.f90 | 表面はどう帯電するか、表面電荷更新の数値仕様、Zhao closure |
| stats、output、checkpoint、restart | bem_simulator_stats.f90、bem_simulator_io.f90、bem_output_writer.f90、bem_periodic_checkpoint.f90、bem_restart.f90 | test_output_writer_io.f90、test_restart.f90 | 出力ガイド、実行と再開、SPEC.md の出力・再開契約 |
| Python reader、解析、可視化 | beach/io/(reader、numpy のみ)、beach/native/(ctypes kernel)、beach/analysis/、beach/plot/(matplotlib)、beach/facade.py(Beach) | tests/python/io/、test_import_layers.py(層の依存方向)、test_beach_session.py(Beach の kernel cache と委譲 signature)、対応する CLI / analysis test | 後処理チュートリアル、Python API |
module 名や use 依存を検索するときは、自動生成した
Fortran 依存関係マップとFortran APIを使います。
依存関係マップは source inventory であり、runtime の呼出順、state ownership、behavioral contract の正本ではありません。
正本の責務を区別する
Section titled “正本の責務を区別する”| 情報 | 正本 | guide / reference の責務 |
|---|---|---|
| 現行 simulation behavior と model scope | Fortran 実装と SPEC.md | model / numerical-method page は理由、式、適用範囲、検証方法を説明する |
| 公開 TOML の table、key、型、構造制約 | schemas/beach.schema.json と Python lint。派生値・参照解決・モデル成立条件は Fortran | Parameters.md / .en.md は検索可能な人間向け reference、Configuration は編集手順を示す |
| output file の生成条件 | schemas/beach.output-manifest.json と Fortran writer | OutputGuide は column の意味、確認順、restart での役割を説明する |
| checkpoint compatibility | checkpoint contract、mesh identity、writer / loader、SPEC.md | Execution は安全な再開手順を示す |
| test target と tier | fpm.toml と Makefile | Workflow は変更範囲から実行すべき target へ案内する |
| site の page inventory と sidebar | docs-site/navigation.json | docs/*.md と .en.md が編集する source で、docs-site/src/content/docs/ は生成物 |
| module / procedure API と依存 | Fortran source、生成した FORD API、FortranDependencyMap | Architecture は人が読む実行フローと subsystem 境界だけを維持する |
tutorial、task guide、example は正本の契約を短く適用する入口です。そこへ全 parameter や全分岐を複製せず、 該当する reference または specification へリンクします。behavior、config、output を変更するときの同期対象は 公開契約を変更するときで確認してください。