qlat.inverter — Fermion-Matrix Inverter Framework¶
Source: qlat/qlat/inverter.py
Note: Update this document when updating the source file.
Outline¶
Overview¶
inverter provides a lightweight framework for applying the inverse of the
domain-wall Dirac operator to Prop (propagator) fields. All concrete
inverters share a common interface: multiplying an inverter by a source
propagator returns the solution propagator.
The module defines:
Inverter— empty base class establishing the interface convention.InverterDwfFreeField— analytic (free-field) inverse of the DWF operator; no gauge field is needed.InverterDomainWall— CG-based inversion backed by the C/C++ library; requires a gauge field and aFermionAction.InverterGaugeTransform— decorator that wraps anyInverter, applying a gauge transformation before and after inversion so that the result is in a different gauge.EigSystem— placeholder for future eigenvalue-system support.
All inverter classes support multiplication with a single Prop or a
list of Prop objects.
Inverter Base Class¶
class Inverter:
pass
Empty base class. All concrete inverters inherit from it and implement
__mul__ to apply the inverse Dirac operator.
InverterDwfFreeField Class¶
Analytically inverts the free (no gauge field) domain-wall Dirac operator. Useful for testing and as a reference solution.
Constructor¶
InverterDwfFreeField(*, mass, m5=1.0, momtwist=None, qtimer=TimerNone())
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
— |
Fermion mass |
|
|
|
Fifth-dimensional mass parameter |
|
|
|
Momentum twist (4-vector); defaults to zero |
|
|
|
Optional timer for profiling |
Methods¶
__mul__(prop_src) -> Prop¶
Apply the free-field inverse to a propagator source.
Parameter |
Type |
Description |
|---|---|---|
|
|
Source propagator(s) |
Returns the solution propagator, or a list of solution propagators if
prop_src is a list.
InverterDomainWall Class¶
CG-based domain-wall fermion inverter backed by the C/C++ library. Requires
a gauge field and a FermionAction specification.
Constructor¶
InverterDomainWall(*, gf, fa, qtimer=TimerNone())
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
— |
Gauge field configuration |
|
|
— |
Fermion action parameters (mass, Ls, m5, etc.) |
|
|
|
Optional timer for profiling |
Methods¶
__mul__(prop_src) -> Prop¶
Apply the domain-wall inverse to a propagator source using CG iteration.
Parameter |
Type |
Description |
|---|---|---|
|
|
Source propagator(s) |
Returns the solution propagator, or a list of solution propagators.
Solver Parameters¶
stop_rsd() -> float¶
Return the current stopping residual for the CG solver.
set_stop_rsd(stop_rsd) -> None¶
Set the stopping residual for the CG solver.
max_num_iter() -> int¶
Return the maximum number of CG iterations.
set_max_num_iter(max_num_iter) -> None¶
Set the maximum number of CG iterations.
max_mixed_precision_cycle() -> int¶
Return the maximum number of mixed-precision refinement cycles.
set_max_mixed_precision_cycle(max_mixed_precision_cycle) -> None¶
Set the maximum number of mixed-precision refinement cycles.
InverterGaugeTransform Class¶
Decorator inverter that wraps any Inverter with gauge transformations.
Given a gauge transform gt, it computes gt_inv * src, inverts using the
wrapped inverter, then applies gt * sol so the result is in the
transformed gauge.
Constructor¶
InverterGaugeTransform(*, inverter, gt, qtimer=TimerNone())
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
— |
Inner inverter to wrap |
|
|
— |
Gauge transformation to apply |
|
|
|
Optional timer for profiling |
Methods¶
__mul__(prop_src) -> Prop | FermionField4d¶
Apply the gauge-transformed inversion: gt * (inverter * (gt_inv * src)).
Parameter |
Type |
Description |
|---|---|---|
|
|
Source field(s) |
Returns the solution in the transformed gauge.
EigSystem Class¶
class EigSystem:
pass
Placeholder class for future eigenvalue-system support. Currently empty.
Module-Level Cache¶
cache_inv = mk_cache("inv")
A module-level cache created via mk_cache("inv"). Used internally to
store and reuse intermediate inversion results.
Examples¶
Free-Field vs. Domain-Wall Inversion¶
import qlat as q
size_node_list = [
[1, 1, 1, 1],
]
q.begin_with_mpi(size_node_list)
total_site = q.Coordinate([4, 4, 4, 8])
geo = q.Geometry(total_site)
rs = q.RngState("seed")
gf = q.GaugeField(geo)
gf.set_unit()
fa = q.FermionAction(mass=0.05, ls=16, m5=1.0)
qinv_free = q.InverterDwfFreeField(
mass=fa.mass(), m5=fa.m5(), qtimer=q.Timer("InverterDwfFreeField")
)
qinv_dwf = q.InverterDomainWall(
gf=gf, fa=fa, qtimer=q.Timer("InverterDomainWall")
)
src = q.Prop(geo)
src.set_rand(rs.split("src"))
sol_free = qinv_free * src
sol_dwf = qinv_dwf * src
sol_diff = sol_dwf.copy()
sol_diff -= sol_free
print(f"free sol qnorm = {sol_free.qnorm():.6E}")
print(f"dwf sol qnorm = {sol_dwf.qnorm():.6E}")
print(f"diff sol qnorm = {sol_diff.qnorm():.3E}")
q.end_with_mpi()
Gauge-Transformed Inversion¶
import qlat as q
size_node_list = [
[1, 1, 1, 1],
]
q.begin_with_mpi(size_node_list)
total_site = q.Coordinate([4, 4, 4, 8])
geo = q.Geometry(total_site)
rs = q.RngState("gfix-test")
gf = q.GaugeField(geo)
gf.set_rand(rs.split("gf"), 0.05, 2)
fa = q.FermionAction(mass=0.1, ls=8, m5=1.0)
gt = q.GaugeTransform(geo)
gt.set_rand(rs.split("gt"), 0.1, 1)
gf_gfix = gt * gf
inv = q.InverterDomainWall(gf=gf_gfix, fa=fa, qtimer=q.Timer("inv"))
inv_gt = q.InverterGaugeTransform(
inverter=q.InverterDomainWall(gf=gf, fa=fa, qtimer=q.Timer("inv-inner")),
gt=gt,
qtimer=q.Timer("inv-gt"),
)
src = q.Prop(geo)
src.set_rand(rs.split("src"))
sol = inv * src
sol_gt = inv_gt * src
print(f"sol qnorm = {sol.qnorm():.6E}")
print(f"sol_gt qnorm = {sol_gt.qnorm():.6E}")
q.end_with_mpi()
Inverting a List of Sources¶
import qlat as q
size_node_list = [
[1, 1, 1, 1],
]
q.begin_with_mpi(size_node_list)
total_site = q.Coordinate([4, 4, 4, 8])
geo = q.Geometry(total_site)
rs = q.RngState("list-test")
gf = q.GaugeField(geo)
gf.set_unit()
fa = q.FermionAction(mass=0.05, ls=16, m5=1.0)
qinv = q.InverterDomainWall(gf=gf, fa=fa)
sources = []
for i in range(3):
src = q.Prop(geo)
src.set_rand(rs.split(f"src-{i}"))
sources.append(src)
solutions = qinv * sources
for i, sol in enumerate(solutions):
print(f"solution[{i}] qnorm = {sol.qnorm():.6E}")
q.end_with_mpi()