HILA
Loading...
Searching...
No Matches
degauss.h
1#ifndef DEGAUSS_H_
2#define DEGAUSS_H_
3
4#include "hila.h"
5
6/////////////////////////////////////////////////////////////////////////////
7/// Remove Gauss' law violation from a gauge field + E-field - assuming no charged
8/// fields
9/// Call:
10/// degauss( const GaugeField<grp> &U, VectorField<Algebra<grp>> &E, double tolerance);
11/// tolerance is the max violation / site
12// Gauss' law violation is
13//
14// G^a(x) = D_i E_i^a
15//
16// Restoration is done by evolving the fields 'downhill' towards
17// G == 0
18
19
20template <typename group>
21void get_gauss_violation(const GaugeField<group> &U,
23 Field<Algebra<group>> &gauss) {
24
25
26 // Measure Gauss
27 gauss = 0;
28 foralldir(d) {
29 gauss[ALL] +=
30 E[d][X] - (U[d][X - d].dagger() * E[d][X - d].expand() * U[d][X - d])
31 .project_to_algebra();
32 }
33}
34
35
36template <typename group>
37void gauss_fix_step(const GaugeField<group> &U, VectorField<Algebra<group>> &E,
38 const Field<Algebra<group>> &violation,
39 const hila::arithmetic_type<group> mag) {
40
41 foralldir(dir) {
42 onsites(ALL) {
43 // get violation from "up"
44 auto ta = (U[dir][X] * violation[X + dir].expand() * U[dir][X].dagger())
45 .project_to_algebra();
46 E[dir][X] -= mag * (violation[X] - ta);
47 }
48 }
49}
50
51
52template <typename group>
53auto degauss_step(const GaugeField<group> &U, VectorField<Algebra<group>> &E) {
54
55 Field<Algebra<group>> violation;
56
57 // Use here the trick of 2 step sizes, the smaller one guarantees
58 // that the UV is stable and the larger one makes gradient flow
59 // faster.
60
61 constexpr double aleph = 1.25;
62 constexpr hila::arithmetic_type<group> onealeph = aleph / 12.0;
63 constexpr hila::arithmetic_type<group> twoaleph = 2.0 * onealeph;
64
65 // Now what's the initial violation
66 get_gauss_violation(U, E, violation);
67 // Apply as a correction
68 gauss_fix_step(U, E, violation, onealeph);
69
70 // and repeat with twoaleph
71 get_gauss_violation(U, E, violation);
72 gauss_fix_step(U, E, violation, twoaleph);
73
74 // we return not the last violation, thus the real violation
75 // should be smaller than this
76 // Return violation per site
77 return violation.squarenorm() / lattice.volume();
78}
79
80
81/////////////////////////////////////////////////////////////////////
82/// De-Gauss the gauge + E(momenta) -system. quality is the violation/site
83///
84template <typename group>
85int degauss(const GaugeField<group> &U, VectorField<Algebra<group>> &E,
86 double quality) {
87
88 constexpr int loop_max = 10000;
89 double viol;
90 int loop;
91
92 static hila::timer degauss_timer("Degauss");
93
94 /* loop over Degauss_step until violation small enough */
95
96 degauss_timer.start();
97
98 loop = 0;
99 do {
100 loop++;
101 viol = degauss_step(U, E);
102 } while (viol > quality && loop <= loop_max);
103
104 if (loop > loop_max && hila::myrank() == 0) {
105 hila::out << " ********** LOOP_MAX " << loop_max
106 << " reached in degauss, violation/site " << viol << '\n';
107 }
108
109 degauss_timer.stop();
110
111 return loop;
112}
113
114
115#endif
Definition su2.h:7
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
Definition field.h:61
double squarenorm() const
Squarenorm.
Definition field.h:1120
Gauge field class.
Definition gaugefield.h:22
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:78
constexpr Parity ALL
bit pattern: 011
int myrank()
rank of this node
Definition com_mpi.cpp:235
std::ostream out
this is our default output file stream