Matrix-free `getDiagonal` returns 1 on EquationBC rows

オープン
#5,641 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
半日
初心者へのやさしさ
62/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
backend

調査の方向性

The bug is in ImplicitMatrixContext.getDiagonal, which calls bc.set(diagonal, 1) for every bc, including EquationBCSplit. Run the reproduction script in the issue and compare the matfree and aij diagonals on ebc.nodes. Then read how the aij path handles EquationBC rows and check tests/firedrake/multigrid/test_equation_bc.py. Done when the matfree diagonal matches aij on EquationBC rows and the nested test takes 8 and 9 iterations with matfree.

索引モデルが issue の本文から書いたものです。

説明

For an operator with an EquationBC, getDiagonal of the matrix-free operator returns 1 on every EquationBC row that is not a nested DirichletBC row. The aij matrix has the diagonal of the EquationBC form on these rows. All other rows agree, also the rows of a DirichletBC nested in the EquationBC.

from firedrake import *

mesh = UnitSquareMesh(8, 8)
V = FunctionSpace(mesh, "CG", 2)
u, v = TrialFunction(V), TestFunction(V)
a = inner(grad(u), grad(v)) * dx
e2 = as_vector([0, 1])
a1 = (-inner(dot(grad(u), e2), dot(e2, grad(v))) + 4 * pi**2 * inner(u, v)) * ds(1)
corners = DirichletBC(V, 0, ((1, 3), (1, 4)))

for nested in ([], [corners]):
    ebc = EquationBC(a1 == inner(Constant(0), v) * ds(1), Function(V), 1, bcs=nested).extract_form("J")
    A = assemble(a, bcs=[ebc], mat_type="aij").petscmat
    M = assemble(a, bcs=[ebc], mat_type="matfree").petscmat
    dA, dM = A.getDiagonal(), M.getDiagonal()
    print("aij", dA.array[ebc.nodes[:4]], "matfree", dM.array[ebc.nodes[:4]])

prints

aij [-40.03477216 -36.01738608 -18.00869304 -40.03477216] matfree [1. 1. 1. 1.]
aij [-40.03477216 -36.01738608   1.         -40.03477216] matfree [1. 1. 1. 1.]

ImplicitMatrixContext.getDiagonal assembles the diagonal of the form without the bcs and then calls bc.set(diagonal, 1) for every bc, also for an EquationBCSplit.

This changes the convergence of Jacobi with a matrix-free preconditioning matrix. The converged solution is the same. For example, test_nested_equation_bc in tests/firedrake/multigrid/test_equation_bc.py with mat_type: matfree and the coarse level through AssembledPC takes 22 Krylov iterations instead of 8 in 2D and 15 instead of 9 in 3D. With pmat_type: aij it takes 8 and 9 again.

I see this on release and on main. getDiagonal has been like this since it was added in 2019. An LLM (Claude Code) found this while I was digging into #5609 and the redesign discussion on #5620. G-ADOPT does not use this path but I am flagging it anyway.

主要言語
Python
スター
684
フォーク
204
平均マージ
4日 14時間
マージ済み PR(30日)
46

環境構築

  • Dockerfile・Docker Compose ファイルなし
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

firedrakeproject/firedrake のほかの issue

firedrakeproject/firedrake の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。