Skip to content
Leon Hostetler edited this page Apr 22, 2025 · 8 revisions

To compute gauge observables in QUDA, start by creating a QudaGaugeObservableParam object:

param = newQudaGaugeObservableParam();

With this struct, you can set various booleans to compute gauge observables such as plaquette, rectangle, Polyakov loop, topological charge, and topological charge density. You can also compute traces of custom gauge loops by providing arrays for the paths and path lengths. The observables are computed by calling:

gaugeObservables(gauge, param);

where gauge is the input gauge field. The results are then accessed via the relevant param member variables. For example, the plaquette average, the purely spatial average, and the purely temporal average would be given respectively by param.plaquette[0] , param.plaquette[1], and param.plaquette[2].

Plaquette and Rectangle

The Wilson plaquette action is defined as the averaged sum of the real part of the trace of all 1x1 plaquettes, and a plaquette U_{mu,nu}(x) is an ordered and oriented product of gauge links U_{mu}(x) defined at a lattice point x.

          x+nu--<--x+mu+nu
            |        |
            v        ^
            |        |
C_{mu}(x) = x--->---x+mu

Computing this number is a simple matter of creating a QudaGaugeObservableParam object as described above, and setting param.compute_plaquette = QUDA_BOOLEAN_TRUE. After the call to gaugeObservables, the values can be accessed as:

double plaq = param.plaquette[0]; //Plaquette average
double plaqs = param.plaquette[1]; //Purely spatial plaquette average
double plaqt = param.plaquette[2]; //Purely temporal plaquette average

If one is interested only in the plaquette and no other gauge observables, then instead of creating a QudaGaugeObservableParam object and calling gaugeObservables, one can alternatively call the QUDA interface function:

void plaqQuda(double plaq[3]);

Then plaq[0], plaq[1], and plaq[2] will be populated with the plaquette average, the purely spatial average, and the purely temporal average, respectively.

The rectangle observable is analogous to the plaquette, but now for all $1\times 2$ and $2\times 1$ rectangles. The rectangle and the clover action can be used to reconstruct certain "improved" observables. The rectangle observable is enabled by setting param.compute_rectangle = QUDA_BOOLEAN_TRUE. After the call to gaugeObservables, the rectangle average, the purely spatial average, and the purely temporal average are accessed via param.rectangle[0], param.rectangle[1], and param.rectangle[2].

Clover Energy

On the lattice, a convenient definition of the field strength tensor $F_{\mu\nu}(x)$ at a point $x$ involves the sum of the four plaquettes in the $\mu\nu$ plane that touch the lattice site $x$.

F_{mu,nu}(x) = 1/8[U_{mu,nu}(x)+U_{mu,nu}(x-mu)+U_{mu,nu}(x-nu)+U_{mu,nu}(x-mu-nu) -
                   (U_{mu,nu}^dag(x)+U_{mu,nu}^dag(x-mu)+U_{mu,nu}^dag(x-nu)+U_{mu,nu}^dag(x-mu-nu))]

Visually, the four plaquettes form a 4-leaf clover shape, hence the name given to this construction. Adding a term involving $F_{\mu\nu}$ to the Wilson plaquette action leads to the improved Clover action. The real trace of $F_{\mu\nu}F^{\mu\nu}$ gives the clover energy.

To compute the clover energy in QUDA, enable the topological charge (param.compute_qcharge = QUDA_BOOLEAN_TRUE) and/or charge density (param.compute_qcharge_density = QUDA_BOOLEAN_TRUE) computation. This triggers the computation of F_{mu,nu}(x) and the clover energy in addition to the topological charge and/or charge density. After the call to gaugeObservables, the total, spatial, and temporal clover energies are accessed via param.energy[0], param.energy[1], and param.energy[2].

Topological Charge and Density

One can define a topological charge for the lattice as:

Q(x) = 1/(32*pi*pi) * (Re Tr[F_{1,0}(x) - F_{3,2}(x)] + Re Tr[F_{3,0}(x) - F_{2,1}(x)] - Re Tr[F_{2,0}(x) - F_{3,1}(x)])

where F_{mu,nu}(x) is described above in the section on clover energy.

To enable the topological charge computation, set param.compute_qcharge = QUDA_BOOLEAN_TRUE. After the call to gaugeObservables, the topological charge is given by param.qcharge.

To compute the topological charge density, set param.compute_qcharge_density = QUDA_BOOLEAN_TRUE. You also need to allocate a host array of length volume, and point the param.qcharge_density to this array. After the call to gaugeObservables, the array will be populated with $Q(x)$, the topological charge at each lattice site. This can be useful for eta prime computations.

Polyakov Loop

The Polyakov loop is a Wilson loop that goes around the full temporal extent of the lattice. It is an order parameter for confinement.

To compute the Polyakov loop, set param.compute_polyakov_loop = QUDA_BOOLEAN_TRUE. After the call to gaugeObservables, the real and imaginary parts of the Polyakov loop are accessed via param.ploop[0] and param.ploop[1].

Custom Gauge Loop Traces

In addition to the plaquette, rectangle, clover, and Polakov loop, one can also compute the trace of custom gauge loops by setting the following members of param:

QudaBoolean compute_gauge_loop_trace; /**< Whether to compute gauge loop traces */
double_complex *traces;               /**< Individual complex traces of each loop */
int **input_path_buff;                /**< Array of paths */
int *path_length;                     /**< Length of each path */
double *loop_coeff;                   /**< Multiplicative factor for each loop */
int num_paths;                        /**< Total number of paths */
int max_length;                       /**< Maximum length of any path */

For an example of this in action, see tests/gauge_path_test.cpp.

Clone this wiki locally