solver モジュール

線形系の求解・Newton 法・疑似過渡継続を担当する。


モジュール構成

solver/
├── mod.rs               — サブモジュールの公開宣言
├── banded.rs            — 帯行列 LU 分解・求解
├── dense.rs             — 密行列 LU 分解・求解 (faer)
├── newton.rs            — 減衰 Newton 法(直線探索付き)
└── pseudo_transient.rs  — 疑似過渡継続 (PT)

banded.rs — 帯行列

BandedMatrix

LAPACK 互換の一般帯行列 (GB) 形式で係数行列を保持する。

格納レイアウト: data[col × ldab + (kl + ku + row − col)]

  • ldab = 2×kl + ku + 1(部分ピボッティングの fill-in 分の kl 行を余分に確保)
メソッド説明
BandedMatrix::new(n, kl, ku)n×n 帯行列を確保(全ゼロ初期化)
set(row, col, val)要素を書き込む
get(row, col)要素を読む
factor_in_place()部分ピボッティング付き帯 LU 分解を in-place で実施。ピボット行インデックスを ipiv に格納。計算量 O(n·kl·ku)
solve_factored(b)factor_in_place 済みの行列で A·x = b を解く(b を上書き)。前進代入 → 後退代入
solve(b)factor_in_place + solve_factored を一括実行

fill-in の扱い: ピボット行入れ替え後、行 k の非ゼロ範囲は k+ku+kl 列まで 拡張しうる。後退代入でも同じ幅を使用することで fill-in を正確に処理する。

テスト (3 テスト、全 PASS)

テスト名検証内容
test_banded_tridiagonal_solve5×5 三重対角系 (kl=ku=1)。厳密解 [5,8,9,8,5]
test_banded_wider_band4×4 非対称帯行列 (kl=2, ku=1)。厳密解 [1,1,1,1]
test_banded_pivoting_requiredA[0][0]=0 でピボッティング必須な 3×3 系。厳密解 [1,2,2]

dense.rs — 密行列

DenseMatrix

faer の部分ピボッティング LU で n×n 密行列を求解する。

帯行列では帯外に落ちる質量流束 M 列(解ベクトル末尾、全残差に結合)を 正確に扱うために使用する。

メソッド説明
DenseMatrix::new(n)n×n ゼロ行列を確保
set(row, col, val)要素を書き込む
get(row, col)要素を読む
solve(b)faer の partial_piv_lu().solve() で A·x = b を解く(b を上書き)

テスト (2 テスト、全 PASS)

テスト名検証内容
test_dense_tridiagonal_solve5×5 三重対角系。厳密解 [5,8,9,8,5]
test_dense_with_global_coupling最終列が全行に結合する 4×4 系(M 変数の模擬)。厳密解 [0.75,0.75,0.75,1.5]

newton.rs — 減衰 Newton 法

アルゴリズム概要

for iter in 0..max_iter:
    評価: F(x)
    収束判定: ‖F‖ < atol·√n + rtol·‖x‖
    Jacobian: (J_int, m_col, jfc) = numerical_jacobian(x, F)  ← 最大 max_jac_age 反復再利用
    線形系:   枠付き帯行列系を bordered_solve_m で解く
                δx_int = J_int⁻¹(-F_int + F_M / (jfc - m_col·J_int⁻¹·e_M) × m_col)
                δM    = シュア補完で決定
    ステップクリップ: 物理スケール上限を超える成分を縮小
    直線探索: α を 1 から 0.5 刻みで最大 12 回試行
    更新:     x ← x + α·step
    物理クランプ: T, Y, M を有効範囲に制限
    失速検出: best ‖F‖ が 1% 以上改善しない反復が max_stall_iter 回続いたら受理

帯行列 + 枠付きシュア補完方式: numerical_jacobian が返す (n-1)×(n-1) 帯行列 J_int、 M 列ベクトル m_col、M 行ベクトル jfc を使って bordered_solve_m が 1 回の帯 LU で δM を含む完全な Newton ステップを求める。密 Jacobian 不要で O(n·kl) のコスト。

NewtonConfig

フィールドデフォルト説明
atol1e-9絶対収束許容値
rtol1e-6相対収束許容値
max_iter50最大反復回数
max_jac_age3Jacobian の再利用上限反復数
max_stall_iter5失速と判定するまでの反復数

Jacobian の強制再計算: ‖F‖ が前回評価時から 10 倍以上改善した場合、 線形化点が大きく変わったとみなして jac_age をリセットする。

ステップクリップ (step_clip_factor)

変数最大変化量
T (温度)500 K
Yk (質量分率)0.5
M (質量流束)2 × max(

物理クランプ (clamp_physical)

変数有効範囲
T[1, 10000] K
Yk[0, 1]
M(0, ∞) (下限 1e-6)

テスト (2 テスト、全 PASS)

テスト名検証内容
test_newton_converges_immediately_at_zero_residual‖F‖ ≈ 0 の一様 N2 プロファイルで iter 0 に収束すること
test_newton_scaled_convergence_criterion‖F‖ < atol·√n + rtol·‖x‖ が一様解で成立すること

pseudo_transient.rs — 疑似過渡継続

目的

Newton 法の収束域外(点火前の急勾配・スティッフ化学反応領域)から Newton 域へ 誘導する。TWOPNT スタイルの後退オイラー法を採用。

アルゴリズム概要

for step in 0..n_steps:
    評価: F_steady(x)
    ‖F_steady‖ < 1e7 → Newton 域に達したので終了
    dt < 1e-13 → 収束断念して Newton へ

    rdt = 1/dt
    x_old = x

    内側 Newton (max_inner_iter 回):
        F_pt(x) = F_steady(x) + D/dt·(x − x_old)
        J_pt    = J_steady(x) + D/dt の対角(ρ·cp で T、ρ で Yk、1 で M)
        M 列をゼロクリア(M の疑似時間項は対角のみ)
        step = −J_pt⁻¹·F_pt
        ステップクリップ + 直線探索 + 物理クランプ

    外側受理: ‖F_steady(x_new)‖ ≤ 1.1×‖F_steady(x_old)‖
        成功 → dt *= dt_grow (最大 dt_max まで)
        失敗 → x = x_old, dt *= 0.5; 30 回連続失敗で中断

PseudoTransientConfig

フィールドデフォルト説明
n_steps300最大外側ステップ数
dt_initial1e-7初期タイムステップ [s]
dt_max1e-3タイムステップ上限 [s]
dt_grow1.5成功後のタイムステップ成長係数
max_inner_iter5内側 Newton の最大反復数

設計上の注意

直線探索の初期化: 内側直線探索の best_norm を ∞ で初期化することで、 J_pt が不定値(D/dt < |λ_chem|)のとき全 α で F_pt が増加しても α = 0 に停滞しない。最小の有限 F_pt を与える α を返す。

外側受理の 10% マージン: 化学反応が非常に剛な点火フェーズでは、 良い内側 Newton ステップでも F_steady が一時的に増加することがある。 1.1 倍の許容マージンにより探索的なステップを通過させ、Newton 域への 到達を可能にする。

D/dt 対角: ρ·cp (T 方程式)、ρ (Yk 方程式)、1 (M) で各変数の 次元が整合した疑似時間スケーリングを実現する(residual.rs の PT 埋め込みと同一)。

テスト (2 テスト、全 PASS)

テスト名検証内容
test_pseudo_transient_reduces_residualT に小さな摂動を加えた N2 プロファイルに 5 ステップ適用し、T と M が物理的範囲内に収まること
test_pseudo_transient_preserves_steady_solution厳密定常解 (N2 均一) に 10 ステップ適用しても x が変化しないこと (max Δ < 1e-10)